diff options
author | Hendrik Leppkes <h.leppkes@gmail.com> | 2015-02-21 14:00:02 +0300 |
---|---|---|
committer | Hendrik Leppkes <h.leppkes@gmail.com> | 2015-02-21 14:00:02 +0300 |
commit | 7d4030f9687b2e9b5d53cfc8fd02905ec2488ec7 (patch) | |
tree | 7f02414a7d13d4d9669ea343accb4e17d07987ee | |
parent | 0291ab4fc11331c52a4db6556d90ea70782798c5 (diff) |
dxva2: ground work for DXVA2-Native 10-bit output
The feature remains disabled however, due to EVR falling over when its in use.
-rw-r--r-- | decoder/LAVVideo/LAVPixFmtConverter.cpp | 23 | ||||
-rw-r--r-- | decoder/LAVVideo/decoders/dxva2dec.cpp | 17 |
2 files changed, 32 insertions, 8 deletions
diff --git a/decoder/LAVVideo/LAVPixFmtConverter.cpp b/decoder/LAVVideo/LAVPixFmtConverter.cpp index 367266a9..5abf6779 100644 --- a/decoder/LAVVideo/LAVPixFmtConverter.cpp +++ b/decoder/LAVVideo/LAVPixFmtConverter.cpp @@ -102,7 +102,9 @@ static LAV_INOUT_PIXFMT_MAP lav_pixfmt_map[] = { { LAVPixFmt_ARGB32, 8, { PIXOUT_RGB_8, PIXOUT_RGB_16, PIXOUT_444_16, PIXOUT_444_10, PIXOUT_444_8, PIXOUT_422_16, PIXOUT_422_10, PIXOUT_422_8, PIXOUT_420_16, PIXOUT_420_10, PIXOUT_420_8 } }, { LAVPixFmt_RGB48, 8, { PIXOUT_RGB_16, PIXOUT_RGB_8, PIXOUT_444_16, PIXOUT_444_10, PIXOUT_444_8, PIXOUT_422_16, PIXOUT_422_10, PIXOUT_422_8, PIXOUT_420_16, PIXOUT_420_10, PIXOUT_420_8 } }, - { LAVPixFmt_DXVA2, 8, { PIXOUT_420_8, PIXOUT_420_10, PIXOUT_420_16, PIXOUT_422_16, PIXOUT_422_10, PIXOUT_422_8, PIXOUT_RGB_8, PIXOUT_444_16, PIXOUT_444_10, PIXOUT_444_8, PIXOUT_RGB_16 } }, + { LAVPixFmt_DXVA2, 8, { PIXOUT_420_8, PIXOUT_420_10, PIXOUT_420_16, PIXOUT_422_16, PIXOUT_422_10, PIXOUT_422_8, PIXOUT_RGB_8, PIXOUT_444_16, PIXOUT_444_10, PIXOUT_444_8, PIXOUT_RGB_16 } }, + { LAVPixFmt_DXVA2, 10, { PIXOUT_420_10, PIXOUT_420_16, PIXOUT_420_8, PIXOUT_422_16, PIXOUT_422_10, PIXOUT_422_8, PIXOUT_RGB_8, PIXOUT_RGB_16, PIXOUT_444_16, PIXOUT_444_10, PIXOUT_444_8 } }, + { LAVPixFmt_DXVA2, 16, { PIXOUT_420_16, PIXOUT_420_10, PIXOUT_420_8, PIXOUT_422_16, PIXOUT_422_10, PIXOUT_422_8, PIXOUT_RGB_8, PIXOUT_RGB_16, PIXOUT_444_16, PIXOUT_444_10, PIXOUT_444_8 } }, }; LAVOutPixFmtDesc lav_pixfmt_desc[] = { @@ -164,12 +166,27 @@ LAVOutPixFmts CLAVPixFmtConverter::GetOutputBySubtype(const GUID *guid) return LAVOutPixFmt_None; } +static bool IsDXVAPixFmt(LAVPixelFormat inputFormat, LAVOutPixFmts outputFormat, int bpp) +{ + if (inputFormat != LAVPixFmt_DXVA2) + return false; + + if (bpp == 8 && outputFormat == LAVOutPixFmt_NV12) + return true; + else if (bpp == 10 && outputFormat == LAVOutPixFmt_P010) + return true; + else if (bpp == 16 && outputFormat == LAVOutPixFmt_P016) + return true; + + return false; +} + int CLAVPixFmtConverter::GetFilteredFormatCount() { LAV_INOUT_PIXFMT_MAP *pixFmtMap = lookupFormatMap(m_InputPixFmt, m_InBpp); int count = 0; for (int i = 0; i < LAVOutPixFmt_NB; ++i) { - if (m_pSettings->GetPixelFormat(pixFmtMap->lav_pix_fmts[i]) || (m_InputPixFmt == LAVPixFmt_DXVA2 && pixFmtMap->lav_pix_fmts[i] == LAVOutPixFmt_NV12)) + if (m_pSettings->GetPixelFormat(pixFmtMap->lav_pix_fmts[i]) || IsDXVAPixFmt(m_InputPixFmt, pixFmtMap->lav_pix_fmts[i], m_InBpp)) count++; } @@ -184,7 +201,7 @@ LAVOutPixFmts CLAVPixFmtConverter::GetFilteredFormat(int index) LAV_INOUT_PIXFMT_MAP *pixFmtMap = lookupFormatMap(m_InputPixFmt, m_InBpp); int actualIndex = -1; for (int i = 0; i < LAVOutPixFmt_NB; ++i) { - if (m_pSettings->GetPixelFormat(pixFmtMap->lav_pix_fmts[i]) || (m_InputPixFmt == LAVPixFmt_DXVA2 && pixFmtMap->lav_pix_fmts[i] == LAVOutPixFmt_NV12)) + if (m_pSettings->GetPixelFormat(pixFmtMap->lav_pix_fmts[i]) || IsDXVAPixFmt(m_InputPixFmt, pixFmtMap->lav_pix_fmts[i], m_InBpp)) actualIndex++; if (index == actualIndex) return pixFmtMap->lav_pix_fmts[i]; diff --git a/decoder/LAVVideo/decoders/dxva2dec.cpp b/decoder/LAVVideo/decoders/dxva2dec.cpp index 40334b85..0597fd41 100644 --- a/decoder/LAVVideo/decoders/dxva2dec.cpp +++ b/decoder/LAVVideo/decoders/dxva2dec.cpp @@ -340,8 +340,10 @@ STDMETHODIMP CDecDXVA2::PostConnect(IPin *pPin) } CMediaType mt = m_pCallback->GetOutputMediaType(); - if (mt.subtype != MEDIASUBTYPE_NV12) { - DbgLog((LOG_ERROR, 10, L"-> Connection is not NV12")); + if ( (m_eSurfaceFormat == FOURCC_NV12 && mt.subtype != MEDIASUBTYPE_NV12) + || (m_eSurfaceFormat == FOURCC_P010 && mt.subtype != MEDIASUBTYPE_P010) + || (m_eSurfaceFormat == FOURCC_P016 && mt.subtype != MEDIASUBTYPE_P016)) { + DbgLog((LOG_ERROR, 10, L"-> Connection is not the appropriate pixel format for DXVA2 Native")); hr = E_FAIL; goto done; } @@ -927,13 +929,18 @@ STDMETHODIMP CDecDXVA2::InitDecoder(AVCodecID codec, const CMediaType *pmt) // If we don't have one yet, it may be handed to us later, and compat is checked at that point GUID input = GUID_NULL; D3DFORMAT output = D3DFMT_UNKNOWN; + bool bHighBitdepth = (m_pAVCtx->codec_id == AV_CODEC_ID_HEVC && (m_pAVCtx->sw_pix_fmt == AV_PIX_FMT_YUV420P10 || m_pAVCtx->profile == FF_PROFILE_HEVC_MAIN_10)); if (m_pDXVADecoderService) { - bool bHighBitdepth = (m_pAVCtx->codec_id == AV_CODEC_ID_HEVC && (m_pAVCtx->sw_pix_fmt == AV_PIX_FMT_YUV420P10 || m_pAVCtx->profile == FF_PROFILE_HEVC_MAIN_10)); hr = FindVideoServiceConversion(codec, bHighBitdepth, &input, &output); if (FAILED(hr)) { DbgLog((LOG_TRACE, 10, L"-> No decoder device available that can decode codec '%S' to a matching output", avcodec_get_name(codec))); return E_FAIL; } + } else { + if (bHighBitdepth) + output = (D3DFORMAT)FOURCC_P010; + else + output = (D3DFORMAT)FOURCC_NV12; } if (((codec == AV_CODEC_ID_H264 || codec == AV_CODEC_ID_MPEG2VIDEO) && m_pAVCtx->pix_fmt != AV_PIX_FMT_YUV420P && m_pAVCtx->pix_fmt != AV_PIX_FMT_YUVJ420P && m_pAVCtx->pix_fmt != AV_PIX_FMT_DXVA2_VLD && m_pAVCtx->pix_fmt != AV_PIX_FMT_NONE) @@ -1439,7 +1446,7 @@ HRESULT CDecDXVA2::DeliverDXVA2Frame(LAVFrame *pFrame) return S_FALSE; } - pFrame->format = LAVPixFmt_DXVA2; + GetPixelFormat(&pFrame->format, &pFrame->bpp); Deliver(pFrame); } else { if (m_bDirect) { @@ -1465,7 +1472,7 @@ STDMETHODIMP CDecDXVA2::GetPixelFormat(LAVPixelFormat *pPix, int *pBpp) *pPix = (m_eSurfaceFormat == FOURCC_P010 || m_eSurfaceFormat == FOURCC_P016) ? LAVPixFmt_P010 : LAVPixFmt_NV12; } if (pBpp) - *pBpp = (m_eSurfaceFormat == FOURCC_P010 || m_eSurfaceFormat == FOURCC_P016) ? 10 : 8; + *pBpp = (m_eSurfaceFormat == FOURCC_P016) ? 16 : ((m_eSurfaceFormat == FOURCC_P010) ? 10 : 8); return S_OK; } |