ffmpeg解码出现no frame的问题

为取经而来 2018-01-10 08:47:54
这几天测试ffmpeg实时解码的问题。先用X264编码,编码完的多个NAL拼接成一帧,将其复制到内存空间,丢给解码器,但是解码时一直出现no frame 的问题。
下面是我的所有代码,由于是测试,只对一张图片进行了编码,没有调用摄像头:

int video_decode(unsigned char *videoData)
{
int len = sizeof(videoData);
int ret;
int got_picture;

avcodec_register_all();
AVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_H264);
AVCodecContext *codecCtx = avcodec_alloc_context3(codec);
avcodec_open2(codecCtx, codec, NULL);

AVFrame *frame = av_frame_alloc();
AVPacket *packet = new AVPacket;

av_new_packet(packet, len);
//memcpy(packet.data, videoData, len);
packet->data = videoData;



ret = avcodec_decode_video2(codecCtx, frame, &got_picture, packet);
printf("ret = %d\n",ret);
printf("got_picture = %d\n", got_picture);

if (ret > 0)
{
if (got_picture)
{
printf("1111111111111111\n");
}
}
return 0;
}

int handle(int width, int height, unsigned char *yuv_frame)
{
int fps = 25;
size_t yuv_size = width * height * 3 / 2;
x264_t *encoder;
x264_picture_t pic_in, pic_out;
uint8_t *yuv_buffer;

x264_param_t param;
x264_param_default_preset(¶m, "veryfast", "zerolatency");
param.i_threads = 1;
param.i_width = width;
param.i_height = height;
param.i_fps_num = fps;
param.i_fps_den = 1;
param.b_intra_refresh = 1;
param.b_annexb = 1;
param.b_repeat_headers = 1;
param.rc.b_mb_tree = 0;
param.i_level_idc = 30;//编码复杂度
param.rc.f_rf_constant = 25; //图像质量
param.rc.f_rf_constant_max = 45; //图像质量
param.i_keyint_max = 10;
param.i_bframe_adaptive = X264_B_ADAPT_TRELLIS;
param.i_threads = 1;
param.b_sliced_threads = 0;

x264_param_apply_profile(¶m, "baseline");
encoder = x264_encoder_open(¶m);
x264_picture_alloc(&pic_in, X264_CSP_I420, width, height);
yuv_buffer = (uint8_t*)malloc(yuv_size);

memcpy(yuv_buffer, yuv_frame, yuv_size);

pic_in.img.plane[0] = yuv_buffer;
pic_in.img.plane[1] = pic_in.img.plane[0] + width * height;
pic_in.img.plane[2] = pic_in.img.plane[1] + width * height / 4;

int64_t i_pts = 0;
x264_nal_t *nals = NULL;
x264_nal_t *nal;
int nnal;

pic_in.i_pts = i_pts++;

x264_encoder_encode(encoder, &nals, &nnal, &pic_in, &pic_out);

unsigned char *nalu_buf = (unsigned char *)malloc(800000);
printf("%d\n", nnal);

int i = 0;
for (nal = nals; nal < nals + nnal; nal++)
{
memcpy(nalu_buf + i, nal->p_payload, nal->i_payload);
/*for (int j = 0; j < 24; j++)
{
printf("%x\n", nalu_buf[j]);
}*/

i = i + nal->i_payload;
}
video_decode(nalu_buf);

x264_encoder_close(encoder);
free(yuv_buffer);
return 0;
}

int main(int argc, char* argv[])
{
const char* image_name = "1.jpg";
Mat img = imread(image_name);

cv::Mat yuvImg;
cv::cvtColor(img, yuvImg, CV_BGR2YUV_I420);
memcpy(pYuvBuf, yuvImg.data, yuv_bufLen);
handle(w, h, pYuvBuf);

return 0;
}

求解啊,我看网上差不多也是这么写的,就是不清楚为什么会有no frame,查看数据的时候SPS、PPS也都存在。。。。
...全文
2586 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
luckyjungle 2018-01-25
  • 打赏
  • 举报
回复
把每个nal给ffmpeg就ok了。
百灵工作室 2018-01-19
  • 打赏
  • 举报
