Message ID | 20200331122019.21934-1-lq@chinaffmpeg.org |
---|---|
State | Accepted |
Commit | 51db0a472a0517ce76bb97cac56d3d40c5a009bf |
Headers | show |
Series | [FFmpeg-devel,v2] avformat/dashdec: add attribute lang for audio and subtitle streams | expand |
Context | Check | Description |
---|---|---|
andriy/ffmpeg-patchwork | success | Make fate finished |
> 2020年4月8日 下午10:39,Steven Liu <lq@chinaffmpeg.org> 写道: > > > >> 2020年3月31日 下午8:20,Steven Liu <lq@chinaffmpeg.org> 写道: >> >> There should have language in the metadata of streams which show to user >> >> Signed-off-by: Steven Liu <lq@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. Thanks Steven Liu
> 2020年4月11日 上午9:55,Steven Liu <lq@chinaffmpeg.org> 写道: > > > >> 2020年4月8日 下午10:39,Steven Liu <lq@chinaffmpeg.org> 写道: >> >> >> >>> 2020年3月31日 下午8:20,Steven Liu <lq@chinaffmpeg.org> 写道: >>> >>> There should have language in the metadata of streams which show to user >>> >>> Signed-off-by: Steven Liu <lq@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
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); + } } }
There should have language in the metadata of streams which show to user Signed-off-by: Steven Liu <lq@chinaffmpeg.org> --- libavformat/dashdec.c | 49 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-)