Я пытаюсь написать класс 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;
}
Игнорируйте мои странные префиксы переменных.
Моя проблема в том, что 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).
Других решений пока нет …