[FFmpeg-devel] dash: add descriptor which is useful to the scheme defined by ISO/IEC 23009-1:2014/Amd.2:2015.

Submitted by Leo Zhang on July 19, 2019, 3:08 a.m.

Details

Message ID 1563505680-131660-1-git-send-email-leozhang@qiyi.com
State New
Headers show

Commit Message

Leo Zhang July 19, 2019, 3:08 a.m.
change history:
1. Use normal descriptor string instead of base64 encoded
2. Add example to muxers.texi
3. Change descriptor char * and allocate it dynamically

Please review, thanks

Signed-off-by: leozhang <leozhang@qiyi.com>
---
 doc/muxers.texi       |  4 ++++
 libavformat/dashenc.c | 27 +++++++++++++++++++++++----
 2 files changed, 27 insertions(+), 4 deletions(-)

Comments

kjeyapal@akamai.com July 19, 2019, 3:16 a.m.
On 7/19/19 8:38 AM, leozhang wrote:
> change history:

> 1. Use normal descriptor string instead of base64 encoded

> 2. Add example to muxers.texi

> 3. Change descriptor char * and allocate it dynamically

>

> Please review, thanks

Thanks for sending the revised patch. LGTM.
I will wait for 3 days and then push it, if there are no other objections.

Regards,
Karthick
>

> Signed-off-by: leozhang <leozhang@qiyi.com>

> ---

>  doc/muxers.texi       |  4 ++++

>  libavformat/dashenc.c | 27 +++++++++++++++++++++++----

>  2 files changed, 27 insertions(+), 4 deletions(-)

>

> diff --git a/doc/muxers.texi b/doc/muxers.texi

> index b109297..bc38cf6 100644

> --- a/doc/muxers.texi

> +++ b/doc/muxers.texi

> @@ -275,6 +275,10 @@ of the adaptation sets and a,b,c,d and e are the indices of the mapped streams.

>  To map all video (or audio) streams to an AdaptationSet, "v" (or "a") can be used as stream identifier instead of IDs.

>  

>  When no assignment is defined, this defaults to an AdaptationSet for each stream.

> +

> +Optional syntax is "id=x,descriptor=descriptor_string,streams=a,b,c id=y,streams=d,e" and so on, descriptor is useful to the scheme defined by ISO/IEC 23009-1:2014/Amd.2:2015.

> +For example, -adaptation_sets "id=0,descriptor=<SupplementalProperty schemeIdUri=\"urn:mpeg:dash:srd:2014\" value=\"0,0,0,1,1,2,2\"/>,streams=v".

> +Please note that descriptor string should be a self-closing xml tag.

>  @item timeout @var{timeout}

>  Set timeout for socket I/O operations. Applicable only for HTTP output.

>  @item index_correction @var{index_correction}

> diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c

> index b25afb4..24f8d4d 100644

> --- a/libavformat/dashenc.c

> +++ b/libavformat/dashenc.c

