D3D11 имеет видео API, который в основном представляет собой DXVA2 со слегка измененным интерфейсом выше. Вам нужно хорошо понять Bitstreams H.264, чтобы продолжить (правда!). т.е. убедитесь, что у вас есть анализатор H.264 под рукой для извлечения полей SPS и PPS -структур и всех срезов кодированной рамы.
1) Получите экземпляр ID3D11VideoDevice из вашего ID3D11DEVICE и ID3D11VideOcontext из вашего непосредственного контекста устройства D3D11 Примечание: на Win7 вы должны создать свое устройство с уровнем функций 9_3, чтобы получить поддержку видео! (В Win8 это просто работает)
2) Создайте экземпляр id3d11videodecoder для H.264 Использовать id3d11videodevice :: getVideoDecoderProfilEcount, getVideoDecoderProfile, checkvideodecoderformat ... для Itteation через все поддерживаемые профили и найдите один с Guide D3D11_Decoder_Profile_H264_VLD_NOFGT FORGRAIN. В качестве OutputFormat ваш лучший выбор - dxgi_format_nv12.
3) Декодирование отдельных кадров видит Поддержка Direct3d 11 видео декодирование в медиа -фонде:
- Id3d11videocontext :: decoderbeginframe (decoder, 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 :: Opperbuffers для совершения всех заполненных буферов
- Id3d11videocontext :: decoderendframe, чтобы закончить текущий кадр
3) D3D11_Video_Decoder_buffer_picture_parameters Buffer также содержит информацию обо всех формах ссылок/поверхности - вам нужно самостоятельно управлять ими, то есть убедитесь, что поверхности/текстуры доступны для ГПУ!
Это довольно сложно, проверьте 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);