tffdshowenc.cpp.svn-base

来自「ffshow源码」· SVN-BASE 代码 · 共 1,074 行 · 第 1/2 页

SVN-BASE
1,074
字号
 if (coSettings->storeExt && !ownStoreExt && coSettings->storeExtFlnm[0])  mux=Tmuxer::getMuxer(coSettings->muxer,this); else   mux=NULL;  switch (cfgcomode)  {   case ENC_MODE::PASS2_1:    pass=new T2passFirst(*coSettings);    break;   case ENC_MODE::PASS2_2_EXT:    pass=new T2passSecond(this);   case ENC_MODE::PASS2_2_INT:    pass=new T2passSecond(this);    break;  } dx=inhdr->biWidth;dy=inhdr->biHeight; totalsize=keyspacing=0; if (coSettings->isProc && ffproc)  ffproc->begin(dx,dy,fpsRate,fpsScale);  if (mux)  mux->writeHeader(extradata.data,extradata.size,1,biOutput.bmiHeader);   memset(&params,0,sizeof(params)); encStats.init(outDx,outDy,enccsp); outputdebug=globalSettings->outputdebug;outputdebugfile=globalSettings->outputdebugfile; working=true;firstrun=true; return ICERR_OK;}HRESULT TffdshowEnc::EndOfStream(void){ HRESULT hr=compress(&inpin->biIn.bmiHeader,NULL,0,_I64_MIN,_I64_MIN); return FAILED(hr)?hr:CTransformFilter::EndOfStream();}STDMETHODIMP_(LRESULT) TffdshowEnc::end(void){ if (working && (outputdebug || outputdebugfile) && encStats.count>0)  {   if (int(encStats.sumQuants)>0) dbgWrite(_l("Average quantizer: %-5.2f\n"),float(encStats.sumQuants)/encStats.count);   if (coSettings->mode!=ENC_MODE::VBR_QUANT)    {     dbgWrite(_l("Quantizer distribution:"));     for (int i=1;i<countof(encStats.quantCount);i++)      if (encStats.quantCount[i])       dbgWrite(_l("Q:%i:%i"),i,encStats.quantCount[i]);    }   dbgWrite(_l("Bitrate: %i kbps"),int((8ULL*encStats.sumFramesize*fpsRate)/(1000ULL*encStats.count*fpsScale)));   if (globalSettings->psnr)    {     double psnrY,psnrU,psnrV;encStats.calcPSNR(&psnrY,&psnrU,&psnrV);     if (psnrY!=-1)      dbgWrite(_l("Average PSNR: %6.2f,%6.2f,%6.2f\n"),psnrY,psnrU,psnrV);    }   } working=false; if (h_graph) PostMessage(h_graph,TencStats::MSG_FF_CLEAR,0,0); hideTrayIcon();  if (coSettings->isProc && ffproc) ffproc->end(); if (pass) delete pass;pass=NULL; if (enc) enc->end(); if (mux) delete mux;mux=NULL; if (convert) delete convert;convert=NULL; if (ownpictbuf.size()) {ownpictbuf.clear();memset(&ownpict,0,sizeof(ownpict));} enccsps.clear();   dbgDone(); return ICERR_OK;}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::PASS2_1:    params.quant=getQuantFirst();    break;    case ENC_MODE::PASS2_2_EXT:   case ENC_MODE::PASS2_2_INT:    if (!pass->getQuantSecond(params)) return ICERR_ERROR;    if (params.quant!=-1) params.quant&=Txvid_2pass::NNSTATS_QUANTMASK;    break;   case ENC_MODE::UNKNOWN:    break;   default:    DPRINTF(_l("Invalid encoding mode"));    return ICERR_ERROR;  }   params.quanttype=coSettings->getQuantType(params.quant); params.gray=coSettings->gray || (coSettings->graycredits && coSettings->isInCredits(params.framenum)); if (keyspacing<coSettings->min_key_interval && params.framenum)  params.frametype=FRAME_TYPE::P; //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 (csp_isPAL(pict.csp))  {   pict.palette.pal=(unsigned char*)(inhdr+1);   pict.palette.numcolors=inhdr->biClrUsed;  }   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)  return ffproc->processPict(params.framenum,pict,enccsp); else   return src?enc->compress(pict,params):enc->flushEnc(pict,params);}STDMETHODIMP TffdshowEnc::TffProcVideoEnc::deliverProcessedSample(TffPict &pict){ return self->enc->compress(pict,self->params);}STDMETHODIMP TffdshowEnc::deliverEncodedSample(const TmediaSample &sample,TencFrameParams &params){ _mm_empty();  params.outlength=coSettings->storeAVI?params.length:0; if (mux)  mux->writeFrame(sample,params.length,params); if (params.keyframe)  keyspacing=0; totalsize+=params.length; if (outputdebug || outputdebugfile)  if (cfgcomode==ENC_MODE::PASS2_2_INT || cfgcomode==ENC_MODE::PASS2_2_EXT)   pass->writeInfo(params);  else   dbgWrite(_l("1st-pass: size:%d total-kbytes:%d %s quant:%d %s kblocks:%d mblocks:%d\n"),params.length,int(totalsize/1024),FRAME_TYPE::name(params.frametype),params.quant,encQuantTypes[params.quanttype],params.kblks,params.mblks); if (pass)  if (pass->update(params)==false)   return ICERR_ERROR; params.framenum++;keyspacing++;  encStats.add(params); if (h_graph) PostMessage(h_graph,TencStats::MSG_FF_FRAME,params.length,(params.quant<<20)|params.frametype); return ICERR_OK;}STDMETHODIMP TffdshowEnc::JoinFilterGraph(IFilterGraph *pGraph,LPCWSTR pName){  return onJoinFilterGraph(pGraph,pName);}HRESULT TffdshowEnc::onGraphRemove(void){ _release(); return TffdshowBase::onGraphRemove();}void TffdshowEnc::sendOnChange(int paramID,int val){ if (paramID!=IDFF_enc_fpsRate && paramID!=IDFF_enc_fpsScale &&     paramID!=IDFF_enc_fpsScale    )  TffdshowBase::sendOnChange(paramID,val);}STDMETHODIMP TffdshowEnc::setCoSettingsPtr(TcoSettings *coSettingsPtr){ if (!coSettingsPtr) return E_POINTER; coSettings=coSettingsPtr; new(coSettings)TcoSettings(options); notifyParamsChanged(); return S_OK;}STDMETHODIMP TffdshowEnc::getCoSettingsPtr(const TcoSettings* *coSettingsPtr){ if (!coSettingsPtr) return E_POINTER; *coSettingsPtr=coSettings; return S_OK;}STDMETHODIMP TffdshowEnc::loadEncodingSettings(void){ initCo(); return S_OK;}STDMETHODIMP TffdshowEnc::saveEncodingSettings(void){ initCo(); if (!notreg) coSettings->saveReg(); return S_OK;}HRESULT TffdshowEnc::onInitDialog(void){ loadEncodingSettings(); return S_OK;}void TffdshowEnc::onTrayIconChange(int id,int newval){ if (working)  TffdshowBase::onTrayIconChange(id,newval);}void TffdshowEnc::lockReceive(void){ m_csReceive.Lock();}void TffdshowEnc::unlockReceive(void){ m_csReceive.Unlock();}void TffdshowEnc::getColls(TintStrColls &colls){ if (coSettings)  colls.push_back(coSettings->options); TffdshowBase::getColls(colls); }TinfoBase* TffdshowEnc::createInfo(void){ return new TinfoBase(this);}HRESULT TffdshowEnc::muxHeader(const void *data,size_t datalen,int flush){ if (!mux) return E_UNEXPECTED; return mux->writeHeader(data,datalen,!!flush,biOutput.bmiHeader)==0?S_FALSE:S_OK;}STDMETHODIMP TffdshowEnc::getEncStats(TencStats* *encStatsPtr){ if (!encStatsPtr) return E_POINTER; *encStatsPtr=&encStats; return S_OK;}STDMETHODIMP TffdshowEnc::isLAVCadaptiveQuant(void){ return coSettings->isLAVCadaptiveQuant();}STDMETHODIMP TffdshowEnc::isQuantControlActive(void){ return coSettings->isQuantControlActive();}STDMETHODIMP_(int) TffdshowEnc::getQuantType2(int quant){ return coSettings->getQuantType(quant);}STDMETHODIMP TffdshowEnc::getCustomQuantMatrixes(unsigned char* *intra8,unsigned char* *inter8,unsigned char* *intra4Y,unsigned char* *inter4Y,unsigned char* *intra4C,unsigned char* *inter4C){ if (intra8) *intra8=(unsigned char*)&coSettings->qmatrix_intra_custom0; if (inter8) *inter8=(unsigned char*)&coSettings->qmatrix_inter_custom0; if (intra4Y) *intra4Y=(unsigned char*)&coSettings->qmatrix_intra4x4Y_custom0; if (inter4Y) *inter4Y=(unsigned char*)&coSettings->qmatrix_inter4x4Y_custom0; if (intra4C) *intra4C=(unsigned char*)&coSettings->qmatrix_intra4x4C_custom0; if (inter4C) *inter4C=(unsigned char*)&coSettings->qmatrix_inter4x4C_custom0; return S_OK;}STDMETHODIMP TffdshowEnc::getEncoder(int codecId,const Tencoder* *encPtr){ if (!encPtr) return E_POINTER; *encPtr=enclibs.getEncoder(codecId); return S_OK;}STDMETHODIMP TffdshowEnc::getVideoCodecs(const TvideoCodecs* *codecs){ if (!codecs) return E_POINTER; *codecs=&enclibs; return S_OK;}void TffdshowEnc::getFFproc(void){ if (!ffproc)   {   HRESULT hr;   ffproc=new TffProcVideoEnc(NULL,&hr,this);   ffproc->setTempPreset("ffdshowenc temporary preset");   ffproc->loadPreset("ffdshowenc");  }}STDMETHODIMP TffdshowEnc::getFFproc(TffProcVideo* *procPtr){ if (!procPtr) return E_POINTER; getFFproc(); *procPtr=ffproc; return S_OK;}STDMETHODIMP_(int) TffdshowEnc::loadEncodingSettingsMem(const void *buf,int len){ initCo(); lzo_uint lenD=len*10; unsigned char *bufD=(unsigned char*)malloc(lenD); if (lzo1x_decompress((unsigned char*)buf,len,bufD,&lenD,NULL)<0) return 0; const unsigned char *last; TregOpIDstreamRead t(bufD,lenD,(const void**)&last); coSettings->reg_op(t); getFFproc(); if (ffproc && last!=bufD+lenD && *(short*)last==0)  {   last+=3;   ffproc->loadConfig(!!notreg,last,lenD-(last-bufD));  }  free(bufD); coSettings->fillIncsps(); return len;}STDMETHODIMP_(int) TffdshowEnc::saveEncodingSettingsMem(void *buf,int len){ initCo(); TregOpIDstreamWrite t; coSettings->reg_op(t); getFFproc(); if (ffproc) ffproc->saveConfig(t); lzo_uint lenC=(lzo_uint)t.size()*2; unsigned char *bufC=(unsigned char*)malloc(lenC); unsigned char work[LZO1X_MEM_COMPRESS]; lzo1x_1_compress(&*t.begin(),(lzo_uint)t.size(),bufC,&lenC,work); if (buf) memcpy(buf,bufC,lenC); free(bufC); return (int)lenC;}STDMETHODIMP TffdshowEnc::getInCodecString(char_t *buf,size_t buflen){ if (!buf) return E_POINTER; if (inColorspace==0)  buf[0]='\0'; else  csp_getName(inColorspace,buf,buflen); return S_OK;}STDMETHODIMP TffdshowEnc::getOutCodecString(char_t *buf,size_t buflen){ if (!buf) return E_POINTER; if (!enc) return E_UNEXPECTED; strncpy(buf,enc->getName(),buflen); buf[buflen-1]='\0'; return S_OK;}//================================== DirectShow ====================================STDMETHODIMP_(LRESULT) TffdshowEncDshow::begin(const BITMAPINFOHEADER *inhdr){ HRESULT hr=TffdshowEnc::begin(inhdr); if (SUCCEEDED(hr))  times.clear(); return hr; }HRESULT TffdshowEncDshow::Receive(IMediaSample *pIn){ if (!started)  if (!start()) return E_FAIL;   BYTE *src=NULL; if (pIn->GetPointer(&src)!=S_OK) return S_FALSE; size_t srcLen=pIn->GetActualDataLength(); REFERENCE_TIME rtStart,rtStop; if (FAILED(pIn->GetTime(&rtStart,&rtStop)))  rtStart=rtStop=REFTIME_INVALID; return (HRESULT)compress(&inpin->biIn.bmiHeader,src,srcLen,rtStart,rtStop);}STDMETHODIMP TffdshowEncDshow::getDstBuffer(IMediaSample* *pOut,const TffPict &pict){ *pOut=NULL;BYTE *data; HRESULT hr; if (FAILED(hr=getDeliveryBuffer(pOut,&data)))  return hr;  if (coSettings->isFPSoverride || pict.rtStart==REFTIME_INVALID || pict.rtStop==REFTIME_INVALID)   {   REFERENCE_TIME tStart=(params.framenum  )*inpin->avgTimePerFrame;   REFERENCE_TIME tStop =(params.framenum+1)*inpin->avgTimePerFrame;   setPropsTime(*pOut,tStart,tStop,m_pInput->SampleProps(),&m_bSampleSkipped);   //DPRINTF("tStart:%i, tStop:%i, AVIfps:%i",int(tStart),int(tStop),timePerFrame);  } else  (*pOut)->SetTime((REFERENCE_TIME*)&pict.rtStart,(REFERENCE_TIME*)&pict.rtStop); AM_MEDIA_TYPE *mtOut; (*pOut)->GetMediaType(&mtOut); if (mtOut!=NULL)  {   HRESULT result=S_OK;   DeleteMediaType(mtOut);   if (result!=S_OK) return result;  } return S_OK;}STDMETHODIMP TffdshowEncDshow::deliverError(void){ return E_FAIL;}STDMETHODIMP TffdshowEncDshow::deliverEncodedSample(const TmediaSample &sample,TencFrameParams &params){ REFERENCE_TIME rtStart,rtStop; if (sample->GetTime(&rtStart,&rtStop)==S_OK)  times.push_back(std::make_pair(rtStart,rtStop)); if (params.frametype==FRAME_TYPE::DELAY)  {   sample->Release();   return S_OK;  } HRESULT hr; if (FAILED(hr=TffdshowEnc::deliverEncodedSample(sample,params)))  return hr;   if (!times.empty())   {   rtStart=times.front().first;   rtStop=times.front().second;   sample->SetTime(&rtStart,&rtStop);   times.pop_front();  } sample->SetSyncPoint(params.keyframe?TRUE:FALSE); sample->SetActualDataLength(params.outlength);  if (fileout)  {   ft2+=params.outlength;   sample->SetTime(&ft1,&ft2);   ft1+=params.outlength;  } IMediaSample **s=(IMediaSample**)&sample;  return m_pOutput->Deliver(*s);}//===================================== VFW ========================================STDMETHODIMP TffdshowEncVFW::getDstBuffer(IMediaSample* *samplePtr,const TffPict &pict){ if (!samplePtr) return E_POINTER; struct TfakeEncMediaSample : TfakeMediaSample,CUnknown  {  private:   void *buf;long bufsize;  public:   TfakeEncMediaSample(void *Ibuf,long Ibufsize):buf(Ibuf),bufsize(Ibufsize),CUnknown("TfakeEncMediaSample",NULL) {}   DECLARE_IUNKNOWN   virtual HRESULT STDMETHODCALLTYPE GetPointer(BYTE **ppBuffer)     {     if (!ppBuffer) return E_POINTER;     return (*ppBuffer=(uint8_t*)buf)!=NULL?S_OK:E_FAIL;    }   virtual long STDMETHODCALLTYPE GetSize(void) {return bufsize;}  }; *samplePtr=new TfakeEncMediaSample(icc->lpOutput,icc->lpbiOutput->biSizeImage); (*samplePtr)->AddRef(); return S_OK;}STDMETHODIMP TffdshowEncVFW::deliverError(void){ return ICERR_ERROR;}STDMETHODIMP TffdshowEncVFW::deliverEncodedSample(const TmediaSample &sample,TencFrameParams &params){ HRESULT hr; if (FAILED(hr=TffdshowEnc::deliverEncodedSample(sample,params)))  return hr; icc->lpbiOutput->biSizeImage=params.outlength; if (icc->lpdwFlags) *icc->lpdwFlags=params.keyframe?AVIIF_KEYFRAME:0; return hr;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?