回复
引用 4 楼 qq_41051855 的回复:
[quote=引用 3 楼 sharkka 的回复:] [quote=引用 2 楼 qq_41051855 的回复:] [quote=引用 1 楼 sharkka 的回复:] 给你提供解决问题的思路如下(希望能帮到你): 1. 首先,你要相信,如果H.264的码流不存在什么问题,只要有I帧 ,解码交给ffmpeg,那一定不是什么问题; 2. so,你第一步,将你用x264编码后的码流片段交给ffmpeg,或者更简单一些,你直接将其保存为a.264的文件,蓝后,你直接拖进elecard,这样,你可以清晰地看到码流的所有信息,是否可以看到图像,如果能,跳到3,如果不能,跳到4; 3.重新检查你的x264编码,一般这个不难,只要将yuv数据填到指定的plane中 ,编码参数参照网上,给最简单的就好 比如 (*pictIn)->i_type = X264_TYPE_AUTO; (*pictIn)->i_qpplus1 = 0; (*pictIn)->img.i_csp = X264_CSP_I420; (*pictIn)->img.i_plane = iplane; (*pictIn)->img.i_stride[0] = width; (*pictIn)->img.i_stride[1] = width / 2; (*pictIn)->img.i_stride[2] = width / 2; (*pictIn)->i_type = X264_TYPE_AUTO; (*pictIn)->i_qpplus1 = 0; ,直到你编码成正确的H.264码流,如果真的没成功,那你先直接用x264的命令去编码,蓝后,回头再解决这个问题; 4. 如果能,那说明,你的x264编码是正确的,恭喜你,编码ok; 5. 既然你是一帧,那编码后,你的这一帧必须是I帧,而且要包含pps,sps信息; 希望帮到你
真的太感谢了,我又仔细检查了一下,编码没有问题,是我在解码时设置的packet.size的大小出现问题,所以解码器收到的数据不是完整的一帧。修改后解码就可以了。[/quote] 恭喜你,有了进展。[/quote] 现在编码又出现了X264[error]:malloc of size xxxxxx failed这样的错误[/quote] 看看你的x264有没有没有释放内存,如果一直这么malloc,就会有failed的那一天
为取经而来 2018-01-15
  • 打赏
  • 举报
回复
引用 3 楼 sharkka 的回复:
[quote=引用 2 楼 qq_41051855 的回复:] [quote=引用 1 楼 sharkka 的回复:] 给你提供解决问题的思路如下(希望能帮到你): 1. 首先,你要相信,如果H.264的码流不存在什么问题,只要有I帧 ,解码交给ffmpeg,那一定不是什么问题; 2. so,你第一步,将你用x264编码后的码流片段交给ffmpeg,或者更简单一些,你直接将其保存为a.264的文件,蓝后,你直接拖进elecard,这样,你可以清晰地看到码流的所有信息,是否可以看到图像,如果能,跳到3,如果不能,跳到4; 3.重新检查你的x264编码,一般这个不难,只要将yuv数据填到指定的plane中 ,编码参数参照网上,给最简单的就好 比如 (*pictIn)->i_type = X264_TYPE_AUTO; (*pictIn)->i_qpplus1 = 0; (*pictIn)->img.i_csp = X264_CSP_I420; (*pictIn)->img.i_plane = iplane; (*pictIn)->img.i_stride[0] = width; (*pictIn)->img.i_stride[1] = width / 2; (*pictIn)->img.i_stride[2] = width / 2; (*pictIn)->i_type = X264_TYPE_AUTO; (*pictIn)->i_qpplus1 = 0; ,直到你编码成正确的H.264码流,如果真的没成功,那你先直接用x264的命令去编码,蓝后,回头再解决这个问题; 4. 如果能,那说明,你的x264编码是正确的,恭喜你,编码ok; 5. 既然你是一帧,那编码后,你的这一帧必须是I帧,而且要包含pps,sps信息; 希望帮到你
真的太感谢了,我又仔细检查了一下,编码没有问题,是我在解码时设置的packet.size的大小出现问题,所以解码器收到的数据不是完整的一帧。修改后解码就可以了。[/quote] 恭喜你,有了进展。[/quote] 现在编码又出现了X264[error]:malloc of size xxxxxx failed这样的错误
百灵工作室 2018-01-11
  • 打赏
  • 举报
