Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / gst-libs / gst / riff / riff-read.c
index 314c19f..5fc6df5 100644 (file)
@@ -52,8 +52,10 @@ gst_riff_read_chunk (GstElement * element,
 {
   GstBuffer *buf;
   GstFlowReturn res;
+  guint8 *data;
   guint size;
   guint64 offset = *_offset;
+  gsize bsize;
 
   g_return_val_if_fail (element != NULL, GST_FLOW_ERROR);
   g_return_val_if_fail (pad != NULL, GST_FLOW_ERROR);
@@ -65,11 +67,13 @@ skip_junk:
   size = 8;
   if ((res = gst_pad_pull_range (pad, offset, size, &buf)) != GST_FLOW_OK)
     return res;
-  else if (GST_BUFFER_SIZE (buf) < size)
+  else if (gst_buffer_get_size (buf) < size)
     goto too_small;
 
-  *tag = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf));
-  size = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf) + 4);
+  data = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+  *tag = GST_READ_UINT32_LE (data);
+  size = GST_READ_UINT32_LE (data + 4);
+  gst_buffer_unmap (buf, data, bsize);
   gst_buffer_unref (buf);
 
   GST_DEBUG_OBJECT (element, "fourcc=%" GST_FOURCC_FORMAT ", size=%u",
@@ -86,7 +90,7 @@ skip_junk:
 
   if ((res = gst_pad_pull_range (pad, offset + 8, size, &buf)) != GST_FLOW_OK)
     return res;
-  else if (GST_BUFFER_SIZE (buf) < size)
+  else if (gst_buffer_get_size (buf) < size)
     goto too_small;
 
   *_chunk_data = buf;
@@ -99,7 +103,7 @@ too_small:
   {
     /* short read, we return UNEXPECTED to mark the EOS case */
     GST_DEBUG_OBJECT (element, "not enough data (available=%u, needed=%u)",
-        GST_BUFFER_SIZE (buf), size);
+        gst_buffer_get_size (buf), size);
     gst_buffer_unref (buf);
     return GST_FLOW_UNEXPECTED;
   }
