HRESULT TffdshowDecVideoDXVA::setOutputMediaType(const CMediaType &mt) { DPRINTF(_l("TffdshowDecVideoDXVA::setOutputMediaType")); TvideoCodecDec *pDecoder=NULL; getMovieSource((const TvideoCodecDec**)&pDecoder); TcspInfos ocsps; // DXVA mode : special output format TvideoCodecLibavcodecDxva *pDecoderDxva = (TvideoCodecLibavcodecDxva*)pDecoder; pDecoderDxva->getDXVAOutputFormats(ocsps); for (int i=0; cspFccs[i].name; i++) { const TcspInfo *cspInfo; // Look for the right DXVA colorspace bool ok=false; for (TcspInfos::const_iterator oc=ocsps.begin(); oc!=ocsps.end(); oc++) { if (mt.subtype==*(*oc)->subtype) { cspInfo=(const TcspInfo *)(*oc); ok=true; break; } } if (!ok) { continue; } m_frame.dstColorspace=FF_CSP_NV12; int biWidth,outDy; BITMAPINFOHEADER *bih; if (mt.formattype==FORMAT_VideoInfo && mt.pbFormat) { // && mt.pbFormat = work around other filter's bug. VIDEOINFOHEADER *vih=(VIDEOINFOHEADER*)mt.pbFormat; m_frame.dstStride=calcBIstride(biWidth=vih->bmiHeader.biWidth,cspInfo->Bpp*8); outDy=vih->bmiHeader.biHeight; bih=&vih->bmiHeader; } else if (mt.formattype==FORMAT_VideoInfo2 && mt.pbFormat) { VIDEOINFOHEADER2 *vih2=(VIDEOINFOHEADER2*)mt.pbFormat; m_frame.dstStride=calcBIstride(biWidth=vih2->bmiHeader.biWidth,cspInfo->Bpp*8); outDy=vih2->bmiHeader.biHeight; bih=&vih2->bmiHeader; } else { return VFW_E_TYPE_NOT_ACCEPTED; //S_FALSE; } m_frame.dstSize=DIBSIZE(*bih); char_t s[256]; DPRINTF(_l("TffdshowDecVideoDXVA::setOutputMediaType: colorspace:%s, biWidth:%i, dstStride:%i, Bpp:%i, dstSize:%i"),csp_getName(m_frame.dstColorspace,s,256),biWidth,m_frame.dstStride,cspInfo->Bpp,m_frame.dstSize); if (csp_isRGB(m_frame.dstColorspace) && outDy>0) { m_frame.dstColorspace|=FF_CSP_FLAGS_VFLIP; } //else if (biheight<0) // m_frame.colorspace|=FF_CSP_FLAGS_VFLIP; return S_OK; } m_frame.dstColorspace=FF_CSP_NULL; DPRINTF(_l("TffdshowDecVideoDXVA::setOutputMediaType Type not supported by FFDShow DXVA")); return VFW_E_TYPE_NOT_ACCEPTED; //S_FALSE; }
uint64_t getBMPcolorspace(const BITMAPINFOHEADER *hdr, const TcspInfos &forcedCsps) { uint64_t csp; switch (hdr->biCompression) { case BI_RGB: switch (hdr->biBitCount) { case 15: csp = FF_CSP_RGB15 | FF_CSP_FLAGS_VFLIP; break; case 16: csp = FF_CSP_RGB16 | FF_CSP_FLAGS_VFLIP; break; case 24: csp = FF_CSP_RGB24 | FF_CSP_FLAGS_VFLIP; break; case 32: csp = FF_CSP_RGB32 | FF_CSP_FLAGS_VFLIP; break; default: return FF_CSP_NULL; } break; case FOURCC_I420: case FOURCC_IYUV: csp = FF_CSP_420P | FF_CSP_FLAGS_YUV_ADJ | FF_CSP_FLAGS_YUV_ORDER; break; case FOURCC_YV12: csp = FF_CSP_420P | FF_CSP_FLAGS_YUV_ADJ; break; case FOURCC_YUYV: case FOURCC_YUY2: case FOURCC_V422: csp = FF_CSP_YUY2; break; case FOURCC_YVYU: csp = FF_CSP_YVYU; break; case FOURCC_UYVY: csp = FF_CSP_UYVY; break; case FOURCC_VYUY: csp = FF_CSP_VYUY; break; case FOURCC_Y800: csp = FF_CSP_Y800; break; case FOURCC_444P: case FOURCC_YV24: csp = FF_CSP_444P; break; case FOURCC_422P: csp = FF_CSP_422P; break; case FOURCC_YV16: csp = FF_CSP_422P | FF_CSP_FLAGS_YUV_ADJ; break; case FOURCC_411P: case FOURCC_Y41B: csp = FF_CSP_411P; break; case FOURCC_410P: csp = FF_CSP_410P; break; case FOURCC_420R: csp = FF_CSP_420P10; break; case FOURCC_422R: csp = FF_CSP_422P10; break; case FOURCC_444R: csp = FF_CSP_444P10; break; case FOURCC_P016: csp = FF_CSP_P016; break; case FOURCC_P010: csp = FF_CSP_P010; break; case FOURCC_P210: csp = FF_CSP_P210; break; case FOURCC_P216: csp = FF_CSP_P216; break; case FOURCC_AYUV: csp = FF_CSP_AYUV; break; case FOURCC_Y416: csp = FF_CSP_Y416; break; default: return FF_CSP_NULL; } bool ok; if (!forcedCsps.empty()) { ok = std::find(forcedCsps.begin(), forcedCsps.end(), csp_getInfo(csp)) != forcedCsps.end(); } else { ok = true; } return ok ? csp : FF_CSP_NULL; }