From: Jaroslav Kysela Date: Mon, 25 Sep 2017 15:26:09 +0000 (+0200) Subject: transcoding: fix memory leaks X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=90b20661199d3c4ff11d021ed676c54ed481037b;p=thirdparty%2Ftvheadend.git transcoding: fix memory leaks --- diff --git a/src/profile.c b/src/profile.c index 75c06c8ec..ab654bcbc 100644 --- a/src/profile.c +++ b/src/profile.c @@ -2459,8 +2459,11 @@ profile_transcode_free(profile_t *_pro) { profile_transcode_t *pro = (profile_transcode_t *)_pro; free(pro->pro_vcodec); + free(pro->pro_src_vcodec); free(pro->pro_acodec); + free(pro->pro_src_acodec); free(pro->pro_scodec); + free(pro->pro_src_scodec); } static profile_t * diff --git a/src/transcoding/codec.h b/src/transcoding/codec.h index 06d581839..1568ce6f7 100644 --- a/src/transcoding/codec.h +++ b/src/transcoding/codec.h @@ -67,6 +67,7 @@ struct tvh_codec { AVCodec *codec; const AVProfile *profiles; int (*profile_init)(TVHCodecProfile *, htsmsg_t *conf); + void (*profile_destroy)(TVHCodecProfile *); SLIST_ENTRY(tvh_codec) link; }; @@ -90,9 +91,9 @@ extern const codec_profile_class_t codec_profile_class; struct tvh_codec_profile { idnode_t idnode; TVHCodec *codec; - const char *name; - const char *description; - const char *codec_name; + char *name; + char *description; + char *codec_name; double bit_rate; double qscale; int profile; @@ -131,6 +132,9 @@ tvh_codec_profile_open(TVHCodecProfile *self, AVDictionary **opts); int tvh_codec_profile_video_init(TVHCodecProfile *_self, htsmsg_t *conf); +void +tvh_codec_profile_video_destroy(TVHCodecProfile *_self); + int tvh_codec_profile_video_get_hwaccel(TVHCodecProfile *self); @@ -142,6 +146,9 @@ tvh_codec_profile_video_get_pix_fmts(TVHCodecProfile *self); int tvh_codec_profile_audio_init(TVHCodecProfile *_self, htsmsg_t *conf); +void +tvh_codec_profile_audio_destroy(TVHCodecProfile *_self); + const enum AVSampleFormat * tvh_codec_profile_audio_get_sample_fmts(TVHCodecProfile *self); diff --git a/src/transcoding/codec/codecs/aac.c b/src/transcoding/codec/codecs/aac.c index bd310ee3a..4c51736e2 100644 --- a/src/transcoding/codec/codecs/aac.c +++ b/src/transcoding/codec/codecs/aac.c @@ -45,7 +45,7 @@ static const uint64_t aac_channel_layouts[] = { typedef struct { TVHAudioCodecProfile; - const char *coder; + char *coder; } tvh_codec_profile_aac_t; @@ -122,11 +122,21 @@ static const codec_profile_class_t codec_profile_aac_class = { }; +static void +tvh_codec_profile_aac_destroy(TVHCodecProfile *_self) +{ + tvh_codec_profile_aac_t *self = (tvh_codec_profile_aac_t *)_self; + tvh_codec_profile_audio_destroy(_self); + free(self->coder); +} + + TVHAudioCodec tvh_codec_aac = { .name = "aac", .size = sizeof(tvh_codec_profile_aac_t), .idclass = &codec_profile_aac_class, .profiles = aac_profiles, .profile_init = tvh_codec_profile_audio_init, + .profile_destroy = tvh_codec_profile_aac_destroy, .channel_layouts = aac_channel_layouts, }; diff --git a/src/transcoding/codec/codecs/libs/libfdk_aac.c b/src/transcoding/codec/codecs/libs/libfdk_aac.c index 2a062af66..6aeeb43d2 100644 --- a/src/transcoding/codec/codecs/libs/libfdk_aac.c +++ b/src/transcoding/codec/codecs/libs/libfdk_aac.c @@ -137,5 +137,5 @@ TVHAudioCodec tvh_codec_libfdk_aac = { .size = sizeof(tvh_codec_profile_libfdk_aac_t), .idclass = &codec_profile_libfdk_aac_class, .profile_init = tvh_codec_profile_audio_init, - + .profile_destroy = tvh_codec_profile_audio_destroy, }; diff --git a/src/transcoding/codec/codecs/libs/libopus.c b/src/transcoding/codec/codecs/libs/libopus.c index 49b394027..0efdca617 100644 --- a/src/transcoding/codec/codecs/libs/libopus.c +++ b/src/transcoding/codec/codecs/libs/libopus.c @@ -134,4 +134,5 @@ TVHAudioCodec tvh_codec_libopus = { .size = sizeof(tvh_codec_profile_libopus_t), .idclass = &codec_profile_libopus_class, .profile_init = tvh_codec_profile_audio_init, + .profile_destroy = tvh_codec_profile_audio_destroy, }; diff --git a/src/transcoding/codec/codecs/libs/libtheora.c b/src/transcoding/codec/codecs/libs/libtheora.c index 49d316bc1..cc64ed0af 100644 --- a/src/transcoding/codec/codecs/libs/libtheora.c +++ b/src/transcoding/codec/codecs/libs/libtheora.c @@ -76,4 +76,5 @@ TVHVideoCodec tvh_codec_libtheora = { .size = sizeof(TVHVideoCodecProfile), .idclass = &codec_profile_libtheora_class, .profile_init = tvh_codec_profile_video_init, + .profile_destroy = tvh_codec_profile_video_destroy, }; diff --git a/src/transcoding/codec/codecs/libs/libvorbis.c b/src/transcoding/codec/codecs/libs/libvorbis.c index 543bc3507..230f52009 100644 --- a/src/transcoding/codec/codecs/libs/libvorbis.c +++ b/src/transcoding/codec/codecs/libs/libvorbis.c @@ -96,4 +96,5 @@ TVHAudioCodec tvh_codec_libvorbis = { .idclass = &codec_profile_libvorbis_class, .channel_layouts = libvorbis_channel_layouts, .profile_init = tvh_codec_profile_audio_init, + .profile_destroy = tvh_codec_profile_audio_destroy, }; diff --git a/src/transcoding/codec/codecs/libs/libvpx.c b/src/transcoding/codec/codecs/libs/libvpx.c index 481825cd8..ee9445f3c 100644 --- a/src/transcoding/codec/codecs/libs/libvpx.c +++ b/src/transcoding/codec/codecs/libs/libvpx.c @@ -149,6 +149,8 @@ TVHVideoCodec tvh_codec_libvpx_vp8 = { .name = "libvpx", .size = sizeof(tvh_codec_profile_libvpx_t), .idclass = &codec_profile_libvpx_class, + .profile_init = tvh_codec_profile_video_init, + .profile_destroy = tvh_codec_profile_video_destroy, }; @@ -159,4 +161,5 @@ TVHVideoCodec tvh_codec_libvpx_vp9 = { .size = sizeof(tvh_codec_profile_libvpx_t), .idclass = &codec_profile_libvpx_class, .profile_init = tvh_codec_profile_video_init, + .profile_destroy = tvh_codec_profile_video_destroy, }; diff --git a/src/transcoding/codec/codecs/libs/libx26x.c b/src/transcoding/codec/codecs/libs/libx26x.c index 4ae2fea3b..8506e2226 100644 --- a/src/transcoding/codec/codecs/libs/libx26x.c +++ b/src/transcoding/codec/codecs/libs/libx26x.c @@ -48,9 +48,9 @@ strlist2htsmsg(const char * const *values) typedef struct { TVHVideoCodecProfile; - const char *preset; - const char *tune; - const char *params; + char *preset; + char *tune; + char *params; } tvh_codec_profile_libx26x_t; @@ -294,11 +294,23 @@ static const codec_profile_class_t codec_profile_libx265_class = { }; +static void +tvh_codec_profile_libx265_destroy(TVHCodecProfile *_self) +{ + tvh_codec_profile_libx26x_t *self = (tvh_codec_profile_libx26x_t *)_self; + tvh_codec_profile_video_destroy(_self); + free(self->preset); + free(self->tune); + free(self->params); +} + + TVHVideoCodec tvh_codec_libx265 = { .name = "libx265", .size = sizeof(tvh_codec_profile_libx26x_t), .idclass = &codec_profile_libx265_class, .profile_init = tvh_codec_profile_video_init, + .profile_destroy = tvh_codec_profile_libx265_destroy, }; #endif diff --git a/src/transcoding/codec/codecs/libs/nvenc.c b/src/transcoding/codec/codecs/libs/nvenc.c index 4acbb28c6..fdbb59326 100644 --- a/src/transcoding/codec/codecs/libs/nvenc.c +++ b/src/transcoding/codec/codecs/libs/nvenc.c @@ -317,4 +317,5 @@ TVHVideoCodec tvh_codec_nvenc_hevc = { .idclass = &codec_profile_nvenc_hevc_class, .profiles = nvenc_hevc_profiles, .profile_init = tvh_codec_profile_video_init, + .profile_destroy = tvh_codec_profile_video_destroy, }; diff --git a/src/transcoding/codec/codecs/libs/omx.c b/src/transcoding/codec/codecs/libs/omx.c index 862da09c9..1180b6472 100644 --- a/src/transcoding/codec/codecs/libs/omx.c +++ b/src/transcoding/codec/codecs/libs/omx.c @@ -33,7 +33,7 @@ typedef struct { static int tvh_codec_profile_omx_open(tvh_codec_profile_omx_t *self, AVDictionary **opts) -{ +k{ AV_DICT_SET_FLAGS_GLOBAL_HEADER(opts); // bit_rate if (self->bit_rate) { @@ -106,9 +106,19 @@ static const codec_profile_class_t codec_profile_omx_class = { /* h264_omx ================================================================= */ +static void +tvh_codec_profile_omx_destroy(TVHCodecProfile *_self) +{ + tvh_codec_profile_omx_t *self = (tvh_codec_profile_omx_t *)_self; + tvh_codec_profile_video_destroy(_self); + free(self->libname); + free(self->libprefix); +} + TVHVideoCodec tvh_codec_omx_h264 = { .name = "h264_omx", .size = sizeof(tvh_codec_profile_omx_t), .idclass = &codec_profile_omx_class, .profile_init = tvh_codec_profile_video_init, + .profile_destroy = tvh_codec_profile_omx_destroy, }; diff --git a/src/transcoding/codec/codecs/libs/vaapi.c b/src/transcoding/codec/codecs/libs/vaapi.c index 5858c49b6..b5da9907c 100644 --- a/src/transcoding/codec/codecs/libs/vaapi.c +++ b/src/transcoding/codec/codecs/libs/vaapi.c @@ -261,6 +261,7 @@ TVHVideoCodec tvh_codec_vaapi_hevc = { .idclass = &codec_profile_vaapi_hevc_class, .profiles = vaapi_hevc_profiles, .profile_init = tvh_codec_profile_video_init, + .profile_destroy = tvh_codec_profile_video_destroy, }; @@ -303,4 +304,5 @@ TVHVideoCodec tvh_codec_vaapi_vp8 = { .idclass = &codec_profile_vaapi_vp8_class, .profiles = vaapi_vp8_profiles, .profile_init = tvh_codec_profile_video_init, + .profile_destroy = tvh_codec_profile_video_destroy, }; diff --git a/src/transcoding/codec/codecs/mp2.c b/src/transcoding/codec/codecs/mp2.c index 61795659a..e26ad3eb8 100644 --- a/src/transcoding/codec/codecs/mp2.c +++ b/src/transcoding/codec/codecs/mp2.c @@ -73,5 +73,5 @@ TVHAudioCodec tvh_codec_mp2 = { .size = sizeof(TVHAudioCodecProfile), .idclass = &codec_profile_mp2_class, .profile_init = tvh_codec_profile_audio_init, - + .profile_destroy = tvh_codec_profile_audio_destroy, }; diff --git a/src/transcoding/codec/codecs/mpeg2video.c b/src/transcoding/codec/codecs/mpeg2video.c index 1b1c3099d..d50601f87 100644 --- a/src/transcoding/codec/codecs/mpeg2video.c +++ b/src/transcoding/codec/codecs/mpeg2video.c @@ -76,4 +76,5 @@ TVHVideoCodec tvh_codec_mpeg2video = { .size = sizeof(TVHVideoCodecProfile), .idclass = &codec_profile_mpeg2video_class, .profile_init = tvh_codec_profile_video_init, + .profile_destroy = tvh_codec_profile_video_destroy, }; diff --git a/src/transcoding/codec/codecs/vorbis.c b/src/transcoding/codec/codecs/vorbis.c index c1b88e663..abd35d51e 100644 --- a/src/transcoding/codec/codecs/vorbis.c +++ b/src/transcoding/codec/codecs/vorbis.c @@ -67,5 +67,6 @@ TVHAudioCodec tvh_codec_vorbis = { .size = sizeof(TVHAudioCodecProfile), .idclass = &codec_profile_vorbis_class, .profile_init = tvh_codec_profile_audio_init, + .profile_destroy = tvh_codec_profile_audio_destroy, .channel_layouts = vorbis_channel_layouts, }; diff --git a/src/transcoding/codec/internals.h b/src/transcoding/codec/internals.h index 63e83338b..908f172a5 100644 --- a/src/transcoding/codec/internals.h +++ b/src/transcoding/codec/internals.h @@ -225,9 +225,9 @@ extern const codec_profile_class_t codec_profile_audio_class; typedef struct tvh_codec_profile_audio { TVHCodecProfile; int tracks; - const char *language1; - const char *language2; - const char *language3; + char *language1; + char *language2; + char *language3; int sample_fmt; int sample_rate; int64_t channel_layout; diff --git a/src/transcoding/codec/profile.c b/src/transcoding/codec/profile.c index a6efe497a..3fd85571e 100644 --- a/src/transcoding/codec/profile.c +++ b/src/transcoding/codec/profile.c @@ -49,10 +49,18 @@ tvh_codec_profile_alloc(TVHCodec *codec, htsmsg_t *conf) static void tvh_codec_profile_free(TVHCodecProfile *self) { + TVHCodec *codec; + if (self) { - self->codec = NULL; + codec = self->codec; + if (codec && codec->profile_destroy) { + codec->profile_destroy(self); + } + free(self->name); + free(self->description); + free(self->codec_name); + free(self->device); free(self); - self = NULL; } } @@ -262,6 +270,11 @@ tvh_codec_profile_video_init(TVHCodecProfile *_self, htsmsg_t *conf) return 0; } +void +tvh_codec_profile_video_destroy(TVHCodecProfile *_self) +{ +} + int tvh_codec_profile_video_get_hwaccel(TVHCodecProfile *self) { @@ -291,6 +304,15 @@ tvh_codec_profile_audio_init(TVHCodecProfile *_self, htsmsg_t *conf) return 0; } +void +tvh_codec_profile_audio_destroy(TVHCodecProfile *_self) +{ + TVHAudioCodecProfile *self = (TVHAudioCodecProfile *)_self; + free(self->language1); + free(self->language2); + free(self->language3); +} + const enum AVSampleFormat * tvh_codec_profile_audio_get_sample_fmts(TVHCodecProfile *self) { diff --git a/src/transcoding/codec/profile_class.c b/src/transcoding/codec/profile_class.c index 8a2236c90..24501b55d 100644 --- a/src/transcoding/codec/profile_class.c +++ b/src/transcoding/codec/profile_class.c @@ -124,10 +124,7 @@ codec_profile_class_name_set(void *obj, const void *val) tvherror(LS_CODEC, "profile '%s' already exists", name); } else { - if (self->name) { - free((void *)self->name); - self->name = NULL; - } + free(self->name); self->name = strdup(name); return 1; } @@ -137,6 +134,19 @@ codec_profile_class_name_set(void *obj, const void *val) } +/* codec_profile_class.name */ + +static const void * +codec_profile_class_name_get(void *obj) +{ + static const char *type; + + TVHCodec *codec = tvh_codec_profile_get_codec(obj); + type = codec ? tvh_codec_get_title(codec) : ""; + return &type; +} + + /* codec_profile_class.type */ static const void * @@ -226,8 +236,17 @@ const codec_profile_class_t codec_profile_class = { }, { .type = PT_STR, - .id = "codec_name", + .id = "codec_title", .name = N_("Codec"), + .desc = N_("Codec title."), + .group = 1, + .opts = PO_RDONLY | PO_NOSAVE, + .get = codec_profile_class_name_get, + }, + { + .type = PT_STR, + .id = "codec_name", + .name = N_("Codec name"), .desc = N_("Codec name."), .group = 1, .opts = PO_RDONLY, diff --git a/src/transcoding/transcode/transcoder.c b/src/transcoding/transcode/transcoder.c index b033b9b28..ad185c788 100644 --- a/src/transcoding/transcode/transcoder.c +++ b/src/transcoding/transcode/transcoder.c @@ -22,7 +22,7 @@ #include "../codec/internals.h" -static TVHCodecProfile _codec_profile_copy = { .name = "copy" }; +static TVHCodecProfile _codec_profile_copy = { .name = (char *)"copy" }; TVHCodecProfile *tvh_codec_profile_copy = &_codec_profile_copy;