示例#1
0
STDMETHODIMP_(LRESULT) Tffvfw::decRun(void *icd0)
{
    if (!decVFW) {
        return VFW_E_RUNTIME_ERROR;
    }
    icd=(ICDECOMPRESS*)icd0;
    if (~((icd->dwFlags&ICDECOMPRESS_HURRYUP) | (icd->dwFlags&ICDECOMPRESS_UPDATE) | (icd->dwFlags&ICDECOMPRESS_PREROLL))) {
        if ((colorspace=getBMPcolorspace(icd->lpbiOutput,autoforcedcolorspaces.decGetForcedCsp(decVFW)))==FF_CSP_NULL) {
            return ICERR_UNSUPPORTED;
        }
        if (colorspace&FF_CSP_RGB16) {
            colorspace=(colorspace&~FF_CSP_RGB16)|FF_CSP_RGB15;
        }
        if (sign(icd->lpbiInput->biHeight)!=sign(icd->lpbiOutput->biHeight) && !csp_isYUVpacked(colorspace)) {
            colorspace^=FF_CSP_FLAGS_VFLIP;
        }
    } else {
        colorspace=FF_CSP_NULL;
    }

    unsigned char *inData=(unsigned char*)icd->lpInput;
    unsigned int inLen=icd->lpbiInput->biSizeImage;

    isSyncPoint=(icd->dwFlags&ICDECOMPRESS_NOTKEYFRAME)==0;
    return dec->decompress(inData,inLen,this);
}
示例#2
0
STDMETHODIMP_(LRESULT) TffdshowEnc::getFormat(const BITMAPINFOHEADER *inhdr, BITMAPINFO *lpbiOutput)
{
    extraDataSize = 0;
    initCo();
    if (getBMPcolorspace(inhdr, coSettings->incsps) == FF_CSP_NULL) {
        return ICERR_BADFORMAT;
    }

    unsigned int outDx, outDy;
    getOut(inhdr->biWidth, inhdr->biHeight, &outDx, &outDy);
    if (!findEncLib()) {
        return 0;
    }
    extradata.clear();
    if (enc->supExtradata()) {
        if (enccsps.empty()) {
            enc->getCompressColorspaces(enccsps, outDx, outDy);
        }
        enccsp = enccsps[0];
        enc->beginCompress(coSettings->mode, enccsp, Trect(0, 0, outDx, outDy));
        const void *edata0;
        enc->getExtradata(&edata0, &extraDataSize);
        if (extraDataSize) {
            extradata.set(edata0, extraDataSize, 0, true);
        }
        enc->end();
    }

    if (lpbiOutput == NULL) {
        return sizeof(BITMAPINFOHEADER) + extradata.size;
    }
    BITMAPINFOHEADER *outhdr = &lpbiOutput->bmiHeader;

    memcpy(outhdr, inhdr, sizeof(BITMAPINFOHEADER));
    outhdr->biSize = DWORD(sizeof(BITMAPINFOHEADER) + extradata.size);
    findEncLib();
    outhdr->biWidth = outDx;
    outhdr->biHeight = outDy;
    if (!enc || !enc->prepareHeader(outhdr)) {
        outhdr->biCompression = coSettings->fourcc;
        outhdr->biBitCount = 24; // or 16
        outhdr->biSizeImage = outDx * outDy * 3;
    }
    //TODO: maybe encoders should be allowed to modify other outhdr properties
    outhdr->biPlanes = 1;
    outhdr->biXPelsPerMeter = 0;
    outhdr->biYPelsPerMeter = 0;
    outhdr->biClrUsed = 0;
    outhdr->biClrImportant = 0;
    if (extradata.data) {
        memcpy((unsigned char*)outhdr + sizeof(BITMAPINFOHEADER), extradata.data, extradata.size);
    }
    biOutput.bmiHeader = lpbiOutput->bmiHeader;
    return ICERR_OK;
}
示例#3
0
STDMETHODIMP_(LRESULT) TffdshowEnc::query(const BITMAPINFOHEADER *inhdr, BITMAPINFOHEADER *outhdr)
{
    initCo();
    if (getBMPcolorspace(inhdr, coSettings->incsps) == FF_CSP_NULL) {
        return ICERR_BADFORMAT;
    }
    if (outhdr == NULL) {
        unsigned int outDx, outDy;
        getOut(inhdr->biWidth, inhdr->biHeight, &outDx, &outDy);
        if (outDx & 1 || outDy & 1) {
            return ICERR_BADFORMAT;
        }
        return ICERR_OK;
    }
    if (inhdr->biWidth != outhdr->biWidth || inhdr->biHeight != outhdr->biHeight) {
        return ICERR_BADFORMAT;
    }
    if (outhdr->biCompression == coSettings->fourcc) {
        return ICERR_OK;    //FIX ?
    }
    return ICERR_BADFORMAT;
}
示例#4
0
STDMETHODIMP_(LRESULT) TffdshowEnc::compress(const BITMAPINFOHEADER *inhdr, const uint8_t *src, size_t /*srclen*/, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop)
{
    if (firstrun) {
        firstrun = false;
        showTrayIcon();
    }

    _mm_empty();
    inColorspace = getBMPcolorspace(inhdr, coSettings->incsps);
    if (inColorspace == FF_CSP_NULL) {
        return ICERR_BADFORMAT;
    }
    if (coSettings->flip) {
        inColorspace ^= FF_CSP_FLAGS_VFLIP;
    }
    if (globalSettings->isDyInterlaced && dy > (unsigned int)globalSettings->dyInterlaced) {
        inColorspace |= FF_CSP_FLAGS_INTERLACED;
    }
    params.quant = -1;
    params.frametype = FRAME_TYPE::UNKNOWN;
    params.keyframe = false;
    switch (cfgcomode) {
        case ENC_MODE::CBR:
        case ENC_MODE::VBR_QUAL:
            break;
        case ENC_MODE::VBR_QUANT:
            params.quant = getQuantQuant();
            break;
        case ENC_MODE::UNKNOWN:
            break;
        default:
            DPRINTF(_l("Invalid encoding mode"));
            return ICERR_ERROR;
    }

    params.gray = !!coSettings->gray;

    //if (!src || !srclen) return ICERR_ERROR;

    if (pict.csp != inColorspace) {
        pict.csp = inColorspace;
        pict.cspInfo = *csp_getInfo(pict.csp);
    }
    pict.setSize(dx, dy);
    pict.data[0] = (unsigned char*)src;
    pict.stride[0] = dx * pict.cspInfo.Bpp;
    if (src) {
        csp_yuv_adj_to_plane(pict.csp, &pict.cspInfo, dy, pict.data, pict.stride);
        csp_yuv_order(pict.csp, pict.data, pict.stride);
        csp_vflip(pict.csp, &pict.cspInfo, pict.data, pict.stride, dy);
    }

    if (!coSettings->isProc || !ffproc) {
        bool directYV12 = false;
        for (Tcsps::const_iterator c = enccsps.begin(); c != enccsps.end(); c++)
            if (*c == pict.csp) {
                directYV12 = true;
                break;
            }
        if (!directYV12) {
            if (!convert) {
                convert = new Tconvert(this, dx, dy);
            }
            if (!ownpict.data[0]) {
                ownpict.alloc(dx, dy, enccsp, ownpictbuf);
            }
            if (src) {
                convert->convert(pict, ownpict.csp, ownpict.data, ownpict.stride);
            }
            //srclen=ownpict.cspInfo.bpp*ownpict.rectFull.dx*ownpict.rectFull.dy/8;
            pict = ownpict;
            if (!src) {
                pict.data[0] = NULL;
            }
        }
    }

    params.length = 0;
    params.priv = NULL;
    pict.rtStart = rtStart;
    pict.rtStop = rtStop;
    if (src && coSettings->isProc && ffproc) {
        HRESULT hr = ffproc->processPict(params.framenum, pict, enccsp);
        if (hr == S_OK) {
            hr = src ? enc->compress(pict, params) : enc->flushEnc(pict, params);
        }
        return hr;
    } else {
        return src ? enc->compress(pict, params) : enc->flushEnc(pict, params);
    }
}
示例#5
0
STDMETHODIMP_(LRESULT) Tffvfw::decQuery(BITMAPINFO *lpbiInput,BITMAPINFO *lpbiOutput)
{
    if (initDec()) {
        if (lpbiInput==NULL) {
            return ICERR_ERROR;
        }
        CodecID codecId;
        autoptr<TvideoCodecDec> dec=initDecoder(lpbiInput,&codecId);
        if (codecId==CODEC_ID_NONE) {
            return ICERR_UNSUPPORTED;
        }
        if (lpbiOutput!=NULL) {
            if (!dec) {
                return ICERR_UNSUPPORTED;
            }
            dec->forceOutputColorspace(&lpbiInput->bmiHeader,&autoforcedilace,autoforcedcolorspaces);
            const BITMAPINFOHEADER *outhdr=&lpbiOutput->bmiHeader;
            char_t pomS[60];
            DPRINTF(_l("Tffvfw::decQuery: %s"),fourcc2str(hdr2fourcc(outhdr,NULL),pomS,60));
            if (lpbiInput->bmiHeader.biWidth!=outhdr->biWidth || abs(lpbiInput->bmiHeader.biHeight)!=abs(outhdr->biHeight) || getBMPcolorspace(outhdr,autoforcedcolorspaces.decGetForcedCsp(decVFW))==FF_CSP_NULL) {
                return ICERR_BADFORMAT;
            }
        }
        return ICERR_OK;
    } else {
        return VFW_E_RUNTIME_ERROR;
    }
}