微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

FFMPEG库-将原始图像转码为h264流,并且输出文件不包含pts和dts info

如何解决FFMPEG库-将原始图像转码为h264流,并且输出文件不包含pts和dts info

我正在尝试使用ffmpeg c ++库将几个原始yuyv图像转换为h264流,该图像来自内存并以大约24fps的字符串形式传递,我按照以下步骤进行约定:

  1. 初始化AVFormatContext,AVCodec,AVCodecContext并创建新的AVStream。此步骤中,我主要参考ffmpeg-libav-tutorial,而AVFormatContext使用自定义write_buffer()函数(参考simplest_ffmpeg_mem_handler
  2. 接收原始帧数据,设置宽度和高度(1920x1080),并设置pts和dts。在这里,我手动将输出fps设置为24,并使用全局计数器对帧数进行计数,并且pts由该计数器计算,代码段(video_avs是AVStream,output_fps是24,{ {1}}是1/24):
time_base
  1. 将其从yuyv转换为yuv422(因为h264不支持yuyv),并将其尺寸从1920x1080调整为640x480(因为我需要此分辨率输出),请使用 input_frame->width = w; // 1920 input_frame->height = h; // 1080 input_frame->pkt_dts = input_frame->pts = global_pts; global_pts += video_avs->time_base.den/video_avs->time_base.num / output_fps.num * output_fps.den;

  2. 使用sws_scale()avcodec_send_frame()获取输出数据包。设置avcodec_receive_packet()的持续时间和stream_index,然后使用output_packet写入帧数据。

av_write_frame()
  1. AVPacket *output_packet = av_packet_alloc(); int response = avcodec_send_frame(encoder->video_avcc,frame); while (response >= 0) { response = avcodec_receive_packet(encoder->video_avcc,output_packet); // !! here output_packet.size is calculated if (response == AVERROR(EAGAIN) || response == AVERROR_EOF) { break; } else if (response < 0) { printf("Error while sending packet to decoder"); // ??av_err2str(response)会报错 return response; } // duration = next_pts - this_pts = timescale / fps = 1 / timebase / fps output_packet->duration = (encoder->video_avs->time_base.den / encoder->video_avs->time_base.num) / (output_fps.num / output_fps.den); output_packet->stream_index = 0; int response = av_write_frame(encoder->avfc,output_packet); // packet order are not ensure if (response != 0) { printf("Error %d while receiving packet from decoder",response); return -1;} } av_packet_unref(output_packet); av_packet_free(&output_packet); 函数中,视频流输出存储到字符串变量中,然后我将此字符串写入带有ostream和后缀mp4的文件中。

完成上述所有步骤后,无法播放output.mp4,write_buffer()输出为 (image):

ffprobe output.mp4 -show_frames

请注意,在第4步调用Input #0,h264,from '/Users/ming/code/dev/haomo/output.mp4': Duration: N/A,bitrate: N/A Stream #0:0: Video: h264 (High 4:2:2),yuv422p(progressive),640x480,24.92 fps,24 tbr,1200k tbn,48 tbc [FRAME] media_type=video stream_index=0 key_frame=1 pkt_pts=N/A pkt_pts_time=N/A pkt_dts=N/A pkt_dts_time=N/A best_effort_timestamp=N/A best_effort_timestamp_time=N/A 之前和之后,传递的参数av_write_frame()包含正确的pts和dts信息,我无法弄清楚输出流为何丢失这些信息。

解决方法

我弄清楚了,输出流是原始的h264流,我直接将此流存储到后缀为“ .mp4”的文件中,因此它实际上不是正确的mp4文件。

然后将流存储到output.h264文件中,并使用ffmpeg将其转换为mp4文件:ffmpeg -framerate 24 -i output.h264 -c copy output.mp4,最后该output.mp4包含正确的pts数据并且可以播放。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。