[FFmpeg-devel] [PATCH] RTMP seek support

Michael Niedermayer michaelni
Sat Apr 3 23:40:15 CEST 2010


On Thu, Apr 01, 2010 at 03:36:26PM -0700, Howard Chu wrote:
> Michael Niedermayer wrote:
>> On Thu, Apr 01, 2010 at 01:11:24PM -0700, Howard Chu wrote:
>>> Michael Niedermayer wrote:
>>>> On Wed, Mar 31, 2010 at 05:24:49PM -0700, Howard Chu wrote:
>>>>> Howard Chu wrote:
>>>>>> Michael Niedermayer wrote:
>>>>>>> removial is planed but the new API might be changed if we find the 
>>>>>>> need
>>>>>>> to change it still ...
>>>>>
>>>>> It seems to me that one thing that ought to be changed is that 
>>>>> rescaling
>>>>> the timestamp should still be done by the caller, not in read_seek2.
>>>>> Right
>>>>> now each implementation of read_seek2() has to duplicate this code.
>>>>
>>>> if rescaling is done outside then exact seeking becomes impossible
>>>> because rescaling implicates rounding
>>>
>>> But that's always true, regardless. If you sepcify a seek timestamp in
>>> nanoseconds and the stream only supports microseconds, it is going to 
>>> have
>>> to round anyway.
>>
>> there are normally several streams, and their timebases normally differ.
>
> Does that mean a high level seek request is expected to result in several 
> low-level seek operations, one for each individual stream?

i give you an example, for avi, the file position to seek to would be found
by looking at the index in memory and a single low level seek would be done
for each high level seek. That looking would have to consider all active
streams always though but that uses no low level seeks.


>
>>>>> Index: libavformat/flvdec.c
>>>>> ===================================================================
>>>>> --- libavformat/flvdec.c	(revision 22713)
>>>>> +++ libavformat/flvdec.c	(working copy)
>>>>> @@ -442,6 +442,38 @@
>>>>>        return ret;
>>>>>    }
>>>>>
>>>>> +static int flv_read_seek(AVFormatContext *s, int stream_index,
>>>>> +    int64_t ts, int flags)
>>>>> +{
>>>>> +    return av_url_read_fseek(s->pb, stream_index, ts, flags);
>>>>> +}
>>>>> +
>>>>> +static int flv_read_seek2(AVFormatContext *s, int stream_index,
>>>>> +    int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
>>>>> +{
>>>>> +    int ret = AVERROR_NOTSUPP;
>>>>> +
>>>>> +    if (url_is_streamed(s->pb)) {
>>>>> +        if (stream_index<   0) {
>>>>> +            AVStream *st;
>>>>> +
>>>>> +            stream_index = av_find_default_stream_index(s);
>>>>> +            if (stream_index<   0)
>>>>> +                return -1;
>>>>> +
>>>>> +            st = s->streams[stream_index];
>>>>> +            // timestamp for default must be expressed in AV_TIME_BASE
>>>>> units
>>>>> +            ts = av_rescale(ts, st->time_base.den,
>>>>> +                                AV_TIME_BASE *
>>>>> (int64_t)st->time_base.num);
>>>>> +        }
>>>>> +        ret = av_url_read_fseek(s->pb, stream_index, ts, flags);
>>>>> +    }
>>>>> +
>>>>> +    if (ret == AVERROR_NOTSUPP)
>>>>> +        ret = av_seek_frame(s, stream_index, ts, flags | (ts - min_ts>
>>>>> (uint64_t)(max_ts - ts) ? AVSEEK_FLAG_BACKWARD : 0));
>>>>> +    return ret;
>>>>> +}
>>>>
>>>> now i see what you meant by that this will need to be changed again
>>>> either way this does not implement the new API correctly
>>>
>>> It's simply based on the behavior of avformat_seek_file(). I just aimed 
>>> at
>>> producing the same result for non-streams, while giving the protocol
>>> handler read_seek a chance to run.
>>
>> the behavior of above in case av_url_read_fseek() is used seems to
>> differ quite a bit from what the new api docs expect
>
> What docs? find|grep in ffmpeg/doc doesn't have any hits on read_seek2.

avformat.h

/**
 * Seeks to timestamp ts.
 * Seeking will be done so that the point from which all active streams
 * can be presented successfully will be closest to ts and within min/max_ts.
 * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL.
 *
 * If flags contain AVSEEK_FLAG_BYTE, then all timestamps are in bytes and
 * are the file position (this may not be supported by all demuxers).
 * If flags contain AVSEEK_FLAG_FRAME, then all timestamps are in frames
 * in the stream with stream_index (this may not be supported by all demuxers).
 * Otherwise all timestamps are in units of the stream selected by stream_index
 * or if stream_index is -1, in AV_TIME_BASE units.
 * If flags contain AVSEEK_FLAG_ANY, then non-keyframes are treated as
 * keyframes (this may not be supported by all demuxers).
 *
 * @param stream_index index of the stream which is used as time base reference
 * @param min_ts smallest acceptable timestamp
 * @param ts target timestamp
 * @param max_ts largest acceptable timestamp
 * @param flags flags
 * @return >=0 on success, error code otherwise
 *
 * @NOTE This is part of the new seek API which is still under construction.
 *       Thus do not use this yet. It may change at any time, do not expect
 *       ABI compatibility yet!
 */
int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags);



>
> The end result is identical to the avformat_seek_file() case where 
> read_seek2() does not exist, so how can the behavior be different? If 
> that's true then avformat_seek_file() is also broken.

We change the API because the old was incapable of some things.
Thus it is not possible to emulate the new over the old. And
the fallback code does just a best effort ...


[...]

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

No great genius has ever existed without some touch of madness. -- Aristotle
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20100403/50dc6d3c/attachment.pgp>



More information about the ffmpeg-devel mailing list