[FFmpeg-devel] [PATCH v2] avformat/dashdec: add attribute lang for audio and subtitle streams

Steven Liu lq at chinaffmpeg.org
Wed Apr 15 07:46:11 EEST 2020



> 2020年4月11日 上午9:55,Steven Liu <lq at chinaffmpeg.org> 写道:
> 
> 
> 
>> 2020年4月8日 下午10:39,Steven Liu <lq at chinaffmpeg.org> 写道:
>> 
>> 
>> 
>>> 2020年3月31日 下午8:20,Steven Liu <lq at chinaffmpeg.org> 写道:
>>> 
>>> There should have language in the metadata of streams which show to user
>>> 
>>> Signed-off-by: Steven Liu <lq at chinaffmpeg.org>
>>> ---
>>> libavformat/dashdec.c | 49 +++++++++++++++++++++++++++++++++++++++----
>>> 1 file changed, 45 insertions(+), 4 deletions(-)
>>> 
>>> diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
>>> index 271202b0a5..5ba7feb245 100644
>>> --- a/libavformat/dashdec.c
>>> +++ b/libavformat/dashdec.c
>>> @@ -85,6 +85,7 @@ struct representation {
>>> 
>>>   enum AVMediaType type;
>>>   char id[20];
>>> +    char *lang;
>>>   int bandwidth;
>>>   AVRational framerate;
>>>   AVStream *assoc_stream; /* demuxer stream associated with this representation */
>>> @@ -144,6 +145,9 @@ typedef struct DASHContext {
>>>   uint64_t period_duration;
>>>   uint64_t period_start;
>>> 
>>> +    /* AdaptationSet Attribute */
>>> +    char *adaptionset_lang;
>>> +
>>>   int is_live;
>>>   AVIOInterruptCB *interrupt_callback;
>>>   char *allowed_extensions;
>>> @@ -872,6 +876,15 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
>>>           ret = AVERROR(ENOMEM);
>>>           goto end;
>>>       }
>>> +        if (c->adaptionset_lang) {
>>> +            rep->lang = av_strdup(c->adaptionset_lang);
>>> +            if (!rep->lang) {
>>> +                av_log(s, AV_LOG_ERROR, "alloc language memory failure\n");
>>> +                av_freep(&rep);
>>> +                ret = AVERROR(ENOMEM);
>>> +                goto end;
>>> +            }
>>> +        }
>>>       rep->parent = s;
>>>       representation_segmenttemplate_node = find_child_node_by_name(representation_node, "SegmentTemplate");
>>>       representation_baseurl_node = find_child_node_by_name(representation_node, "BaseURL");
>>> @@ -1103,6 +1116,19 @@ end:
>>>   return ret;
>>> }
>>> 
>>> +static int parse_manifest_adaptationset_attr(AVFormatContext *s, xmlNodePtr adaptionset_node)
>>> +{
>>> +    DASHContext *c = s->priv_data;
>>> +
>>> +    if (!adaptionset_node) {
>>> +        av_log(s, AV_LOG_WARNING, "Cannot get AdaptionSet\n");
>>> +        return AVERROR(EINVAL);
>>> +    }
>>> +    c->adaptionset_lang = xmlGetProp(adaptionset_node, "lang");
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> static int parse_manifest_adaptationset(AVFormatContext *s, const char *url,
>>>                                       xmlNodePtr adaptionset_node,
>>>                                       xmlNodePtr mpd_baseurl_node,
>>> @@ -1111,6 +1137,7 @@ static int parse_manifest_adaptationset(AVFormatContext *s, const char *url,
>>>                                       xmlNodePtr period_segmentlist_node)
>>> {
>>>   int ret = 0;
>>> +    DASHContext *c = s->priv_data;
>>>   xmlNodePtr fragment_template_node = NULL;
>>>   xmlNodePtr content_component_node = NULL;
>>>   xmlNodePtr adaptionset_baseurl_node = NULL;
>>> @@ -1118,6 +1145,10 @@ static int parse_manifest_adaptationset(AVFormatContext *s, const char *url,
>>>   xmlNodePtr adaptionset_supplementalproperty_node = NULL;
>>>   xmlNodePtr node = NULL;
>>> 
>>> +    ret = parse_manifest_adaptationset_attr(s, adaptionset_node);
>>> +    if (ret < 0)
>>> +        return ret;
>>> +
>>>   node = xmlFirstElementChild(adaptionset_node);
>>>   while (node) {
>>>       if (!av_strcasecmp(node->name, (const char *)"SegmentTemplate")) {
>>> @@ -1142,13 +1173,15 @@ static int parse_manifest_adaptationset(AVFormatContext *s, const char *url,
>>>                                               adaptionset_baseurl_node,
>>>                                               adaptionset_segmentlist_node,
>>>                                               adaptionset_supplementalproperty_node);
>>> -            if (ret < 0) {
>>> -                return ret;
>>> -            }
>>> +            if (ret < 0)
>>> +                goto err;
>>>       }
>>>       node = xmlNextElementSibling(node);
>>>   }
>>> -    return 0;
>>> +
>>> +err:
>>> +    av_freep(&c->adaptionset_lang);
>>> +    return ret;
>>> }
>>> 
>>> static int parse_programinformation(AVFormatContext *s, xmlNodePtr node)
>>> @@ -2121,6 +2154,10 @@ static int dash_read_header(AVFormatContext *s)
>>>               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);
>>> +            }
>>>       }
>>>       for (i = 0; i < c->n_subtitles; i++) {
>>>           rep = c->subtitles[i];
>>> @@ -2128,6 +2165,10 @@ static int dash_read_header(AVFormatContext *s)
>>>           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);
>>> +            }
>>>       }
>>>   }
>>> 
>>> -- 
>>> 2.25.0
>>> 
>> 
>> Ping
>> 
>> 
> 
> Will push if have no objections.
Pushed

Thanks

Steven Liu





More information about the ffmpeg-devel mailing list