/** * get addresses of current picture buffer (Current picture is usually a picture to feed into image filter.) * If color space conversion is necessary, own1 will be used. * If color space conversion is not necessary, picture buffer will not be copied. * * @param[in] csp requested color space. * @param[in,out] pict current picture (will be modifed if necessary) * @param[in] full * @param[in,out] src[4] pointer to the array to receive the addresses * *return true if color space is changed. * stride will be set to TimgFilter::stride1 */ bool TimgFilter::getCur(uint64_t csp,TffPict &pict,int full,const unsigned char **src[4]) { uint64_t wasAdj=pict.csp&FF_CSP_FLAGS_YUV_ADJ; csp_yuv_adj_to_plane(pict.csp,&pict.cspInfo,pict.rectFull.dy,pict.data,pict.stride); csp_yuv_order(pict.csp,pict.data,pict.stride); // if color space is different or FF_CSP_FLAGS_YUV_ADJ is different if (((csp&FF_CSPS_MASK)&(pict.csp&FF_CSPS_MASK))==0 || ((csp&FF_CSP_FLAGS_YUV_ADJ) && !wasAdj)) { if (!convert1) { convert1=new Tconvert(deci,pict.rectFull.dx,pict.rectFull.dy); } pict.convertCSP(csp_bestMatch(pict.csp,csp&FF_CSPS_MASK)|(csp&(FF_CSP_FLAGS_VFLIP|FF_CSP_FLAGS_YUV_ADJ|FF_CSP_FLAGS_YUV_ORDER)),own1,convert1); pict.setRO(false); } bool cspChanged=csp1!=pict.csp; csp1=pict.csp; const Trect &r=pictRect; //full?pict.rectFull:pict.rectClip; unsigned int i = 0; for (; i<pict.cspInfo.numPlanes; i++) { if (src[i]) { *src[i]=pict.data[i]+(full?0:pict.diff[i])+(pictHalf?r.x*pict.cspInfo.Bpp>>pict.cspInfo.shiftX[i]:0); } stride1[i]=pict.stride[i]; dx1[i]=r.dx>>pict.cspInfo.shiftX[i]; dy1[i]=r.dy>>pict.cspInfo.shiftY[i]; } for (; i<4; i++) { src[i] = NULL; stride1[i] = 0; dx1[i] = 0; dy1[i] = 0; } return cspChanged; }
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); } }