[haiku-development] Re: BMediaTrack::SeekToFrame/Time()

  • From: "David McPaul" <dlmcpaul@xxxxxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Sat, 22 Mar 2008 00:54:15 +1100

Stephan,

On 21/03/2008, Stephan Assmus <superstippi@xxxxxx> wrote:
> Hi all,
>
>  I am currently looking into these Media Kit tasks and was wondering about
>  something. The documentation for SeekToFrame() and SeekToTime() mentions
>  this:
>
>  "Seeks to the specified position in the track. [...] They each return (in
>  ioFrame or in ioTime) the position to which they actually moved.
>
>  For example, if a video codec is only capable of seeking to key frames, the
>  returned ioFrame might be different than the one specified on input."
>
>  Let alone that on BeOS/ZETA, both of these functions don't work, they will
>  not seek to keyframes, no matter what flags you specify. You can work
>  around that by using BMediaTrack::FindKeyFrameForXXX(). However, from the
>  intention of these methods, it could be understood, that if you don't
>  specify either B_MEDIA_SEEK_CLOSEST_BACKWARD or
>  B_MEDIA_SEEK_CLOSEST_FORWARD, that the extractor will seek to the *closest*
>  keyframe to the specified position, if the track is keyframe based. Another
>  interpretation is that if possible, the extractor will seek to the
>  specified frame, by seeking to the closest keyframe backwards and then
>  decoding until the frame you wanted. Depending on the situation, this may
>  take a while (!). BUT - We also have the ReadChunk() method, meaning that
>  you might actually want to use the SeekToXXX() methods to seek to a
>  specific chunk/frame, regardless of keyframes.
>
>  For now, I have implemented seeking in the avi reader,
>  B_MEDIA_SEEK_CLOSEST_BACKWARD works, at least for non-interlaced videos.
>  B_MEDIA_SEEK_CLOSEST_FORWARD should work, but is untested. Specifying no
>  flag, the stream is seeked to the specified frame, but video will be
>  garbled, because it has not been decoded from the last keyframe up to the
>  specified frame (would need to be implemented on a different level).
>
>  Should we leave it like that? Any thoughts from anyone? It might be the
>  most flexible setup, though specifying no flags will likely not do what
>  newbie developers expect (could be properly documented though).

Seeking is one of the areas I have struggled with in developing the
3ivx decoder for BeOS.  Just when I think I got it right I find a
problem.

Anyway, my current understanding is that the decoder is passed the
last keyframe decoded AND the frame that is required.  The next
ReadChunk call will return the chunk associated with the keyframe.
The decoder then decodes forward until it reaches the frame required.
This has always been in a forward direction which is the only thing
the decoder can do (well any video decoder that relies on previous
frames).  This is how the 3ivx decoder works.  When decoding frames
that are not required for display it can shortcut some of the decoding
so it is quicker to do.  But video with few keyframes will be a
problematic.

The extractor though is often requested to find a keyframe in a
backward direction presumably to set up the call to the decoder.

I think the decoder can refuse to do anything but seek to keyframes by
returning the keyframe instead of the required frame.

All the above applies to time based seeking as well.

I originally thought that the media kit did all the work and the
decoder just decoded a frame whenever it was called but the decoder
needs to also know that it is just seeking forward and does not need
to do all the decoding work.

Of course I could be wrong, my MP4 extractor with seeking added in is
pretty broken but I think that is because there is some code somewhere
that disagrees with my audio/video sync and tries to adjust it.  But
what I have done above seems to be fine for AVI and MOV files under
BeOS.

-- 
Cheers
David

Other related posts: