[FFmpeg-devel] dashdec: Support SegmentTimeline inside Period

Submitted by Stefan _ on Feb. 6, 2018, 9:30 p.m.

Details

Message ID DB3PR0202MB345291362D654628F66056DFECFD0@DB3PR0202MB3452.eurprd02.prod.outlook.com
State New
Headers show

Commit Message

Stefan _ Feb. 6, 2018, 9:30 p.m.
Hi,

attached patch adds support for yet another small detail of the standard 
that YouTube happens to use for DVR functionality of livestreams.

Ideally dashdec would be fully standards compliant implementation, but 
that doesn't look like it's planned or happening anytime soon.

Comments

Steven Liu Feb. 6, 2018, 10:40 p.m.
> 在 2018年2月7日,上午5:30,Stefan _ <sfan5@live.de> 写道:
> 
> Hi,
> 
> attached patch adds support for yet another small detail of the standard 
> that YouTube happens to use for DVR functionality of livestreams.
> 
> Ideally dashdec would be fully standards compliant implementation, but 
> that doesn't look like it's planned or happening anytime soon.
Ah, I’m busying for myself production, so this maybe some weeks after will todo :(



> 
> <0001-dashdec-Support-SegmentTimeline-inside-Period.patch>
LGTM

You can maintaining it if you have interested in it ;)
Steven Liu Feb. 9, 2018, 3:06 a.m.
>> 在 2018年2月7日,上午5:30,Stefan _ <sfan5@live.de> 写道:
>>
>>
>> <0001-dashdec-Support-SegmentTimeline-inside-Period.patch>
> LGTM


Pushed

Thanks
Steven

Patch hide | download patch | download mbox

From 168a7dca7bef54927cf58b61d7140f1d2984693c Mon Sep 17 00:00:00 2001
From: sfan5 <sfan5@live.de>
Date: Tue, 6 Feb 2018 22:23:41 +0100
Subject: [PATCH] dashdec: Support SegmentTimeline inside Period

---
 libavformat/dashdec.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
index f9dc03309..2b396a01b 100644
--- a/libavformat/dashdec.c
+++ b/libavformat/dashdec.c
@@ -801,6 +801,7 @@  static int parse_manifest_representation(AVFormatContext *s, const char *url,
                                          xmlNodePtr mpd_baseurl_node,
                                          xmlNodePtr period_baseurl_node,
                                          xmlNodePtr period_segmenttemplate_node,
+                                         xmlNodePtr period_segmentlist_node,
                                          xmlNodePtr fragment_template_node,
                                          xmlNodePtr content_component_node,
                                          xmlNodePtr adaptionset_baseurl_node,
@@ -817,7 +818,7 @@  static int parse_manifest_representation(AVFormatContext *s, const char *url,
     xmlNodePtr representation_segmentlist_node = NULL;
     xmlNodePtr segmentlists_tab[2];
     xmlNodePtr fragment_timeline_node = NULL;
-    xmlNodePtr fragment_templates_tab[4];
+    xmlNodePtr fragment_templates_tab[5];
     char *duration_val = NULL;
     char *presentation_timeoffset_val = NULL;
     char *startnumber_val = NULL;
@@ -869,6 +870,7 @@  static int parse_manifest_representation(AVFormatContext *s, const char *url,
             fragment_templates_tab[1] = adaptionset_segmentlist_node;
             fragment_templates_tab[2] = fragment_template_node;
             fragment_templates_tab[3] = period_segmenttemplate_node;
+            fragment_templates_tab[4] = period_segmentlist_node;
 
             presentation_timeoffset_val = get_val_from_nodes_tab(fragment_templates_tab, 4, "presentationTimeOffset");
             duration_val = get_val_from_nodes_tab(fragment_templates_tab, 4, "duration");
@@ -925,6 +927,8 @@  static int parse_manifest_representation(AVFormatContext *s, const char *url,
                 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)
+                fragment_timeline_node = find_child_node_by_name(period_segmentlist_node, "SegmentTimeline");
             if (fragment_timeline_node) {
                 fragment_timeline_node = xmlFirstElementChild(fragment_timeline_node);
                 while (fragment_timeline_node) {
@@ -984,6 +988,8 @@  static int parse_manifest_representation(AVFormatContext *s, const char *url,
                 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)
+                fragment_timeline_node = find_child_node_by_name(period_segmentlist_node, "SegmentTimeline");
             if (fragment_timeline_node) {
                 fragment_timeline_node = xmlFirstElementChild(fragment_timeline_node);
                 while (fragment_timeline_node) {
@@ -1040,7 +1046,8 @@  static int parse_manifest_adaptationset(AVFormatContext *s, const char *url,
                                         xmlNodePtr adaptionset_node,
                                         xmlNodePtr mpd_baseurl_node,
                                         xmlNodePtr period_baseurl_node,
-                                        xmlNodePtr period_segmenttemplate_node)
+                                        xmlNodePtr period_segmenttemplate_node,
+                                        xmlNodePtr period_segmentlist_node)
 {
     int ret = 0;
     xmlNodePtr fragment_template_node = NULL;
@@ -1065,6 +1072,7 @@  static int parse_manifest_adaptationset(AVFormatContext *s, const char *url,
                                                 mpd_baseurl_node,
                                                 period_baseurl_node,
                                                 period_segmenttemplate_node,
+                                                period_segmentlist_node,
                                                 fragment_template_node,
                                                 content_component_node,
                                                 adaptionset_baseurl_node,
@@ -1094,6 +1102,7 @@  static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in)
     xmlNodePtr mpd_baseurl_node = NULL;
     xmlNodePtr period_baseurl_node = NULL;
     xmlNodePtr period_segmenttemplate_node = NULL;
+    xmlNodePtr period_segmentlist_node = NULL;
     xmlNodePtr adaptionset_node = NULL;
     xmlAttrPtr attr = NULL;
     char *val  = NULL;
@@ -1228,8 +1237,10 @@  static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in)
                 period_baseurl_node = adaptionset_node;
             } else if (!av_strcasecmp(adaptionset_node->name, (const char *)"SegmentTemplate")) {
                 period_segmenttemplate_node = adaptionset_node;
+            } else if (!av_strcasecmp(adaptionset_node->name, (const char *)"SegmentList")) {
+                period_segmentlist_node = adaptionset_node;
             } else if (!av_strcasecmp(adaptionset_node->name, (const char *)"AdaptationSet")) {
-                parse_manifest_adaptationset(s, url, adaptionset_node, mpd_baseurl_node, period_baseurl_node, period_segmenttemplate_node);
+                parse_manifest_adaptationset(s, url, adaptionset_node, mpd_baseurl_node, period_baseurl_node, period_segmenttemplate_node, period_segmentlist_node);
             }
             adaptionset_node = xmlNextElementSibling(adaptionset_node);
         }
-- 
2.16.1