VFW API
Имена многих функций VFW API начинаются с букв AVI. Другие функции (например, относящиеся к сжатию) начинаются с IC. Существуют некоторые исключения, но большинство функций VFW снабжается одним из этих префиксов. Алфавитный список всех функций VFW приведен в табл. 8.1.
Таблица 8.1. Функции VFW
AVIBuildFilter() AVICLearClipboard() AVIFileAddRef() AVIFileCreateStream() AVIFileEndRecord() AVIFileExit() AVIFileGetStream() AVIFileInfo() AVIFileInit() AVIFileOpen() AVIFileReadData() AVIFileRelease() AVIFileWriteData() AVIGetFromClipboard() AVIMakeCompressedStream() AVIMakeFileFromStream() AVIMakeStreamFromClipboard() AVIPutFileOnClipboard() AVISave() AVISaveOptions() AVISaveOptionsFree() AVISaveV() AVIStreamAddRef() AVIStreamBeginStreaming() AVIStreamCreate() AVIStreamEndStreaming() AVIStreamCreate() AVIStreamEndStreaming() AVIStreamFindSample() AVIStreamGetFrame() AVIStreamGetFrameClose() AVIStreamGetFrameOpen() AVIStreamInfo() AVIStreamLength() AVIStreamOpenFromFile() AVIStreamRead() AVIStreamReadData() AVIStreamReadFormat() AVIStreamRelease() AVIStreamSampleToTime() AVIStreamSetFormat() AVIStreamStart() AVIStreamTimeToSample() AVIStreamWrite() AVIStreamWriteData() CreateEditableStream() EditStreamClone() EditStreamCopy() EditStreamCut() EditStreamPaste() EditStreamSetInfo() EditStreamSetName() ICClose() ICCompress() ICCompressorChoose() ICCompressorFree() ICDecompress() ICDecompressEx() ICDecompressExBegin() ICDecompressExQuery() ICDraw() ICDrawBegin() ICDrawSuggestFormat() ICGetInfo() ICGetDisplayFormat() ICImageCompress() ICImageDecompress() ICInfo() ICInstall() ICLocate() ICOpen() ICOpenFunction() ICRemove() ICSendMessage() ICSeqCompressFrame() ICCompressFrameEnd() ICCompressFrameStart() ICGetStatusProc() MyStatusProc() |
Конечно, для воспроизведения роликов нужна лишь небольшая часть функций VFW, но чтобы изменить или расширить возможности программы из этой главы, вам, скорее всего, понадобятся и другие функции. Давайте рассмотрим те функции, с которыми нам придется работать.
СОВЕТ
Не забудьте включить VFW в проект
Перед тем как пользоваться функциями Video For Windows, необходимо включить в проект заголовочный файл vfw.h и добавить vfw32.lib в список файлов компоновщика.
Для правильной работы функций из табл. 8.1 необходимо инициализировать VFW функцией AVIFileInit(). Эта функция не получает аргументов и не возвращает никакого значения, поэтому работать с ней проще простого.
После инициализации VFW можно создавать поток функцией AVIStreamOpenFromFile(). Эта функция получает в одном из аргументов имя AVI-файла и инициализирует по нему логический номер потока. Полученный логический номер затем используется как аргумент большинства функций VFW и определяет поток, с которым выполняется операция.
В частности, по логическому номеру, возвращаемому AVIStreamOpenFromFile(), можно получить сведения о видеоролике. Функция AVIStreamReadFormat() сообщает такие данные, как количество кадров, размер изображения и глубина пикселей; для этого она заполняет структуру BITMAPINFOHEADER (возможно, структура BITMAPINFOHEADER покажется вам знакомой — мы уже встречались с ней при описании BMP-файлов). Я снова приведу определение этой структуры, взятое из файла Windows wingdi.h:
typedef struct tagBITMAPINFOHEADER{ DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER; |
Некоторые поля структуры (например, biXPelsPerMeter и biYPelsPerMeter) не имеют отношения к AVI-файлам, но таких полей немного. Размеры, глубина пикселей, алгоритм сжатия и количество цветов — все это можно взять из структуры BITMAPINFOHEADER после успешного вызова функции AVIStreamReadFormat().
Более подробные сведения о потоке можно получить с помощью функции AVIStreamInfo(). Функция AVIStreamInfo(), как и функция AVIStreamReadFormat(), получает в качестве аргумента логический номер и заполняет структуру данными о потоке. Для передачи информации AVIStreamInfo() использует структуру AVISTREAMINFO. Ее определение в файле vfw.h выглядит так:
typedef struct _AVISTREAMINFOW { DWORD fccType; DWORD fccHandler; DWORD dwFlags; DWORD dwCaps; WORD wPriority; WORD wLanguage; DWORD dwScale; DWORD dwRate; DWORD dwStart; DWORD dwLength; DWORD dwInitialFrames; DWORD dwSuggestedBufferSize; DWORD dwQuality; DWORD dwSampleSize; RECT rcFrame; DWORD dwEditCount; DWORD dwFormatChangeCount; WCHAR szName[64]; } AVISTREAMINFOW, FAR * LPAVISTREAMINFOW; |
Давайте рассмотрим некоторые ключевые поля этой структуры. Первое поле, fccType, определяет тип потока. В файлах формата AVI поддерживаются четыре типа потоковых данных: видео, аудио, MIDI (музыка) и текст. В этой книге будут рассматриваться только видеопотоки.
Второе поле структуры AVISTREAMINFO, fccHandler, определяет алгоритм сжатия, примененный при сохранении видеопотока. Как вы вскоре увидите, в Video For Windows это поле можно использовать для создания «декомпрессоров», которые способны восстановить каждый сжатый кадр из потока.
Поле dwStart определяет индекс первого кадра потока (это важно, потому что первый кадр видеоролика может иметь индекс 0 или 1). Эту же величину можно непосредственно получить функцией AVIStreamStart().В поле dwLength хранится общее количество кадров видеоролика. Его можно либо взять из структуры AVISTREAMINFO, либо получить с помощью функции AVIStreamLength().
Теперь мы знаем, как открыть видеопоток и получить сведения о нем. Можно переходить к процессу чтения и отображения видеокадров. Чтение кадров выполняется функцией AVIStreamRead(). Эта функция, получив логический номер потока и индекс интересующего нас кадра, помещает данные кадра в буфер, который мы также должны ей передать. Данные кадра хранятся в сжатом виде, поэтому перед отображением их необходимо восстановить.
Для восстановления кадров применяется функция ICDecompress(). Она получает два буфера: в одном находятся сжатые данные, а в другой будет помещен восстановленный кадр. Функции ICDecompress() также следует передать логический номер декомпрессора, используемого функцией ICDecompress() для обработки сжатых данных.
Логический номер декомпрессора можно получить функцией ICDecompressOpen(). По описанию видеоданных функция ICDecompressOpen() ищет декомпрессор с поддержкой нужного алгоритма восстановления.
После завершения работы с потоком необходимо закрыть его функцией AVIStreamRelease(). После вызова функции AVIStreamRelease() логический номер потока становится недействительным (до повторного открытия потока). Наконец, перед завершением программы необходимо вызвать функцию AVIFileExit(), которая освобождает программные модули VFW.