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

📄 tconvert.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright (c) 2003-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 "IffdshowBase.h"
#include "ffdshow_constants.h"
#include "Tconfig.h"
#include "Tconvert.h"
#include "ffImgfmt.h"
#include "convert_yv12.h"
#include "convert_yuy2.h"
#include "Tswscale.h"
#include "image.h"
#include "ffdebug.h"
#include "TffPict.h"
#include "Tlibmplayer.h"
#include "libavcodec/bitstream.h"

//======================================= Tconvert =======================================
Tconvert::Tconvert(IffdshowBase *deci,unsigned int Idx,unsigned int Idy)
{
 Tlibmplayer *libmplayer;
 deci->getPostproc(&libmplayer);
 bool avisynthYV12_RGB=!!deci->getParam2(IDFF_avisynthYV12_RGB);
 init(libmplayer,avisynthYV12_RGB,Idx,Idy);
}
Tconvert::Tconvert(Tlibmplayer *Ilibmplayer,bool IavisynthYV12_RGB,unsigned int Idx,unsigned int Idy)
{
 Ilibmplayer->AddRef();
 init(Ilibmplayer,IavisynthYV12_RGB,Idx,Idy);
}
void Tconvert::init(Tlibmplayer *Ilibmplayer,bool IavisynthYV12_RGB,unsigned int Idx,unsigned int Idy)
{
 libmplayer=Ilibmplayer;
 dx=Idx;
 dy=Idy&~1;
 outdy=Idy;
 swscale=NULL;
 oldincsp=oldoutcsp=-1;incspInfo=outcspInfo=NULL;
 initsws=true;
 tmp[0]=tmp[1]=tmp[2]=NULL;
 tmpConvert1=tmpConvert2=NULL;
 avisynthYV12_RGB=IavisynthYV12_RGB;
}

Tconvert::~Tconvert()
{
 freeTmpConvert();
 if (swscale) delete swscale;
 libmplayer->Release();
}

const char_t* Tconvert::getModeName(int mode)
{
 switch (mode)
  {
   case MODE_none:return _l("none");
   case MODE_avisynth_yv12_to_yuy2:return _l("avisynth_yv12_to_yuy2");
   case MODE_xvidImage_output:return _l("xvidImage_output");
   case MODE_avisynth_yuy2_to_yv12:return _l("avisynth_yuy2_to_yv12");
   case MODE_mmx_ConvertRGB32toYUY2:return _l("mmx_ConvertRGB32toYUY2");
   case MODE_mmx_ConvertRGB24toYUY2:return _l("mmx_ConvertRGB24toYUY2");
   case MODE_mmx_ConvertYUY2toRGB32:return _l("mmx_ConvertYUY2toRGB32");
   case MODE_mmx_ConvertYUY2toRGB24:return _l("mmx_ConvertYUY2toRGB24");
   case MODE_mmx_ConvertUYVYtoRGB32:return _l("mmx_ConvertUYVYtoRGB32");
   case MODE_mmx_ConvertUYVYtoRGB24:return _l("mmx_ConvertUYVYtoRGB24");
   case MODE_palette8torgb:return _l("palette8torgb");
   case MODE_CLJR:return _l("CLJR");
   case MODE_xvidImage_input:return _l("xvidImage_input");
   case MODE_swscale:return _l("swscale");
   case MODE_avisynth_bitblt:return _l("avisynth_bitblt");
   case MODE_fallback:return _l("fallback");
   default:return _l("unknown");
  }
}

void Tconvert::freeTmpConvert(void)
{
 if (tmp[0]) aligned_free(tmp[0]);tmp[0]=NULL;
 if (tmp[1]) aligned_free(tmp[1]);tmp[1]=NULL;
 if (tmp[2]) aligned_free(tmp[2]);tmp[2]=NULL;
 if (tmpConvert1) delete tmpConvert1;tmpConvert1=NULL;
 if (tmpConvert2) delete tmpConvert2;tmpConvert2=NULL;
}

