[Ffmpeg-devel] Getting wrong PTS values for MP3 audio stream embedded in an AVI file.

Sibnath GHOSH sibnath.ghosh
Wed Apr 18 19:10:28 CEST 2007


Hi,

I am working in a application which uses ffmpeg to play AVI streams with MP3/AC3 audio stream. I would like to encapsulate the video and audio ES streams to TS PES streams with proper PTS values. 

I am using the ffmpeg version FFMPEG_VERSION "SVN-r6664.

While debugging, I observed that the PTS and DTS values of the MP3 audio streams goes wrong from time to time (actually it the PTS counter and not the actual value). The PTS for the video stream is OK. For example for a AVI file with MP3 audio the following print displays that sometimes the PTS is wrong (lines marked in red).

pts:0 dts:0 data0:0xff data1:0xfb data2:0x90 data3:0x0 data4:0x0 data5:0x0 size:417 idx:1 dur:418 pos:0x29824628
pts:418 dts:418 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xa data5:0x6 size:418 idx:1 dur:418 pos:0x29824628
pts:1 dts:1 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0x22 data5:0x86 size:418 idx:1 dur:418 pos:0x29824628
pts:2 dts:2 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0x3c data5:0x86 size:418 idx:1 dur:418 pos:0x29824628
pts:3 dts:3 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0x59 data5:0x6 size:418 idx:1 dur:418 pos:0x29824628
pts:4 dts:4 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0x78 data5:0x86 size:418 idx:1 dur:418 pos:0x29824628
pts:422 dts:422 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0x8f data5:0x6 size:418 idx:1 dur:418 pos:0x29824628
pts:6 dts:6 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xa9 data5:0xe size:418 idx:1 dur:418 pos:0x29824628
pts:7 dts:7 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xc3 data5:0xc size:418 idx:1 dur:418 pos:0x29824628
pts:8 dts:8 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xde data5:0x86 size:418 idx:1 dur:418 pos:0x29824628
pts:9 dts:9 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xeb data5:0x6 size:418 idx:1 dur:418 pos:0x29824628
pts:427 dts:427 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xe9 data5:0x86 size:418 idx:1 dur:418 pos:0x29824628
pts:10 dts:10 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xe8 data5:0x8e size:418 idx:1 dur:418 pos:0x29824628
pts:11 dts:11 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xed data5:0x84 size:418 idx:1 dur:418 pos:0x29824628
pts:12 dts:12 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xdf data5:0x4 size:418 idx:1 dur:418 pos:0x29824628
pts:13 dts:13 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xe9 data5:0x6 size:418 idx:1 dur:418 pos:0x29824628
pts:431 dts:431 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xea data5:0x7 size:418 idx:1 dur:418 pos:0x29824628
pts:14 dts:14 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xf1 data5:0x8e size:418 idx:1 dur:418 pos:0x29824628
pts:15 dts:15 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xe6 data5:0x6 size:418 idx:1 dur:418 pos:0x29824628
pts:16 dts:16 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xe8 data5:0x8f size:418 idx:1 dur:418 pos:0x29824628
pts:17 dts:17 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xeb data5:0x8f size:418 idx:1 dur:418 pos:0x29824628
pts:18 dts:18 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xe7 data5:0x8f size:418 idx:1 dur:418 pos:0x29824628
pts:436 dts:436 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xec data5:0x8a size:418 idx:1 dur:418 pos:0x29824628
pts:19 dts:19 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xeb data5:0x6 size:418 idx:1 dur:418 pos:0x29824628
pts:20 dts:20 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xe9 data5:0x86 size:418 idx:1 dur:418 pos:0x29824628
pts:21 dts:21 data0:0xff data1:0xfb data2:0x90 data3:0x0 data4:0xe6 data5:0x8f size:417 idx:1 dur:418 pos:0x29824628
pts:22 dts:22 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xec data5:0x8f size:418 idx:1 dur:418 pos:0x29824628
pts:440 dts:440 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xec data5:0xf size:418 idx:1 dur:418 pos:0x29824628
pts:23 dts:23 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xef data5:0xf size:418 idx:1 dur:418 pos:0x29824628
pts:24 dts:24 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xed data5:0xe size:418 idx:1 dur:418 pos:0x29824628
pts:25 dts:25 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xee data5:0x6 size:418 idx:1 dur:418 pos:0x29824628
pts:26 dts:26 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xec data5:0xf size:418 idx:1 dur:418 pos:0x29824628
pts:27 dts:27 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xec data5:0x6 size:418 idx:1 dur:418 pos:0x29824628
pts:445 dts:445 data0:0xff data1:0xfb data2:0x92 data3:0x0 data4:0xed data5:0xf size:418 idx:1 dur:418 pos:0x29824628


Also I did not understand why av_rescale() is used in the file libavformat/utils.c in the function compute_pkt_fields(...)
pkt->duration = av_rescale(1, num * (int64_t)st->time_base.den, den * (int64_t)st->time_base.num);

The duration it returns is always 418 which does not represent the actual frame_length of MPEG Layer 3 audio. The frame_length should be calculated as [ 144 * BitRate / SampleRate + Padding ], which has been done in the file mpegaudio.c. So this duration in /libavformat/utils.c is not only confusing but also represents a wrong value. The duration value should have been 1, like in case of video since the ffmpeg is stripping the MP3 audio chunks into frames of size nBlockAlign bytes.

Also in libavcodec/parser.c in the function av_parser_parse(...)

        if (s->fetch_timestamp){
            s->fetch_timestamp=0;
            s->last_pts = pts;
            s->last_dts = dts;
            s->cur_frame_pts[k] =
            s->cur_frame_dts[k] = AV_NOPTS_VALUE;
        }
So it enters this portion of the code only once for the first audio frame for MP3 audio. Since it enters this code for the first frame the last_pts and last_dts are set to values AV_NOPTS_VALUE near the end of this function.

        s->last_pts = s->cur_frame_pts[k];
        s->last_dts = s->cur_frame_dts[k];

 So for the next frame onwards the pts and dts values of the current frame are set to wrong values in the following code, since the variable s->fetch_timestamp is 0, which is not the case with MPEG video.
        s->pts = s->last_pts;
        s->dts = s->last_dts;

I would like to calculate the PTS value like to following:

Actual PTS = s->pts / Byte_Rate   in which case Byte_Rate = dwRate / dwScale (in DivX File Format Functional Specification, Article 4.8.2.9)

I would appreciate if you would help me to resolve this issue.

Thanks and Regards
Sibnath







More information about the ffmpeg-devel mailing list