ffmpeg解码h264到yuv

时间:2021-09-21 04:35:48
各位大牛好,
    小菜鸟请教个问题,具体是这样的:
    我从音视频会议中已经获取了sps和pps后,这个就是i帧,我想解码该帧,用的是ffmpeg的方法
AVFrame *pFrame_ = NULL;

if (!videoCodec) 
{
fprintf(stdout , "codec not found!");
return NULL;
}

//初始化参数,下面的参数应该由具体的业务决定
codec_->time_base.num = 1;
codec_->frame_number = 1; //每包一个视频帧
codec_->codec_type = AVMEDIA_TYPE_VIDEO;
codec_->bit_rate = 0;
codec_->time_base.den = frameRate;//帧率
codec_->width = width;//视频宽
codec_->height = height;//视频高

if(avcodec_open2(codec_, videoCodec, NULL) >= 0)
pFrame_ = avcodec_alloc_frame();// Allocate video frame
else
return NULL;

AVPacket packet = {0};
av_init_packet(&packet);
int frameFinished = dwBufsize;//这个是随便填入数字,没什么作用

packet.data = buf;//这里填入一个指向完整H264数据帧的指针
packet.size = size;//这个填入H264数据帧的大小

//下面开始真正的解码
int ret = avcodec_decode_video2(codec_, pFrame_, &frameFinished, &packet);
if(frameFinished)//成功解码
{
if (pFrame_->key_frame == 1)
{
printf("I frame!\n");
}
if (frameFinished)
{
printf("Got a picture!\n");
}
int picSize = codec_->height * codec_->width;
int newSize = picSize * 1.5;

//申请内存
unsigned char *buf = new unsigned char[newSize];

/*int height = p->codec->height;
int width = p->codec->width;*/
int height = codec_->height;
int width = codec_->width;


//写入数据
int a = 0, i; 
for (i = 0; i < height; i++) 

memcpy(buf + a,pFrame_->data[0] + i * pFrame_->linesize[0], width); 
a += width; 

for (i = 0; i < height/2; i++) 

memcpy(buf + a,pFrame_->data[1] + i * pFrame_->linesize[1], width/2); 
a += width/2; 

for (i = 0; i < height/2; i++) 

memcpy(buf + a,pFrame_->data[2] + i * pFrame_->linesize[2], width/2); 
a += width/2; 
}
}
从网上找的方法,也了解,ret 等于我解码之前的size,frameFinished等于1,但是同时终端报告一个错误
ffmpeg解码h264到yuv
请问这个有可能是由于什么问题造成的呢?希望大牛帮忙~~~

8 个解决方案

#1


该回复于2015-01-01 11:23:47被管理员删除

#2


if(frameFinished)//成功解码
{

struct SwsContext *img_convert_ctx=NULL;
img_convert_ctx = sws_getContext(pCodeCtx->width, pCodeCtx->height,
pCodeCtx->pix_fmt, pCodeCtx->width, pCodeCtx->height,
PIX_FMT_BGR24, SWS_BICUBIC, NULL, NULL, NULL);
// img_convert_ctx=sws_getCachedContext(img_convert_ctx,pCodeCtx->width,pCodeCtx->height,pCodeCtx->pix_fmt,pCodeCtx->width,pCodeCtx->height,PIX_FMT_RGB24,SWS_BICUBIC,NULL,NULL,NULL);

if(img_convert_ctx==NULL){
abort();
}
//将YUV12转换为RGB24

//如果图像格式是YUV420,可以这样实现图像翻转
pFrame->data[0] += pFrame->linesize[0] * (pCodeCtx->height - 1);
pFrame->linesize[0] *= -1;                      
pFrame->data[1] += pFrame->linesize[1] * (pCodeCtx->height / 2 - 1);
pFrame->linesize[1] *= -1;
pFrame->data[2] += pFrame->linesize[2] * (pCodeCtx->height / 2 - 1);
pFrame->linesize[2] *= -1;//*/

sws_scale(img_convert_ctx,(const uint8_t*const*)pFrame->data,pFrame->linesize,0,pCodeCtx->height,pFrameRGB->data,pFrameRGB->linesize);

char temp[10];
_itoa_s(num,temp,10);
char path[256]="bmp/";
strcat_s(path,sizeof(path),temp);strcat_s(path,sizeof(path),fileEx);
++num;
// av_create_bmp(pFrameRGB, pCodeCtx->width, pCodeCtx->height, 24);
BMP_SaveFile(path,pFrameRGB->data[0],pCodeCtx->width,pCodeCtx->height,24);
memset(cTest, 0, 640*480*3);

}

