[Libav-user] Helo in understanding PTS and DTS

hatred adrozdoff at gmail.com
Thu Nov 29 00:23:52 CET 2012


Hi Igor, my comments below

2012/11/28 Morduhaev, Igor (igorm at stats.com) <igorm at stats.com>

>   I had fps issues when transcoding from avi to mp4(x264). Eventually the
> problem was in PTS and DTS values, so lines 12-15 where added before
> av_interleaved_write_frame function:
>
>
>
> 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)
>
>
>
> After reading many posts I still do not understand:
>
> 1.    outStream->codec->time_base = 1/25 and outStream->time_base =
> 1/12800. The 1st one was set by me but I cannot figure out why and who set
> 12800? I noticed that before line (7) outStream->time_base = 1/90000 and
> right after it it changes to 1/12800, why?
>

Read docs:
1. AVStream::time_base:
   This is the fundamental unit of time (in seconds) in terms
   of which frame timestamps are represented.

   decoding: set by libavformat
   encoding: set by libavformat in av_write_header. The muxer may use the
   user-provided value of @ref AVCodecContext.time_base "codec->time_base"
   as a hint.

So for AVStream you shold not set time-base - it will be setted automatic
after av_write_header() call

2. AVCodecContext::time_base:
 This is the fundamental unit of time (in seconds) in terms
   of which frame timestamps are represented. For fixed-fps content,
   timebase should be 1/framerate and timestamp increments should be
   identically 1.
   - encoding: MUST be set by user.
   - decoding: Set by libavcodec.

So for AVCodecContext you MUST set time-base for encoding

 When I transcode from avi to avi, meaning changing the line (2) to
avformat_alloc_output_context2(&outContainer,
> NULL, "avi", "c:\\test.avi"; , so before and after line (7)
> outStream->time_base remains always 1/25 and not like in mp4 case, why?
>

see above

 2.    What is the difference between time_base of outStream->codec and
> outStream?
>

see above


>  3.    To calc the pts av_rescale_q does: takes 2 time_base, multiplies
> their fractions in cross and then compute the pts. Why it does this in this
> way? As I debugged, the encodedPacket.pts has value incremental by 1, so
> why changing it if it does has value?
>

Generaly coder time base is inverse Frame Rate, so we can increment PTS
simple by 1 for next frame, but Stream time base can depend on some
format/codec specifications. Packets PTS/DTS must be in Stream time-base
units before writing so rescaling between coder and stream time bases is
required.


>  4.    At the beginning the dts value is -2 and after each rescaling it
> still has negative number, but despite this the video played correctly!
> Shouldn't it be positive?
>

Its strange for me :-)


>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20121129/265e9d3f/attachment.html>


More information about the Libav-user mailing list