summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland Jon <rlandjon@gmail.com>2018-05-31 17:28:44 +0800
committerTim-Philipp Müller <tim@centricular.com>2018-07-18 17:35:28 +0100
commit5972fa8a02a39e714c2c6f31d086c3d9d3966904 (patch)
treeb2a0dba190c2b3ccde36113d422054112870b98b
parent4c3e87fec718c64282f35ab58492771a77147da6 (diff)
downloadgst-libav-5972fa8a02a39e714c2c6f31d086c3d9d3966904.tar.gz
avdemux: fix memory leaks
https://bugzilla.gnome.org/show_bug.cgi?id=796452
-rw-r--r--ext/libav/gstavdemux.c89
1 files changed, 47 insertions, 42 deletions
diff --git a/ext/libav/gstavdemux.c b/ext/libav/gstavdemux.c
index 001e2f1..6f3a7af 100644
--- a/ext/libav/gstavdemux.c
+++ b/ext/libav/gstavdemux.c
@@ -1077,53 +1077,55 @@ safe_utf8_copy (gchar * input)
return output;
}
-/* g_hash_table_insert requires non-const arguments, so
- * we need to cast const strings to void * */
-#define ADD_TAG_MAPPING(h, k, g) \
- g_hash_table_insert ((h), (void *) (k), (void *) (g));
+/* This is a list of standard tag keys taken from the avformat.h
+ * header, without handling any variants. */
+static const struct
+{
+ const gchar *ffmpeg_tag_name;
+ const gchar *gst_tag_name;
+} tagmapping[] = {
+ {
+ "album", GST_TAG_ALBUM}, {
+ "album_artist", GST_TAG_ALBUM_ARTIST}, {
+ "artist", GST_TAG_ARTIST}, {
+ "comment", GST_TAG_COMMENT}, {
+ "composer", GST_TAG_COMPOSER}, {
+ "copyright", GST_TAG_COPYRIGHT}, {
+ /* Need to convert ISO 8601 to GstDateTime: */
+ "creation_time", GST_TAG_DATE_TIME}, {
+ /* Need to convert ISO 8601 to GDateTime: */
+ "date", GST_TAG_DATE_TIME}, {
+ "disc", GST_TAG_ALBUM_VOLUME_NUMBER}, {
+ "encoder", GST_TAG_ENCODER}, {
+ "encoded_by", GST_TAG_ENCODED_BY}, {
+ "genre", GST_TAG_GENRE}, {
+ "language", GST_TAG_LANGUAGE_CODE}, {
+ "performer", GST_TAG_PERFORMER}, {
+ "publisher", GST_TAG_PUBLISHER}, {
+ "title", GST_TAG_TITLE}, {
+ "track", GST_TAG_TRACK_NUMBER}
+};
+
+static const gchar *
+match_tag_name (gchar * ffmpeg_tag_name)
+{
+ gint i;
+ for (i = 0; i < G_N_ELEMENTS (tagmapping); i++) {
+ if (!g_strcmp0 (tagmapping[i].ffmpeg_tag_name, ffmpeg_tag_name))
+ return tagmapping[i].gst_tag_name;
+ }
+ return NULL;
+}
static GstTagList *
gst_ffmpeg_metadata_to_tag_list (AVDictionary * metadata)
{
- GHashTable *tagmap = NULL;
AVDictionaryEntry *tag = NULL;
GstTagList *list;
-
- if (g_once_init_enter (&tagmap)) {
- GHashTable *tmp = g_hash_table_new (g_str_hash, g_str_equal);
-
- /* This is a list of standard tag keys taken from the avformat.h
- * header, without handling any variants. */
- ADD_TAG_MAPPING (tmp, "album", GST_TAG_ALBUM);
- ADD_TAG_MAPPING (tmp, "album_artist", GST_TAG_ALBUM_ARTIST);
- ADD_TAG_MAPPING (tmp, "artist", GST_TAG_ARTIST);
- ADD_TAG_MAPPING (tmp, "comment", GST_TAG_COMMENT);
- ADD_TAG_MAPPING (tmp, "composer", GST_TAG_COMPOSER);
- ADD_TAG_MAPPING (tmp, "copyright", GST_TAG_COPYRIGHT);
- /* Need to convert ISO 8601 to GstDateTime: */
- ADD_TAG_MAPPING (tmp, "creation_time", GST_TAG_DATE_TIME);
- /* Need to convert ISO 8601 to GDateTime: */
- ADD_TAG_MAPPING (tmp, "date", GST_TAG_DATE_TIME);
- ADD_TAG_MAPPING (tmp, "disc", GST_TAG_ALBUM_VOLUME_NUMBER);
- ADD_TAG_MAPPING (tmp, "encoder", GST_TAG_ENCODER);
- ADD_TAG_MAPPING (tmp, "encoded_by", GST_TAG_ENCODED_BY);
- /* ADD_TAG_MAPPING (tmp, "filename", ); -- No mapping */
- ADD_TAG_MAPPING (tmp, "genre", GST_TAG_GENRE);
- ADD_TAG_MAPPING (tmp, "language", GST_TAG_LANGUAGE_CODE);
- ADD_TAG_MAPPING (tmp, "performer", GST_TAG_PERFORMER);
- ADD_TAG_MAPPING (tmp, "publisher", GST_TAG_PUBLISHER);
- /* ADD_TAG_MAPPING(tmp, "service_name", ); -- No mapping */
- /* ADD_TAG_MAPPING(tmp, "service_provider", ); -- No mapping */
- ADD_TAG_MAPPING (tmp, "title", GST_TAG_TITLE);
- ADD_TAG_MAPPING (tmp, "track", GST_TAG_TRACK_NUMBER);
-
- g_once_init_leave (&tagmap, tmp);
- }
-
list = gst_tag_list_new_empty ();
while ((tag = av_dict_get (metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
- const gchar *gsttag = g_hash_table_lookup (tagmap, tag->key);
+ const gchar *gsttag = match_tag_name (tag->key);
GType t;
GST_LOG ("mapping tag %s=%s\n", tag->key, tag->value);
if (gsttag == NULL) {
@@ -1315,7 +1317,8 @@ gst_ffmpegdemux_open (GstFFMpegDemux * demux)
}
}
}
-
+ if (tags)
+ gst_tag_list_unref (tags);
return TRUE;
/* ERRORS */
@@ -1389,7 +1392,7 @@ static void
gst_ffmpegdemux_loop (GstFFMpegDemux * demux)
{
GstFlowReturn ret;
- gint res;
+ gint res = -1;
AVPacket pkt;
GstPad *srcpad;
GstFFStream *stream;
@@ -1541,7 +1544,9 @@ gst_ffmpegdemux_loop (GstFFMpegDemux * demux)
done:
/* can destroy the packet now */
- av_packet_unref (&pkt);
+ if (res == 0) {
+ av_packet_unref (&pkt);
+ }
return;
@@ -1585,7 +1590,7 @@ pause:
GST_ELEMENT_FLOW_ERROR (demux, ret);
gst_ffmpegdemux_push_event (demux, gst_event_new_eos ());
}
- return;
+ goto done;
}
open_failed:
{