> @@ -68,6 +68,7 @@ typedef struct Segment {

>  

>  typedef struct AdaptationSet {

>      char id[10];

> +    char *descriptor;

>      enum AVMediaType media_type;

>      AVDictionary *metadata;

>      AVRational min_frame_rate, max_frame_rate;

> @@ -552,8 +553,10 @@ static void dash_free(AVFormatContext *s)

>      int i, j;

>  

>      if (c->as) {

> -        for (i = 0; i < c->nb_as; i++)

> +        for (i = 0; i < c->nb_as; i++) {

>              av_dict_free(&c->as[i].metadata);

> +            av_freep(&c->as[i].descriptor);

> +        }

>          av_freep(&c->as);

>          c->nb_as = 0;

>      }

> @@ -748,7 +751,8 @@ static int write_adaptation_set(AVFormatContext *s, AVIOContext *out, int as_ind

>      role = av_dict_get(as->metadata, "role", NULL, 0);

>      if (role)

>          avio_printf(out, "\t\t\t<Role schemeIdUri=\"urn:mpeg:dash:role:2011\" value=\"%s\"/>\n", role->value);

> -

> +    if (as->descriptor)

> +        avio_printf(out, "\t\t\t%s\n", as->descriptor);

>      for (i = 0; i < s->nb_streams; i++) {

>          OutputStream *os = &c->streams[i];

>          char bandwidth_str[64] = {'\0'};

> @@ -820,7 +824,7 @@ static int parse_adaptation_sets(AVFormatContext *s)

>  {

>      DASHContext *c = s->priv_data;

>      const char *p = c->adaptation_sets;

> -    enum { new_set, parse_id, parsing_streams } state;

> +    enum { new_set, parse_id, parsing_streams, parse_descriptor } state;

>      AdaptationSet *as;

>      int i, n, ret;

>  

> @@ -837,6 +841,9 @@ static int parse_adaptation_sets(AVFormatContext *s)

>      }

>  

>      // syntax id=0,streams=0,1,2 id=1,streams=3,4 and so on

> +    // option id=0,descriptor=descriptor_str,streams=0,1,2 and so on

> +    // descriptor is useful to the scheme defined by ISO/IEC 23009-1:2014/Amd.2:2015

> +    // descriptor_str should be a self-closing xml tag.

>      state = new_set;

>      while (*p) {

>          if (*p == ' ') {

> @@ -854,7 +861,19 @@ static int parse_adaptation_sets(AVFormatContext *s)

>              if (*p)

>                  p++;

>              state = parse_id;

> -        } else if (state == parse_id && av_strstart(p, "streams=", &p)) {

> +        } else if (state == parse_id && av_strstart(p, "descriptor=", &p)) {

> +            n = strcspn(p, ">") + 1; //followed by one comma, so plus 1

> +            if (n < strlen(p)) {

> +                as->descriptor = av_strndup(p, n);

> +            } else {

> +                av_log(s, AV_LOG_ERROR, "Parse error, descriptor string should be a self-closing xml tag\n");

> +                return AVERROR(EINVAL);

> +            }

> +            p += n;

> +            if (*p)

> +                p++;

> +            state = parse_descriptor;

> +        } else if ((state == parse_id || state == parse_descriptor) && av_strstart(p, "streams=", &p)) { //descriptor is optional 

>              state = parsing_streams;

>          } else if (state == parsing_streams) {

>              AdaptationSet *as = &c->as[c->nb_as - 1];
Moritz Barsnick July 19, 2019, 7:24 a.m.
On Fri, Jul 19, 2019 at 11:08:00 +0800, leozhang wrote:
> change history:
> 1. Use normal descriptor string instead of base64 encoded
> 2. Add example to muxers.texi
> 3. Change descriptor char * and allocate it dynamically
>
> Please review, thanks

Please take care, the above text has become part of the commit message
but shouldn't be, so it shouldn't be pushed that way either.

You need to add remarks to your emails below the '---' line:
>
> Signed-off-by: leozhang <leozhang@qiyi.com>
> ---

Right here.

>  doc/muxers.texi       |  4 ++++
>  libavformat/dashenc.c | 27 +++++++++++++++++++++++----
>  2 files changed, 27 insertions(+), 4 deletions(-)

Cheers,
Moritz

Patch hide | download patch | download mbox

diff --git a/doc/muxers.texi b/doc/muxers.texi
index b109297..bc38cf6 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -275,6 +275,10 @@  of the adaptation sets and a,b,c,d and e are the indices of the mapped streams.
 To map all video (or audio) streams to an AdaptationSet, "v" (or "a") can be used as stream identifier instead of IDs.
 
 When no assignment is defined, this defaults to an AdaptationSet for each stream.
+
+Optional syntax is "id=x,descriptor=descriptor_string,streams=a,b,c id=y,streams=d,e" and so on, descriptor is useful to the scheme defined by ISO/IEC 23009-1:2014/Amd.2:2015.
+For example, -adaptation_sets "id=0,descriptor=<SupplementalProperty schemeIdUri=\"urn:mpeg:dash:srd:2014\" value=\"0,0,0,1,1,2,2\"/>,streams=v".
+Please note that descriptor string should be a self-closing xml tag.
 @item timeout @var{timeout}
 Set timeout for socket I/O operations. Applicable only for HTTP output.
 @item index_correction @var{index_correction}
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index b25afb4..24f8d4d 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -68,6 +68,7 @@  typedef struct Segment {
 
 typedef struct AdaptationSet {
     char id[10];
+    char *descriptor;
     enum AVMediaType media_type;
     AVDictionary *metadata;
     AVRational min_frame_rate, max_frame_rate;
@@ -552,8 +553,10 @@  static void dash_free(AVFormatContext *s)
     int i, j;
 
     if (c->as) {
-        for (i = 0; i < c->nb_as; i++)
+        for (i = 0; i < c->nb_as; i++) {
             av_dict_free(&c->as[i].metadata);
+            av_freep(&c->as[i].descriptor);
+        }
         av_freep(&c->as);
         c->nb_as = 0;
     }
@@ -748,7 +751,8 @@  static int write_adaptation_set(AVFormatContext *s, AVIOContext *out, int as_ind
     role = av_dict_get(as->metadata, "role", NULL, 0);
     if (role)
         avio_printf(out, "\t\t\t<Role schemeIdUri=\"urn:mpeg:dash:role:2011\" value=\"%s\"/>\n", role->value);
-
+    if (as->descriptor)
+        avio_printf(out, "\t\t\t%s\n", as->descriptor);
     for (i = 0; i < s->nb_streams; i++) {
         OutputStream *os = &c->streams[i];
         char bandwidth_str[64] = {'\0'};
@@ -820,7 +824,7 @@  static int parse_adaptation_sets(AVFormatContext *s)
 {
     DASHContext *c = s->priv_data;
     const char *p = c->adaptation_sets;
-    enum { new_set, parse_id, parsing_streams } state;
+    enum { new_set, parse_id, parsing_streams, parse_descriptor } state;
     AdaptationSet *as;
     int i, n, ret;
 
@@ -837,6 +841,9 @@  static int parse_adaptation_sets(AVFormatContext *s)
     }
 
     // syntax id=0,streams=0,1,2 id=1,streams=3,4 and so on
+    // option id=0,descriptor=descriptor_str,streams=0,1,2 and so on
+    // descriptor is useful to the scheme defined by ISO/IEC 23009-1:2014/Amd.2:2015
+    // descriptor_str should be a self-closing xml tag.
     state = new_set;
     while (*p) {
         if (*p == ' ') {
@@ -854,7 +861,19 @@  static int parse_adaptation_sets(AVFormatContext *s)
             if (*p)
                 p++;
             state = parse_id;
-        } else if (state == parse_id && av_strstart(p, "streams=", &p)) {
+        } else if (state == parse_id && av_strstart(p, "descriptor=", &p)) {
+            n = strcspn(p, ">") + 1; //followed by one comma, so plus 1
+            if (n < strlen(p)) {
+                as->descriptor = av_strndup(p, n);
+            } else {
+                av_log(s, AV_LOG_ERROR, "Parse error, descriptor string should be a self-closing xml tag\n");
+                return AVERROR(EINVAL);
+            }
+            p += n;
+            if (*p)
+                p++;
+            state = parse_descriptor;
+        } else if ((state == parse_id || state == parse_descriptor) && av_strstart(p, "streams=", &p)) { //descriptor is optional 
             state = parsing_streams;
         } else if (state == parsing_streams) {
             AdaptationSet *as = &c->as[c->nb_as - 1];