@@ -125,7 +129,8 @@ gst_riff_parse_chunk (GstElement * element, GstBuffer * buf,
 {
   guint size, bufsize;
   guint32 fourcc;
-  guint8 *data;
+  guint8 *data, *ptr;
+  gsize bsize;
   guint offset = *_offset;
 
   g_return_val_if_fail (element != NULL, FALSE);
@@ -137,7 +142,7 @@ gst_riff_parse_chunk (GstElement * element, GstBuffer * buf,
   *chunk_data = NULL;
   *_fourcc = 0;
 
-  bufsize = GST_BUFFER_SIZE (buf);
+  bufsize = gst_buffer_get_size (buf);
 
   if (bufsize == offset)
     goto end_offset;
@@ -146,9 +151,11 @@ gst_riff_parse_chunk (GstElement * element, GstBuffer * buf,
     goto too_small;
 
   /* read header */
-  data = GST_BUFFER_DATA (buf) + offset;
-  fourcc = GST_READ_UINT32_LE (data);
-  size = GST_READ_UINT32_LE (data + 4);
+  data = ptr = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+  ptr += offset;
+  fourcc = GST_READ_UINT32_LE (ptr);
+  size = GST_READ_UINT32_LE (ptr + 4);
+  gst_buffer_unmap (buf, data, bsize);
 
   GST_DEBUG_OBJECT (element, "fourcc=%" GST_FOURCC_FORMAT ", size=%u",
       GST_FOURCC_ARGS (fourcc), size);
@@ -165,7 +172,8 @@ gst_riff_parse_chunk (GstElement * element, GstBuffer * buf,
   }
 
   if (size)
-    *chunk_data = gst_buffer_create_sub (buf, offset + 8, size);
+    *chunk_data =
+        gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, offset + 8, size);
   else
     *chunk_data = NULL;
 
@@ -217,19 +225,21 @@ gst_riff_parse_file_header (GstElement * element,
 {
   guint8 *data;
   guint32 tag;
+  gsize size;
 
   g_return_val_if_fail (buf != NULL, FALSE);
   g_return_val_if_fail (doctype != NULL, FALSE);
 
-  if (GST_BUFFER_SIZE (buf) < 12)
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  if (size < 12)
     goto too_small;
 
-  data = GST_BUFFER_DATA (buf);
   tag = GST_READ_UINT32_LE (data);
   if (tag != GST_RIFF_TAG_RIFF && tag != GST_RIFF_TAG_AVF0)
     goto not_riff;
 
   *doctype = GST_READ_UINT32_LE (data + 8);
+  gst_buffer_unmap (buf, data, size);
 
   gst_buffer_unref (buf);
 
@@ -240,7 +250,8 @@ too_small:
   {
     GST_ELEMENT_ERROR (element, STREAM, WRONG_TYPE, (NULL),
         ("Not enough data to parse RIFF header (%d available, %d needed)",
-            GST_BUFFER_SIZE (buf), 12));
+            size, 12));
+    gst_buffer_unmap (buf, data, size);
     gst_buffer_unref (buf);
     return FALSE;
   }
@@ -249,6 +260,7 @@ not_riff:
     GST_ELEMENT_ERROR (element, STREAM, WRONG_TYPE, (NULL),
         ("Stream is no RIFF stream: %" GST_FOURCC_FORMAT,
             GST_FOURCC_ARGS (tag)));
+    gst_buffer_unmap (buf, data, size);
     gst_buffer_unref (buf);
     return FALSE;
   }
@@ -272,14 +284,19 @@ gst_riff_parse_strh (GstElement * element,
     GstBuffer * buf, gst_riff_strh ** _strh)
 {
   gst_riff_strh *strh;
+  guint8 *data;
+  gsize size;
 
   g_return_val_if_fail (buf != NULL, FALSE);
   g_return_val_if_fail (_strh != NULL, FALSE);
 
-  if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_strh))
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  if (size < sizeof (gst_riff_strh))
     goto too_small;
 
-  strh = g_memdup (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+  strh = g_memdup (data, size);
+  gst_buffer_unmap (buf, data, size);
+
   gst_buffer_unref (buf);
 
 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
@@ -329,7 +346,8 @@ too_small:
   {
     GST_ERROR_OBJECT (element,
         "Too small strh (%d available, %d needed)",
-        GST_BUFFER_SIZE (buf), (int) sizeof (gst_riff_strh));
+        size, (int) sizeof (gst_riff_strh));
+    gst_buffer_unmap (buf, data, size);
     gst_buffer_unref (buf);
     return FALSE;
   }
@@ -357,15 +375,19 @@ gst_riff_parse_strf_vids (GstElement * element,
     GstBuffer * buf, gst_riff_strf_vids ** _strf, GstBuffer ** data)
 {
   gst_riff_strf_vids *strf;
+  guint8 *bdata;
+  gsize size;
 
   g_return_val_if_fail (buf != NULL, FALSE);
   g_return_val_if_fail (_strf != NULL, FALSE);
   g_return_val_if_fail (data != NULL, FALSE);
 
-  if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_strf_vids))
+  bdata = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  if (size < sizeof (gst_riff_strf_vids))
     goto too_small;
 
