从avi转码到mp4(x264)时,我遇到了fps问题。最终问题出现在PTS和DTS值中,所以第12-15行在av_interleaved_write_frame函数之前添加:
1. AVFormatContext* outContainer = NULL;
2. avformat_alloc_output_context2(&outContainer, NULL, "mp4", "c:\\test.mp4";
3. AVCodec *encoder = avcodec_find_encoder(AV_CODEC_ID_H264);
4. AVStream *outStream = avformat_new_stream(outContainer, encoder);
5. // outStream->codec initiation
6. // ...
7. avformat_write_header(outContainer, NULL);
8. // reading and decoding packet
9. // ...
10. avcodec_encode_video2(outStream->codec, &encodedPacket, decodedFrame, &got_frame)
11.
12. if (encodedPacket.pts != AV_NOPTS_VALUE)
13. encodedPacket.pts = av_rescale_q(encodedPacket.pts, outStream->codec->time_base, outStream->time_base);
14. if (encodedPacket.dts != AV_NOPTS_VALUE)
15. encodedPacket.dts = av_rescale_q(encodedPacket.dts, outStream->codec->time_base, outStream->time_base);
16.
17. av_interleaved_write_frame(outContainer, &encodedPacket)
阅读了很多帖子之后我还是不明白:
outStream->codec->time_base
= 1/25且outStream->time_base
= 1/12800。第一个由我设定,但我无法弄清楚为什么和谁设置12800?我注意到在第(7)行outStream->time_base
= 1/90000之前和之后它变为1/12800,为什么?
当我从avi转码为avi时,意思是将行(2)改为avformat_alloc_output_context2(&outContainer, NULL, "avi", "c:\\test.avi";
,所以行(7)之前和之后outStream->time_base
总是保持1/25并且不像mp4那样,为什么?< / LI>
outStream->codec
和outStream
的时间基础有什么区别?av_rescale_q
进行计算:取2个time_base,将它们的分数乘以交叉,然后计算pts。为什么这样做呢?在调试时,encodedPacket.pts
的值增量为1,那么为什么要更改它呢?答案 0 :(得分:37)
time_base只是衡量的单位。可以使用不同的单位来表示相同的时间(大约,如果它们不是精确的倍数)。在某些情况下,容器格式需要一定的时基,并且它将由多路复用器设置为。在其他情况下,容器不需要时基,但它具有您可能必须覆盖的默认值。我不确定1/12800具体,我知道1/600是mp4规格的特殊值。
两个时基是编解码器和容器的时间测量单位。如果使用常量fps,则编解码器测量单位通常设置为每帧与下一帧之间的间隔(每帧显示的持续时间),因此帧时间是连续的整数。然而,只要在所使用的单位中pts时间正确,它就不必设置为1 / fps。
您所描述的只是将一个单位转换为另一个单位所需要做的事情。 (即:乘以旧单位,除以新单位)。以a/b
为单位的时间t可以转换为c/d
单位t*(a*d)/(b*c)
。
dts序列可以从任何值开始,对dts 0没有特别的意义。在播放开始时,计算挂钟时间和起始dts之间的差值,并将所有未来的dts转换为墙时钟使用它。 dts = -10,-9,-8,...的视频流完全可以。连续dts之间的差异是使用的,绝对值无关紧要。