X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fhls.c;h=72e28ab94f4194866e0f88833f5459c91d057bcb;hb=b5ca8f2c66954614d81579082025f580efc0cffc;hp=96bddfa4107c51b344f3ea93204d0ab774ae5ed7;hpb=f08853b284514820d42f81999f4adb09ff5d95b4;p=ffmpeg diff --git a/libavformat/hls.c b/libavformat/hls.c index 96bddfa4107..72e28ab94f4 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -293,24 +293,18 @@ static void free_rendition_list(HLSContext *c) c->n_renditions = 0; } -/* - * Used to reset a statically allocated AVPacket to a clean state, - * containing no data. - */ -static void reset_packet(AVPacket *pkt) -{ - av_init_packet(pkt); - pkt->data = NULL; -} - static struct playlist *new_playlist(HLSContext *c, const char *url, const char *base) { struct playlist *pls = av_mallocz(sizeof(struct playlist)); if (!pls) return NULL; - reset_packet(&pls->pkt); ff_make_absolute_url(pls->url, sizeof(pls->url), base, url); + if (!pls->url[0]) { + av_free(pls); + return NULL; + } + av_init_packet(&pls->pkt); pls->seek_timestamp = AV_NOPTS_VALUE; pls->is_id3_timestamped = -1; @@ -416,6 +410,10 @@ static struct segment *new_init_section(struct playlist *pls, ptr = info->uri; } else { ff_make_absolute_url(tmp_str, sizeof(tmp_str), url_base, info->uri); + if (!tmp_str[0]) { + av_free(sec); + return NULL; + } } sec->url = av_strdup(ptr); if (!sec->url) { @@ -619,7 +617,7 @@ static int open_url_keepalive(AVFormatContext *s, AVIOContext **pb, } static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, - AVDictionary *opts, AVDictionary *opts2, int *is_http_out) + AVDictionary **opts, AVDictionary *opts2, int *is_http_out) { HLSContext *c = s->priv_data; AVDictionary *tmp = NULL; @@ -666,7 +664,7 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) return AVERROR_INVALIDDATA; - av_dict_copy(&tmp, opts, 0); + av_dict_copy(&tmp, *opts, 0); av_dict_copy(&tmp, opts2, 0); if (is_http && c->http_persistent && *pb) { @@ -692,7 +690,7 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, av_opt_get(*pb, "cookies", AV_OPT_SEARCH_CHILDREN, (uint8_t**)&new_cookies); if (new_cookies) - av_dict_set(&opts, "cookies", new_cookies, AV_DICT_DONT_STRDUP_VAL); + av_dict_set(opts, "cookies", new_cookies, AV_DICT_DONT_STRDUP_VAL); } av_dict_free(&tmp); @@ -841,6 +839,11 @@ static int parse_playlist(HLSContext *c, const char *url, if (key_type != KEY_NONE) { ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, key); + if (!tmp_str[0]) { + av_free(cur_init_section); + ret = AVERROR_INVALIDDATA; + goto fail; + } cur_init_section->key = av_strdup(tmp_str); if (!cur_init_section->key) { av_free(cur_init_section); @@ -883,8 +886,6 @@ static int parse_playlist(HLSContext *c, const char *url, ret = AVERROR(ENOMEM); goto fail; } - seg->duration = duration; - seg->key_type = key_type; if (has_iv) { memcpy(seg->iv, iv, sizeof(iv)); } else { @@ -895,6 +896,11 @@ static int parse_playlist(HLSContext *c, const char *url, if (key_type != KEY_NONE) { ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, key); + if (!tmp_str[0]) { + ret = AVERROR_INVALIDDATA; + av_free(seg); + goto fail; + } seg->key = av_strdup(tmp_str); if (!seg->key) { av_free(seg); @@ -906,6 +912,13 @@ static int parse_playlist(HLSContext *c, const char *url, } ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, line); + if (!tmp_str[0]) { + ret = AVERROR_INVALIDDATA; + if (seg->key) + av_free(seg->key); + av_free(seg); + goto fail; + } seg->url = av_strdup(tmp_str); if (!seg->url) { av_free(seg->key); @@ -914,6 +927,13 @@ static int parse_playlist(HLSContext *c, const char *url, goto fail; } + if (duration < 0.001 * AV_TIME_BASE) { + av_log(c->ctx, AV_LOG_WARNING, "Cannot get correct #EXTINF value of segment %s," + " set to default value to 1ms.\n", seg->url); + duration = 0.001 * AV_TIME_BASE; + } + seg->duration = duration; + seg->key_type = key_type; dynarray_add(&pls->segments, &pls->n_segments, seg); is_segment = 0; @@ -1070,12 +1090,12 @@ static void handle_id3(AVIOContext *pb, struct playlist *pls) /* get picture attachment and set text metadata */ if (pls->ctx->nb_streams) - ff_id3v2_parse_apic(pls->ctx, &extra_meta); + ff_id3v2_parse_apic(pls->ctx, extra_meta); else /* demuxer not yet opened, defer picture attachment */ pls->id3_deferred_extra = extra_meta; - ff_id3v2_parse_priv_dict(&metadata, &extra_meta); + ff_id3v2_parse_priv_dict(&metadata, extra_meta); av_dict_copy(&pls->ctx->metadata, metadata, 0); pls->id3_initial = metadata; @@ -1211,12 +1231,12 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, seg->url, seg->url_offset, pls->index); if (seg->key_type == KEY_NONE) { - ret = open_url(pls->parent, in, seg->url, c->avio_opts, opts, &is_http); + ret = open_url(pls->parent, in, seg->url, &c->avio_opts, opts, &is_http); } else if (seg->key_type == KEY_AES_128) { char iv[33], key[33], url[MAX_URL_SIZE]; if (strcmp(seg->key, pls->key_url)) { AVIOContext *pb = NULL; - if (open_url(pls->parent, &pb, seg->key, c->avio_opts, opts, NULL) == 0) { + if (open_url(pls->parent, &pb, seg->key, &c->avio_opts, opts, NULL) == 0) { ret = avio_read(pb, pls->key, sizeof(pls->key)); if (ret != sizeof(pls->key)) { av_log(pls->parent, AV_LOG_ERROR, "Unable to read key file %s\n", @@ -1240,7 +1260,7 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, av_dict_set(&opts, "key", key, 0); av_dict_set(&opts, "iv", iv, 0); - ret = open_url(pls->parent, in, url, c->avio_opts, opts, &is_http); + ret = open_url(pls->parent, in, url, &c->avio_opts, opts, &is_http); if (ret < 0) { goto cleanup; } @@ -1263,7 +1283,7 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, * as would be expected. Wrong offset received from the server will not be * noticed without the call, though. */ - if (ret == 0 && !is_http && seg->key_type == KEY_NONE && seg->url_offset) { + if (ret == 0 && !is_http && seg->url_offset) { int64_t seekret = avio_seek(*in, seg->url_offset, SEEK_SET); if (seekret < 0) { av_log(pls->parent, AV_LOG_ERROR, "Unable to seek to offset %"PRId64" of HLS segment '%s'\n", seg->url_offset, seg->url); @@ -1740,6 +1760,20 @@ static int set_stream_info_from_input_stream(AVStream *st, struct playlist *pls, else avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den); + // copy disposition + st->disposition = ist->disposition; + + // copy side data + for (int i = 0; i < ist->nb_side_data; i++) { + const AVPacketSideData *sd_src = &ist->side_data[i]; + uint8_t *dst_data; + + dst_data = av_stream_new_side_data(st, sd_src->type, sd_src->size); + if (!dst_data) + return AVERROR(ENOMEM); + memcpy(dst_data, sd_src->data, sd_src->size); + } + st->internal->need_context_update = 1; return 0; @@ -1904,6 +1938,7 @@ static int hls_read_header(AVFormatContext *s) /* Open the demuxer for each playlist */ for (i = 0; i < c->n_playlists; i++) { struct playlist *pls = c->playlists[i]; + char *url; ff_const59 AVInputFormat *in_fmt = NULL; if (!(pls->ctx = avformat_alloc_context())) { @@ -1941,8 +1976,10 @@ static int hls_read_header(AVFormatContext *s) read_data, NULL, NULL); pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; - ret = av_probe_input_buffer(&pls->pb, &in_fmt, pls->segments[0]->url, - NULL, 0, 0); + pls->ctx->interrupt_callback = s->interrupt_callback; + url = av_strdup(pls->segments[0]->url); + ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); + av_free(url); if (ret < 0) { /* Free the ctx - it isn't initialized properly at this point, * so avformat_close_input shouldn't be called. If @@ -1965,9 +2002,9 @@ static int hls_read_header(AVFormatContext *s) goto fail; if (pls->id3_deferred_extra && pls->ctx->nb_streams == 1) { - ff_id3v2_parse_apic(pls->ctx, &pls->id3_deferred_extra); + ff_id3v2_parse_apic(pls->ctx, pls->id3_deferred_extra); avformat_queue_attached_pictures(pls->ctx); - ff_id3v2_parse_priv(pls->ctx, &pls->id3_deferred_extra); + ff_id3v2_parse_priv(pls->ctx, pls->id3_deferred_extra); ff_id3v2_free_extra_meta(&pls->id3_deferred_extra); } @@ -2115,7 +2152,6 @@ static int hls_read_packet(AVFormatContext *s, AVPacket *pkt) if (ret < 0) { if (!avio_feof(&pls->pb) && ret != AVERROR_EOF) return ret; - reset_packet(&pls->pkt); break; } else { /* stream_index check prevents matching picture attachments etc. */ @@ -2335,7 +2371,7 @@ static const AVOption hls_options[] = { OFFSET(live_start_index), AV_OPT_TYPE_INT, {.i64 = -3}, INT_MIN, INT_MAX, FLAGS}, {"allowed_extensions", "List of file extensions that hls is allowed to access", OFFSET(allowed_extensions), AV_OPT_TYPE_STRING, - {.str = "3gp,aac,avi,flac,mkv,m3u8,m4a,m4s,m4v,mpg,mov,mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,wav"}, + {.str = "3gp,aac,avi,ac3,eac3,flac,mkv,m3u8,m4a,m4s,m4v,mpg,mov,mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,wav"}, INT_MIN, INT_MAX, FLAGS}, {"max_reload", "Maximum number of times a insufficient list is attempted to be reloaded", OFFSET(max_reload), AV_OPT_TYPE_INT, {.i64 = 1000}, 0, INT_MAX, FLAGS},