AVFormatContext *ctx;
int stream_index;
- char id[20];
+ char *id;
char *lang;
int bandwidth;
AVRational framerate;
/* Flags for init section*/
int is_init_section_common_video;
int is_init_section_common_audio;
+ int is_init_section_common_subtitle;
} DASHContext;
static int ishttp(char *url)
{
const char *proto_name = avio_find_protocol_name(url);
- return av_strstart(proto_name, "http", NULL);
+ return proto_name && av_strstart(proto_name, "http", NULL);
}
static int aligned(int val)
av_freep(&pls->url_template);
av_freep(&pls->lang);
+ av_freep(&pls->id);
av_freep(&pls);
}
char *val = NULL;
xmlNodePtr baseurl_nodes[4];
xmlNodePtr representation_node = node;
- char *rep_id_val, *rep_bandwidth_val;
+ char *rep_bandwidth_val;
enum AVMediaType type = AVMEDIA_TYPE_UNKNOWN;
// try get information from representation
representation_segmenttemplate_node = find_child_node_by_name(representation_node, "SegmentTemplate");
representation_baseurl_node = find_child_node_by_name(representation_node, "BaseURL");
representation_segmentlist_node = find_child_node_by_name(representation_node, "SegmentList");
- rep_id_val = xmlGetProp(representation_node, "id");
rep_bandwidth_val = xmlGetProp(representation_node, "bandwidth");
+ val = xmlGetProp(representation_node, "id");
+ if (val) {
+ rep->id = av_strdup(val);
+ xmlFree(val);
+ if (!rep->id)
+ goto enomem;
+ }
baseurl_nodes[0] = mpd_baseurl_node;
baseurl_nodes[1] = period_baseurl_node;
ret = resolve_content_path(s, url, &c->max_url_size, baseurl_nodes, 4);
c->max_url_size = aligned(c->max_url_size
- + (rep_id_val ? strlen(rep_id_val) : 0)
+ + (rep->id ? strlen(rep->id) : 0)
+ (rep_bandwidth_val ? strlen(rep_bandwidth_val) : 0));
if (ret == AVERROR(ENOMEM) || ret == 0)
goto free;
goto enomem;
}
c->max_url_size = aligned(c->max_url_size + strlen(val));
- rep->init_section->url = get_content_url(baseurl_nodes, 4, c->max_url_size, rep_id_val, rep_bandwidth_val, val);
+ rep->init_section->url = get_content_url(baseurl_nodes, 4,
+ c->max_url_size, rep->id,
+ rep_bandwidth_val, val);
xmlFree(val);
if (!rep->init_section->url)
goto enomem;
val = get_val_from_nodes_tab(fragment_templates_tab, 4, "media");
if (val) {
c->max_url_size = aligned(c->max_url_size + strlen(val));
- rep->url_template = get_content_url(baseurl_nodes, 4, c->max_url_size, rep_id_val, rep_bandwidth_val, val);
+ rep->url_template = get_content_url(baseurl_nodes, 4,
+ c->max_url_size, rep->id,
+ rep_bandwidth_val, val);
xmlFree(val);
}
val = get_val_from_nodes_tab(fragment_templates_tab, 4, "presentationTimeOffset");
av_free(seg);
goto free;
}
- seg->url = get_content_url(baseurl_nodes, 4, c->max_url_size, rep_id_val, rep_bandwidth_val, NULL);
+ seg->url = get_content_url(baseurl_nodes, 4, c->max_url_size,
+ rep->id, rep_bandwidth_val, NULL);
if (!seg->url)
goto enomem;
seg->size = -1;
fragmenturl_node = xmlFirstElementChild(representation_segmentlist_node);
while (fragmenturl_node) {
ret = parse_manifest_segmenturlnode(s, rep, fragmenturl_node,
- baseurl_nodes,
- rep_id_val,
+ baseurl_nodes, rep->id,
rep_bandwidth_val);
if (ret < 0)
goto free;
}
}
} else {
- av_log(s, AV_LOG_ERROR, "Unknown format of Representation node id[%s] \n", rep_id_val);
+ av_log(s, AV_LOG_ERROR, "Unknown format of Representation node id '%s' \n",
+ rep->id ? rep->id : "");
goto free;
}
if (rep->fragment_duration > 0 && !rep->fragment_timescale)
rep->fragment_timescale = 1;
rep->bandwidth = rep_bandwidth_val ? atoi(rep_bandwidth_val) : 0;
- strncpy(rep->id, rep_id_val ? rep_id_val : "", sizeof(rep->id));
rep->framerate = av_make_q(0, 0);
if (type == AVMEDIA_TYPE_VIDEO) {
char *rep_framerate_val = xmlGetProp(representation_node, "frameRate");
goto free;
end:
- if (rep_id_val)
- xmlFree(rep_id_val);
if (rep_bandwidth_val)
xmlFree(rep_bandwidth_val);
} else if (c->is_live && pls->fragment_duration) {
num = pls->first_seq_no + (((get_current_time_in_sec() - c->availability_start_time)) * pls->fragment_timescale) / pls->fragment_duration;
} else if (pls->fragment_duration) {
- num = pls->first_seq_no + (c->media_presentation_duration * pls->fragment_timescale) / pls->fragment_duration;
+ num = pls->first_seq_no + av_rescale_rnd(1, c->media_presentation_duration * pls->fragment_timescale, pls->fragment_duration, AV_ROUND_UP);
}
return num;
}
}
if (seg) {
- char *tmpfilename= av_mallocz(c->max_url_size);
+ char *tmpfilename;
+ if (!pls->url_template) {
+ av_log(pls->parent, AV_LOG_ERROR, "Cannot get fragment, missing template URL\n");
+ av_free(seg);
+ return NULL;
+ }
+ tmpfilename = av_mallocz(c->max_url_size);
if (!tmpfilename) {
+ av_free(seg);
return NULL;
}
ff_dash_fill_tmpl_params(tmpfilename, c->max_url_size, pls->url_template, 0, pls->cur_seq_no, 0, get_segment_start_time_based_on_timeline(pls, pls->cur_seq_no));
if (!seg->url) {
av_log(pls->parent, AV_LOG_ERROR, "Cannot resolve template url '%s'\n", pls->url_template);
av_free(tmpfilename);
+ av_free(seg);
return NULL;
}
}
static int reopen_demux_for_component(AVFormatContext *s, struct representation *pls)
{
DASHContext *c = s->priv_data;
- ff_const59 AVInputFormat *in_fmt = NULL;
+ const AVInputFormat *in_fmt = NULL;
AVDictionary *in_fmt_opts = NULL;
uint8_t *avio_ctx_buffer = NULL;
int ret = 0, i;
static int dash_close(AVFormatContext *s);
+static void move_metadata(AVStream *st, const char *key, char **value)
+{
+ if (*value) {
+ av_dict_set(&st->metadata, key, *value, AV_DICT_DONT_STRDUP_VAL);
+ *value = NULL;
+ }
+}
+
static int dash_read_header(AVFormatContext *s)
{
DASHContext *c = s->priv_data;
}
if (c->n_subtitles)
- c->is_init_section_common_audio = is_common_init_section_exist(c->subtitles, c->n_subtitles);
+ c->is_init_section_common_subtitle = is_common_init_section_exist(c->subtitles, c->n_subtitles);
for (i = 0; i < c->n_subtitles; i++) {
rep = c->subtitles[i];
- if (i > 0 && c->is_init_section_common_audio) {
+ if (i > 0 && c->is_init_section_common_subtitle) {
ret = copy_init_section(rep, c->subtitles[0]);
if (ret < 0)
goto fail;
rep->assoc_stream = s->streams[rep->stream_index];
if (rep->bandwidth > 0)
av_dict_set_int(&rep->assoc_stream->metadata, "variant_bitrate", rep->bandwidth, 0);
- if (rep->id[0])
- av_dict_set(&rep->assoc_stream->metadata, "id", rep->id, 0);
+ move_metadata(rep->assoc_stream, "id", &rep->id);
}
for (i = 0; i < c->n_audios; i++) {
rep = c->audios[i];
rep->assoc_stream = s->streams[rep->stream_index];
if (rep->bandwidth > 0)
av_dict_set_int(&rep->assoc_stream->metadata, "variant_bitrate", rep->bandwidth, 0);
- if (rep->id[0])
- av_dict_set(&rep->assoc_stream->metadata, "id", rep->id, 0);
- if (rep->lang) {
- av_dict_set(&rep->assoc_stream->metadata, "language", rep->lang, 0);
- av_freep(&rep->lang);
- }
+ move_metadata(rep->assoc_stream, "id", &rep->id);
+ move_metadata(rep->assoc_stream, "language", &rep->lang);
}
for (i = 0; i < c->n_subtitles; i++) {
rep = c->subtitles[i];
av_program_add_stream_index(s, 0, rep->stream_index);
rep->assoc_stream = s->streams[rep->stream_index];
- if (rep->id[0])
- av_dict_set(&rep->assoc_stream->metadata, "id", rep->id, 0);
- if (rep->lang) {
- av_dict_set(&rep->assoc_stream->metadata, "language", rep->lang, 0);
- av_freep(&rep->lang);
- }
+ move_metadata(rep->assoc_stream, "id", &rep->id);
+ move_metadata(rep->assoc_stream, "language", &rep->lang);
}
return 0;
.version = LIBAVUTIL_VERSION_INT,
};
-AVInputFormat ff_dash_demuxer = {
+const AVInputFormat ff_dash_demuxer = {
.name = "dash",
.long_name = NULL_IF_CONFIG_SMALL("Dynamic Adaptive Streaming over HTTP"),
.priv_class = &dash_class,