VFW: AVIStreamGetFrameOpen () возвращает NULL

Я пытаюсь написать класс C ++ Video с использованием интерфейса Video For Windows, основанного на концепциях из этот NeHe учебник, но с более современным кодом (для OpenGL 3/4). В моей функции, которая изначально загружает видео (не извлекает кадры), я имею в виду AVIStreamGetFrameOpen()который согласно MSDN:

Возвращает объект GetFrame, который можно использовать с функцией AVIStreamGetFrame.

На этой же странице написано:

Если система не может найти декомпрессор, который может распаковать поток в заданный формат или в любой формат RGB, функция возвращает NULL.

Моя проблема тот AVIStreamGetFrameOpen() возвращается NULL, что, как указано, означает, что не найден декомпрессор, соответствующий файлу. Тем не менее, мой файл может быть воспроизведен с помощью проигрывателя Windows Media без проблем, которые я верю означает, что декомпрессор должен быть доступен.

Кажется, что не хватает документации, когда дело доходит до VFW, а страницы MSDN не всегда чрезвычайно полезны. Кто-нибудь знает, что может быть причиной этой проблемы?

Вот код для рассматриваемой функции:

bool Video::Load(std::string FileName) {
try {
if (this->bLoaded)
this->UnLoad();

AVIFileInit();

if (AVIStreamOpenFromFile(&pavi, FileName.c_str(), streamtypeVIDEO, 0, OF_READ, NULL) != 0)
throw "Failed to open the AVI video stream.";

AVIStreamInfo(pavi, &psi, sizeof(psi));             // Reads Information About The Stream Into psi
this->szWidth = psi.rcFrame.right - psi.rcFrame.left;           // Width Is Right Side Of Frame Minus Left
this->szHeight = psi.rcFrame.bottom - psi.rcFrame.top;          // Height Is Bottom Of Frame Minus Top

ulnLastFrame = AVIStreamLength(pavi);                // The Last Frame Of The Stream

this->dDuration = AVIStreamSampleToTime(pavi, ulnLastFrame) / 1000.0f;
this->dSecondsPerFrame = this->dDuration / ulnLastFrame;

pgf = AVIStreamGetFrameOpen(pavi, NULL);              // Create The PGETFRAME Using Our Request Mode
if (pgf == NULL)
// ===== ERROR THROWN HERE =====
throw "Failed to open the AVI GetFrame object.";

glGenTextures(1, &this->unTexID);
glBindTexture(GL_TEXTURE_2D, this->unTexID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, this->szWidth, this->szHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
}
catch (const char* e) {
Message((std::string("Error: ") + e + "\nFile: \"" + FileName + "\"").c_str(), "Error");
return false;
}this->bLoaded = true;
return true;
}

Игнорируйте мои странные префиксы переменных.

1

Решение

Моя проблема в том, что AVIStreamGetFrameOpen () возвращает NULL, что, как указано, означает, что не найден декомпрессор, соответствующий файлу. Тем не менее, мой файл может быть воспроизведен с помощью проигрывателя Windows Media без проблем, что, я считаю, означает, что должен быть доступен декомпрессор.

Ваше предположение, что декомпрессор должен быть доступен, неверно.

Windows предлагает несколько базовых API-интерфейсов, связанных с видео и аудио: Video for Windows, DirectShow, Media Foundation, а также Windows Media. Кроме того, есть слои (AudioVideoPlayback, MediaElement и т. Д.).

Существует определенная совместимость между API: иногда кодеки и другие объекты совместно используются API, или один API обеспечивает оболочку совместимости над объектами других.

Однако это не так в вашем сценарии. Video For Windows является устаревшим API и не может использовать кодеки для новых API. Проигрыватель Windows Media, в свою очередь, использует Media Foundation в качестве основного API, а DirectShow — в качестве резервного API для сложных сценариев, где он дает вторую возможность попытаться воспроизвести файл. По сути, единственной причиной, по которой Video For Windows по-прежнему присутствует в текущей версии Windows, является поддержка устаревших приложений: новые доступные функции, связанные с видео / аудио, не доступны для VFW, не только Microsoft, но и третьих лиц.

Кроме того, 32-разрядные кодеки и 64-разрядные кодеки являются независимыми, и определенный фрагмент кода может использовать только кодеки соответствующей битности.

То есть между проигрывателем Windows Media и вашим кодом нет пересечения с точки зрения использования одного и того же API. Тот факт, что проигрыватель Windows Media воспроизводит файл, не означает, что ваш код VFW должен это делать. Вы столкнулись с проблемой, что не существует подходящего декодера для чтения и декодирования видео из файла (вы не упоминаете формат, слепое предположение здесь — это AVI с видео H.264).

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]