[FFmpeg-devel] [PATCH] Fix MPEG-TS seek and frame positions in general
Sun Mar 1 17:58:30 CET 2009
Michael Niedermayer wrote:
> On Sun, Mar 01, 2009 at 02:31:27PM +0100, Ivan Schreter wrote:
>> Why do we need the array with several timestamps? I'd say the code can be
>> simplified to (names possibly suboptimal):
>> 1) set cur_pts, cur_dts, cur_pos to pts/dts/pos of currently-arriving
>> (packet) buffer,
>> 2) if frame_pts, frame_dts and frame_pos is unset, set them to cur_pts,
>> cur_dts and cur_pos,
>> 3) unset next_pts, next_dts and next_pos,
>> 4) call actual parser,
>> 5) if the parser returns a buffer, frame_pts, frame_dts and frame_pos are
>> actual pts/dts/pos for the parsed buffer, so return them in pts, dts and
>> 6) reset frame_pts, frame_dts and frame_pos to next_pts, next_dts and
>> 7) reset next_pts, next_dts and next_pos to unset.
> this will not work, not at all
> packet1 50% of frame1 pts=0 (iam just writing one timestamp due to lazyness)
> (1) cur_pts=0
> (2) frame_pts=0
> (3) next_pts=-
> (45) parser says nothing yet
> (6) frame_pts=-
> (7) next_pts=-
> packet2 50% of frame1 pts=-
> (1) cur_pts=-
> (2) frame_pts=-
> (3) next_pts=-
> (45) parser returns the packet, correct pts is 0 but you return nothing
> this is just the most trivial case, a frame split in 2 packets and detected
> in the second
Uhm, I think this is a misunderstanding of (2). For packet 2, (2) will
NOT set frame_pts to (unset) cur_pts, but leave it set. Even if packet2
had pts=1, frame_pts would stay set at 0, since this is relevant pts for
the first frame. I.e., the parser will return correct pts=0 and _then_
set frame_pts to undefined (so next call with next packet will set it
again to the pts of the packet3, which contains frame2).
In case packet2 having pts=1 and containing already portion of frame2,
the codec-specific parser would call a function to announce this fact.
This would then set next_pts to cur_pts (i.e., 1), so after returning
the first frame with frame_pts == 0 copied to pts, frame_pts would be
set to next_pts == 1. So packet3 completing frame2 would return pts 1,
which is correct pts for frame2.
AFAIK, we have only following cases, what a packet (buffer coming into
the parser) can contain:
a) data for frame i
b) data for end of frame i _and_ data for beginning of frame i+1 (either
one can also be a complete frame)
c) data for end of frame i, several complete frames i+1 to i+k and data
for beginning of frame i+k+1 (either i or i+k+1 can also be complete frames)
Any other case? If yes, what?
pts/dts/position of the frame is equal to pts/dts/position of first
packet in stream which contains starting portion of frame data.
All of these cases will be handled correctly by my algorithm.
Note: even though for instance MPEG-TS interleaves packets, this is not
a problem, since parser only handles one substream, which contains
packetized contiguous frame stream. For each frame, relevant position is
the position of first TS packet of PES packet containing (beginning of)
My algorithm is missing resetting cur_pts/cur_dts after it has been
consumed somewhere, so we don't get two or more frames with same pts/dts
(second and further frames starting in same packet would get unset
pts/dts). I don't know if this case comes in practice (above case c).
More information about the ffmpeg-devel