我正在尝试将视频文件转码为标准格式。这是我的主要循环:
for(frame_count = 0; av_read_frame(input_ctx, &in_packet) >= 0; frame_count++) {
if(in_packet.stream_index == video_stream_index) {
decodedPacket = 0;
rc = avcodec_decode_video2(video_in_codec, inputFrame, &decodedPacket, &in_packet);
if(decodedPacket) {
out_frames++;
rc = sws_scale(sws_ctx, inputFrame->data, inputFrame->linesize, 0, video_out_codec->height, outputFrame->data, outputFrame->linesize);
if(rc != video_out_codec->height) {
puts("scaling error");
}
outputFrame->pts = (1.0 / 30.0) * 90.0 * video_out_codec->frame_number;
rc = avcodec_encode_video2(video_out_codec, &out_packet, outputFrame, &encodedPacket);
if(rc != 0) {
puts("encoding error");
}
if(encodedPacket) {
if (video_out_stream->codec->coded_frame->key_frame) { // deprecated, what to use instead
out_packet.flags |= AV_PKT_FLAG_KEY;
}
out_packet.stream_index = 0;
rc = av_interleaved_write_frame(output_ctx, &out_packet);
if(rc != 0) {
puts("frame write error");
}
av_free_packet(&out_packet);
memset(&out_packet, 0, sizeof(AVPacket));
packet_count++;
}
av_free_packet(&in_packet);
}
}
...
当我运行这个时,我得到了ffprobe报告的tbr / tbn / tbc的奇怪值,视频很乱。
我尝试按照this answer添加代码,例如
if (out_packet.pts != AV_NOPTS_VALUE) {
out_packet.pts = av_rescale_q(out_packet.pts, video_out_stream->codec->time_base, video_out_stream->time_base);
}
if (out_packet.pts != AV_NOPTS_VALUE) {
out_packet.dts = av_rescale_q(out_packet.dts, video_out_stream->codec->time_base, video_out_stream->time_base);
}
...但后来我收到错误,比如这是调试输出:
[mp4 @ 0x1038aba00] Delay between the first packet and last packet in the muxing queue is 10100000 > 10000000: forcing output
我正确设置时基(我认为)......
video_out_stream = avformat_new_stream(output_ctx, videoEncoder);
video_out_stream->id = 0;
video_out_stream->time_base.den = 30;
video_out_stream->time_base.num = 1;
video_out_codec = video_out_stream->codec;
avcodec_get_context_defaults3(video_out_codec, videoEncoder);
video_out_codec->codec_id = AV_CODEC_ID_H264;
video_out_codec->bit_rate = 2048;
video_out_codec->width = 854;
video_out_codec->height = 480;
video_out_codec->time_base.den = 30;
video_out_codec->time_base.num = 1;
video_out_codec->gop_size = 30;
video_out_codec->pix_fmt = AV_PIX_FMT_YUV420P;
有关如何计算正确输出帧pts和编码数据包dts / pts的任何想法?我显然做错了什么。