Directx 11 및 Windows 7과 함께 하드웨어 가속 비디오/H.264 디코딩을 어떻게 사용합니까?

StackOverflow https://stackoverflow.com/questions/19846770

문제

나는 하루 종일 연구를 해왔고 멀지 않았다. 나는 Directx 11을 사용하여 Windows 7에 있습니다. (최종 출력은 DX11 텍스처에 비디오 프레임이라는 것입니다) 매우 큰 H.264 비디오 파일을 해독하고 싶습니다. CPU (libav 사용)는 그렇지 않습니다. 그걸 잘 라라.

DXVA2를 사용하여 libav의 hwaccel 기능을 살펴 보았지만 d3d9 인터페이스로 만 만들 수있는 idirectxvideodecoder를 만들어야 할 때로드 블록을 쳤습니다. (DX11을 사용하지 않는 것)

DXVA 문서를 찾을 때마다 DX11을 참조하지 않고 DX10 또는 11에서 제거 되었습니까? (이 확인을 찾을 수 없으며 DXVA2가 중복되어 DXVA-HD에 의해 초과되었을 수 있습니까?)

그런 다음 DX11에 사용해야 할 것 같지 않은 Media Foundation SDK를 조사했습니다. 그러나 내 헤더에는 유형이 없습니다 (문서에는 포함한다고 말합니다.u003Cd3d11.h> 그러나 이것은 아무것도 얻지 못합니다). 또한 사용하려면 최소의 Windows 8을 지정합니다.

MF를 사용한다고 생각합니다. Windows 8 SDK가 필요합니다. 이제 모든 Directx Libs/헤더가 포함되어 있습니다.

그래서 이것은 Windows 7과의 차이를 남깁니다 ... 하드웨어 가속화 된 비디오 디코딩을 얻을 수 있습니까? 그렇다면 어떤 API를 사용해야합니까?

편집 : 또 다른 후속 조치로, 내 미디어 펀딩 (및 AVF, Android, Magic Leap 등) 구현은 오픈 소스 프로젝트에 있습니다.https://github.com/newchromantics/poph264edit2 : 그러나 그것이 Win7을 지원하는지 모르겠습니다. :)

도움이 되었습니까?

해결책

D3D11은 기본적으로 위의 약간 변경된 인터페이스를 갖는 DXVA2 인 비디오 API를 특징으로합니다. H.264 비트 스트림을 잘 이해해야합니다 (실제로!). 즉, SPS 및 PPS 구조의 필드와 인코딩 된 프레임의 모든 슬라이스를 추출하기 위해 H.264 파서가 손에 든다.

1) ID3D11Device에서 ID3D11VideoDevice 인스턴스와 id3d11videocontext에서 id3d11videodevice 인스턴스를 얻으십시오. (Win8에서는 단지 작동합니다)

2) H.264에 대한 Id3d11videodecoder 인스턴스를 만듭니다. id3d11videodevice :: getVideodecoderProfilecount, getVideodeCoderProfile, CheckVideoDecoDerformat ... 모든 지원되는 프로파일을 통해 반복하고 D3D11_DECODER_PROFILE_H264_VLD _NOFTORATION을 사용하여 찾아 내고 있습니다. outputformat로서 가장 좋은 방법은 dxgi_format_nv12입니다.

3) 개별 프레임의 디코딩 참조 Media Foundation에서 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 :: 제출 버퍼를 모두 채워진 버퍼를 커밋합니다
  • id3d11videocontext :: decoderendframe 현재 프레임을 완료합니다

3) d3d11_video_decoder_buffer_picture_parameters 버퍼도 모든 참조 프레임/표면에 대한 정보도 포함되어 있습니다 - 직접 관리해야합니다. 즉, GPU에 표면/텍스처를 사용할 수 있는지 확인하십시오!

FFMPEG 및 미디어 플레이어 클래식을 확인하고 DXVA2 (DX11을 통한 것은 아니지만) 지원이 매우 복잡합니다.

4) NV12에서 RGB (A)로 변환하면 일부 GPU (D3D11 기능 레벨)는 NV12를 셰이더 입력으로 사용할 수있게되며 일부는 그렇지 않습니다. NV12를 직접 사용할 수없는 경우 D3D11 지원이있는 모든 GPU에 대한 NV12/YUV420-> RGB 변환을 특징으로하는 D3D11Videoprocessor 인터페이스를 살펴보십시오.

변환은 다음과 같은 코드로 수행 될 수 있습니다.

// 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);

다른 팁

후속 조치로, 나는 현재 Windows 7,8 및 10과 함께 MediaFoundation을 사용하고 있으며 DirectX (또는 8+의 경우 Windows SDK 만)를 사용하고 있습니다.

훨씬 적은 형식 (또는 해상도/프로필 수준)을 지원하며 현재 하드웨어 가속을 사용하고 있는지 아닌지 확실하지 않습니다 ...

그러나이 API는 호환 가능합니다. 원래 쿼리였습니다.

Directx 11 및 Windows 7과 함께 하드웨어 가속 비디오/H.264 디코딩을 어떻게 사용합니까?

당신은 할 수 없습니다.

Id3d11videodevice는 Windows 8에만 적용됩니다 Id3d11videodevice.

Id3d11videodecoder는 Windows 8에만 적용됩니다 Id3d11videodecoder.

Windows 7에서는 하드웨어 가속화 된 비디오/H.264에 Directx 9를 사용할 수 있습니다. 감사합니다 Microsoft. 새롭고 Idirect3d9ex는 작동합니다 ... 예 ... 다른 좋은 소식, GPU 디코딩 성능은 Windows 7에서 DirectX9를 사용하여 매우 좋습니다.

다음은 Windows 7 및 Directx 9의 소스 코드입니다. MOFO7777, H264dxva2decoder 프로젝트에 따라.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top