我使用ffmpeg SDK解码h.264文件 希望直接输出RGB格式 应该如何设置、初始化解码器呢, 现在我遇到的问题是使用ffmpgeg封装解码插件输出YV12格式 连接微软的AVI decompress filter之后输出到render 无法收到反馈信息 所以希望直接解码输出RGB 试了ffmpeg的swscale函数 似乎有些问题。 多谢回复
------解决方案--------------------------------------------------------
ffmpeg默认解出来的是YUV420P,不是YV12。
如果要转成RGB的话,swscale是最佳的转换方案,但是如果你不想用swscale,也可以用一些普通的转换算法。
此外,如果要用AVI decompress filter,可以用RGB24,或者RGB32都可以。
下面是一个YUV420P转RGB24的算法:
#include "convert.h"
// Convert from RGB to YUV420
int RGB2YUV_YR[256], RGB2YUV_YG[256], RGB2YUV_YB[256];
int RGB2YUV_UR[256], RGB2YUV_UG[256], RGB2YUV_UBVR[256];
int RGB2YUV_VG[256], RGB2YUV_VB[256];
// Conversion from YUV420 to RGB24
static long int crv_tab[256];
static long int cbu_tab[256];
static long int cgu_tab[256];
static long int cgv_tab[256];
static long int tab_76309[256];
static unsigned char clp[1024]; //for clip in CCIR601
//
// Table used for RGB to YUV420 conversion
//
void InitLookupTable()
{
int i;
for (i = 0; i < 256; i++) RGB2YUV_YR[i] = (float)65.481 * (i<<8);
for (i = 0; i < 256; i++) RGB2YUV_YG[i] = (float)128.553 * (i<<8);
for (i = 0; i < 256; i++) RGB2YUV_YB[i] = (float)24.966 * (i<<8);
for (i = 0; i < 256; i++) RGB2YUV_UR[i] = (float)37.797 * (i<<8);
for (i = 0; i < 256; i++) RGB2YUV_UG[i] = (float)74.203 * (i<<8);
for (i = 0; i < 256; i++) RGB2YUV_VG[i] = (float)93.786 * (i<<8);
for (i = 0; i < 256; i++) RGB2YUV_VB[i] = (float)18.214 * (i<<8);
for (i = 0; i < 256; i++) RGB2YUV_UBVR[i] = (float)112 * (i<<8);
}
//
// Convert from RGB24 to YUV420
//
int ConvertRGB2YUV(int w,int h,unsigned char *bmp,unsigned int *yuv)
{
unsigned int *u,*v,*y,*uu,*vv;
unsigned int *pu1,*pu2,*pu3,*pu4;
unsigned int *pv1,*pv2,*pv3,*pv4;
unsigned char *r,*g,*b;
int i,j;
uu=new unsigned int[w*h];
vv=new unsigned int[w*h];
if(uu==NULL || vv==NULL)
return 0;
y=yuv;
u=uu;
v=vv;
// Get r,g,b pointers from bmp image data....
r=bmp;
g=bmp+1;
b=bmp+2;
//Get YUV values for rgb values...
for(i=0;i<h;i++)
{
for(j=0;j<w;j++)
{
*y++=( RGB2YUV_YR[*r] +RGB2YUV_YG[*g]+RGB2YUV_YB[*b]+1048576)>>16;
*u++=(-RGB2YUV_UR[*r] -RGB2YUV_UG[*g]+RGB2YUV_UBVR[*b]+8388608)>>16;
*v++=( RGB2YUV_UBVR[*r]-RGB2YUV_VG[*g]-RGB2YUV_VB[*b]+8388608)>>16;
r+=3;
g+=3;
b+=3;
}
}
// Now sample the U & V to obtain YUV 4:2:0 format
// Sampling mechanism...
/* @ -> Y
# -> U or V
@ @ @ @
# #
@ @ @ @
@ @ @ @
# #
@ @ @ @
*/
// Get the right pointers...
u=yuv+w*h;
v=u+(w*h)/4;
// For U
pu1=uu;
pu2=pu1+1;
pu3=pu1+w;
pu4=pu3+1;
// For V
pv1=vv;
pv2=pv1+1;
pv3=pv1+w;
pv4=pv3+1;
// Do sampling....
for(i=0;i<h;i+=2)
{
for(j=0;j<w;j+=2)
{
*u++=(*pu1+*pu2+*pu3+*pu4)>>2;
*v++=(*pv1+*pv2+*pv3+*pv4)>>2;
pu1+=2;
pu2+=2;
pu3+=2;
pu4+=2;
pv1+=2;
pv2+=2;
pv3+=2;
pv4+=2;
}
pu1+=w;
pu2+=w;
pu3+=w;
pu4+=w;
pv1+=w;
pv2+=w;
pv3+=w;
pv4+=w;
}