#3


百度下有代码,我以前弄过。。不过代码不知放哪里去了。。

#4


不是转换的问题哦,是在int ret = avcodec_decode_video2(codec_, pFrame_, &frameFinished, &packet);
的时候终端报错: ffmpeg解码h264到yuv
请问有人遇到吗?

#5


你自己构造了packet,看下packet的stream_index是否为视频,之前把音频帧扔进去用这个函数解码是有错误的。

#6


使用这个函数分析一下,av_parser_parse2

#7


楼主,有没h264解码的demo,求个一份

#8


直接解H264裸流的,不是解本地和传URL的

#1


该回复于2015-01-01 11:23:47被管理员删除

#2


if(frameFinished)//成功解码
{

struct SwsContext *img_convert_ctx=NULL;
img_convert_ctx = sws_getContext(pCodeCtx->width, pCodeCtx->height,
pCodeCtx->pix_fmt, pCodeCtx->width, pCodeCtx->height,
PIX_FMT_BGR24, SWS_BICUBIC, NULL, NULL, NULL);
// img_convert_ctx=sws_getCachedContext(img_convert_ctx,pCodeCtx->width,pCodeCtx->height,pCodeCtx->pix_fmt,pCodeCtx->width,pCodeCtx->height,PIX_FMT_RGB24,SWS_BICUBIC,NULL,NULL,NULL);

if(img_convert_ctx==NULL){
abort();
}
//将YUV12转换为RGB24

//如果图像格式是YUV420,可以这样实现图像翻转
pFrame->data[0] += pFrame->linesize[0] * (pCodeCtx->height - 1);
pFrame->linesize[0] *= -1;                      
pFrame->data[1] += pFrame->linesize[1] * (pCodeCtx->height / 2 - 1);
pFrame->linesize[1] *= -1;
pFrame->data[2] += pFrame->linesize[2] * (pCodeCtx->height / 2 - 1);
pFrame->linesize[2] *= -1;//*/

sws_scale(img_convert_ctx,(const uint8_t*const*)pFrame->data,pFrame->linesize,0,pCodeCtx->height,pFrameRGB->data,pFrameRGB->linesize);

char temp[10];
_itoa_s(num,temp,10);
char path[256]="bmp/";
strcat_s(path,sizeof(path),temp);strcat_s(path,sizeof(path),fileEx);
++num;
// av_create_bmp(pFrameRGB, pCodeCtx->width, pCodeCtx->height, 24);
BMP_SaveFile(path,pFrameRGB->data[0],pCodeCtx->width,pCodeCtx->height,24);
memset(cTest, 0, 640*480*3);

}

#3


百度下有代码,我以前弄过。。不过代码不知放哪里去了。。

#4


不是转换的问题哦,是在int ret = avcodec_decode_video2(codec_, pFrame_, &frameFinished, &packet);
的时候终端报错: ffmpeg解码h264到yuv
请问有人遇到吗?

#5


你自己构造了packet,看下packet的stream_index是否为视频,之前把音频帧扔进去用这个函数解码是有错误的。

#6


使用这个函数分析一下,av_parser_parse2

#7


楼主,有没h264解码的demo,求个一份

#8


直接解H264裸流的,不是解本地和传URL的