From d8a8326d7c5fe3fb3041d3916494b482e1b6a47d Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Mon, 6 Jun 2011 12:43:14 +0530 Subject: [PATCH] matroska: refactor code common to matroskademux and matroskaparse Move the following function to matroska-read-common.[ch] from matroska-demux.c and matroska-parse.c: - gst_matroska_{demux,parse}_parse_attached_file https://bugzilla.gnome.org/show_bug.cgi?id=650877 --- gst/matroska/matroska-demux.c | 159 +--------------------------- gst/matroska/matroska-parse.c | 159 +--------------------------- gst/matroska/matroska-read-common.c | 158 +++++++++++++++++++++++++++ gst/matroska/matroska-read-common.h | 2 + 4 files changed, 164 insertions(+), 314 deletions(-) diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c index 4b2f1604fb..0d08a1c4f4 100644 --- a/gst/matroska/matroska-demux.c +++ b/gst/matroska/matroska-demux.c @@ -61,8 +61,6 @@ #include -#include - #include #include "matroska-demux.h" @@ -2259,160 +2257,6 @@ gst_matroska_demux_parse_tracks (GstMatroskaDemux * demux, GstEbmlRead * ebml) return ret; } -static GstFlowReturn -gst_matroska_demux_parse_attached_file (GstMatroskaDemux * demux, - GstEbmlRead * ebml, GstTagList * taglist) -{ - guint32 id; - GstFlowReturn ret; - gchar *description = NULL; - gchar *filename = NULL; - gchar *mimetype = NULL; - guint8 *data = NULL; - guint64 datalen = 0; - - DEBUG_ELEMENT_START (demux, ebml, "AttachedFile"); - - if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) { - DEBUG_ELEMENT_STOP (demux, ebml, "AttachedFile", ret); - return ret; - } - - while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) { - /* read all sub-entries */ - - if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) - break; - - switch (id) { - case GST_MATROSKA_ID_FILEDESCRIPTION: - if (description) { - GST_WARNING_OBJECT (demux, "FileDescription can only appear once"); - break; - } - - ret = gst_ebml_read_utf8 (ebml, &id, &description); - GST_DEBUG_OBJECT (demux, "FileDescription: %s", - GST_STR_NULL (description)); - break; - case GST_MATROSKA_ID_FILENAME: - if (filename) { - GST_WARNING_OBJECT (demux, "FileName can only appear once"); - break; - } - - ret = gst_ebml_read_utf8 (ebml, &id, &filename); - - GST_DEBUG_OBJECT (demux, "FileName: %s", GST_STR_NULL (filename)); - break; - case GST_MATROSKA_ID_FILEMIMETYPE: - if (mimetype) { - GST_WARNING_OBJECT (demux, "FileMimeType can only appear once"); - break; - } - - ret = gst_ebml_read_ascii (ebml, &id, &mimetype); - GST_DEBUG_OBJECT (demux, "FileMimeType: %s", GST_STR_NULL (mimetype)); - break; - case GST_MATROSKA_ID_FILEDATA: - if (data) { - GST_WARNING_OBJECT (demux, "FileData can only appear once"); - break; - } - - ret = gst_ebml_read_binary (ebml, &id, &data, &datalen); - GST_DEBUG_OBJECT (demux, "FileData of size %" G_GUINT64_FORMAT, - datalen); - break; - - default: - ret = gst_matroska_read_common_parse_skip (&demux->common, ebml, - "AttachedFile", id); - break; - case GST_MATROSKA_ID_FILEUID: - ret = gst_ebml_read_skip (ebml); - break; - } - } - - DEBUG_ELEMENT_STOP (demux, ebml, "AttachedFile", ret); - - if (filename && mimetype && data && datalen > 0) { - GstTagImageType image_type = GST_TAG_IMAGE_TYPE_NONE; - GstBuffer *tagbuffer = NULL; - GstCaps *caps; - gchar *filename_lc = g_utf8_strdown (filename, -1); - - GST_DEBUG_OBJECT (demux, "Creating tag for attachment with filename '%s', " - "mimetype '%s', description '%s', size %" G_GUINT64_FORMAT, filename, - mimetype, GST_STR_NULL (description), datalen); - - /* TODO: better heuristics for different image types */ - if (strstr (filename_lc, "cover")) { - if (strstr (filename_lc, "back")) - image_type = GST_TAG_IMAGE_TYPE_BACK_COVER; - else - image_type = GST_TAG_IMAGE_TYPE_FRONT_COVER; - } else if (g_str_has_prefix (mimetype, "image/") || - g_str_has_suffix (filename_lc, "png") || - g_str_has_suffix (filename_lc, "jpg") || - g_str_has_suffix (filename_lc, "jpeg") || - g_str_has_suffix (filename_lc, "gif") || - g_str_has_suffix (filename_lc, "bmp")) { - image_type = GST_TAG_IMAGE_TYPE_UNDEFINED; - } - g_free (filename_lc); - - /* First try to create an image tag buffer from this */ - if (image_type != GST_TAG_IMAGE_TYPE_NONE) { - tagbuffer = - gst_tag_image_data_to_image_buffer (data, datalen, image_type); - - if (!tagbuffer) - image_type = GST_TAG_IMAGE_TYPE_NONE; - } - - /* if this failed create an attachment buffer */ - if (!tagbuffer) { - tagbuffer = gst_buffer_new_and_alloc (datalen); - - memcpy (GST_BUFFER_DATA (tagbuffer), data, datalen); - GST_BUFFER_SIZE (tagbuffer) = datalen; - - caps = gst_type_find_helper_for_buffer (NULL, tagbuffer, NULL); - if (caps == NULL) - caps = gst_caps_new_simple (mimetype, NULL); - gst_buffer_set_caps (tagbuffer, caps); - gst_caps_unref (caps); - } - - /* Set filename and description on the caps */ - caps = GST_BUFFER_CAPS (tagbuffer); - gst_caps_set_simple (caps, "filename", G_TYPE_STRING, filename, NULL); - if (description) - gst_caps_set_simple (caps, "description", G_TYPE_STRING, description, - NULL); - - GST_DEBUG_OBJECT (demux, - "Created attachment buffer with caps: %" GST_PTR_FORMAT, caps); - - /* and append to the tag list */ - if (image_type != GST_TAG_IMAGE_TYPE_NONE) - gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, tagbuffer, - NULL); - else - gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_ATTACHMENT, - tagbuffer, NULL); - } - - g_free (filename); - g_free (mimetype); - g_free (data); - g_free (description); - - return ret; -} - static GstFlowReturn gst_matroska_demux_parse_attachments (GstMatroskaDemux * demux, GstEbmlRead * ebml) @@ -2436,7 +2280,8 @@ gst_matroska_demux_parse_attachments (GstMatroskaDemux * demux, switch (id) { case GST_MATROSKA_ID_ATTACHEDFILE: - ret = gst_matroska_demux_parse_attached_file (demux, ebml, taglist); + ret = gst_matroska_read_common_parse_attached_file (&demux->common, + ebml, taglist); break; default: diff --git a/gst/matroska/matroska-parse.c b/gst/matroska/matroska-parse.c index 30f862b37c..7534ed0ed7 100644 --- a/gst/matroska/matroska-parse.c +++ b/gst/matroska/matroska-parse.c @@ -61,8 +61,6 @@ #include -#include - #include #include "matroska-parse.h" @@ -1559,160 +1557,6 @@ gst_matroska_parse_parse_tracks (GstMatroskaParse * parse, GstEbmlRead * ebml) return ret; } -static GstFlowReturn -gst_matroska_parse_parse_attached_file (GstMatroskaParse * parse, - GstEbmlRead * ebml, GstTagList * taglist) -{ - guint32 id; - GstFlowReturn ret; - gchar *description = NULL; - gchar *filename = NULL; - gchar *mimetype = NULL; - guint8 *data = NULL; - guint64 datalen = 0; - - DEBUG_ELEMENT_START (parse, ebml, "AttachedFile"); - - if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) { - DEBUG_ELEMENT_STOP (parse, ebml, "AttachedFile", ret); - return ret; - } - - while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) { - /* read all sub-entries */ - - if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) - break; - - switch (id) { - case GST_MATROSKA_ID_FILEDESCRIPTION: - if (description) { - GST_WARNING_OBJECT (parse, "FileDescription can only appear once"); - break; - } - - ret = gst_ebml_read_utf8 (ebml, &id, &description); - GST_DEBUG_OBJECT (parse, "FileDescription: %s", - GST_STR_NULL (description)); - break; - case GST_MATROSKA_ID_FILENAME: - if (filename) { - GST_WARNING_OBJECT (parse, "FileName can only appear once"); - break; - } - - ret = gst_ebml_read_utf8 (ebml, &id, &filename); - - GST_DEBUG_OBJECT (parse, "FileName: %s", GST_STR_NULL (filename)); - break; - case GST_MATROSKA_ID_FILEMIMETYPE: - if (mimetype) { - GST_WARNING_OBJECT (parse, "FileMimeType can only appear once"); - break; - } - - ret = gst_ebml_read_ascii (ebml, &id, &mimetype); - GST_DEBUG_OBJECT (parse, "FileMimeType: %s", GST_STR_NULL (mimetype)); - break; - case GST_MATROSKA_ID_FILEDATA: - if (data) { - GST_WARNING_OBJECT (parse, "FileData can only appear once"); - break; - } - - ret = gst_ebml_read_binary (ebml, &id, &data, &datalen); - GST_DEBUG_OBJECT (parse, "FileData of size %" G_GUINT64_FORMAT, - datalen); - break; - - default: - ret = gst_matroska_read_common_parse_skip (&parse->common, ebml, - "AttachedFile", id); - break; - case GST_MATROSKA_ID_FILEUID: - ret = gst_ebml_read_skip (ebml); - break; - } - } - - DEBUG_ELEMENT_STOP (parse, ebml, "AttachedFile", ret); - - if (filename && mimetype && data && datalen > 0) { - GstTagImageType image_type = GST_TAG_IMAGE_TYPE_NONE; - GstBuffer *tagbuffer = NULL; - GstCaps *caps; - gchar *filename_lc = g_utf8_strdown (filename, -1); - - GST_DEBUG_OBJECT (parse, "Creating tag for attachment with filename '%s', " - "mimetype '%s', description '%s', size %" G_GUINT64_FORMAT, filename, - mimetype, GST_STR_NULL (description), datalen); - - /* TODO: better heuristics for different image types */ - if (strstr (filename_lc, "cover")) { - if (strstr (filename_lc, "back")) - image_type = GST_TAG_IMAGE_TYPE_BACK_COVER; - else - image_type = GST_TAG_IMAGE_TYPE_FRONT_COVER; - } else if (g_str_has_prefix (mimetype, "image/") || - g_str_has_suffix (filename_lc, "png") || - g_str_has_suffix (filename_lc, "jpg") || - g_str_has_suffix (filename_lc, "jpeg") || - g_str_has_suffix (filename_lc, "gif") || - g_str_has_suffix (filename_lc, "bmp")) { - image_type = GST_TAG_IMAGE_TYPE_UNDEFINED; - } - g_free (filename_lc); - - /* First try to create an image tag buffer from this */ - if (image_type != GST_TAG_IMAGE_TYPE_NONE) { - tagbuffer = - gst_tag_image_data_to_image_buffer (data, datalen, image_type); - - if (!tagbuffer) - image_type = GST_TAG_IMAGE_TYPE_NONE; - } - - /* if this failed create an attachment buffer */ - if (!tagbuffer) { - tagbuffer = gst_buffer_new_and_alloc (datalen); - - memcpy (GST_BUFFER_DATA (tagbuffer), data, datalen); - GST_BUFFER_SIZE (tagbuffer) = datalen; - - caps = gst_type_find_helper_for_buffer (NULL, tagbuffer, NULL); - if (caps == NULL) - caps = gst_caps_new_simple (mimetype, NULL); - gst_buffer_set_caps (tagbuffer, caps); - gst_caps_unref (caps); - } - - /* Set filename and description on the caps */ - caps = GST_BUFFER_CAPS (tagbuffer); - gst_caps_set_simple (caps, "filename", G_TYPE_STRING, filename, NULL); - if (description) - gst_caps_set_simple (caps, "description", G_TYPE_STRING, description, - NULL); - - GST_DEBUG_OBJECT (parse, - "Created attachment buffer with caps: %" GST_PTR_FORMAT, caps); - - /* and append to the tag list */ - if (image_type != GST_TAG_IMAGE_TYPE_NONE) - gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, tagbuffer, - NULL); - else - gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_ATTACHMENT, - tagbuffer, NULL); - } - - g_free (filename); - g_free (mimetype); - g_free (data); - g_free (description); - - return ret; -} - static GstFlowReturn gst_matroska_parse_parse_attachments (GstMatroskaParse * parse, GstEbmlRead * ebml) @@ -1736,7 +1580,8 @@ gst_matroska_parse_parse_attachments (GstMatroskaParse * parse, switch (id) { case GST_MATROSKA_ID_ATTACHEDFILE: - ret = gst_matroska_parse_parse_attached_file (parse, ebml, taglist); + ret = gst_matroska_read_common_parse_attached_file (&parse->common, + ebml, taglist); break; default: diff --git a/gst/matroska/matroska-read-common.c b/gst/matroska/matroska-read-common.c index af6b696cdf..bbe3e74014 100644 --- a/gst/matroska/matroska-read-common.c +++ b/gst/matroska/matroska-read-common.c @@ -36,6 +36,9 @@ #include #endif +#include +#include + #include "lzo.h" #include "ebml-read.h" @@ -484,6 +487,161 @@ gst_matroska_read_common_parse_skip (GstMatroskaReadCommon * common, return gst_ebml_read_skip (ebml); } +GstFlowReturn +gst_matroska_read_common_parse_attached_file (GstMatroskaReadCommon * common, + GstEbmlRead * ebml, GstTagList * taglist) +{ + guint32 id; + GstFlowReturn ret; + gchar *description = NULL; + gchar *filename = NULL; + gchar *mimetype = NULL; + guint8 *data = NULL; + guint64 datalen = 0; + + DEBUG_ELEMENT_START (common, ebml, "AttachedFile"); + + if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) { + DEBUG_ELEMENT_STOP (common, ebml, "AttachedFile", ret); + return ret; + } + + while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) { + /* read all sub-entries */ + + if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK) + break; + + switch (id) { + case GST_MATROSKA_ID_FILEDESCRIPTION: + if (description) { + GST_WARNING_OBJECT (common, "FileDescription can only appear once"); + break; + } + + ret = gst_ebml_read_utf8 (ebml, &id, &description); + GST_DEBUG_OBJECT (common, "FileDescription: %s", + GST_STR_NULL (description)); + break; + case GST_MATROSKA_ID_FILENAME: + if (filename) { + GST_WARNING_OBJECT (common, "FileName can only appear once"); + break; + } + + ret = gst_ebml_read_utf8 (ebml, &id, &filename); + + GST_DEBUG_OBJECT (common, "FileName: %s", GST_STR_NULL (filename)); + break; + case GST_MATROSKA_ID_FILEMIMETYPE: + if (mimetype) { + GST_WARNING_OBJECT (common, "FileMimeType can only appear once"); + break; + } + + ret = gst_ebml_read_ascii (ebml, &id, &mimetype); + GST_DEBUG_OBJECT (common, "FileMimeType: %s", GST_STR_NULL (mimetype)); + break; + case GST_MATROSKA_ID_FILEDATA: + if (data) { + GST_WARNING_OBJECT (common, "FileData can only appear once"); + break; + } + + ret = gst_ebml_read_binary (ebml, &id, &data, &datalen); + GST_DEBUG_OBJECT (common, "FileData of size %" G_GUINT64_FORMAT, + datalen); + break; + + default: + ret = gst_matroska_read_common_parse_skip (common, ebml, + "AttachedFile", id); + break; + case GST_MATROSKA_ID_FILEUID: + ret = gst_ebml_read_skip (ebml); + break; + } + } + + DEBUG_ELEMENT_STOP (common, ebml, "AttachedFile", ret); + + if (filename && mimetype && data && datalen > 0) { + GstTagImageType image_type = GST_TAG_IMAGE_TYPE_NONE; + GstBuffer *tagbuffer = NULL; + GstCaps *caps; + gchar *filename_lc = g_utf8_strdown (filename, -1); + + GST_DEBUG_OBJECT (common, "Creating tag for attachment with " + "filename '%s', mimetype '%s', description '%s', " + "size %" G_GUINT64_FORMAT, filename, mimetype, + GST_STR_NULL (description), datalen); + + /* TODO: better heuristics for different image types */ + if (strstr (filename_lc, "cover")) { + if (strstr (filename_lc, "back")) + image_type = GST_TAG_IMAGE_TYPE_BACK_COVER; + else + image_type = GST_TAG_IMAGE_TYPE_FRONT_COVER; + } else if (g_str_has_prefix (mimetype, "image/") || + g_str_has_suffix (filename_lc, "png") || + g_str_has_suffix (filename_lc, "jpg") || + g_str_has_suffix (filename_lc, "jpeg") || + g_str_has_suffix (filename_lc, "gif") || + g_str_has_suffix (filename_lc, "bmp")) { + image_type = GST_TAG_IMAGE_TYPE_UNDEFINED; + } + g_free (filename_lc); + + /* First try to create an image tag buffer from this */ + if (image_type != GST_TAG_IMAGE_TYPE_NONE) { + tagbuffer = + gst_tag_image_data_to_image_buffer (data, datalen, image_type); + + if (!tagbuffer) + image_type = GST_TAG_IMAGE_TYPE_NONE; + } + + /* if this failed create an attachment buffer */ + if (!tagbuffer) { + tagbuffer = gst_buffer_new_and_alloc (datalen); + + memcpy (GST_BUFFER_DATA (tagbuffer), data, datalen); + GST_BUFFER_SIZE (tagbuffer) = datalen; + + caps = gst_type_find_helper_for_buffer (NULL, tagbuffer, NULL); + if (caps == NULL) + caps = gst_caps_new_simple (mimetype, NULL); + gst_buffer_set_caps (tagbuffer, caps); + gst_caps_unref (caps); + } + + /* Set filename and description on the caps */ + caps = GST_BUFFER_CAPS (tagbuffer); + gst_caps_set_simple (caps, "filename", G_TYPE_STRING, filename, NULL); + if (description) + gst_caps_set_simple (caps, "description", G_TYPE_STRING, description, + NULL); + + GST_DEBUG_OBJECT (common, + "Created attachment buffer with caps: %" GST_PTR_FORMAT, caps); + + /* and append to the tag list */ + if (image_type != GST_TAG_IMAGE_TYPE_NONE) + gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, tagbuffer, + NULL); + else + gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_ATTACHMENT, + tagbuffer, NULL); + } + + g_free (filename); + g_free (mimetype); + g_free (data); + g_free (description); + + return ret; +} + GstFlowReturn gst_matroska_read_common_parse_header (GstMatroskaReadCommon * common, GstEbmlRead * ebml) diff --git a/gst/matroska/matroska-read-common.h b/gst/matroska/matroska-read-common.h index bdfdd35b68..4fb489c613 100644 --- a/gst/matroska/matroska-read-common.h +++ b/gst/matroska/matroska-read-common.h @@ -103,6 +103,8 @@ GstFlowReturn gst_matroska_read_common_parse_index (GstMatroskaReadCommon * common, GstEbmlRead * ebml); GstFlowReturn gst_matroska_read_common_parse_info (GstMatroskaReadCommon * common, GstElement * el, GstEbmlRead * ebml); +GstFlowReturn gst_matroska_read_common_parse_attached_file ( + GstMatroskaReadCommon * common, GstEbmlRead * ebml, GstTagList * taglist); GstFlowReturn gst_matroska_read_common_parse_header (GstMatroskaReadCommon * common, GstEbmlRead * ebml); GstFlowReturn gst_matroska_read_common_parse_metadata (GstMatroskaReadCommon *