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;
}
Exemple #2
0
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;
}