mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
avidemux: copy the riff api for ncdt into the element
This chunk is avi specific, no need to expose this as public api.
This commit is contained in:
parent
a4a7dafc32
commit
9a203fceeb
1 changed files with 166 additions and 2 deletions
|
@ -53,7 +53,7 @@
|
||||||
#include "avi-ids.h"
|
#include "avi-ids.h"
|
||||||
#include <gst/gst-i18n-plugin.h>
|
#include <gst/gst-i18n-plugin.h>
|
||||||
#include <gst/base/gstadapter.h>
|
#include <gst/base/gstadapter.h>
|
||||||
|
#include <gst/tag/tag.h>
|
||||||
|
|
||||||
#define DIV_ROUND_UP(s,v) (((s) + ((v)-1)) / (v))
|
#define DIV_ROUND_UP(s,v) (((s) + ((v)-1)) / (v))
|
||||||
|
|
||||||
|
@ -3687,6 +3687,170 @@ non_parsable:
|
||||||
gst_buffer_unmap (buf, &map);
|
gst_buffer_unmap (buf, &map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_tag_value (GstAviDemux * avi, GstTagList * taglist, const gchar * type,
|
||||||
|
guint8 * ptr, guint tsize)
|
||||||
|
{
|
||||||
|
static const gchar *env_vars[] = { "GST_AVI_TAG_ENCODING",
|
||||||
|
"GST_RIFF_TAG_ENCODING", "GST_TAG_ENCODING", NULL
|
||||||
|
};
|
||||||
|
GType tag_type;
|
||||||
|
gchar *val;
|
||||||
|
|
||||||
|
tag_type = gst_tag_get_type (type);
|
||||||
|
val = gst_tag_freeform_string_to_utf8 ((gchar *) ptr, tsize, env_vars);
|
||||||
|
|
||||||
|
if (val != NULL) {
|
||||||
|
if (tag_type == G_TYPE_STRING) {
|
||||||
|
gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, type, val, NULL);
|
||||||
|
} else {
|
||||||
|
GValue tag_val = { 0, };
|
||||||
|
|
||||||
|
g_value_init (&tag_val, tag_type);
|
||||||
|
if (gst_value_deserialize (&tag_val, val)) {
|
||||||
|
gst_tag_list_add_value (taglist, GST_TAG_MERGE_APPEND, type, &tag_val);
|
||||||
|
} else {
|
||||||
|
GST_WARNING_OBJECT (avi, "could not deserialize '%s' into a "
|
||||||
|
"tag %s of type %s", val, type, g_type_name (tag_type));
|
||||||
|
}
|
||||||
|
g_value_unset (&tag_val);
|
||||||
|
}
|
||||||
|
g_free (val);
|
||||||
|
} else {
|
||||||
|
GST_WARNING_OBJECT (avi, "could not extract %s tag", type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* gst_avi_demux_parse_ncdt:
|
||||||
|
* @element: caller element (used for debugging/error).
|
||||||
|
* @buf: input data to be used for parsing, stripped from header.
|
||||||
|
* @taglist: a pointer to a taglist (returned by this function)
|
||||||
|
* containing information about this stream. May be
|
||||||
|
* NULL if no supported tags were found.
|
||||||
|
*
|
||||||
|
* Parses Nikon metadata from input data.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
gst_avi_demux_parse_ncdt (GstAviDemux * avi, GstBuffer * buf,
|
||||||
|
GstTagList ** _taglist)
|
||||||
|
{
|
||||||
|
GstMapInfo info;
|
||||||
|
guint8 *ptr;
|
||||||
|
gsize left;
|
||||||
|
guint tsize;
|
||||||
|
guint32 tag;
|
||||||
|
const gchar *type;
|
||||||
|
GstTagList *taglist;
|
||||||
|
|
||||||
|
g_return_if_fail (_taglist != NULL);
|
||||||
|
|
||||||
|
if (!buf) {
|
||||||
|
*_taglist = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gst_buffer_map (buf, &info, GST_MAP_READ);
|
||||||
|
|
||||||
|
taglist = gst_tag_list_new_empty ();
|
||||||
|
|
||||||
|
ptr = info.data;
|
||||||
|
left = info.size;
|
||||||
|
|
||||||
|
while (left > 8) {
|
||||||
|
tag = GST_READ_UINT32_LE (ptr);
|
||||||
|
tsize = GST_READ_UINT32_LE (ptr + 4);
|
||||||
|
|
||||||
|
GST_MEMDUMP_OBJECT (avi, "tag chunk", ptr, MIN (tsize + 8, left));
|
||||||
|
|
||||||
|
left -= 8;
|
||||||
|
ptr += 8;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (avi, "tag %" GST_FOURCC_FORMAT ", size %u",
|
||||||
|
GST_FOURCC_ARGS (tag), tsize);
|
||||||
|
|
||||||
|
if (tsize > left) {
|
||||||
|
GST_WARNING_OBJECT (avi,
|
||||||
|
"Tagsize %d is larger than available data %" G_GSIZE_FORMAT,
|
||||||
|
tsize, left);
|
||||||
|
tsize = left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find out the type of metadata */
|
||||||
|
switch (tag) {
|
||||||
|
case GST_RIFF_LIST_nctg:
|
||||||
|
while (tsize > 4) {
|
||||||
|
guint16 sub_tag = GST_READ_UINT16_LE (ptr);
|
||||||
|
guint16 sub_size = GST_READ_UINT16_LE (ptr + 2);
|
||||||
|
|
||||||
|
tsize -= 4;
|
||||||
|
ptr += 4;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (avi, "sub-tag %u, size %u", sub_tag, sub_size);
|
||||||
|
/* http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#NCTG
|
||||||
|
* for some reason the sub_tag has a +2 offset
|
||||||
|
*/
|
||||||
|
switch (sub_tag) {
|
||||||
|
case 0x03: /* Make */
|
||||||
|
type = GST_TAG_DEVICE_MANUFACTURER;
|
||||||
|
break;
|
||||||
|
case 0x04: /* Model */
|
||||||
|
type = GST_TAG_DEVICE_MODEL;
|
||||||
|
break;
|
||||||
|
/* TODO: 0x05: is software version, like V1.0 */
|
||||||
|
case 0x06: /* Software */
|
||||||
|
type = GST_TAG_ENCODER;
|
||||||
|
break;
|
||||||
|
case 0x13: /* CreationDate */
|
||||||
|
type = GST_TAG_DATE_TIME;
|
||||||
|
if (ptr[4] == ':')
|
||||||
|
ptr[4] = '-';
|
||||||
|
if (ptr[7] == ':')
|
||||||
|
ptr[7] = '-';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
type = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (type != NULL && ptr[0] != '\0') {
|
||||||
|
GST_DEBUG_OBJECT (avi, "mapped tag %u to tag %s", sub_tag, type);
|
||||||
|
|
||||||
|
parse_tag_value (avi, taglist, type, ptr, sub_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr += sub_size;
|
||||||
|
tsize -= sub_size;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
type = NULL;
|
||||||
|
GST_WARNING_OBJECT (avi,
|
||||||
|
"Unknown ncdt (metadata) tag entry %" GST_FOURCC_FORMAT,
|
||||||
|
GST_FOURCC_ARGS (tag));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tsize & 1) {
|
||||||
|
tsize++;
|
||||||
|
if (tsize > left)
|
||||||
|
tsize = left;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr += tsize;
|
||||||
|
left -= tsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gst_tag_list_is_empty (taglist)) {
|
||||||
|
GST_INFO_OBJECT (avi, "extracted tags: %" GST_PTR_FORMAT, taglist);
|
||||||
|
*_taglist = taglist;
|
||||||
|
} else {
|
||||||
|
*_taglist = NULL;
|
||||||
|
gst_tag_list_unref (taglist);
|
||||||
|
}
|
||||||
|
gst_buffer_unmap (buf, &info);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read full AVI headers.
|
* Read full AVI headers.
|
||||||
*/
|
*/
|
||||||
|
@ -3798,7 +3962,7 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
|
||||||
case GST_RIFF_LIST_ncdt:
|
case GST_RIFF_LIST_ncdt:
|
||||||
gst_buffer_unmap (sub, &map);
|
gst_buffer_unmap (sub, &map);
|
||||||
gst_buffer_resize (sub, 4, -1);
|
gst_buffer_resize (sub, 4, -1);
|
||||||
gst_riff_parse_ncdt (element, sub, &tags);
|
gst_avi_demux_parse_ncdt (avi, sub, &tags);
|
||||||
if (tags) {
|
if (tags) {
|
||||||
if (avi->globaltags) {
|
if (avi->globaltags) {
|
||||||
gst_tag_list_insert (avi->globaltags, tags,
|
gst_tag_list_insert (avi->globaltags, tags,
|
||||||
|
|
Loading…
Reference in a new issue