Merge commit '6df9d9b55d3f56ee7782639a7678eeeaf77f14ea'
authorMichael Niedermayer <michaelni@gmx.at>
Fri, 24 Oct 2014 10:40:08 +0000 (12:40 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 24 Oct 2014 10:40:36 +0000 (12:40 +0200)
* commit '6df9d9b55d3f56ee7782639a7678eeeaf77f14ea':
  lavf: Use av_gettime_relative

Conflicts:
libavformat/hls.c

See: f78bc96b7c1c74caf99a7139cf81ce1110404965
Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavformat/hls.c
libavformat/hlsproto.c
libavformat/rtpdec.c
libavformat/rtsp.c
libavformat/rtspdec.c

@@@ -665,8 -319,8 +665,8 @@@ static int parse_playlist(HLSContext *c
              }
          }
      }
 -    if (var)
 -        var->last_load_time = av_gettime_relative();
 +    if (pls)
-         pls->last_load_time = av_gettime();
++        pls->last_load_time = av_gettime_relative();
  
  fail:
      av_free(new_url);
@@@ -1035,12 -392,9 +1035,12 @@@ restart
  
  reload:
          if (!v->finished &&
-             av_gettime() - v->last_load_time >= reload_interval) {
+             av_gettime_relative() - v->last_load_time >= reload_interval) {
 -            if ((ret = parse_playlist(c, v->url, v, NULL)) < 0)
 +            if ((ret = parse_playlist(c, v->url, v, NULL)) < 0) {
 +                av_log(v->parent, AV_LOG_WARNING, "Failed to reload playlist %d\n",
 +                       v->index);
                  return ret;
 +            }
              /* If we need to reload the playlist again below (if
               * there's still no more segments), switch to a reload
               * interval of half the target duration. */
      v->input = NULL;
      v->cur_seq_no++;
  
 -    c->end_of_segment = 1;
      c->cur_seq_no = v->cur_seq_no;
  
 -    if (v->ctx && v->ctx->nb_streams &&
 -        v->parent->nb_streams >= v->stream_offset + v->ctx->nb_streams) {
 -        v->needed = 0;
 -        for (i = v->stream_offset; i < v->stream_offset + v->ctx->nb_streams;
 -             i++) {
 -            if (v->parent->streams[i]->discard < AVDISCARD_ALL)
 -                v->needed = 1;
 +    goto restart;
 +}
 +
 +static int playlist_in_multiple_variants(HLSContext *c, struct playlist *pls)
 +{
 +    int variant_count = 0;
 +    int i, j;
 +
 +    for (i = 0; i < c->n_variants && variant_count < 2; i++) {
 +        struct variant *v = c->variants[i];
 +
 +        for (j = 0; j < v->n_playlists; j++) {
 +            if (v->playlists[j] == pls) {
 +                variant_count++;
 +                break;
 +            }
          }
      }
 -    if (!v->needed) {
 -        av_log(v->parent, AV_LOG_INFO, "No longer receiving variant %d\n",
 -               v->index);
 -        return AVERROR_EOF;
 +
 +    return variant_count >= 2;
 +}
 +
 +static void add_renditions_to_variant(HLSContext *c, struct variant *var,
 +                                      enum AVMediaType type, const char *group_id)
 +{
 +    int i;
 +
 +    for (i = 0; i < c->n_renditions; i++) {
 +        struct rendition *rend = c->renditions[i];
 +
 +        if (rend->type == type && !strcmp(rend->group_id, group_id)) {
 +
 +            if (rend->playlist)
 +                /* rendition is an external playlist
 +                 * => add the playlist to the variant */
 +                dynarray_add(&var->playlists, &var->n_playlists, rend->playlist);
 +            else
 +                /* rendition is part of the variant main Media Playlist
 +                 * => add the rendition to the main Media Playlist */
 +                dynarray_add(&var->playlists[0]->renditions,
 +                             &var->playlists[0]->n_renditions,
 +                             rend);
 +        }
      }
 -    goto restart;
 +}
 +
 +static void add_metadata_from_renditions(AVFormatContext *s, struct playlist *pls,
 +                                         enum AVMediaType type)
 +{
 +    int rend_idx = 0;
 +    int i;
 +
 +    for (i = 0; i < pls->ctx->nb_streams; i++) {
 +        AVStream *st = s->streams[pls->stream_offset + i];
 +
 +        if (st->codec->codec_type != type)
 +            continue;
 +
 +        for (; rend_idx < pls->n_renditions; rend_idx++) {
 +            struct rendition *rend = pls->renditions[rend_idx];
 +
 +            if (rend->type != type)
 +                continue;
 +
 +            if (rend->language[0])
 +                av_dict_set(&st->metadata, "language", rend->language, 0);
 +            if (rend->name[0])
 +                av_dict_set(&st->metadata, "comment", rend->name, 0);
 +
 +            st->disposition |= rend->disposition;
 +        }
 +        if (rend_idx >=pls->n_renditions)
 +            break;
 +    }
 +}
 +
 +/* if timestamp was in valid range: returns 1 and sets seq_no
 + * if not: returns 0 and sets seq_no to closest segment */
 +static int find_timestamp_in_playlist(HLSContext *c, struct playlist *pls,
 +                                      int64_t timestamp, int *seq_no)
 +{
 +    int i;
 +    int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ?
 +                  0 : c->first_timestamp;
 +
 +    if (timestamp < pos) {
 +        *seq_no = pls->start_seq_no;
 +        return 0;
 +    }
 +
 +    for (i = 0; i < pls->n_segments; i++) {
 +        int64_t diff = pos + pls->segments[i]->duration - timestamp;
 +        if (diff > 0) {
 +            *seq_no = pls->start_seq_no + i;
 +            return 1;
 +        }
 +        pos += pls->segments[i]->duration;
 +    }
 +
 +    *seq_no = pls->start_seq_no + pls->n_segments - 1;
 +
 +    return 0;
 +}
 +
 +static int select_cur_seq_no(HLSContext *c, struct playlist *pls)
 +{
 +    int seq_no;
 +
 +    if (!pls->finished && !c->first_packet &&
-         av_gettime() - pls->last_load_time >= default_reload_interval(pls))
++        av_gettime_relative() - pls->last_load_time >= default_reload_interval(pls))
 +        /* reload the playlist since it was suspended */
 +        parse_playlist(c, pls->url, pls, NULL);
 +
 +    /* If playback is already in progress (we are just selecting a new
 +     * playlist) and this is a complete file, find the matching segment
 +     * by counting durations. */
 +    if (pls->finished && c->cur_timestamp != AV_NOPTS_VALUE) {
 +        find_timestamp_in_playlist(c, pls, c->cur_timestamp, &seq_no);
 +        return seq_no;
 +    }
 +
 +    if (!pls->finished) {
 +        if (!c->first_packet && /* we are doing a segment selection during playback */
 +            c->cur_seq_no >= pls->start_seq_no &&
 +            c->cur_seq_no < pls->start_seq_no + pls->n_segments)
 +            /* While spec 3.4.3 says that we cannot assume anything about the
 +             * content at the same sequence number on different playlists,
 +             * in practice this seems to work and doing it otherwise would
 +             * require us to download a segment to inspect its timestamps. */
 +            return c->cur_seq_no;
 +
 +        /* If this is a live stream with more than 3 segments, start at the
 +         * third last segment. */
 +        if (pls->n_segments > 3)
 +            return pls->start_seq_no + pls->n_segments - 3;
 +    }
 +
 +    /* Otherwise just start on the first segment. */
 +    return pls->start_seq_no;
  }
  
  static int hls_read_header(AVFormatContext *s)
Simple merge
Simple merge
Simple merge
Simple merge