int Tconvert::convert(int incsp0,const uint8_t*const src0[],const stride_t srcStride0[],int outcsp0,uint8_t* dst0[],stride_t dstStride0[],const Tpalette *srcpal)
{
 bool wasChange;
 int incsp=incsp0,outcsp=outcsp0;
 if (!incspInfo || incspInfo->id!=(incsp&FF_CSPS_MASK) || !outcspInfo || outcspInfo->id!=(outcsp&FF_CSPS_MASK))
  {
   incspInfo=csp_getInfo(incsp);
   outcspInfo=csp_getInfo(outcsp);
   wasChange=true;
  }
 else wasChange=false;

 const unsigned char *src[]={src0[0],src0[1],src0[2],src0[3]};
 stride_t srcStride[]={srcStride0[0],srcStride0[1],srcStride0[2],srcStride0[3]};
 csp_yuv_adj_to_plane(incsp ,incspInfo ,dy,(unsigned char**)src,srcStride);
 csp_yuv_order(incsp ,(unsigned char**)src,srcStride);
 csp_vflip(incsp ,incspInfo, (unsigned char**)src,srcStride,dy);

 unsigned char *dst[]={dst0[0],dst0[1],dst0[2],dst0[3]};
 stride_t dstStride[]={dstStride0[0],dstStride0[1],dstStride0[2],dstStride0[3]};
 if(outcspInfo->id==FF_CSP_420P)
  csp_yuv_adj_to_plane(outcsp,outcspInfo,ODD2EVEN(outdy),(unsigned char**)dst,dstStride);
 else
  csp_yuv_adj_to_plane(outcsp,outcspInfo,dy,(unsigned char**)dst,dstStride);
 csp_yuv_order(outcsp,(unsigned char**)dst,dstStride);
 csp_vflip(outcsp,outcspInfo,(unsigned char**)dst,dstStride,dy);

 if (wasChange || oldincsp!=incsp || oldoutcsp!=outcsp)
  {
   oldincsp=incsp;oldoutcsp=outcsp;
   freeTmpConvert();
   incsp1=incsp&FF_CSPS_MASK;outcsp1=outcsp&FF_CSPS_MASK;
   mode=MODE_none;
   #ifdef AVISYNTH_BITBLT
   if (incsp1==outcsp1)
    {
     rowsize=dx*incspInfo->Bpp;
     mode=MODE_avisynth_bitblt;
    }
   else
   #else
    switch (incsp1)
     {
      case FF_CSP_420P:
       switch (outcsp1)
        {
         case FF_CSP_YUY2: //YV12 -> YUY2
          mode=MODE_avisynth_yv12_to_yuy2;
          if (incsp&FF_CSP_FLAGS_INTERLACED)
         #ifdef __SSE2__
           if (Tconfig::cpu_flags&FF_CPU_SSE2)
            avisynth_yv12_to_yuy2=TconvertYV12<Tsse2>::yv12_i_to_yuy2;
           else
         #endif
           if (Tconfig::cpu_flags&FF_CPU_MMXEXT)
            avisynth_yv12_to_yuy2=TconvertYV12<Tmmxext>::yv12_i_to_yuy2;
           else
            avisynth_yv12_to_yuy2=TconvertYV12<Tmmx>::yv12_i_to_yuy2;
          else
         #ifdef __SSE2__
           if (Tconfig::cpu_flags&FF_CPU_SSE2)
            avisynth_yv12_to_yuy2=TconvertYV12<Tsse2>::yv12_to_yuy2;
           else
         #endif
           if (Tconfig::cpu_flags&FF_CPU_MMXEXT)
            avisynth_yv12_to_yuy2=TconvertYV12<Tmmxext>::yv12_to_yuy2;
           else
            avisynth_yv12_to_yuy2=TconvertYV12<Tmmx>::yv12_to_yuy2;
          break;
         default:
          if (avisynthYV12_RGB && (outcsp1==FF_CSP_RGB24 || outcsp1==FF_CSP_RGB32))
           {
            mode=MODE_fallback;
            tmpcsp=FF_CSP_YUY2;
            tmpStride[0]=2*(dx/16+2)*16;
            tmp[0]=(unsigned char*)aligned_malloc(tmpStride[0]*dy);
            tmpConvert1=new Tconvert(libmplayer,avisynthYV12_RGB,dx,dy);
            tmpConvert2=new Tconvert(libmplayer,avisynthYV12_RGB,dx,dy);
            if (incsp&FF_CSP_FLAGS_INTERLACED || outcsp&FF_CSP_FLAGS_INTERLACED) tmpcsp|=FF_CSP_FLAGS_INTERLACED;
           }
          else
           if (csp_supXvid(outcsp1)
            #ifndef XVID_BITBLT
             && outcsp1!=FF_CSP_420P
            #endif
             )
            mode=MODE_xvidImage_output;
          break;
        }
       break;
      case FF_CSP_YUY2:
       switch (outcsp1)
        {
         case FF_CSP_420P: // YUY2 -> YV12
          mode=MODE_avisynth_yuy2_to_yv12;
          if (incsp&FF_CSP_FLAGS_INTERLACED)
         #ifdef __SSE2__
           if (Tconfig::cpu_flags&FF_CPU_SSE2)
            avisynth_yuy2_to_yv12=TconvertYV12<Tsse2>::yuy2_i_to_yv12;
           else
         #endif
           if (Tconfig::cpu_flags&FF_CPU_MMXEXT)
            avisynth_yuy2_to_yv12=TconvertYV12<Tmmxext>::yuy2_i_to_yv12;
           else
            avisynth_yuy2_to_yv12=TconvertYV12<Tmmx>::yuy2_i_to_yv12;
          else
         #ifdef __SSE2__
           if (Tconfig::cpu_flags&FF_CPU_SSE2)
            avisynth_yuy2_to_yv12=TconvertYV12<Tsse2>::yuy2_to_yv12;
           else
         #endif
           if (Tconfig::cpu_flags&FF_CPU_MMXEXT)
            avisynth_yuy2_to_yv12=TconvertYV12<Tmmxext>::yuy2_to_yv12;
           else
            avisynth_yuy2_to_yv12=TconvertYV12<Tmmx>::yuy2_to_yv12;
          break;
         case FF_CSP_RGB24:
          mode=MODE_mmx_ConvertYUY2toRGB24; // YUY2 -> RGB24
          break;
         case FF_CSP_RGB32:
          mode=MODE_mmx_ConvertYUY2toRGB32; // YUY2 -> RGB32
          break;
        }
       break;
      case FF_CSP_UYVY:
       switch (outcsp1)
        {
         case FF_CSP_RGB24:
          mode=MODE_mmx_ConvertUYVYtoRGB24; // UYVY -> RGB24
          break;
         case FF_CSP_RGB32:
          mode=MODE_mmx_ConvertUYVYtoRGB32; // UYVY -> RGB32
          break;
        }
       break;
      case FF_CSP_RGB32:
       if (outcsp1==FF_CSP_YUY2) // RGB32 -> YUY2
        mode=MODE_mmx_ConvertRGB32toYUY2;
       break;
      case FF_CSP_RGB24:

⌨️ 快捷键说明

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