26

从 avi 转码为 mp4(x264) 时出现 fps 问题。最终问题出在 PTS 和 DTS 值中,因此在 av_interleaved_write_frame 函数之前添加了第 12-15 行:

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 情况下那样,为什么?
  2. outStream->codectime_base of和有什么区别outStream
  3. 要计算 pts av_rescale_q:需要 2 个 time_base,将它们的分数相乘,然后计算 pts。为什么会这样?正如我调试的那样,encodedPacket.pts它的值增加了 1,那么如果它确实有值,为什么要改变它呢?
  4. 开始时 dts 值为 -2 并且在每次重新缩放后它仍然有负数,但尽管如此视频播放正确!不应该是积极的吗?
4

1 回答 1

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

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

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

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

于 2012-11-30T13:32:41.590 回答