*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
* @tag: fourcc of the chunk (returned by this function).
* @chunk_data: buffer (returned by this function).
*
- * Reads a single chunk of data. Since 0.10.8 'JUNK' chunks
- * are skipped automatically.
+ * Reads a single chunk of data. 'JUNK' chunks are skipped
+ * automatically.
*
* Returns: flow status.
*/
skip_junk:
size = 8;
+ buf = NULL;
if ((res = gst_pad_pull_range (pad, offset, size, &buf)) != GST_FLOW_OK)
return res;
else if (gst_buffer_get_size (buf) < size)
goto skip_junk;
}
+ buf = NULL;
if ((res = gst_pad_pull_range (pad, offset + 8, size, &buf)) != GST_FLOW_OK)
return res;
else if (gst_buffer_get_size (buf) < size)
goto too_small;
tag = GST_READ_UINT32_LE (info.data);
- if (tag != GST_RIFF_TAG_RIFF && tag != GST_RIFF_TAG_AVF0)
+ if (tag != GST_RIFF_TAG_RIFF && tag != GST_RIFF_TAG_AVF0
+ && tag != GST_RIFF_TAG_RF64)
goto not_riff;
*doctype = GST_READ_UINT32_LE (info.data + 8);
not_riff:
{
GST_ELEMENT_ERROR (element, STREAM, WRONG_TYPE, (NULL),
- ("Stream is no RIFF stream: %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (tag)));
+ ("Stream is no RIFF stream: 0x%" G_GINT32_MODIFIER "x", tag));
gst_buffer_unmap (buf, &info);
gst_buffer_unref (buf);
return FALSE;
if (info.size < sizeof (gst_riff_strh))
goto too_small;
- strh = g_memdup (info.data, info.size);
+ strh = g_memdup2 (info.data, info.size);
gst_buffer_unmap (buf, &info);
gst_buffer_unref (buf);
* containing extradata for this particular stream (e.g.
* palette, codec initialization data).
*
- * Parses a video stream´s strf structure plus optionally some
+ * Parses a video stream's strf structure plus optionally some
* extradata from input data. This function takes ownership of @buf.
*
* Returns: TRUE if parsing succeeded, otherwise FALSE. The stream
if (info.size < sizeof (gst_riff_strf_vids))
goto too_small;
- strf = g_memdup (info.data, info.size);
+ strf = g_memdup2 (info.data, info.size);
gst_buffer_unmap (buf, &info);
#if (G_BYTE_ORDER == G_BIG_ENDIAN)
* containing extradata for this particular stream (e.g.
* codec initialization data).
*
- * Parses an audio stream´s strf structure plus optionally some
+ * Parses an audio stream's strf structure plus optionally some
* extradata from input data. This function takes ownership of @buf.
* use.
*
if (info.size < sizeof (gst_riff_strf_auds))
goto too_small;
- strf = g_memdup (info.data, info.size);
+ strf = g_memdup2 (info.data, info.size);
#if (G_BYTE_ORDER == G_BIG_ENDIAN)
strf->format = GUINT16_FROM_LE (strf->format);
strf->rate = GUINT32_FROM_LE (strf->rate);
strf->av_bps = GUINT32_FROM_LE (strf->av_bps);
strf->blockalign = GUINT16_FROM_LE (strf->blockalign);
- strf->size = GUINT16_FROM_LE (strf->size);
+ strf->bits_per_sample = GUINT16_FROM_LE (strf->bits_per_sample);
#endif
/* size checking */
if (info.size > sizeof (gst_riff_strf_auds) + 2) {
gint len;
- len = GST_READ_UINT16_LE (&data[16]);
+ len = GST_READ_UINT16_LE (&info.data[16]);
if (len + 2 + sizeof (gst_riff_strf_auds) > info.size) {
GST_WARNING_OBJECT (element,
- "Extradata indicated %d bytes, but only %" G_GSSIZE_FORMAT
+ "Extradata indicated %d bytes, but only %" G_GSIZE_FORMAT
" available", len, info.size - 2 - sizeof (gst_riff_strf_auds));
len = info.size - 2 - sizeof (gst_riff_strf_auds);
}
GST_INFO_OBJECT (element, " rate %d", strf->rate);
GST_INFO_OBJECT (element, " av_bps %d", strf->av_bps);
GST_INFO_OBJECT (element, " blockalign %d", strf->blockalign);
- GST_INFO_OBJECT (element, " size %d", strf->size);
+ GST_INFO_OBJECT (element, " bits/sample %d", strf->bits_per_sample);
if (*data)
GST_INFO_OBJECT (element, " %" G_GSIZE_FORMAT " bytes extradata",
gst_buffer_get_size (*data));
{
GST_ERROR_OBJECT (element,
"Too small strf_auds (%" G_GSIZE_FORMAT " available"
- ", %" G_GSSIZE_FORMAT " needed)", info.size,
+ ", %" G_GSIZE_FORMAT " needed)", info.size,
sizeof (gst_riff_strf_auds));
gst_buffer_unmap (buf, &info);
gst_buffer_unref (buf);
if (info.size < sizeof (gst_riff_strf_iavs))
goto too_small;
- strf = g_memdup (info.data, info.size);
+ strf = g_memdup2 (info.data, info.size);
gst_buffer_unmap (buf, &info);
gst_buffer_unref (buf);
{
GST_ERROR_OBJECT (element,
"Too small strf_iavs (%" G_GSIZE_FORMAT "available"
- ", %" G_GSSIZE_FORMAT " needed)", info.size,
+ ", %" G_GSIZE_FORMAT " needed)", info.size,
sizeof (gst_riff_strf_iavs));
gst_buffer_unmap (buf, &info);
gst_buffer_unref (buf);
}
}
+static void
+parse_tag_value (GstElement * element, 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 (element, "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 (element, "could not extract %s tag", type);
+ }
+}
+
/**
* gst_riff_parse_info:
* @element: caller element (used for debugging/error).
while (left > 8) {
tag = GST_READ_UINT32_LE (ptr);
tsize = GST_READ_UINT32_LE (ptr + 4);
+
+ GST_MEMDUMP_OBJECT (element, "tag chunk", ptr, MIN (tsize + 8, left));
+
left -= 8;
ptr += 8;
tsize = left;
}
+ /* make uppercase */
+ tag = tag & 0xDFDFDFDF;
+
/* find out the type of metadata */
switch (tag) {
case GST_RIFF_INFO_IARL:
type = GST_TAG_LOCATION;
break;
+ case GST_RIFF_INFO_IAAR:
+ type = GST_TAG_ALBUM_ARTIST;
+ break;
case GST_RIFF_INFO_IART:
type = GST_TAG_ARTIST;
break;
type = GST_TAG_COPYRIGHT;
break;
case GST_RIFF_INFO_ICRD:
- type = GST_TAG_DATE;
+ type = GST_TAG_DATE_TIME;
break;
case GST_RIFF_INFO_ICRP:
type = NULL; /*"Cropped"; */
type = NULL; /*"Palette"; */
break;
case GST_RIFF_INFO_IPRD:
- type = NULL; /*"Product"; */
+ type = GST_TAG_ALBUM;
break;
case GST_RIFF_INFO_ISBJ:
- type = NULL; /*"Subject"; */
+ type = GST_TAG_ALBUM_ARTIST;
break;
case GST_RIFF_INFO_ISFT:
type = GST_TAG_ENCODER;
case GST_RIFF_INFO_ITCH:
type = NULL; /*"Technician"; */
break;
+ case GST_RIFF_INFO_ITRK:
+ type = GST_TAG_TRACK_NUMBER;
+ break;
default:
type = NULL;
GST_WARNING_OBJECT (element,
}
if (type != NULL && ptr[0] != '\0') {
- static const gchar *env_vars[] = { "GST_AVI_TAG_ENCODING",
- "GST_RIFF_TAG_ENCODING", "GST_TAG_ENCODING", NULL
- };
- gchar *val;
-
- val = gst_tag_freeform_string_to_utf8 ((gchar *) ptr, tsize, env_vars);
+ GST_DEBUG_OBJECT (element, "mapped tag %" GST_FOURCC_FORMAT " to tag %s",
+ GST_FOURCC_ARGS (tag), type);
- if (val) {
- gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, type, val, NULL);
- g_free (val);
- } else {
- GST_WARNING_OBJECT (element, "could not extract %s tag", type);
- }
+ parse_tag_value (element, taglist, type, ptr, tsize);
}
if (tsize & 1) {
}
if (!gst_tag_list_is_empty (taglist)) {
+ GST_INFO_OBJECT (element, "extracted tags: %" GST_PTR_FORMAT, taglist);
*_taglist = taglist;
} else {
*_taglist = NULL;
- gst_tag_list_free (taglist);
+ gst_tag_list_unref (taglist);
}
gst_buffer_unmap (buf, &info);