-  strf = g_memdup (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+  strf = g_memdup (bdata, size);
+  gst_buffer_unmap (buf, bdata, size);
 
 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
   strf->size = GUINT32_FROM_LE (strf->size);
@@ -383,16 +405,18 @@ gst_riff_parse_strf_vids (GstElement * element,
 
   /* size checking */
   *data = NULL;
-  if (strf->size > GST_BUFFER_SIZE (buf)) {
+  if (strf->size > size) {
     GST_WARNING_OBJECT (element,
         "strf_vids header gave %d bytes data, only %d available",
-        strf->size, GST_BUFFER_SIZE (buf));
-    strf->size = GST_BUFFER_SIZE (buf);
+        strf->size, size);
+    strf->size = size;
   }
-  if (sizeof (gst_riff_strf_vids) < GST_BUFFER_SIZE (buf)) {
-    *data = gst_buffer_create_sub (buf, sizeof (gst_riff_strf_vids),
-        GST_BUFFER_SIZE (buf) - sizeof (gst_riff_strf_vids));
+  if (sizeof (gst_riff_strf_vids) < size) {
+    *data =
+        gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
+        sizeof (gst_riff_strf_vids), size - sizeof (gst_riff_strf_vids));
   }
+  gst_buffer_unref (buf);
 
   /* debug */
   GST_INFO_OBJECT (element, "strf tag found in context vids:");
@@ -409,9 +433,8 @@ gst_riff_parse_strf_vids (GstElement * element,
   GST_INFO_OBJECT (element, " num_colors  %d", strf->num_colors);
   GST_INFO_OBJECT (element, " imp_colors  %d", strf->imp_colors);
   if (*data)
-    GST_INFO_OBJECT (element, " %d bytes extradata", GST_BUFFER_SIZE (*data));
-
-  gst_buffer_unref (buf);
+    GST_INFO_OBJECT (element, " %d bytes extradata",
+        gst_buffer_get_size (*data));
 
   *_strf = strf;
 
@@ -422,7 +445,8 @@ too_small:
   {
     GST_ERROR_OBJECT (element,
         "Too small strf_vids (%d available, %d needed)",
-        GST_BUFFER_SIZE (buf), (int) sizeof (gst_riff_strf_vids));
+        size, (int) sizeof (gst_riff_strf_vids));
+    gst_buffer_unmap (buf, data, size);
     gst_buffer_unref (buf);
     return FALSE;
   }
@@ -450,18 +474,18 @@ gst_riff_parse_strf_auds (GstElement * element,
     GstBuffer * buf, gst_riff_strf_auds ** _strf, GstBuffer ** data)
 {
   gst_riff_strf_auds *strf;
-  guint bufsize;
+  gsize bsize;
+  guint8 *bdata;
 
   g_return_val_if_fail (buf != NULL, FALSE);
   g_return_val_if_fail (_strf != NULL, FALSE);
   g_return_val_if_fail (data != NULL, FALSE);
 
-  bufsize = GST_BUFFER_SIZE (buf);
-
-  if (bufsize < sizeof (gst_riff_strf_auds))
+  bdata = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+  if (bsize < sizeof (gst_riff_strf_auds))
     goto too_small;
 
-  strf = g_memdup (GST_BUFFER_DATA (buf), bufsize);
+  strf = g_memdup (bdata, bsize);
 
 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
   strf->format = GUINT16_FROM_LE (strf->format);
@@ -474,18 +498,19 @@ gst_riff_parse_strf_auds (GstElement * element,
 
   /* size checking */
   *data = NULL;
-  if (bufsize > sizeof (gst_riff_strf_auds) + 2) {
+  if (bsize > sizeof (gst_riff_strf_auds) + 2) {
     gint len;
 
-    len = GST_READ_UINT16_LE (&GST_BUFFER_DATA (buf)[16]);
-    if (len + 2 + sizeof (gst_riff_strf_auds) > bufsize) {
+    len = GST_READ_UINT16_LE (&data[16]);
+    if (len + 2 + sizeof (gst_riff_strf_auds) > bsize) {
       GST_WARNING_OBJECT (element,
           "Extradata indicated %d bytes, but only %" G_GSSIZE_FORMAT
-          " available", len, bufsize - 2 - sizeof (gst_riff_strf_auds));
-      len = bufsize - 2 - sizeof (gst_riff_strf_auds);
+          " available", len, bsize - 2 - sizeof (gst_riff_strf_auds));
+      len = bsize - 2 - sizeof (gst_riff_strf_auds);
     }
     if (len)
-      *data = gst_buffer_create_sub (buf, sizeof (gst_riff_strf_auds) + 2, len);
+      *data = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
+          sizeof (gst_riff_strf_auds) + 2, len);
   }
 
   /* debug */
@@ -497,8 +522,10 @@ gst_riff_parse_strf_auds (GstElement * element,
   GST_INFO_OBJECT (element, " blockalign  %d", strf->blockalign);
   GST_INFO_OBJECT (element, " size        %d", strf->size);
   if (*data)
-    GST_INFO_OBJECT (element, " %d bytes extradata", GST_BUFFER_SIZE (*data));
+    GST_INFO_OBJECT (element, " %d bytes extradata",
+        gst_buffer_get_size (*data));
 
+  gst_buffer_unmap (buf, bdata, bsize);
   gst_buffer_unref (buf);
 
   *_strf = strf;
@@ -510,7 +537,8 @@ too_small:
   {
     GST_ERROR_OBJECT (element,
         "Too small strf_auds (%d available, %" G_GSSIZE_FORMAT " needed)",
-        bufsize, sizeof (gst_riff_strf_auds));
+        bsize, sizeof (gst_riff_strf_auds));
+    gst_buffer_unmap (buf, bdata, bsize);
     gst_buffer_unref (buf);
     return FALSE;
   }
@@ -538,15 +566,20 @@ gst_riff_parse_strf_iavs (GstElement * element,
     GstBuffer * buf, gst_riff_strf_iavs ** _strf, GstBuffer ** data)
 {
   gst_riff_strf_iavs *strf;
+  gsize bsize;
+  guint8 *bdata;
 
   g_return_val_if_fail (buf != NULL, FALSE);
   g_return_val_if_fail (_strf != NULL, FALSE);
   g_return_val_if_fail (data != NULL, FALSE);
 
-  if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_strf_iavs))
+  bdata = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+  if (bsize < sizeof (gst_riff_strf_iavs))
     goto too_small;
 
-  strf = g_memdup (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+  strf = g_memdup (bdata, bsize);
+  gst_buffer_unmap (buf, bdata, bsize);
+
   gst_buffer_unref (buf);
 
 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
@@ -581,7 +614,8 @@ too_small:
   {
     GST_ERROR_OBJECT (element,
         "Too small strf_iavs (%d available, %" G_GSSIZE_FORMAT " needed)",
-        GST_BUFFER_SIZE (buf), sizeof (gst_riff_strf_iavs));
+        bsize, sizeof (gst_riff_strf_iavs));
+    gst_buffer_unmap (buf, bdata, bsize);
     gst_buffer_unref (buf);
     return FALSE;
   }
@@ -601,8 +635,9 @@ void
 gst_riff_parse_info (GstElement * element,
     GstBuffer * buf, GstTagList ** _taglist)
 {
-  guint8 *data;
-  guint size, tsize;
+  guint8 *data, *ptr;
+  gsize size, left;
+  guint tsize;
   guint32 tag;
   const gchar *type;
   GstTagList *taglist;
@@ -613,23 +648,26 @@ gst_riff_parse_info (GstElement * element,
     *_taglist = NULL;
     return;
   }
-  data = GST_BUFFER_DATA (buf);
-  size = GST_BUFFER_SIZE (buf);
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+
   taglist = gst_tag_list_new ();
 
-  while (size > 8) {
-    tag = GST_READ_UINT32_LE (data);
-    tsize = GST_READ_UINT32_LE (data + 4);
-    size -= 8;
-    data += 8;
+  ptr = data;
+  left = size;
+
+  while (left > 8) {
+    tag = GST_READ_UINT32_LE (ptr);
+    tsize = GST_READ_UINT32_LE (ptr + 4);
+    left -= 8;
+    ptr += 8;
 
     GST_DEBUG ("tag %" GST_FOURCC_FORMAT ", size %u",
         GST_FOURCC_ARGS (tag), tsize);
 
-    if (tsize > size) {
+    if (tsize > left) {
       GST_WARNING_OBJECT (element,
-          "Tagsize %d is larger than available data %d", tsize, size);
-      tsize = size;
+          "Tagsize %d is larger than available data %d", tsize, left);
+      tsize = left;
     }
 
     /* find out the type of metadata */
@@ -711,13 +749,13 @@ gst_riff_parse_info (GstElement * element,
         break;
     }
 
-    if (type != NULL && data[0] != '\0') {
+    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 *) data, tsize, env_vars);
+      val = gst_tag_freeform_string_to_utf8 ((gchar *) ptr, tsize, env_vars);
 
       if (val) {
         gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, type, val, NULL);
@@ -729,12 +767,12 @@ gst_riff_parse_info (GstElement * element,
 
     if (tsize & 1) {
       tsize++;
-      if (tsize > size)
-        tsize = size;
+      if (tsize > left)
+        tsize = left;
     }
 
-    data += tsize;
-    size -= tsize;
+    ptr += tsize;
+    left -= tsize;
   }
 
   if (!gst_tag_list_is_empty (taglist)) {
@@ -743,6 +781,7 @@ gst_riff_parse_info (GstElement * element,
     *_taglist = NULL;
     gst_tag_list_free (taglist);
   }
+  gst_buffer_unmap (buf, data, size);
 
   return;
 }