📄 tconvert.cpp
字号:
/*
* 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 + -