>On Fri, 23 Jan 2009 04:15:21 -0500, Bogdan Coanda ><bogdan.coanda at gmail.com> wrote: >> I'm currently working on a project decoding mpeg2ts streams, and my >> problem is if can anyone explain to me why the PTS and DTS values >> seem to be inverted - each packet returned to me by avcodec_decode_video >> has the DTS in increasing order, but the PTS in every third packet is >> out of order. > >This confused the heck out of me when I was first learning libav. The key >is to realize that the PTS of the packet you give to the decoder is NOT >the PTS of the frame it hands back to you. You hand the packets to it in >DTS order, and it hands the frames to you in PTS order. > >So then how can you know when to display the frame? If you look into >ffplay, you will see a trick where a custom frame allocation function is >used, and the PTS of the current packet is read out of a global variable >and attached to the '->opaque' of the frame. Then later when the frame >comes out of the decoder the PTS is retrieved from that pointer. To avoid >the global variable, you can use the ->opaque of the AVFormatContext >(which is accessible in the allocation function).
I am having the same problem, Michael suggests in other emails, using the dranger method used in his tutorial.(http://www.dranger.com/ffmpeg/tutorial05.html) The article suggests overriding the get_buffer and release_buffer functions to pass the PTS around. Unfortunately the myGetBuffer (the override) does not get called until the decoder has the first frame out. By then, it has already received 13 frames. After that it gets called after every frame has been decoded. See the output below: Note that the pts & dts values are devided by 90000.0 Decoded TS pts = 44015.9613 TS dts = 44015.9613 frame pts = 44015.9613 Decoded TS pts = 44016.09477 TS dts = 44015.99467 frame pts = 44015.99467 Decoded TS pts = 44016.02803 TS dts = 44016.02803 frame pts = 44016.02803 Decoded TS pts = 44016.0614 TS dts = 44016.0614 frame pts = 44016.0614 Decoded TS pts = 44016.19487 TS dts = 44016.09477 frame pts = 44016.09477 Decoded TS pts = 44016.12813 TS dts = 44016.12813 frame pts = 44016.12813 Decoded TS pts = 44016.1615 TS dts = 44016.1615 frame pts = 44016.1615 Decoded TS pts = 44016.29497 TS dts = 44016.19487 frame pts = 44016.19487 Decoded TS pts = 44016.22823 TS dts = 44016.22823 frame pts = 44016.22823 Decoded TS pts = 44016.2616 TS dts = 44016.2616 frame pts = 44016.2616 Decoded TS pts = 44016.39507 TS dts = 44016.29497 frame pts = 44016.29497 Decoded TS pts = 44016.32833 TS dts = 44016.32833 frame pts = 44016.32833 Decoded TS pts = 44016.3617 TS dts = 44016.3617 frame pts = 44016.3617 myGetBuffer Decoded TS pts = 44016.49517 TS dts = 44016.39507 frame pts = 44016.39507 Decoded TS pts = 44016.42843 TS dts = 44016.42843 frame pts = 44016.42843 Decoded TS pts = 44016.4618 TS dts = 44016.4618 frame pts = 44016.4618 myGetBuffer Decoded TS pts = 44016.59527 TS dts = 44016.49517 frame pts = 44016.49517 myGetBuffer Decoded TS pts = 44016.52853 TS dts = 44016.52853 frame pts = 44016.52853 TS pts and TS dts are the ones on the AVPacket structure. Frame pts is the one recovered by your method. Furthermore, ffplay.c now uses reordered_opaque to pass around the PTS, but has the same effect. The output below is from ffplay. See how the frame pts (after frame) follows the dts, instead of re-ordering the pts. The first frame out should have a pts of 94828.250944 but instead has 94828.517878. pts= 94828.250944 dts= 94828.250944, frame 94828.250944 gotit 0 pts= 94828.267633 dts= 94828.267633, frame 94828.267633 gotit 0 pts= 94828.317667 dts= 94828.267622, frame 94828.267622 gotit 0 pts= 94828.284311 dts= 94828.284311, frame 94828.284311 gotit 0 pts= 94828.300989 dts= 94828.300989, frame 94828.300989 gotit 0 pts= 94828.367722 dts= 94828.317678, frame 94828.317678 gotit 0 pts= 94828.334356 dts= 94828.334356, frame 94828.334356 gotit 0 pts= 94828.351044 dts= 94828.351044, frame 94828.351044 gotit 0 pts= 94828.417767 dts= 94828.367722, frame 94828.367722 gotit 0 pts= 94828.384411 dts= 94828.384411, frame 94828.384411 gotit 0 pts= 94828.401089 dts= 94828.401089, frame 94828.401089 gotit 0 pts= 94828.467822 dts= 94828.417778, frame 94828.417778 gotit 0 pts= 94828.434456 dts= 94828.434456, frame 94828.434456 gotit 0 pts= 94828.451144 dts= 94828.451144, frame 94828.451144 gotit 0 pts= 94828.517867 dts= 94828.467822, frame 94828.467822 gotit 0 pts= 94828.484511 dts= 94828.484511, frame 94828.484511 gotit 0 pts= 94828.501189 dts= 94828.501189, frame 94828.501189 gotit 0 pts= 94828.567922 dts= 94828.517878, frame 94828.517878 gotit 32 pts= 94828.534556 dts= 94828.534556, frame 94828.534556 gotit 32 pts= 94828.551244 dts= 94828.551244, frame 94828.551244 gotit 32 pts= 94828.617967 dts= 94828.567922, frame 94828.567922 gotit 32 pts= 94828.584611 dts= 94828.584611, frame 94828.584611 gotit 32 pts= 94828.601289 dts= 94828.601289, frame 94828.601289 gotit 32 pts= 94828.668022 dts= 94828.617978, frame 94828.617978 gotit 32 I was wondering if there is a decoder configuration, or something that is missing? By the way, the decoder is the mpeg2 decoder. Thanks, -- Jose _______________________________________________ libav-user mailing list [email protected] https://lists.mplayerhq.hu/mailman/listinfo/libav-user
