char *allowed_extensions;
AVDictionary *avio_opts;
int max_url_size;
+
+ /* Flags for init section*/
+ int is_init_section_common_video;
+ int is_init_section_common_audio;
+
} DASHContext;
static int ishttp(char *url)
if (av_strstart(proto_name, "file", NULL)) {
if (strcmp(c->allowed_extensions, "ALL") && !av_match_ext(url, c->allowed_extensions)) {
av_log(s, AV_LOG_ERROR,
- "Filename extension of \'%s\' is not a common multimedia extension, blocked for security reasons.\n"
- "If you wish to override this adjust allowed_extensions, you can set it to \'ALL\' to allow all\n",
- url);
+ "Filename extension of \'%s\' is not a common multimedia extension, blocked for security reasons.\n"
+ "If you wish to override this adjust allowed_extensions, you can set it to \'ALL\' to allow all\n",
+ url);
return AVERROR_INVALIDDATA;
}
} else if (av_strstart(proto_name, "http", NULL)) {
char *baseurl = NULL;
char *root_url = NULL;
char *text = NULL;
+ char *tmp = NULL;
int isRootHttp = 0;
char token ='/';
goto end;
}
av_strlcpy(text, url, strlen(url)+1);
- while (mpdName = av_strtok(text, "/", &text)) {
+ tmp = text;
+ while (mpdName = av_strtok(tmp, "/", &tmp)) {
size = strlen(mpdName);
}
+ av_free(text);
path = av_mallocz(tmp_max_url_size);
tmp_str = av_mallocz(tmp_max_url_size);
}
av_free(path);
av_free(tmp_str);
+ xmlFree(baseurl);
return updated;
}
rep->last_seq_no =(int64_t) strtoll(val, NULL, 10) - 1;
xmlFree(val);
}
- }
+ }
}
fragment_timeline_node = find_child_node_by_name(representation_segmenttemplate_node, "SegmentTimeline");
xmlNodePtr root_element = NULL;
xmlNodePtr node = NULL;
xmlNodePtr period_node = NULL;
+ xmlNodePtr tmp_node = NULL;
xmlNodePtr mpd_baseurl_node = NULL;
xmlNodePtr period_baseurl_node = NULL;
xmlNodePtr period_segmenttemplate_node = NULL;
} else {
LIBXML_TEST_VERSION
- doc = xmlReadMemory(buffer, filesize, c->base_url, NULL, 0);
+ doc = xmlReadMemory(buffer, filesize, c->base_url, NULL, 0);
root_element = xmlDocGetRootElement(doc);
node = root_element;
xmlFree(val);
}
- mpd_baseurl_node = find_child_node_by_name(node, "BaseURL");
- if (!mpd_baseurl_node) {
+ tmp_node = find_child_node_by_name(node, "BaseURL");
+ if (tmp_node) {
+ mpd_baseurl_node = xmlCopyNode(tmp_node,1);
+ } else {
mpd_baseurl_node = xmlNewNode(NULL, "BaseURL");
}
/*free the document */
xmlFreeDoc(doc);
xmlCleanupParser();
+ xmlFreeNode(mpd_baseurl_node);
}
av_free(new_url);
c->videos = NULL;
c->n_audios = 0;
c->audios = NULL;
- ret = parse_manifest(s, s->filename, NULL);
+ ret = parse_manifest(s, s->url, NULL);
if (ret)
goto finish;
if (c->n_videos != n_videos) {
av_log(c, AV_LOG_ERROR,
- "new manifest has mismatched no. of video representations, %d -> %d\n",
- n_videos, c->n_videos);
+ "new manifest has mismatched no. of video representations, %d -> %d\n",
+ n_videos, c->n_videos);
return AVERROR_INVALIDDATA;
}
if (c->n_audios != n_audios) {
av_log(c, AV_LOG_ERROR,
- "new manifest has mismatched no. of audio representations, %d -> %d\n",
- n_audios, c->n_audios);
+ "new manifest has mismatched no. of audio representations, %d -> %d\n",
+ n_audios, c->n_audios);
return AVERROR_INVALIDDATA;
}
av_log(s, AV_LOG_ERROR,
"A DASH playlist item '%s' referred to an external file '%s'. "
"Opening this file was forbidden for security reasons\n",
- s->filename, url);
+ s->url, url);
return AVERROR(EPERM);
}
return ret;
}
+static int is_common_init_section_exist(struct representation **pls, int n_pls)
+{
+ struct fragment *first_init_section = pls[0]->init_section;
+ char *url =NULL;
+ int64_t url_offset = -1;
+ int64_t size = -1;
+ int i = 0;
+
+ if (first_init_section == NULL || n_pls == 0)
+ return 0;
+
+ url = first_init_section->url;
+ url_offset = first_init_section->url_offset;
+ size = pls[0]->init_section->size;
+ for (i=0;i<n_pls;i++) {
+ if (av_strcasecmp(pls[i]->init_section->url,url) || pls[i]->init_section->url_offset != url_offset || pls[i]->init_section->size != size) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static void copy_init_section(struct representation *rep_dest, struct representation *rep_src)
+{
+ *rep_dest->init_section = *rep_src->init_section;
+ rep_dest->init_sec_buf = av_mallocz(rep_src->init_sec_buf_size);
+ memcpy(rep_dest->init_sec_buf, rep_src->init_sec_buf, rep_src->init_sec_data_len);
+ rep_dest->init_sec_buf_size = rep_src->init_sec_buf_size;
+ rep_dest->init_sec_data_len = rep_src->init_sec_data_len;
+ rep_dest->cur_timestamp = rep_src->cur_timestamp;
+}
+
+
static int dash_read_header(AVFormatContext *s)
{
void *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb;
update_options(&c->headers, "headers", u);
}
- if ((ret = parse_manifest(s, s->filename, s->pb)) < 0)
+ if ((ret = parse_manifest(s, s->url, s->pb)) < 0)
goto fail;
if ((ret = save_avio_options(s)) < 0)
s->duration = (int64_t) c->media_presentation_duration * AV_TIME_BASE;
}
+ c->is_init_section_common_video = is_common_init_section_exist(c->videos, c->n_videos);
+
/* Open the demuxer for video and audio components if available */
for (i = 0; i < c->n_videos; i++) {
struct representation *cur_video = c->videos[i];
+ if (i > 0 && c->is_init_section_common_video) {
+ copy_init_section(cur_video,c->videos[0]);
+ }
ret = open_demux_for_component(s, cur_video);
+
if (ret)
goto fail;
cur_video->stream_index = stream_index;
++stream_index;
}
+ c->is_init_section_common_audio = is_common_init_section_exist(c->audios, c->n_audios);
+
for (i = 0; i < c->n_audios; i++) {
struct representation *cur_audio = c->audios[i];
+ if (i > 0 && c->is_init_section_common_audio) {
+ copy_init_section(cur_audio,c->audios[0]);
+ }
ret = open_demux_for_component(s, cur_audio);
+
if (ret)
goto fail;
cur_audio->stream_index = stream_index;
av_dict_set_int(&pls->assoc_stream->metadata, "variant_bitrate", pls->bandwidth, 0);
if (pls->id[0])
av_dict_set(&pls->assoc_stream->metadata, "id", pls->id, 0);
- }
+ }
for (i = 0; i < c->n_audios; i++) {
struct representation *pls = c->audios[i];
int64_t duration = 0;
av_log(pls->parent, AV_LOG_VERBOSE, "DASH seek pos[%"PRId64"ms], playlist %d%s\n",
- seek_pos_msec, pls->rep_idx, dry_run ? " (dry)" : "");
+ seek_pos_msec, pls->rep_idx, dry_run ? " (dry)" : "");
// single fragment mode
if (pls->n_fragments == 1) {