Как использовать аппаратное ускорение видео /H.264 декодирование с DirectX 11 и Windows 7?
Я занимался исследованиями весь день и не зашел слишком далеко. Я нахожусь на Windows 7, используя DirectX11. (мой последний вывод должен быть кадр видео на текстуру DX11) Я хочу декодировать некоторые очень большие видеофайлы H.264, а процессор (с использованием libav) не порежь это.
Я рассмотрел возможности hwaccel в libav с использованием DXVA2, но столкнулся с проблемой, когда мне нужно создать IDirectXVideoDecoder, который может быть создан только с интерфейсом D3D9. (который я не использую DX11)
Всякий раз, когда я просматривал документацию по DXVA, она не ссылается на DX11, это было удалено в DX10 или 11? (Не может найти подтверждения этому, нигде, где указано, что DXVA2 является избыточным, возможно, что он был заменен DXVA-HD?)
Затем я посмотрел на Media Foundation SDK, так как это похоже на то, что я должен использовать для DX11... Но ни один из типов не существует в моих заголовках (Документы говорят, что просто включают, но это ничего не дает). Они также указывают минимум Windows 8, чтобы использовать его.
Я считаю, что для использования MF мне нужен Windows 8 SDK, который теперь включает в себя все библиотеки / заголовки DirectX.
Таким образом, это оставляет пробел в Windows 7... Возможно ли получить аппаратное ускорение декодирования видео? и если да, то какой API я должен использовать?
3 ответа
D3D11 имеет видео API, в основном это DXVA2 с немного измененным интерфейсом выше. Вам нужно хорошо понимать битовые потоки h.264, чтобы продолжить (действительно!). т.е. убедитесь, что у вас есть парсер h.264 для извлечения полей структур SPS и PPS и всех фрагментов кодированного кадра.
1) Получите экземпляр ID3D11VideoDevice из вашего ID3D11Device и ID3D11VideoContext из вашего непосредственного контекста устройства D3D11. ПРИМЕЧАНИЕ. В Win7 вам необходимо создать свое устройство с уровнем функций 9_3, чтобы получить поддержку видео! (В Win8 это просто работает)
2) Создайте экземпляр ID3D11VideoDecoder для h.264. Используйте ID3D11VideoDevice::GetVideoDecoderProfileCount, GetVideoDecoderProfile, CheckVideoDecodeRFormat..., чтобы перебрать все поддерживаемые профили и найти его с GUID D3D11_DECODER_PROFILE_HF_H6464 для h6464 без графической переменной hF. В качестве формата вывода вам лучше всего выбрать DXGI_FORMAT_NV12.
3) Декодирование отдельных кадров см. В разделе " Поддержка декодирования видео Direct3D 11 в Media Foundation":
- ID3D11VideoContext:: DecoderBeginFrame (декодер, outputView -> текстура декодированного кадра)
- Заполните буферы:
- D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS
- D3D11_VIDEO_DECODER_BUFFER_INVERSE_QUANTIZATION_MATRIX
- D3D11_VIDEO_DECODER_BUFFER_BITSTREAM
- D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL
Буферы заполнены соответствующими структурами DXVA2 (см. Dxva2.h). Здесь есть полная спецификация DXVA2, она вам понадобится для соответствующего отображения полей h.264 sps/pps.
Увидеть:
Затем:
- ID3D11VideoContext:: SubmitBuffers для фиксации всех заполненных буферов
- ID3D11VideoContext::DecoderEndFrame для завершения текущего кадра
3) Буфер D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS также содержит информацию обо всех ссылочных фреймах / поверхностях - вам нужно управлять ими самостоятельно, т.е. убедитесь, что поверхности / текстуры доступны для графического процессора!
Это довольно сложно, проверьте ffmpeg и Media Player Classic, они оба поддерживают DXVA2 (хотя и не через DX11).
4) Преобразование из NV12 в RGB(A), некоторые графические процессоры (уровни функций D3D11) позволяют использовать NV12 в качестве шейдерного входа, а некоторые нет. В случае, если невозможно использовать NV12 напрямую, взгляните на интерфейсы D3D11VideoProcessor, которые имеют преобразование NV12/YUV420->RGB для всех графических процессоров с поддержкой D3D11.
Преобразование может быть выполнено в коде так:
// Setup ID3D11Video*
ID3D11VideoProcessor * d3dVideoProc = ...;
ID3D11VideoDevice * d3dVideoDevice = ...;
ID3D11VideoProcessorEnumerator * d3dVideoProcEnum = ...;
ID3D11Texture2D * srcTextureNV12Fmt = ...;
ID3D11Texture2D * dstTextureRGBFmt = ...;
// Use Video Processor
// Create views for VideoProc In/Output
ID3D11VideoProcessorInputView * videoProcInputView;
ID3D11VideoProcessorOutputView * videoProcOutputView;
{
D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC inputViewDesc = { 0 };
inputViewDesc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D;
inputViewDesc.Texture2D.ArraySlice = arraySliceIdx;
inputViewDesc.Texture2D.MipSlice = 0;
hr = d3dVideoDevice->CreateVideoProcessorInputView(srcTextureNV12Fmt, d3dVideoProcEnum, &inputViewDesc, &videoProcInputView);
}
{
D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC outputViewDesc = { D3D11_VPOV_DIMENSION_TEXTURE2D };
outputViewDesc.Texture2D.MipSlice = 0;
hr = d3dVideoDevice->CreateVideoProcessorOutputView(dstTextureRGBFmt, d3dVideoProcEnum, &outputViewDesc, &videoProcOutputView);
}
// Setup streams
D3D11_VIDEO_PROCESSOR_STREAM streams = { 0 };
streams.Enable = TRUE;
streams.pInputSurface = videoProcInputView.get();
RECT srcRect = { /* source rectangle in pixels*/ };
RECT dstRect = { /* destination rectangle in pixels*/ };
// Perform VideoProc Blit Operation (with color conversion)
hr = videoCtx_->VideoProcessorBlt(d3dVideoProc, videoProcOutputView.get(), 0, 1, &streams);
В качестве продолжения я в настоящее время использую MediaFoundation с Windows 7,8 и 10, с DirectX (или просто Windows SDK в случае 8+)
Он поддерживает гораздо меньше форматов (точнее, разрешений / уровней профиля), и в настоящее время я не совсем уверен, использует ли он аппаратное ускорение или нет...
Но этот API совместим, который был оригинальный запрос
Как использовать аппаратное ускорение видео /H.264 декодирование с DirectX 11 и Windows 7?
Ты не можешь
ID3D11VideoDevice доступен только для Windows 8 ID3D11VideoDevice.
ID3D11VideoDecoder доступен только для Windows 8 ID3D11VideoDecoder.
В Windows 7 вы можете использовать DirectX9 для аппаратного ускорения видео /H.264. Спасибо Microsoft. Хороший новый, IDirect3D9Ex работает... да... Еще одна хорошая новость, производительность декодирования графического процессора очень хорошая при использовании DirectX9 в Windows 7.
Вот исходный код для Windows 7 и DirectX9: mofo7777, в рамках проекта H264Dxva2Decoder.