首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 媒体动画 > 多媒体 >

ffmpeg SDK使用有关问题

2012-05-21 
ffmpeg SDK使用问题我使用ffmpeg SDK解码h.264文件希望直接输出RGB格式应该如何设置、初始化解码器呢, 现在

ffmpeg SDK使用问题
我使用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;
  
 }




 delete uu;
 delete vv;

return 1;
}

 

 

 

//
//Initialize conversion table for YUV420 to RGB
//
void InitConvertTable()
{
long int crv,cbu,cgu,cgv;
int i,ind;

crv = 104597; cbu = 132201; /* fra matrise i global.h */
cgu = 25675; cgv = 53279;
  
for (i = 0; i < 256; i++) {
crv_tab[i] = (i-128) * crv;
cbu_tab[i] = (i-128) * cbu;
cgu_tab[i] = (i-128) * cgu;
cgv_tab[i] = (i-128) * cgv;
tab_76309[i] = 76309*(i-16);
}
  
for (i=0; i<384; i++)
clp[i] =0;
ind=384;
for (i=0;i<256; i++)
clp[ind++]=i;
ind=640;
for (i=0;i<384;i++)
clp[ind++]=255;
}


//
// Convert from YUV420 to RGB24
//
void ConvertYUV2RGB(unsigned char *src0,unsigned char *src1,unsigned char *src2,unsigned char *dst_ori,
int width,int height)
{
 int y1,y2,u,v; 
 unsigned char *py1,*py2;
 int i,j, c1, c2, c3, c4;
 unsigned char *d1, *d2;

 py1=src0;
 py2=py1+width;
 d1=dst_ori;
 d2=d1+3*width;
for (j = 0; j < height; j += 2) { 
for (i = 0; i < width; i += 2) {

u = *src1++;
v = *src2++;

c1 = crv_tab[v];
c2 = cgu_tab[u];
c3 = cgv_tab[v];
c4 = cbu_tab[u];

//up-left
y1 = tab_76309[*py1++]; 
*d1++ = clp[384+((y1 + c1)>>16)];
*d1++ = clp[384+((y1 - c2 - c3)>>16)];
*d1++ = clp[384+((y1 + c4)>>16)];

//down-left
y2 = tab_76309[*py2++];
*d2++ = clp[384+((y2 + c1)>>16)];
*d2++ = clp[384+((y2 - c2 - c3)>>16)];
*d2++ = clp[384+((y2 + c4)>>16)];

//up-right
y1 = tab_76309[*py1++];
*d1++ = clp[384+((y1 + c1)>>16)];
*d1++ = clp[384+((y1 - c2 - c3)>>16)];
*d1++ = clp[384+((y1 + c4)>>16)];

//down-right
y2 = tab_76309[*py2++];
*d2++ = clp[384+((y2 + c1)>>16)];
*d2++ = clp[384+((y2 - c2 - c3)>>16)];
*d2++ = clp[384+((y2 + c4)>>16)];
}
d1 += 3*width;
d2 += 3*width;
py1+= width;
py2+= width;
 }


}

 

上面是CPP函数定义,以下是头文件
分别实现YUV420TORGB24和RGB24TOYUV420的转换
#include<stdio.h>

// Conversion from RGB24 to YUV420
void InitLookupTable();
int ConvertRGB2YUV(int w,int h,unsigned char *rgbdata,unsigned int *yuv);

// Conversion from YUV420 to RGB24
void InitConvertTable();
void ConvertYUV2RGB(unsigned char *src0,unsigned char *src1,unsigned char *src2,unsigned char *dst_ori,
int width,int height);
 
更多的相关算法,可以访问我的博客:
http://www.rosoo.net/a/Media/AVPlay/200911/7969.html

[解决办法]
楼上说的对。ffmpeg解码出来的是YUV420,楼主是否转换方式不对。
[解决办法]
“。。。如果要转成RGB的话,swscale是最佳的转换方案。。。”
[解决办法]
原因可能是你为输出图像分配的空间有问题,你
out_pic这个结构用av_picture_fill填充了没,而且缓存大小要事先指定好,也就是
233 static AVFrame *alloc_picture(enum PixelFormat pix_fmt, int width, int height)
234 {
235 AVFrame *picture;
236 uint8_t *picture_buf;
237 int size;
238 
239 picture = avcodec_alloc_frame();
240 if (!picture)
241 return NULL;
242 size = avpicture_get_size(pix_fmt, width, height);
243 picture_buf = av_malloc(size);
244 if (!picture_buf) {
245 av_free(picture);


246 return NULL;
247 }
248 avpicture_fill((AVPicture *)picture, picture_buf,
249 pix_fmt, width, height);
250 return picture;
251 }
这里avpicture_get_size(pix_fmt, width, height);
按你说的应该是avpicture_get_size(PIX_FMT_BGR32, 320, 240);
 

热点排行