Дополнительные задачи программирования
В этой главе Вы узнаете о других функциях, таких как события DVD и закладки, и как отладить Ваш код приложения.
Регистрация для событий DVD
Когда важные изменения состояния происходят, DVD Playback Services определяет ряд событий DVD для уведомления приложения. Ответ на эти события является дополнительным. Как правило, однако, необходимо разработать приложение, чтобы реагировать на события, а не опросить относительно изменений состояния.
Для получения событий DVD необходимо зарегистрировать одну или более функций обратного вызова события. Для регистрации обратного вызова события Вы вызываете DVDRegisterEventCallBack
функция, передающая в указателе на обратный вызов и список событий обратный вызов, должна получить. Функция пасует назад регистрационный номер, который необходимо будет использовать, когда Вы не зарегистрируете обратный вызов.
Перечисление 3-1 показывает, как зарегистрировать обратный вызов для получения нескольких мероприятий.
Перечисление 3-1 , Регистрирующее обработчик событий DVD
DVDEventCode eventCodes[] = { |
kDVDEventAngle, |
kDVDEventDisplayMode, |
kDVDEventError, |
kDVDEventPlayback, |
kDVDEventPTT, |
kDVDEventTitle, |
kDVDEventTitleTime, |
kDVDEventVideoStandard, |
}; // 1 |
OSStatus err = DVDRegisterEventCallBack ( |
MyDVDEventHandler, |
eventCodes, |
sizeof(eventCodes)/sizeof(DVDEventCode), |
(UInt32)self, |
&mEventCallBackID); // 2 |
Вот то, что делает этот код:
Создает массив событий, которые получит наш обратный вызов.
Регистрирует наш обратный вызов для получения этих событий.
DVDRegisterEventCallBack
пасует назад регистрационный номер, который необходим позже, чтобы не зарегистрировать обратный вызов; посмотрите Окончание Сеанса Воспроизведения.
DVD Playback Services вызывает Вашу функцию обратного вызова события DVD в потоке кроме основного потока Вашего приложения. Ваш ответ на событие DVD мог бы включать операции рисования, которые должны выполниться в основном потоке. Чтобы гарантировать, что Ваш код обработки событий выполняется безопасно, Ваша функция обратного вызова может передать информацию о событии методу, который, как гарантируют, выполнится в основном потоке. Перечисление 3-2 показывает, как сделать это в приложении Какао.
Перечисление 3-2 , Разъединяющее событие DVD от потока обратного вызова
void MyDVDEventHandler ( |
DVDEventCode inEventCode, |
UInt32 inEventData1, |
UInt32 inEventData2, |
UInt32 inRefCon |
) |
{ |
Controller *controller = (Controller *)inRefCon; |
DVDEvent *dvdEvent = [[DVDEvent alloc] initWithData:inEventCode |
data1:inEventData1 |
data2:inEventData2]; // 1 |
[controller performSelectorOnMainThread:@selector(handleDVDEvent:) |
withObject:dvdEvent |
waitUntilDone:FALSE]; // 2 |
[dvdEvent release]; // 3 |
} |
Вот то, что делает этот код:
Создает объект, инкапсулирующий информацию о событии DVD. Класс для этого объекта определяется в проекте CocoaDVDPlayer.
Передает объект нашему методу обработки событий, выполняющемуся асинхронно в основном потоке.
Объект сохраняется в нашем обработчике событий, таким образом, безопасно выпустить его здесь.
Корректировка аудиовыхода
DVDSetAudioVolume
функция корректирует объем аудиовыхода или уровень во время воспроизведения. Эта функция берет отдельный аргумент, целое число, которое может колебаться от 0 до 255. Значение 0 не представляет вывода, и значение 255 представляет объем аудиовыхода существующей системы. Оба стереоканала используют ту же установку.
Много мультимедийных приложений обеспечивают управление ползунком для корректировки аудиовыхода. Для пользователей, хотящих использовать клавиатуру вместо мыши для работы этим управлением, необходимо также обеспечить способ изменить объем аудиовыхода в инкрементах. Перечисление 3-3 показывает, как реализовать функцию, корректирующую громкость с помощью инкрементов 16. Эта функция берет отдельный аргумент, представляющий направление изменения (или вниз).
Перечисление 3-3 , Регулирующее громкость аудиовыхода DVD
- (UInt16) setAudioVolume:(BOOL)up |
{ |
UInt16 minLevel, curLevel, maxLevel; |
OSStatus err = DVDGetAudioVolumeInfo (&minLevel, &curLevel, &maxLevel); // 1 |
UInt16 newLevel = curLevel; |
UInt16 delta = (maxLevel - minLevel + 1) / 16; // 2 |
if (up) { // 3 |
newLevel = MIN(curLevel + delta, maxLevel); |
} |
else { |
newLevel = MAX(curLevel - delta, minLevel); |
} |
err = DVDSetAudioVolume (newLevel); // 4 |
return newLevel; // 5 |
} |
Вот то, что делает этот код:
Получает текущие параметры звука. Минимальные и максимальные уровни 0 и 255.
Вычисляет размер каждого инкремента. В этом примере инкремент является 256/16 = 16.
Вычисляет новый параметр звука, фиксируя результат при необходимости.
Устанавливает громкость.
Возвращает новую установку; вызывающая сторона использует это значение для корректировки ползунка.
Используя закладки
Закладки являются объектами, указывающими текущую позицию носителей во время воспроизведения. Вы ответственны за выделение и управление памятью, необходимой при создании закладки. Прежде, чем попытаться создать закладку, носители должны быть открыты и играть.
Создание закладки является трехступенчатым процессом:
Определите размер закладки. Вы делаете это путем вызова
DVDGetBookmark
функция, не предоставляя указатель ни на какую память закладки.Используйте
malloc
функция для выделения памяти для новой закладки. Вы не должны инициализировать содержание памяти.Вызвать
DVDGetBookmark
во второй раз для создания закладки, передающей в указателе на недавно выделенную память. Вы ответственны за выпуск памяти, когда Вы закончены с помощью него.
Для использования закладки для возврата к кадру и воспроизведению резюме необходимо вызвать функцию удобства DVDGotoBookmark
. Прежде, чем вызвать эту функцию, носители должны быть открыты, но не обязательно играть.
Перечисление 3-4 показывает, как записать простой класс закладки.
Перечисление 3-4 простой класс закладки
@interface Bookmark : NSObject { |
void * data; |
UInt32 size; |
} |
- (void) gotoBookmark; |
@end |
@implementation Bookmark |
- (id) init { |
self = [super init]; |
if (self) { |
data = NULL; |
size = 0; |
OSStatus err = DVDGetBookmark (NULL, &size); // 1 |
data = malloc (size); // 2 |
err = DVDGetBookmark (data, &size); // 3 |
} |
return self; |
} |
- (void) gotoBookmark { |
OSStatus err = DVDGotoBookmark (data, size) //4; |
} |
- (void) dealloc { |
free (data); // 5 |
[super dealloc]; |
} |
@end |
Вот то, что делает этот код:
Получает размер закладки.
Выделяет память для данных закладки.
Создает закладку к текущему расположению воспроизведения.
Располагает носители в эту закладку и возобновляет воспроизведение.
Освобождает память для этой закладки.
Используя идентификаторы носителей
Если Вы хотите сохранить закладку в файле для повторного использования в следующий раз, когда пользователь открывает носители, необходимо разработать способ связать закладку с папкой носителей, к которой это относится. DVD Playback Services может генерировать идентификатор носителей, который можно использовать в качестве ассоциативного ключа. Например, Вы могли использовать идентификатор носителей для именования файла, содержащего закладки для той папки носителей. Для получения идентификатора носителей для папки носителей, это в настоящее время открыто, Вы вызываете DVDGetMediaUniqueID
функция. Эта функция возвращает 8 массивов байтов, которые можно преобразовать в строку шестнадцатеричных символов.
Перечисление 3-5 показывает, как получить и вывести на экран идентификатор носителей.
Перечисление 3-5 , Выводящее на экран идентификатор носителей
DVDDiscID id; |
DVDGetMediaUniqueID (id); |
NSLog(@"Media ID: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", |
id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7]); |
Обновление области DVD-привода
Код области является целым числом, идентифицирующим маркетинговую область для Видео DVD носителей. Страны мира были сгруппированы в различные области для размещения образцов выпуска фильмов крупнейшими киностудиями. Видеодиски DVD обычно присваиваются один или больше этих кодов области, когда они произведены. Каждый DVD-привод совместим с единственной областью: областью 1 являются США и Канада, например, и областью 2 является Япония и Европа.
Для данного DVD-привода DVD Playback Services не будет играть Видеодиск DVD, если ни одна из его определяемых областей не будет соответствовать область, присвоенную диску. DVD Playback Services проверяет на соответствующий код области каждый раз, когда Вы открываете носители DVD. Соответствующие функции —DVDOpenMediaFile
иDVDOpenMediaVolume
— укажите несоответствие области путем возврата кода результата kDVDErrorMismatchedRegionCode
.
Если Вы пишете приложение, использующее DVD Playback Services, можно присвоить новый код области DVD-приводу в целях включения воспроизведения Видеодиска DVD, представленного на рынке для определенной области. Эта ситуация могла бы возникнуть каждый раз, когда приложение имеет открытый сеанс воспроизведения, и пользователь вставляет диск, не соответствующий регион диска. Эта функция хитра для реализации правильно, однако, и DVD-плеер Apple уже программируется для обработки изменений региона диска. Если Ваше приложение встречается с несоответствием области во время воспроизведения, рекомендуемая процедура должна закрыть сеанс и направить пользователя для запуска DVD-плеера.
Если Вы решаете использовать DVD Playback Services для изменения области DVD-привода:
Необходимо обеспечить объект авторизации от пользователя с правами администратора. Для получения дополнительной информации см. Руководство по программированию Authorization Services.
Знайте, что присвоения кода области могут быть сделаны максимумом только пяти раз на диск. Это ограничение встроено в аппаратные средства — после того, как пятое присвоение кода области, диск будет постоянно присвоен этой области и не сможет быть изменен.
Не создавайте пункт меню для изменения области. Не необходимо сделать пользователей, знающих об областях и кодах области, если нет фактически несоответствие области.
Отладка
Если Вы хотите отладить приложение, использующее DVD Playback Services во время выполнения, приложение должно соединиться с отладочной версией совместно используемой библиотеки в платформе воспроизведения DVD. Этот раздел объясняет, почему дело обстоит так и показывает, как заставить это произойти.
При запуске приложения с помощью отладчика XCode или с GDB непосредственно можно найти, что приложение завершается, когда это вызывает DVDInitialize
функционируйте для запуска сеанса воспроизведения. Это - средство защиты для защиты кода дешифрования в платформе. Для создания отладки возможной платформа воспроизведения DVD также содержит отладочную версию своей совместно используемой библиотеки. Отладочная версия не содержит код дешифрования, таким образом, это играет незашифрованные носители только. Диски DVD не всегда шифруются. Например, DVD, созданный с iDVD приложением, свободен от шифрования. Другая опция состоит в том, чтобы использовать диск DVD, это включено с книгой DVD Demystified Джима Тейлора.
Когда приложение запускается, динамический загрузчик, необходимо сконфигурировать среду так, чтобы dyld
связывает с отладочной версией воспроизведения DVD. Простое решение должно определить переменную окружения, заставляющую динамический загрузчик искать библиотеки с суффиксом _debug
. При отладке приложения из Окна терминала можно определить переменную окружения с помощью этой команды:
export DYLD_IMAGE_SUFFIX=_debug |
При использовании отладчика XCode рисунок 3-1 показывает, как использовать исполнимое окно инспектора для определения этой переменной окружения:
Возможный недостаток этого решения - то, что оно заставляет динамический загрузчик загружать отладочные версии других системных платформ также. При использовании отладчика XCode это может не вмешаться в сеанс отладки. При использовании GDB в Окне терминала дополнительные сообщения журнала могут быть недовольными. Чтобы изучить, как загрузить отладочную версию воспроизведения DVD, не загружая другие библиотеки отладки, посмотрите Техническое примечание ADC TN2124.
Используя коды результата
Почти все функции в DVD Playback Services возвращают код результата, указывающий, успешно выполнилась ли функция или отказавший. Необходимо записать код для получения этих кодов результата, даже если приложение не всегда проверяет их. Путем получения этих кодов можно исследовать состояние каждого вызова функции при отладке.