回复
给你提供解决问题的思路如下(希望能帮到你): 1. 首先,你要相信,如果H.264的码流不存在什么问题,只要有I帧 ,解码交给ffmpeg,那一定不是什么问题; 2. so,你第一步,将你用x264编码后的码流片段交给ffmpeg,或者更简单一些,你直接将其保存为a.264的文件,蓝后,你直接拖进elecard,这样,你可以清晰地看到码流的所有信息,是否可以看到图像,如果能,跳到3,如果不能,跳到4; 3.重新检查你的x264编码,一般这个不难,只要将yuv数据填到指定的plane中 ,编码参数参照网上,给最简单的就好 比如 (*pictIn)->i_type = X264_TYPE_AUTO; (*pictIn)->i_qpplus1 = 0; (*pictIn)->img.i_csp = X264_CSP_I420; (*pictIn)->img.i_plane = iplane; (*pictIn)->img.i_stride[0] = width; (*pictIn)->img.i_stride[1] = width / 2; (*pictIn)->img.i_stride[2] = width / 2; (*pictIn)->i_type = X264_TYPE_AUTO; (*pictIn)->i_qpplus1 = 0; ,直到你编码成正确的H.264码流,如果真的没成功,那你先直接用x264的命令去编码,蓝后,回头再解决这个问题; 4. 如果能,那说明,你的x264编码是正确的,恭喜你,编码ok; 5. 既然你是一帧,那编码后,你的这一帧必须是I帧,而且要包含pps,sps信息; 希望帮到你
百灵工作室 2018-01-11
  • 打赏
  • 举报
回复
引用 2 楼 qq_41051855 的回复:
[quote=引用 1 楼 sharkka 的回复:] 给你提供解决问题的思路如下(希望能帮到你): 1. 首先,你要相信,如果H.264的码流不存在什么问题,只要有I帧 ,解码交给ffmpeg,那一定不是什么问题; 2. so,你第一步,将你用x264编码后的码流片段交给ffmpeg,或者更简单一些,你直接将其保存为a.264的文件,蓝后,你直接拖进elecard,这样,你可以清晰地看到码流的所有信息,是否可以看到图像,如果能,跳到3,如果不能,跳到4; 3.重新检查你的x264编码,一般这个不难,只要将yuv数据填到指定的plane中 ,编码参数参照网上,给最简单的就好 比如 (*pictIn)->i_type = X264_TYPE_AUTO; (*pictIn)->i_qpplus1 = 0; (*pictIn)->img.i_csp = X264_CSP_I420; (*pictIn)->img.i_plane = iplane; (*pictIn)->img.i_stride[0] = width; (*pictIn)->img.i_stride[1] = width / 2; (*pictIn)->img.i_stride[2] = width / 2; (*pictIn)->i_type = X264_TYPE_AUTO; (*pictIn)->i_qpplus1 = 0; ,直到你编码成正确的H.264码流,如果真的没成功,那你先直接用x264的命令去编码,蓝后,回头再解决这个问题; 4. 如果能,那说明,你的x264编码是正确的,恭喜你,编码ok; 5. 既然你是一帧,那编码后,你的这一帧必须是I帧,而且要包含pps,sps信息; 希望帮到你
真的太感谢了,我又仔细检查了一下,编码没有问题,是我在解码时设置的packet.size的大小出现问题,所以解码器收到的数据不是完整的一帧。修改后解码就可以了。[/quote] 恭喜你,有了进展。
为取经而来 2018-01-11
  • 打赏
  • 举报
回复
引用 1 楼 sharkka 的回复:
给你提供解决问题的思路如下(希望能帮到你): 1. 首先,你要相信,如果H.264的码流不存在什么问题,只要有I帧 ,解码交给ffmpeg,那一定不是什么问题; 2. so,你第一步,将你用x264编码后的码流片段交给ffmpeg,或者更简单一些,你直接将其保存为a.264的文件,蓝后,你直接拖进elecard,这样,你可以清晰地看到码流的所有信息,是否可以看到图像,如果能,跳到3,如果不能,跳到4; 3.重新检查你的x264编码,一般这个不难,只要将yuv数据填到指定的plane中 ,编码参数参照网上,给最简单的就好 比如 (*pictIn)->i_type = X264_TYPE_AUTO; (*pictIn)->i_qpplus1 = 0; (*pictIn)->img.i_csp = X264_CSP_I420; (*pictIn)->img.i_plane = iplane; (*pictIn)->img.i_stride[0] = width; (*pictIn)->img.i_stride[1] = width / 2; (*pictIn)->img.i_stride[2] = width / 2; (*pictIn)->i_type = X264_TYPE_AUTO; (*pictIn)->i_qpplus1 = 0; ,直到你编码成正确的H.264码流,如果真的没成功,那你先直接用x264的命令去编码,蓝后,回头再解决这个问题; 4. 如果能,那说明,你的x264编码是正确的,恭喜你,编码ok; 5. 既然你是一帧,那编码后,你的这一帧必须是I帧,而且要包含pps,sps信息; 希望帮到你
真的太感谢了,我又仔细检查了一下,编码没有问题,是我在解码时设置的packet.size的大小出现问题,所以解码器收到的数据不是完整的一帧。修改后解码就可以了。

2,543

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