Пример #1
0
void TvideoCodecLibavcodecDxva::getDXVAOutputFormats(TcspInfos &ocsps)
{
    int nVideoOutputCount = 0;
    for (nVideoOutputCount = 0; nVideoOutputCount < MAX_SUPPORTED_MODE; nVideoOutputCount++)
        if (dxvaParamsp->Decoder[nVideoOutputCount] == &GUID_NULL) {
            break;
        }
    ocsps.clear();
    TcspInfo csp = {
        FF_CSP_NV12, _l("avxd"),
        1, 12, //Bpp
        1, //numplanes
        {0, 0, 0, 0}, //shiftX
        {0, 1, 1, 0}, //shiftY
        {0, 128, 128, 0}, //black
        'avxd', 'avxd', &GUID_NULL
    };
    // Dynamic DXVA media types for DXVA1
    for (int nPos = 0; nPos < nVideoOutputCount; nPos++) {
        TcspInfo *pCsp = new TcspInfo(csp);
        pCsp->subtype = dxvaParamsp->Decoder[nPos];
        ocsps.push_back(pCsp);
    }
    // Static list for DXVA2
    nVideoOutputCount = SIZEOF_ARRAY(dxva2List);
    for (int nPos = 0; nPos < nVideoOutputCount; nPos++) {
        ocsps.push_back((TcspInfo *)&dxva2List[nPos]);
    }
}
Пример #2
0
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;
}
Пример #3
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;
}
Пример #4
0
// get list of supported output colorspaces
HRESULT TffdshowDecVideoDXVA::GetMediaType(int iPosition, CMediaType *mtOut)
{
    DPRINTF(_l("TffdshowDecVideoDXVA::GetMediaType"));
    CAutoLock lock(&inpin->m_csCodecs_and_imgFilters);

    if (m_pInput->IsConnected()==FALSE) {
        return E_UNEXPECTED;
    }

    if (!presetSettings) {
        initPreset();
    }

    bool isVIH2;

    if (m_pOutput->IsConnected()) {
        const CLSID &ref=GetCLSID(m_pOutput->GetConnected());
        if (ref==CLSID_VideoMixingRenderer || ref==CLSID_VideoMixingRenderer9) {
            isVIH2=true;
        }
    }

    isVIH2 = (iPosition&1)==0;

    iPosition/=2;

    if (iPosition<0) {
        return E_INVALIDARG;
    }

    TvideoCodecDec *pDecoder=NULL;
    getMovieSource((const TvideoCodecDec**)&pDecoder);
    if (!pDecoder->useDXVA()) {
        return VFW_S_NO_MORE_ITEMS;
    }

    TcspInfos ocsps;
    size_t osize;


    // DXVA mode : special output format
    TvideoCodecLibavcodecDxva *pDecoderDxva = (TvideoCodecLibavcodecDxva*)pDecoder;
    pDecoderDxva->getDXVAOutputFormats(ocsps);
    osize=ocsps.size();

    if ((size_t)iPosition>=osize) {
        return VFW_S_NO_MORE_ITEMS;
    }

    TffPictBase pictOut;
    if (inReconnect) {
        pictOut=reconnectRect;
    } else {
        pictOut=inpin->pictIn;
    }

    // Support mediatype with unknown dimension. This is necessary to support MEDIASUBTYPE_H264.
    // http://msdn.microsoft.com/en-us/library/dd757808(VS.85).aspx
    // The downstream filter has to support reconnecting after this.
    if (pictOut.rectFull.dx == 0) {
        pictOut.rectFull.dx = 320;
    }
    if (pictOut.rectFull.dy == 0) {
        pictOut.rectFull.dy = 160;
    }

    oldRect=pictOut.rectFull;

    const TcspInfo *c=ocsps[iPosition];
    BITMAPINFOHEADER bih;
    memset(&bih,0,sizeof(bih));
    bih.biSize  =sizeof(BITMAPINFOHEADER);
    bih.biWidth =pDecoderDxva->pictWidthRounded();
    if(c->id == FF_CSP_420P) {  // YV12 and odd number lines.
        pictOut.rectFull.dy=odd2even(pictOut.rectFull.dy);
    }
    bih.biHeight=pDecoderDxva->pictHeightRounded();
    bih.biPlanes=WORD(c->numPlanes);
    bih.biCompression=c->fcc;
    bih.biBitCount=WORD(c->bpp);
    bih.biSizeImage=DIBSIZE(bih);// bih.biWidth*bih.biHeight*bih.biBitCount>>3;

    mtOut->majortype=MEDIATYPE_Video;
    mtOut->subtype=*c->subtype;
    mtOut->formattype=isVIH2?FORMAT_VideoInfo2:FORMAT_VideoInfo;
    mtOut->SetTemporalCompression(FALSE);
    mtOut->SetSampleSize(bih.biSizeImage);

    if (!isVIH2) {
        VIDEOINFOHEADER *vih=(VIDEOINFOHEADER*)mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER));
        if (!vih) {
            return E_OUTOFMEMORY;
        }
        ZeroMemory(vih,sizeof(VIDEOINFOHEADER));

        vih->rcSource.left=0;
        vih->rcSource.right=pictOut.rectFull.dx;
        vih->rcSource.top=0;
        vih->rcSource.bottom=pictOut.rectFull.dy;
        vih->rcTarget=vih->rcSource;
        vih->AvgTimePerFrame=inpin->avgTimePerFrame;
        vih->bmiHeader=bih;
    } else {
        VIDEOINFOHEADER2 *vih2=(VIDEOINFOHEADER2*)mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER2));
        if (!vih2) {
            return E_OUTOFMEMORY;
        }
        ZeroMemory(vih2,sizeof(VIDEOINFOHEADER2));
        if((presetSettings->resize && presetSettings->resize->is && presetSettings->resize->SARinternally && presetSettings->resize->mode==0)) {
            pictOut.rectFull.sar.num= 1;//pictOut.rectFull.dx; // VMR9 behaves better when this is set to 1(SAR). But in reconnectOutput, it is different(DAR) in my system.
            pictOut.rectFull.sar.den= 1;//pictOut.rectFull.dy;
        }
        setVIH2aspect(vih2,pictOut.rectFull,presetSettings->output->hwOverlayAspect);

        //DPRINTF(_l("AR getMediaType: %i:%i"),vih2->dwPictAspectRatioX,vih2->dwPictAspectRatioY);

        vih2->rcSource.left=0;
        vih2->rcSource.right=pictOut.rectFull.dx;
        vih2->rcSource.top=0;
        vih2->rcSource.bottom=pictOut.rectFull.dy;
        vih2->rcTarget=vih2->rcSource;
        vih2->AvgTimePerFrame=inpin->avgTimePerFrame;
        vih2->bmiHeader=bih;
        //vih2->dwControlFlags=AMCONTROL_USED | AMCONTROL_COLORINFO_PRESENT | (DXVA_NominalRange_Wide << DXVA_NominalRangeShift) | (DXVA_VideoTransferMatrix_BT601 << DXVA_VideoTransferMatrixShift);
        hwDeinterlace=1; // HW deinterlace for DXVA

        if (hwDeinterlace) {
            vih2->dwInterlaceFlags=AMINTERLACE_IsInterlaced|AMINTERLACE_DisplayModeBobOrWeave;
        }
    }
    return S_OK;
}