[英]FFMPEG library- transcode raw image to h264 stream, and the output file does not contains pts and dts info
我正在尝试使用 ffmpeg c++ 库将几个原始 yuyv 图像转换为 h264 流,图像来自内存并作为大约 24fps 的字符串传递,我按照以下步骤执行约定:
write_buffer()
函数(参考simplest_ffmpeg_mem_handler )video_avs
是AVStream, output_fps
是24, time_base
是1/24): 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;
将其从 yuyv 转换为 yuv422(因为 h264 不支持 yuyv)并将其大小从 1920x1080 调整为 640x480(因为我需要此分辨率输出),使用sws_scale()
使用avcodec_send_frame()
和avcodec_receive_packet()
获取输出数据包。 设置output_packet
duration 和 stream_index,然后使用av_write_frame()
写入帧数据。
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);
write_buffer()
函数中,视频流输出被存储到字符串变量中,然后我用 ostream 将此字符串写入文件,并以 mp4 为后缀。 经过以上所有步骤,output.mp4无法播放, ffprobe output.mp4 -show_frames
输出为( image ):
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
请注意,在步骤 4 中调用av_write_frame()
之前和之后,传递的参数output_packet
包含正确的 pts 和 dts 信息,我无法弄清楚为什么输出流会丢失这些信息。
我想通了,输出流是一个原始的h264流,我直接把这个流存到一个后缀为“.mp4”的文件中,所以它实际上不是一个正确的mp4文件。
然后将流存入output.h264
文件,并使用 ffmpeg 将其转换为 mp4 文件: ffmpeg -framerate 24 -i output.h264 -c copy output.mp4
,最后这个output.mp4
包含正确的 pts 数据,可以播放.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.