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

看了很多帖子,我还是不明白:
  • 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一样,为什么?
  • outStream->codec的time_base和outStream之间有什么区别?
  • 要计算pts,av_rescale_q进行以下操作:花费2个time_base,将它们的分数相乘,然后计算pts。为什么这样做呢?正如我调试的那样,encodedPacket.pts的值增加了1,那么为什么要更改它的值呢?
  • 开头的dts值为-2,并且每次重新缩放后,它的值仍为负,但是尽管如此,视频仍能正确播放!不应该是积极的吗?
  • 最佳答案

  • 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之间的差异是所使用的,绝对值无关紧要。
  • 09-15 16:31