[FFmpeg-devel] Seeking in Apple HTTP Live Streaming
Michael Niedermayer
michaelni at gmx.at
Mon Nov 28 22:20:56 CET 2011
On Mon, Nov 28, 2011 at 04:45:18AM -0800, Takis Issaris wrote:
> Hi,
>
> ----- Original Message -----
>
> > From: Michael Niedermayer <michaelni at gmx.at>
> > To: FFmpeg development discussions and patches <ffmpeg-devel at ffmpeg.org>
> > Cc:
> > Sent: Tuesday, November 22, 2011 1:20 AM
> > Subject: Re: [FFmpeg-devel] Seeking in Apple HTTP Live Streaming
> >
> > On Mon, Nov 21, 2011 at 04:14:03PM -0800, Takis Issaris wrote:
> >>
> >>
> >> ----- Original Message -----
> >> > From: Michael Niedermayer <michaelni at gmx.at>
> >> > To: FFmpeg development discussions and patches
> > <ffmpeg-devel at ffmpeg.org>
> >> > Cc:
> >> > Sent: Tuesday, November 22, 2011 12:40 AM
> >> > Subject: Re: [FFmpeg-devel] Seeking in Apple HTTP Live Streaming
> >> >
> >> > On Mon, Nov 21, 2011 at 03:01:43PM -0800, Takis Issaris wrote:
> >> >> Hi Michael,
> >> >>
> >> >>
> >> >> ----- Original Message -----
> >> >> > From: Michael Niedermayer <michaelni at gmx.at>
> >> >> > To: FFmpeg development discussions and patches
> >> > <ffmpeg-devel at ffmpeg.org>
> >> >> > Cc:
> >> >> > Sent: Monday, November 21, 2011 8:34 PM
> >> >> > Subject: Re: [FFmpeg-devel] Seeking in Apple HTTP Live
> > Streaming
> >> >> >
> >> >> > On Mon, Nov 21, 2011 at 08:21:28AM -0800, Takis Issaris
> > wrote:
> >> >> >> Hi all,
> >> >> >>
> >> >> >>
> >> >> >> As a follow-up to my previous patch, I'd like to
> > implement
> >> > more exact
> >> >> > seeking on HTTP Live Streams. Currently, when seeking to a
> > specific
> >> > timestamp in
> >> >> > such a stream, the seeking results in arriving at the start
> > of the
> >> > correct
> >> >> > segment, but not at the requested timestamp within that
> > segment.
> >> > Worse, when
> >> >> > seeking to a specific timestamp which happens to be a part
> > of the
> >> > segment which
> >> >> > is currently being played, the playback resets to the start
> > of the
> >> > current
> >> >> > timestamp (that could most likely be fixed rather easily).
> > So, when
> >> > pressing
> >> >> > forward arrow key when using ffplay, you'll actually
> > move
> >> > backwards to the
> >> >> > start of the segment (if current timestamp+10s lies within
> > the current
> >> > segment).
> >> >> >>
> >> >> >>
> >> >> >> I'd like to change that so that the applehttp.c
> > seeking
> >> > implementation
> >> >> > uses mpegts.c to actually seek to the specified timestamp,
> > but I'm
> >> > not sure
> >> >> > on how to implement this.
> >> >> >> Currently, when seeking using applehttp_read_seek, I
> > think
> >> > there's no
> >> >> > valid MPEG-TS demuxer context in that function. Should I
> > make sure I
> >> > get a valid
> >> >> > demuxer there, or should I defer the actual seeking using
> > the MPEG-TS
> >> > demuxer
> >> >> > until a valid demuxer is constructed elsewhere in the
> > applehttp.c
> >> > file?
> >> >> >
> >> >> > I assume theres no way to tell the server to start a segment
> > from a
> >> >> > specific time? (i havnt found one)
> >> >>
> >> >> No, I don't think so (haven't found one either).
> >> >>
> >> >>
> >> >> > Do the servers support seeking to a specific byte position
> > within a
> >> >> > segment ?
> >> >>
> >> >> Yes, it's just an Apache HTTP server, so it supports GET with
> > a byte
> >> > range (If that
> >> >> was what you were hinting at).
> >> >>
> >> >>
> >> >> > If yes, seeking per CBR assumption is an option which also
> > doesnt need
> >> >> > the demuxer
> >> >>
> >> >> Yes, initially I'd never even considered CBR. But as I start
> > to think
> >> > about it,
> >> >> the seeking speedup could counterweight the quality/bitrate
> > disadvantage.
> >> >>
> >> >>
> >> >> > The reason why i suggect to assume CBR is that the
> > alternative is
> >> >> > the default seek per timestamp which does a binary search
> > and this
> >> >> > could be quite slow with http needing to send a few packets
> > back and
> >> >> > forth for each iteration of the search
> >> >>
> >> >>
> >> >> Yes, but the draft recommends using 10 second segments, so
> > I'd hoped
> >> > that
> >> >> the actual number of HTTP GETs needed would be rather limited.
> >> >>
> >> >>
> >> >> > depending on network speed, bitrate and segment size a
> > linear search
> >> >> > could also be considered, that is demux and throw away
> > packets until
> >> >> > the right time, this may or may not be faster than a binary
> > search
> >> >>
> >> >> Yes, I'd thought about doing something like that as the
> > applehttp.c
> >> > seek
> >> >> already skips to the correct 10s segment, so a linear search
> > within that
> >> > should
> >> >> not take that long.
> >> >>
> >> >> Would something like that be useful in applehttp.c or should it
> > be kept in
> >> > application
> >> >> specific code?
> >> >
> >> > requireing applehttp specific code in every app does not seem a good
> >> > idea to me thus IMHO its better in applehttp.c
> >>
> >> Agreed. Should the seeking be completed after returning from
> > applehttp.c's
> >> seeking call or would it be acceptable that the actual search happens
> > elsewhere?
> >> (f.e. somewhere near the read frame call or near the open url call).
> >
> > do whatever makes most sense technically
> >
> > [...]
>
>
> I had a look at this last Tuesday, and only did some experiments, but,
> nevertheless, I'd rather post the code and get your opinion on the approach, then let it
> rot for another week :-/
>
> It is in no way clean nor did I take into account possible variants, MPEG-TS
> files with many streams etc. But, if the general approach is okay (that is, storing
> seeking state in applehttp_read_seek() and afterwards skipping packets in
> applehttp_read_packet(), I'll start cleaning and correcting the code for all cases.
>
> So, I'm obviously not suggesting committing this :-)
>
> In the patch ending in v0p2.diff, I tried to allow seeking to keyframes, but didn't know how to do this cleanly, thus the horrible hack. Should the MPEG TS demuxer be modified to set AV_PKT_FLAG_KEY in pkt.flags?
the AVParser that comes after the demuxer should set that flag
already. judging from your hack it seems it does for some reason not
do that, i dont know why
>
>
> With friendly regards,
> Takis
> applehttp.c | 34 ++++++++++++++++++++++++++--------
> 1 file changed, 26 insertions(+), 8 deletions(-)
> 2e7bec013da203499f9cdf6392571cbcef63fc5f phmi-20111128T1324-ffmpeg-hls_seek_timestamp_v0.diff
> commit 432ceba2329492669fa19fc87d2114f4b42e67bd
> Author: Panagiotis H.M. Issaris <takis.issaris at uhasselt.be>
> Date: Tue Nov 22 11:33:17 2011 +0100
>
> Seek until right after the requested timestamp
>
> diff --git a/libavformat/applehttp.c b/libavformat/applehttp.c
> index 1694096..0e7074b 100644
> --- a/libavformat/applehttp.c
> +++ b/libavformat/applehttp.c
> @@ -100,6 +100,7 @@ typedef struct AppleHTTPContext {
> int end_of_segment;
> int first_packet;
> int64_t first_timestamp;
> + int64_t seek_timestamp;
> AVIOInterruptCB *interrupt_callback;
> } AppleHTTPContext;
>
> @@ -529,6 +530,7 @@ static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
>
> c->first_packet = 1;
> c->first_timestamp = AV_NOPTS_VALUE;
> + c->seek_timestamp = AV_NOPTS_VALUE;
>
> return 0;
> fail:
> @@ -588,14 +590,29 @@ start:
> /* Make sure we've got one buffered packet from each open variant
> * stream */
> if (var->needed && !var->pkt.data) {
> - ret = av_read_frame(var->ctx, &var->pkt);
> - if (ret < 0) {
> - if (!url_feof(&var->pb))
> - return ret;
> - reset_packet(&var->pkt);
> - } else {
> - if (c->first_timestamp == AV_NOPTS_VALUE)
> - c->first_timestamp = var->pkt.dts;
> + int skipped_packets = 0;
> + while (1) {
> + ret = av_read_frame(var->ctx, &var->pkt);
> + if (ret < 0) {
> + if (!url_feof(&var->pb))
> + return ret;
> + reset_packet(&var->pkt);
> + } else {
> + if (c->first_timestamp == AV_NOPTS_VALUE)
> + c->first_timestamp = var->pkt.dts;
> + }
> +
> + if (c->seek_timestamp==AV_NOPTS_VALUE)
> + break;
> +
> + int64_t ts_diff = var->pkt.dts - c->seek_timestamp;
i dont think dts is guranteed to be != AV_NOPTS_VALUE here
otherwise the principle looks good
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
The educated differ from the uneducated as much as the living from the
dead. -- Aristotle
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20111128/83e34301/attachment.asc>
More information about the ffmpeg-devel
mailing list