Commit bb0cc2e7 authored by sfan5's avatar sfan5 Committed by Steven Liu

dashdec: Search for segment timeline inside AdaptionSets too

parent 94cc1649
...@@ -648,7 +648,8 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, ...@@ -648,7 +648,8 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
xmlNodePtr period_baseurl_node, xmlNodePtr period_baseurl_node,
xmlNodePtr fragment_template_node, xmlNodePtr fragment_template_node,
xmlNodePtr content_component_node, xmlNodePtr content_component_node,
xmlNodePtr adaptionset_baseurl_node) xmlNodePtr adaptionset_baseurl_node,
xmlNodePtr adaptionset_segmentlist_node)
{ {
int32_t ret = 0; int32_t ret = 0;
int32_t audio_rep_idx = 0; int32_t audio_rep_idx = 0;
...@@ -659,8 +660,9 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, ...@@ -659,8 +660,9 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
xmlNodePtr representation_segmenttemplate_node = NULL; xmlNodePtr representation_segmenttemplate_node = NULL;
xmlNodePtr representation_baseurl_node = NULL; xmlNodePtr representation_baseurl_node = NULL;
xmlNodePtr representation_segmentlist_node = NULL; xmlNodePtr representation_segmentlist_node = NULL;
xmlNodePtr segmentlists_tab[2];
xmlNodePtr fragment_timeline_node = NULL; xmlNodePtr fragment_timeline_node = NULL;
xmlNodePtr fragment_templates_tab[2]; xmlNodePtr fragment_templates_tab[3];
char *duration_val = NULL; char *duration_val = NULL;
char *presentation_timeoffset_val = NULL; char *presentation_timeoffset_val = NULL;
char *startnumber_val = NULL; char *startnumber_val = NULL;
...@@ -703,14 +705,15 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, ...@@ -703,14 +705,15 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
if (representation_segmenttemplate_node || fragment_template_node) { if (representation_segmenttemplate_node || fragment_template_node) {
fragment_timeline_node = NULL; fragment_timeline_node = NULL;
fragment_templates_tab[0] = representation_segmenttemplate_node; fragment_templates_tab[0] = representation_segmenttemplate_node;
fragment_templates_tab[1] = fragment_template_node; fragment_templates_tab[1] = adaptionset_segmentlist_node;
fragment_templates_tab[2] = fragment_template_node;
presentation_timeoffset_val = get_val_from_nodes_tab(fragment_templates_tab, 2, "presentationTimeOffset"); presentation_timeoffset_val = get_val_from_nodes_tab(fragment_templates_tab, 3, "presentationTimeOffset");
duration_val = get_val_from_nodes_tab(fragment_templates_tab, 2, "duration"); duration_val = get_val_from_nodes_tab(fragment_templates_tab, 3, "duration");
startnumber_val = get_val_from_nodes_tab(fragment_templates_tab, 2, "startNumber"); startnumber_val = get_val_from_nodes_tab(fragment_templates_tab, 3, "startNumber");
timescale_val = get_val_from_nodes_tab(fragment_templates_tab, 2, "timescale"); timescale_val = get_val_from_nodes_tab(fragment_templates_tab, 3, "timescale");
initialization_val = get_val_from_nodes_tab(fragment_templates_tab, 2, "initialization"); initialization_val = get_val_from_nodes_tab(fragment_templates_tab, 3, "initialization");
media_val = get_val_from_nodes_tab(fragment_templates_tab, 2, "media"); media_val = get_val_from_nodes_tab(fragment_templates_tab, 3, "media");
if (initialization_val) { if (initialization_val) {
rep->init_section = av_mallocz(sizeof(struct fragment)); rep->init_section = av_mallocz(sizeof(struct fragment));
...@@ -756,6 +759,8 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, ...@@ -756,6 +759,8 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
if (!fragment_timeline_node) if (!fragment_timeline_node)
fragment_timeline_node = find_child_node_by_name(fragment_template_node, "SegmentTimeline"); fragment_timeline_node = find_child_node_by_name(fragment_template_node, "SegmentTimeline");
if (!fragment_timeline_node)
fragment_timeline_node = find_child_node_by_name(adaptionset_segmentlist_node, "SegmentTimeline");
if (fragment_timeline_node) { if (fragment_timeline_node) {
fragment_timeline_node = xmlFirstElementChild(fragment_timeline_node); fragment_timeline_node = xmlFirstElementChild(fragment_timeline_node);
while (fragment_timeline_node) { while (fragment_timeline_node) {
...@@ -784,8 +789,11 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, ...@@ -784,8 +789,11 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
// TODO: https://www.brendanlong.com/the-structure-of-an-mpeg-dash-mpd.html // TODO: https://www.brendanlong.com/the-structure-of-an-mpeg-dash-mpd.html
// http://www-itec.uni-klu.ac.at/dash/ddash/mpdGenerator.php?fragmentlength=15&type=full // http://www-itec.uni-klu.ac.at/dash/ddash/mpdGenerator.php?fragmentlength=15&type=full
xmlNodePtr fragmenturl_node = NULL; xmlNodePtr fragmenturl_node = NULL;
duration_val = xmlGetProp(representation_segmentlist_node, "duration"); segmentlists_tab[0] = representation_segmentlist_node;
timescale_val = xmlGetProp(representation_segmentlist_node, "timescale"); segmentlists_tab[1] = adaptionset_segmentlist_node;
duration_val = get_val_from_nodes_tab(segmentlists_tab, 2, "duration");
timescale_val = get_val_from_nodes_tab(segmentlists_tab, 2, "timescale");
if (duration_val) { if (duration_val) {
rep->fragment_duration = (int64_t) strtoll(duration_val, NULL, 10); rep->fragment_duration = (int64_t) strtoll(duration_val, NULL, 10);
xmlFree(duration_val); xmlFree(duration_val);
...@@ -810,6 +818,8 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, ...@@ -810,6 +818,8 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
if (!fragment_timeline_node) if (!fragment_timeline_node)
fragment_timeline_node = find_child_node_by_name(fragment_template_node, "SegmentTimeline"); fragment_timeline_node = find_child_node_by_name(fragment_template_node, "SegmentTimeline");
if (!fragment_timeline_node)
fragment_timeline_node = find_child_node_by_name(adaptionset_segmentlist_node, "SegmentTimeline");
if (fragment_timeline_node) { if (fragment_timeline_node) {
fragment_timeline_node = xmlFirstElementChild(fragment_timeline_node); fragment_timeline_node = xmlFirstElementChild(fragment_timeline_node);
while (fragment_timeline_node) { while (fragment_timeline_node) {
...@@ -862,6 +872,7 @@ static int parse_manifest_adaptationset(AVFormatContext *s, const char *url, ...@@ -862,6 +872,7 @@ static int parse_manifest_adaptationset(AVFormatContext *s, const char *url,
xmlNodePtr fragment_template_node = NULL; xmlNodePtr fragment_template_node = NULL;
xmlNodePtr content_component_node = NULL; xmlNodePtr content_component_node = NULL;
xmlNodePtr adaptionset_baseurl_node = NULL; xmlNodePtr adaptionset_baseurl_node = NULL;
xmlNodePtr adaptionset_segmentlist_node = NULL;
xmlNodePtr node = NULL; xmlNodePtr node = NULL;
node = xmlFirstElementChild(adaptionset_node); node = xmlFirstElementChild(adaptionset_node);
...@@ -872,6 +883,8 @@ static int parse_manifest_adaptationset(AVFormatContext *s, const char *url, ...@@ -872,6 +883,8 @@ static int parse_manifest_adaptationset(AVFormatContext *s, const char *url,
content_component_node = node; content_component_node = node;
} else if (!av_strcasecmp(node->name, (const char *)"BaseURL")) { } else if (!av_strcasecmp(node->name, (const char *)"BaseURL")) {
adaptionset_baseurl_node = node; adaptionset_baseurl_node = node;
} else if (!av_strcasecmp(node->name, (const char *)"SegmentList")) {
adaptionset_segmentlist_node = node;
} else if (!av_strcasecmp(node->name, (const char *)"Representation")) { } else if (!av_strcasecmp(node->name, (const char *)"Representation")) {
ret = parse_manifest_representation(s, url, node, ret = parse_manifest_representation(s, url, node,
adaptionset_node, adaptionset_node,
...@@ -879,7 +892,8 @@ static int parse_manifest_adaptationset(AVFormatContext *s, const char *url, ...@@ -879,7 +892,8 @@ static int parse_manifest_adaptationset(AVFormatContext *s, const char *url,
period_baseurl_node, period_baseurl_node,
fragment_template_node, fragment_template_node,
content_component_node, content_component_node,
adaptionset_baseurl_node); adaptionset_baseurl_node,
adaptionset_segmentlist_node);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
...@@ -1863,7 +1877,7 @@ set_seq_num: ...@@ -1863,7 +1877,7 @@ set_seq_num:
} else if (pls->fragment_duration > 0) { } else if (pls->fragment_duration > 0) {
pls->cur_seq_no = pls->first_seq_no + ((seek_pos_msec * pls->fragment_timescale) / pls->fragment_duration) / 1000; pls->cur_seq_no = pls->first_seq_no + ((seek_pos_msec * pls->fragment_timescale) / pls->fragment_duration) / 1000;
} else { } else {
av_log(pls->parent, AV_LOG_ERROR, "dash_seek missing fragment_duration\n"); av_log(pls->parent, AV_LOG_ERROR, "dash_seek missing timeline or fragment_duration\n");
pls->cur_seq_no = pls->first_seq_no; pls->cur_seq_no = pls->first_seq_no;
} }
pls->cur_timestamp = 0; pls->cur_timestamp = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment