⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tvideocodecwmv9.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
字号:
/*
 * Copyright (c) 2002-2006 Milan Cutka
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "stdafx.h"
#include "wmv9/ff_wmv9.h"
#include "TvideoCodecWmv9.h"
#include "Tdll.h"
#include "ffcodecs.h"
#include "TcodecSettings.h"
#include "IffdshowBase.h"
#include "IffdshowDecVideo.h"
#include "dsutil.h"

const char_t* TvideoCodecWmv9::dllname=_l("ff_wmv9.dll");

TvideoCodecWmv9::TvideoCodecWmv9(IffdshowBase *Ideci,IdecVideoSink *IsinkD):
 Tcodec(Ideci),TcodecDec(Ideci,IsinkD),
 TvideoCodec(Ideci),
 TvideoCodecDec(Ideci,IsinkD),
 TvideoCodecEnc(Ideci,NULL)
{
 create();
}
TvideoCodecWmv9::TvideoCodecWmv9(IffdshowBase *Ideci,IencVideoSink *IsinkE):
 Tcodec(Ideci),TcodecDec(Ideci,NULL),
 TvideoCodec(Ideci),
 TvideoCodecDec(Ideci,NULL),
 TvideoCodecEnc(Ideci,IsinkE),
 codecIndex(-1)
{
 create();
 if (ok)
  {
   size_t cnt=wmv9->getCodecCount();
   infos=new Tff_wmv9codecInfo[cnt];
   for (size_t i=0;i<cnt;i++)
    {
     const Tff_wmv9codecInfo *info;
     wmv9->getCodecInfo(i,&info);
     infos[info->index]=*info;
     encoders.push_back(new TencoderWmv9(info->name,CodecID(CODEC_ID_WMV9_LIB+info->index),Tfourccs(info->fcc,0),info->cmplxMax));
    }
  }
}

void TvideoCodecWmv9::create(void)
{
 ok=false;
 wmv9=NULL;infos=NULL;
 dll=new Tdll(dllname,config);
 dll->loadFunction(createWmv9,"createWmv9");
 dll->loadFunction(destroyWmv9,"destroyWmv9");
 if (dll->ok)
  {
   wmv9=createWmv9();
   ok=wmv9->getOk();
  }
}
TvideoCodecWmv9::~TvideoCodecWmv9()
{
 end();
 if (dll)
  {
   if (wmv9) destroyWmv9(wmv9);
   delete dll;
  }
 if (infos) delete []infos;
}

const char_t* TvideoCodecWmv9::getName(void) const
{
 tsprintf(codecName,_l("wmv9"),codecIndex>=0?_l(" ("):_l(""),codecIndex>=0?infos[codecIndex].name:_l(""),codecIndex>=0?_l(")"):_l(""));
 return codecName;
}

void TvideoCodecWmv9::getCompressColorspaces(Tcsps &csps,unsigned int outDx,unsigned int outDy)
{
 if (coCfg->wmv9_aviout)
  switch (infos[coCfg->codecId-CODEC_ID_WMV9_LIB].fcc)
   {
    case mmioFOURCC('M','S','S','1'):
    case mmioFOURCC('M','S','S','2'):
     csps.addEnd(FF_CSP_NULL,FF_CSP_RGB24|FF_CSP_FLAGS_VFLIP,FF_CSP_RGB32|FF_CSP_FLAGS_VFLIP,FF_CSP_RGB15|FF_CSP_FLAGS_VFLIP,FF_CSP_RGB16|FF_CSP_FLAGS_VFLIP,FF_CSP_NULL);
     return;
   }
 csps.add(FF_CSP_420P|FF_CSP_FLAGS_YUV_ADJ);
}

LRESULT TvideoCodecWmv9::beginCompress(int cfgcomode,int csp,const Trect &r)
{
 if (!wmv9) return ICERR_ERROR;
 Tff_wmv9cfg cfg9;memset(&cfg9,0,sizeof(cfg9));
 cfg9.codecIndex=codecIndex=coCfg->codecId-CODEC_ID_WMV9_LIB;
 cfg9.bitrate=coCfg->bitrate1000*1024;
 cfg9.width=r.dx;
 cfg9.height=r.dy;
 cfg9.csp=csp;
 cfg9.fps=double(deci->getParam2(IDFF_enc_fpsRate))/deci->getParam2(IDFF_enc_fpsScale);
 cfg9.quality=coCfg->qual;
 cfg9.crisp=coCfg->wmv9_crisp;
 cfg9.seckf=coCfg->wmv9_kfsecs;
 cfg9.bUseVBR=(cfgcomode==ENC_MODE::CBR)?FALSE:TRUE;
 cfg9.vbr_mode=(cfgcomode==ENC_MODE::CBR)?VBR_OFF:VBR_QUALITYBASED;
 cfg9.vbrquality=coCfg->qual;
 cfg9.maxbitrate=1000000;
 cfg9.ivtc=!!coCfg->wmv9_ivtc;
 cfg9.deint=!!coCfg->wmv9_deint;
 cfg9.cplx=std::min(coCfg->wmv9_cplx,infos[cfg9.codecIndex].cmplxMax);
 cfg9.avioutput=!!coCfg->wmv9_aviout;
 if (coCfg->storeExt)
  {
   cfg9.flnm=coCfg->storeExtFlnm[0]?coCfg->storeExtFlnm:NULL;
   deci->putParam(IDFF_enc_ownStoreExt,!cfg9.avioutput);
  }
 return wmv9->start(cfg9)?ICERR_OK:ICERR_ERROR;
}
bool TvideoCodecWmv9::getExtradata(const void* *ptr,size_t *len)
{
 if (!len || !wmv9) return false;
 wmv9->getExtradata(ptr,len);
 return true;
}
HRESULT TvideoCodecWmv9::compress(const TffPict &pict,TencFrameParams &params)
{
 TmediaSample sample;
 HRESULT hr;
 if (FAILED(hr=sinkE->getDstBuffer(&sample,pict)))
  return hr;
 int len=wmv9->write(params.framenum,pict.csp,pict.data,pict.stride,sample);
 if (len<0)
  {
   params.frametype=FRAME_TYPE::I;
   params.keyframe=true;
  }
 else
  params.frametype=FRAME_TYPE::P;
 params.quant=1;
 params.length=abs(len);
 return sinkE->deliverEncodedSample(sample,params);
}
void TvideoCodecWmv9::end(void)
{
 if (wmv9) wmv9->end();
 codecIndex=-1;
}

bool TvideoCodecWmv9::testMediaType(FOURCC fcc,const CMediaType &mt)
{
 if (wmv9)
  {
   const Tff_wmv9codecInfo *codec=wmv9->findCodec(fcc);
   if (!codec) return CODEC_ID_NONE;
   codecIndex=codec->index;
   return !!codec;
  }
 else
  return CODEC_ID_NONE;
}

bool TvideoCodecWmv9::beginDecompress(TffPictBase &pict,FOURCC infcc,const CMediaType &mt,int sourceFlags)
{
 Textradata extradata(mt);
 rd=pict.rectFull;
 if (wmv9->decStart(infcc,deciV->getAVIfps1000_2()/1000.0,pict.rectFull.dx,pict.rectFull.dy,extradata.data,extradata.size,&csp))
  {
   pict.csp=csp;
   return true;
  }
 else
  return false;
}

HRESULT TvideoCodecWmv9::decompress(const unsigned char *src,size_t srcLen,IMediaSample *pIn)
{
 unsigned char *dst[4]={NULL,NULL,NULL,NULL};stride_t stride[4]={0,0,0,0};
 if (wmv9->decompress(src,srcLen,&dst[0],&stride[0])!=0 && dst[0])
  {
   if (pIn->IsPreroll()==S_OK)
    return sinkD->deliverPreroll(pIn->IsSyncPoint()?FRAME_TYPE::I:FRAME_TYPE::P);
   TffPict pict(csp,dst,stride,rd,true,pIn);
   return sinkD->deliverDecodedSample(pict);
  }
 else return S_FALSE;
}

⌨️ 快捷键说明

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