小菜鸟请教个问题,具体是这样的:
我从音视频会议中已经获取了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,但是同时终端报告一个错误
请问这个有可能是由于什么问题造成的呢?希望大牛帮忙~~~
8 个解决方案
#1
#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);
}
{
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);
的时候终端报错:
请问有人遇到吗?
的时候终端报错:
请问有人遇到吗?
#5
你自己构造了packet,看下packet的stream_index是否为视频,之前把音频帧扔进去用这个函数解码是有错误的。
#6
使用这个函数分析一下,av_parser_parse2
#7
楼主,有没h264解码的demo,求个一份
#8
直接解H264裸流的,不是解本地和传URL的
#1
#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);
}
{
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);
的时候终端报错:
请问有人遇到吗?
的时候终端报错:
请问有人遇到吗?
#5
你自己构造了packet,看下packet的stream_index是否为视频,之前把音频帧扔进去用这个函数解码是有错误的。
#6
使用这个函数分析一下,av_parser_parse2
#7
楼主,有没h264解码的demo,求个一份
#8
直接解H264裸流的,不是解本地和传URL的