[FFmpeg-devel] [PATCH 4/5] lavf/dashdec: improve memory handling

Andreas Rheinhardt andreas.rheinhardt at gmail.com
Thu Jun 11 18:19:38 EEST 2020


rcombs:
> - Fixes a couple leaks
> - Adds an av_freep equivalent for libxml buffers
> - Avoids some redundant copying
> ---
>  libavformat/dashdec.c | 44 +++++++++++++++++++++++--------------------
>  1 file changed, 24 insertions(+), 20 deletions(-)
> 
> diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
> index c94ce2caca..378c892b87 100644
> --- a/libavformat/dashdec.c
> +++ b/libavformat/dashdec.c
> @@ -147,9 +147,6 @@ typedef struct DASHContext {
>      uint64_t period_duration;
>      uint64_t period_start;
>  
> -    /* AdaptationSet Attribute */
> -    char *adaptationset_lang;
> -
>      int is_live;
>      AVIOInterruptCB *interrupt_callback;
>      char *allowed_extensions;
> @@ -162,6 +159,15 @@ typedef struct DASHContext {
>  
>  } DASHContext;
>  
> +static void xml_freep(void* arg)
> +{
> +    void *val;
> +
> +    memcpy(&val, arg, sizeof(val));
> +    memcpy(arg, &(void *){ NULL }, sizeof(val));
> +    xmlFree(val);
> +}
> +

libxml2 allows to use custom memory allocation functions. Have you tried
to just use our allocation functions which would allow to use av_freep
directly?

>  static int ishttp(char *url)
>  {
>      const char *proto_name = avio_find_protocol_name(url);
> @@ -362,6 +368,8 @@ static void free_representation(struct representation *pls)
>          avformat_close_input(&pls->ctx);
>      }
>  
> +    xml_freep(&pls->lang);
> +
>      av_freep(&pls->url_template);
>      av_freep(&pls);
>  }
> @@ -878,15 +886,9 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
>              ret = AVERROR(ENOMEM);
>              goto end;
>          }
> -        if (c->adaptationset_lang) {
> -            rep->lang = av_strdup(c->adaptationset_lang);
> -            if (!rep->lang) {
> -                av_log(s, AV_LOG_ERROR, "alloc language memory failure\n");
> -                av_freep(&rep);
> -                ret = AVERROR(ENOMEM);
> -                goto end;
> -            }
> -        }
> +
> +        rep->lang = xmlGetProp(adaptationset_node, "lang");
> +
>          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");
> @@ -965,7 +967,8 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
>                  xmlFree(startnumber_val);
>              }
>              if (adaptationset_supplementalproperty_node) {
> -                if (!av_strcasecmp(xmlGetProp(adaptationset_supplementalproperty_node,"schemeIdUri"), "http://dashif.org/guidelines/last-segment-number")) {
> +                char *schemeIdUri = xmlGetProp(adaptationset_supplementalproperty_node, "schemeIdUri");
> +                if (!av_strcasecmp(schemeIdUri, "http://dashif.org/guidelines/last-segment-number")) {
>                      val = xmlGetProp(adaptationset_supplementalproperty_node,"value");
>                      if (!val) {
>                          av_log(s, AV_LOG_ERROR, "Missing value attribute in adaptationset_supplementalproperty_node\n");
> @@ -974,6 +977,7 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
>                          xmlFree(val);
>                      }
>                  }
> +                xmlFree(schemeIdUri);
>              }
>  
>              fragment_timeline_node = find_child_node_by_name(representation_segmenttemplate_node, "SegmentTimeline");
> @@ -1120,13 +1124,10 @@ end:
>  
>  static int parse_manifest_adaptationset_attr(AVFormatContext *s, xmlNodePtr adaptationset_node)
>  {
> -    DASHContext *c = s->priv_data;
> -
>      if (!adaptationset_node) {
>          av_log(s, AV_LOG_WARNING, "Cannot get AdaptationSet\n");
>          return AVERROR(EINVAL);
>      }
> -    c->adaptationset_lang = xmlGetProp(adaptationset_node, "lang");
>  
>      return 0;
>  }
> @@ -1139,7 +1140,6 @@ 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 adaptationset_baseurl_node = NULL;
> @@ -1182,7 +1182,6 @@ static int parse_manifest_adaptationset(AVFormatContext *s, const char *url,
>      }
>  
>  err:
> -    av_freep(&c->adaptationset_lang);
>      return ret;
>  }
>  
> @@ -2157,6 +2156,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);
> +                xml_freep(&rep->lang);
> +            }
>          }
>          for (i = 0; i < c->n_audios; i++) {
>              rep = c->audios[i];
> @@ -2168,7 +2171,7 @@ static int dash_read_header(AVFormatContext *s)
>                  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);
> +                xml_freep(&rep->lang);
>              }
>          }
>          for (i = 0; i < c->n_subtitles; i++) {
> @@ -2179,7 +2182,7 @@ static int dash_read_header(AVFormatContext *s)
>                  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);
> +                xml_freep(&rep->lang);
>              }
>          }
>      }
> @@ -2282,6 +2285,7 @@ static int dash_close(AVFormatContext *s)
>      DASHContext *c = s->priv_data;
>      free_audio_list(c);
>      free_video_list(c);
> +    free_subtitle_list(c);
>      av_dict_free(&c->avio_opts);
>      av_freep(&c->base_url);
>      return 0;
> 



More information about the ffmpeg-devel mailing list