了解视频帧中的PTS和DTS

时间:2012-11-27 23:46:15

标签: video ffmpeg video-streaming pts avcodec

从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)

阅读了很多帖子之后我还是不明白:

  1. 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>
  2. outStream->codecoutStream的时间基础有什么区别?
  3. 要对pts av_rescale_q进行计算:取2个time_base,将它们的分数乘以交叉,然后计算pts。为什么这样做呢?在调试时,encodedPacket.pts的值增量为1,那么为什么要更改它呢?
  4. 一开始dts值为-2,每次重新缩放后仍然有负数,但尽管如此,视频播放正确!不应该是积极的吗?

1 个答案:

答案 0 :(得分:37)

  1. time_base只是衡量的单位。可以使用不同的单位来表示相同的时间(大约,如果它们不是精确的倍数)。在某些情况下,容器格式需要一定的时基,并且它将由多路复用器设置为。在其他情况下,容器不需要时基,但它具有您可能必须覆盖的默认值。我不确定1/12800具体,我知道1/600是mp4规格的特殊值。

  2. 两个时基是编解码器和容器的时间测量单位。如果使用常量fps,则编解码器测量单位通常设置为每帧与下一帧之间的间隔(每帧显示的持续时间),因此帧时间是连续的整数。然而,只要在所使用的单位中pts时间正确,它就不必设置为1 / fps。

  3. 您所描述的只是将一个单位转换为另一个单位所需要做的事情。 (即:乘以旧单位,除以新单位)。以a/b为单位的时间t可以转换为c/d单位t*(a*d)/(b*c)

  4. dts序列可以从任何值开始,对dts 0没有特别的意义。在播放开始时,计算挂钟时间和起始dts之间的差值,并将所有未来的dts转换为墙时钟使用它。 dts = -10,-9,-8,...的视频流完全可以。连续dts之间的差异是使用的,绝对值无关紧要。