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 の場合とは異なります。なぜですか?outStream->codec
との time_base の違いは何outStream
ですか?- pts
av_rescale_q
を計算するには: 2 つの time_base を取り、それらの分数をクロスで乗算し、pts を計算します。なぜこのようにするのですか?私がデバッグしたように、encodedPacket.pts
値が 1 ずつ増加するので、値があるのになぜそれを変更するのでしょうか? - 最初の dts 値は -2 で、再スケーリングのたびにまだ負の数になっていますが、それでもビデオは正しく再生されました! ポジティブでいいのではないですか?