asfparse: port to baseparse
authorThiago Santos <ts.santos@sisa.samsung.com>
Tue, 10 Dec 2013 13:34:02 +0000 (10:34 -0300)
committerThiago Santos <ts.santos@sisa.samsung.com>
Sat, 14 Dec 2013 06:56:44 +0000 (03:56 -0300)
asfparse was not really functional after the port to 1.0

Now porting it to baseparse to get it working again

gst/asfmux/gstasfobjects.c
gst/asfmux/gstasfobjects.h
gst/asfmux/gstasfparse.c
gst/asfmux/gstasfparse.h

index b8ec94d..df4f69c 100644 (file)
@@ -762,25 +762,35 @@ gst_asf_parse_file_properties_obj (GstByteReader * reader,
 gboolean
 gst_asf_parse_headers (GstBuffer * buffer, GstAsfFileInfo * file_info)
 {
+  GstMapInfo map;
+  gboolean ret;
+
+  gst_buffer_map (buffer, &map, GST_MAP_READ);
+  ret = gst_asf_parse_headers_from_data (map.data, map.size, file_info);
+  gst_buffer_unmap (buffer, &map);
+
+  return ret;
+}
+
+gboolean
+gst_asf_parse_headers_from_data (guint8 * data, guint size,
+    GstAsfFileInfo * file_info)
+{
   gboolean ret = TRUE;
   guint32 header_objects = 0;
   guint32 i;
   GstByteReader *reader;
   guint64 object_size;
-  GstMapInfo map;
 
-  gst_buffer_map (buffer, &map, GST_MAP_READ);
-
-  object_size = gst_asf_match_and_peek_obj_size (map.data,
+  object_size = gst_asf_match_and_peek_obj_size (data,
       &(guids[ASF_HEADER_OBJECT_INDEX]));
   if (object_size == 0) {
     GST_WARNING ("ASF: Cannot parse, header guid not found at the beginning "
         " of data");
-    gst_buffer_unmap (buffer, &map);
     return FALSE;
   }
 
-  reader = gst_byte_reader_new (map.data, map.size);
+  reader = gst_byte_reader_new (data, size);
 
   if (!gst_byte_reader_skip (reader, ASF_GUID_OBJSIZE_SIZE))
     goto error;
@@ -818,7 +828,6 @@ error:
   ret = FALSE;
   GST_WARNING ("ASF: Error while parsing headers");
 end:
-  gst_buffer_unmap (buffer, &map);
   gst_byte_reader_free (reader);
   return ret;
 }
index 0c1e202..fd8e97c 100644 (file)
@@ -115,6 +115,7 @@ guint64 gst_asf_match_and_peek_obj_size (const guint8 * data,
 guint64 gst_asf_match_and_peek_obj_size_buf (GstBuffer * buf,
     const Guid * guid);
 gboolean gst_asf_parse_headers (GstBuffer * buffer, GstAsfFileInfo * file_info);
+gboolean gst_asf_parse_headers_from_data (guint8 * data, guint size, GstAsfFileInfo * file_info);
 
 /* ASF tags
  * found at http://msdn.microsoft.com/en-us/library/dd562330(VS.85).aspx
index 55bfe1d..bd23a79 100644 (file)
@@ -42,99 +42,46 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_STATIC_CAPS ("video/x-ms-asf, parsed = (boolean) false")
     );
 
-static GstStateChangeReturn gst_asf_parse_change_state (GstElement * element,
-    GstStateChange transition);
-static void gst_asf_parse_loop (GstPad * pad);
-
 #define gst_asf_parse_parent_class parent_class
-G_DEFINE_TYPE (GstAsfParse, gst_asf_parse, GST_TYPE_ELEMENT);
+G_DEFINE_TYPE (GstAsfParse, gst_asf_parse, GST_TYPE_BASE_PARSE);
 
-static void
-gst_asf_parse_reset (GstAsfParse * asfparse)
+static gboolean
+gst_asf_parse_start (GstBaseParse * parse)
 {
-  gst_adapter_clear (asfparse->adapter);
+  GstAsfParse *asfparse = GST_ASF_PARSE_CAST (parse);
   gst_asf_file_info_reset (asfparse->asfinfo);
   asfparse->parse_state = ASF_PARSING_HEADERS;
-  asfparse->headers_size = 0;
-  asfparse->data_size = 0;
   asfparse->parsed_packets = 0;
-  asfparse->offset = 0;
-}
 
-static gboolean
-gst_asf_parse_sink_activate (GstPad * sinkpad, GstObject * parent)
-{
-  GstQuery *query;
-  gboolean pull_mode;
+  /* ASF Obj header length */
+  gst_base_parse_set_min_frame_size (GST_BASE_PARSE_CAST (asfparse),
+      ASF_GUID_OBJSIZE_SIZE);
 
-  query = gst_query_new_scheduling ();
+  gst_base_parse_set_syncable (GST_BASE_PARSE_CAST (asfparse), FALSE);
 
-  if (!gst_pad_peer_query (sinkpad, query)) {
-    gst_query_unref (query);
-    goto activate_push;
-  }
-
-  pull_mode = gst_query_has_scheduling_mode_with_flags (query,
-      GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
-  gst_query_unref (query);
-
-  if (!pull_mode)
-    goto activate_push;
-
-  GST_DEBUG_OBJECT (sinkpad, "activating pull");
-  return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
-
-activate_push:
-  {
-    GST_DEBUG_OBJECT (sinkpad, "activating push");
-    return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
-  }
+  return TRUE;
 }
 
 static gboolean
-gst_asf_parse_sink_activate_mode (GstPad * pad, GstObject * parent,
-    GstPadMode mode, gboolean active)
+gst_asf_parse_stop (GstBaseParse * parse)
 {
-  gboolean res;
-
-  switch (mode) {
-    case GST_PAD_MODE_PULL:
-      if (active) {
-        res =
-            gst_pad_start_task (pad, (GstTaskFunction) gst_asf_parse_loop, pad,
-            NULL);
-      } else {
-        res = gst_pad_stop_task (pad);
-      }
-    case GST_PAD_MODE_PUSH:
-      res = TRUE;
-      break;
-    default:
-      res = FALSE;
-      break;
-  }
-
-  return res;
-}
+  GstAsfParse *asfparse = GST_ASF_PARSE_CAST (parse);
+  gst_asf_file_info_reset (asfparse->asfinfo);
 
-static GstFlowReturn
-gst_asf_parse_push (GstAsfParse * asfparse, GstBuffer * buf)
-{
-  return gst_pad_push (asfparse->srcpad, buf);
+  return TRUE;
 }
 
 static GstFlowReturn
-gst_asf_parse_parse_data_object (GstAsfParse * asfparse, GstBuffer * buffer)
+gst_asf_parse_parse_data_object (GstAsfParse * asfparse, guint8 * data,
+    gsize size)
 {
   GstByteReader *reader;
   GstFlowReturn ret = GST_FLOW_OK;
   guint64 packet_count = 0;
-  GstMapInfo map;
 
   GST_DEBUG_OBJECT (asfparse, "Parsing data object");
 
-  gst_buffer_map (buffer, &map, GST_MAP_READ);
-  reader = gst_byte_reader_new (map.data, map.size);
+  reader = gst_byte_reader_new (data, size);
   /* skip to packet count */
   if (!gst_byte_reader_skip (reader, 40))
     goto error;
@@ -150,375 +97,279 @@ gst_asf_parse_parse_data_object (GstAsfParse * asfparse, GstBuffer * buffer)
         packet_count);
   }
 
-  gst_buffer_unmap (buffer, &map);
   gst_byte_reader_free (reader);
-  return gst_asf_parse_push (asfparse, buffer);
+  return GST_FLOW_OK;
 
 error:
   ret = GST_FLOW_ERROR;
   GST_ERROR_OBJECT (asfparse, "Error while parsing data object headers");
-  gst_buffer_unmap (buffer, &map);
   gst_byte_reader_free (reader);
   return ret;
 }
 
+/* reads the next object and pushes it through without parsing */
 static GstFlowReturn
-gst_asf_parse_parse_packet (GstAsfParse * asfparse, GstBuffer * buffer)
+gst_asf_parse_handle_frame_push_object (GstAsfParse * asfparse,
+    GstBaseParseFrame * frame, gint * skipsize, const Guid * guid)
 {
-  GstAsfPacketInfo *packetinfo = asfparse->packetinfo;
+  GstBuffer *buffer = frame->buffer;
+  GstMapInfo map;
+  GstFlowReturn ret = GST_FLOW_OK;
 
-  if (!gst_asf_parse_packet (buffer, packetinfo, FALSE,
-          asfparse->asfinfo->packet_size))
-    goto error;
+  gst_buffer_map (buffer, &map, GST_MAP_READ);
+  if (map.size >= ASF_GUID_OBJSIZE_SIZE) {
+    guint64 size;
 
-  GST_DEBUG_OBJECT (asfparse, "Received packet of length %" G_GUINT32_FORMAT
-      ", padding %" G_GUINT32_FORMAT ", send time %" G_GUINT32_FORMAT
-      ", duration %" G_GUINT16_FORMAT " and %s keyframe(s)",
-      packetinfo->packet_size, packetinfo->padding,
-      packetinfo->send_time, packetinfo->duration,
-      (packetinfo->has_keyframe) ? "with" : "without");
+    size = gst_asf_match_and_peek_obj_size (map.data, guid);
 
-  /* set gstbuffer fields */
-  if (!packetinfo->has_keyframe) {
-    GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
-  }
-  GST_BUFFER_TIMESTAMP (buffer) = ((GstClockTime) packetinfo->send_time)
-      * GST_MSECOND;
-  GST_BUFFER_DURATION (buffer) = ((GstClockTime) packetinfo->duration)
-      * GST_MSECOND;
+    if (size == 0) {
+      GST_ERROR_OBJECT (asfparse, "GUID starting identifier missing");
+      ret = GST_FLOW_ERROR;
+      gst_buffer_unmap (buffer, &map);
+      goto end;
+    }
 
-  return gst_asf_parse_push (asfparse, buffer);
+    if (size > map.size) {
+      /* request all the obj data */
+      gst_base_parse_set_min_frame_size (GST_BASE_PARSE_CAST (asfparse), size);
+      gst_buffer_unmap (buffer, &map);
+      goto end;
+    }
 
-error:
-  GST_ERROR_OBJECT (asfparse, "Error while parsing data packet");
-  return GST_FLOW_ERROR;
+    gst_buffer_unmap (buffer, &map);
+
+    gst_base_parse_set_min_frame_size (GST_BASE_PARSE_CAST (asfparse),
+        ASF_GUID_OBJSIZE_SIZE);
+    gst_base_parse_finish_frame (GST_BASE_PARSE_CAST (asfparse), frame, size);
+  } else {
+    gst_buffer_unmap (buffer, &map);
+    *skipsize = 0;
+  }
+
+end:
+  return ret;
 }
 
 static GstFlowReturn
-gst_asf_parse_pull_headers (GstAsfParse * asfparse)
+gst_asf_parse_handle_frame_headers (GstAsfParse * asfparse,
+    GstBaseParseFrame * frame, gint * skipsize)
 {
-  GstBuffer *guid_and_size = NULL;
-  GstBuffer *headers = NULL;
-  guint64 size;
-  GstFlowReturn ret;
+  GstBuffer *buffer = frame->buffer;
   GstMapInfo map;
+  GstFlowReturn ret = GST_FLOW_OK;
 
-  if ((ret = gst_pad_pull_range (asfparse->sinkpad, asfparse->offset,
-              ASF_GUID_OBJSIZE_SIZE, &guid_and_size)) != GST_FLOW_OK) {
-    GST_ERROR_OBJECT (asfparse, "Failed to pull data from headers");
-    goto leave;
-  }
-  asfparse->offset += ASF_GUID_OBJSIZE_SIZE;
-  gst_buffer_map (guid_and_size, &map, GST_MAP_READ);
-  size = gst_asf_match_and_peek_obj_size (map.data,
-      &(guids[ASF_HEADER_OBJECT_INDEX]));
-  gst_buffer_unmap (guid_and_size, &map);
-
-  if (size == 0) {
-    GST_ERROR_OBJECT (asfparse, "ASF starting identifier missing");
-    goto leave;
-  }
+  gst_buffer_map (buffer, &map, GST_MAP_READ);
+  if (map.size >= ASF_GUID_OBJSIZE_SIZE) {
+    guint64 size;
 
-  if ((ret = gst_pad_pull_range (asfparse->sinkpad, asfparse->offset,
-              size - ASF_GUID_OBJSIZE_SIZE, &headers)) != GST_FLOW_OK) {
-    GST_ERROR_OBJECT (asfparse, "Failed to pull data from headers");
-    goto leave;
-  }
-  headers = gst_buffer_append (guid_and_size, headers);
-  guid_and_size = NULL;
-  asfparse->offset += size - ASF_GUID_OBJSIZE_SIZE;
-  if (!gst_asf_parse_headers (headers, asfparse->asfinfo)) {
-    goto leave;
+    size = gst_asf_match_and_peek_obj_size (map.data,
+        &(guids[ASF_HEADER_OBJECT_INDEX]));
+
+    if (size == 0) {
+      GST_ERROR_OBJECT (asfparse, "ASF starting identifier missing");
+      ret = GST_FLOW_ERROR;
+      gst_buffer_unmap (buffer, &map);
+      goto end;
+    }
+
+    if (size > map.size) {
+      /* request all the obj data */
+      gst_base_parse_set_min_frame_size (GST_BASE_PARSE_CAST (asfparse), size);
+      gst_buffer_unmap (buffer, &map);
+      goto end;
+    }
+
+    if (gst_asf_parse_headers_from_data (map.data, map.size, asfparse->asfinfo)) {
+      GST_DEBUG_OBJECT (asfparse, "Successfully parsed headers");
+      asfparse->parse_state = ASF_PARSING_DATA;
+      gst_buffer_unmap (buffer, &map);
+
+      GST_INFO_OBJECT (asfparse, "Broadcast mode %s",
+          asfparse->asfinfo->broadcast ? "on" : "off");
+
+      gst_base_parse_set_min_frame_size (GST_BASE_PARSE_CAST (asfparse),
+          ASF_GUID_OBJSIZE_SIZE);
+
+      gst_pad_push_event (GST_BASE_PARSE_SRC_PAD (asfparse),
+          gst_event_new_caps (gst_caps_new_simple ("video/x-ms-asf", "parsed",
+                  G_TYPE_BOOLEAN, TRUE, NULL)));
+      gst_base_parse_finish_frame (GST_BASE_PARSE_CAST (asfparse), frame, size);
+    } else {
+      ret = GST_FLOW_ERROR;
+    }
+  } else {
+    gst_buffer_unmap (buffer, &map);
+    *skipsize = 0;
   }
-  return gst_asf_parse_push (asfparse, headers);
 
-leave:
-  if (headers)
-    gst_buffer_unref (headers);
-  if (guid_and_size)
-    gst_buffer_unref (guid_and_size);
+end:
   return ret;
 }
 
 static GstFlowReturn
-gst_asf_parse_pull_data_header (GstAsfParse * asfparse)
+gst_asf_parse_handle_frame_data_header (GstAsfParse * asfparse,
+    GstBaseParseFrame * frame, gint * skipsize)
 {
-  GstBuffer *buf = NULL;
-  GstFlowReturn ret;
+  GstBuffer *buffer = frame->buffer;
+  GstMapInfo map;
+  GstFlowReturn ret = GST_FLOW_OK;
 
-  if ((ret = gst_pad_pull_range (asfparse->sinkpad, asfparse->offset,
-              ASF_DATA_OBJECT_SIZE, &buf)) != GST_FLOW_OK) {
-    GST_ERROR_OBJECT (asfparse, "Failed to pull data header");
-    return ret;
-  }
-  asfparse->offset += ASF_DATA_OBJECT_SIZE;
-  asfparse->data_size = gst_asf_match_and_peek_obj_size_buf (buf,
-      &(guids[ASF_DATA_OBJECT_INDEX]));
-  if (asfparse->data_size == 0) {
-    GST_ERROR_OBJECT (asfparse, "Unexpected object, was expecting data object");
-    gst_buffer_unref (buf);
-    return GST_FLOW_ERROR;
+  gst_buffer_map (buffer, &map, GST_MAP_READ);
+  if (map.size >= ASF_GUID_OBJSIZE_SIZE) {
+    guint64 size;
+
+    size = gst_asf_match_and_peek_obj_size (map.data,
+        &(guids[ASF_DATA_OBJECT_INDEX]));
+
+    if (size == 0) {
+      GST_ERROR_OBJECT (asfparse, "ASF data object missing");
+      ret = GST_FLOW_ERROR;
+      gst_buffer_unmap (buffer, &map);
+      goto end;
+    }
+
+    if (ASF_DATA_OBJECT_SIZE > map.size) {
+      /* request all the obj data header size */
+      gst_base_parse_set_min_frame_size (GST_BASE_PARSE_CAST (asfparse),
+          ASF_DATA_OBJECT_SIZE);
+      gst_buffer_unmap (buffer, &map);
+      goto end;
+    }
+
+    if (gst_asf_parse_parse_data_object (asfparse, map.data,
+            map.size) == GST_FLOW_OK) {
+      GST_DEBUG_OBJECT (asfparse, "Successfully parsed data object");
+      asfparse->parse_state = ASF_PARSING_PACKETS;
+      gst_buffer_unmap (buffer, &map);
+
+      gst_base_parse_set_min_frame_size (GST_BASE_PARSE_CAST (asfparse),
+          asfparse->asfinfo->packet_size);
+
+      gst_base_parse_finish_frame (GST_BASE_PARSE_CAST (asfparse), frame,
+          ASF_DATA_OBJECT_SIZE);
+    }
+  } else {
+    gst_buffer_unmap (buffer, &map);
+    *skipsize = 0;
   }
 
-  return gst_asf_parse_parse_data_object (asfparse, buf);
+end:
+  return ret;
 }
 
 static GstFlowReturn
-gst_asf_parse_pull_packets (GstAsfParse * asfparse)
+gst_asf_parse_handle_frame_packets (GstAsfParse * asfparse,
+    GstBaseParseFrame * frame, gint * skipsize)
 {
-  GstFlowReturn ret;
-  while (asfparse->asfinfo->broadcast ||
-      asfparse->parsed_packets < asfparse->asfinfo->packets_count) {
-    GstBuffer *packet;
+  GstBuffer *buffer = frame->buffer;
+  GstMapInfo map;
+  GstFlowReturn ret = GST_FLOW_OK;
+
+  GST_LOG_OBJECT (asfparse, "Packet parsing");
+  gst_buffer_map (buffer, &map, GST_MAP_READ);
+  if (G_LIKELY (map.size >= asfparse->asfinfo->packet_size)) {
+    gst_buffer_unmap (buffer, &map);
 
     GST_DEBUG_OBJECT (asfparse, "Parsing packet %" G_GUINT64_FORMAT,
         asfparse->parsed_packets);
-
-    /* get the packet */
-    packet = NULL;
-    ret = gst_pad_pull_range (asfparse->sinkpad, asfparse->offset,
-        asfparse->asfinfo->packet_size, &packet);
-    if (ret != GST_FLOW_OK)
-      return ret;
     asfparse->parsed_packets++;
-    asfparse->offset += asfparse->asfinfo->packet_size;
+    gst_base_parse_finish_frame (GST_BASE_PARSE_CAST (asfparse), frame,
+        asfparse->asfinfo->packet_size);
+
+    /* test if all packets have been processed */
+    if (G_UNLIKELY (!asfparse->asfinfo->broadcast &&
+            asfparse->parsed_packets == asfparse->asfinfo->packets_count)) {
+      GST_INFO_OBJECT (asfparse,
+          "All %" G_GUINT64_FORMAT " packets processed",
+          asfparse->parsed_packets);
+      asfparse->parse_state = ASF_PARSING_INDEXES;
+      gst_base_parse_set_min_frame_size (GST_BASE_PARSE_CAST (asfparse),
+          ASF_GUID_OBJSIZE_SIZE);
+    }
 
-    /* parse the packet */
-    ret = gst_asf_parse_parse_packet (asfparse, packet);
-    if (ret != GST_FLOW_OK)
-      return ret;
+  } else {
+    gst_base_parse_set_min_frame_size (GST_BASE_PARSE_CAST (asfparse),
+        asfparse->asfinfo->packet_size);
+    gst_buffer_unmap (buffer, &map);
+    *skipsize = 0;
   }
-  return GST_FLOW_OK;
+
+  return ret;
 }
 
 static GstFlowReturn
-gst_asf_parse_pull_indexes (GstAsfParse * asfparse)
+gst_asf_parse_handle_frame_indexes (GstAsfParse * asfparse,
+    GstBaseParseFrame * frame, gint * skipsize)
 {
-  GstBuffer *guid_and_size;
-  GstBuffer *buf;
-  guint64 obj_size;
-  GstFlowReturn ret = GST_FLOW_OK;
-  while (1) {
-    guid_and_size = NULL;
-    ret = gst_pad_pull_range (asfparse->sinkpad, asfparse->offset,
-        ASF_GUID_OBJSIZE_SIZE, &guid_and_size);
-    if (ret != GST_FLOW_OK)
-      break;
-    /* we can peek at the object size */
-    obj_size = gst_asf_match_and_peek_obj_size_buf (guid_and_size, NULL);
-    if (obj_size == 0) {
-      GST_ERROR_OBJECT (asfparse, "Incomplete object found");
-      gst_buffer_unref (guid_and_size);
-      ret = GST_FLOW_ERROR;
-      break;
-    }
-    asfparse->offset += ASF_GUID_OBJSIZE_SIZE;
-
-    /* pull the rest of the object */
-    buf = NULL;
-    ret = gst_pad_pull_range (asfparse->sinkpad, asfparse->offset, obj_size,
-        &buf);
-    if (ret != GST_FLOW_OK) {
-      gst_buffer_unref (guid_and_size);
-      break;
-    }
-    asfparse->offset += obj_size - ASF_GUID_OBJSIZE_SIZE;
-
-    buf = gst_buffer_append (guid_and_size, buf);
-    ret = gst_asf_parse_push (asfparse, buf);
-    if (ret != GST_FLOW_OK)
-      break;
-  }
-  return ret;
+  /* don't care about indexes, just push them forward */
+  return gst_asf_parse_handle_frame_push_object (asfparse, frame, skipsize,
+      NULL);
 }
 
-static void
-gst_asf_parse_loop (GstPad * pad)
+
+static GstFlowReturn
+gst_asf_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize)
 {
-  GstFlowReturn ret = GST_FLOW_OK;
-  GstAsfParse *asfparse = GST_ASF_PARSE_CAST (GST_OBJECT_PARENT (pad));
+  GstAsfParse *asfparse = GST_ASF_PARSE_CAST (parse);
 
-  GST_LOG_OBJECT (asfparse, "Processing data in loop function");
   switch (asfparse->parse_state) {
     case ASF_PARSING_HEADERS:
-      GST_INFO_OBJECT (asfparse, "Starting to parse headers");
-      ret = gst_asf_parse_pull_headers (asfparse);
-      if (ret != GST_FLOW_OK)
-        goto pause;
-      asfparse->parse_state = ASF_PARSING_DATA;
-
+      return gst_asf_parse_handle_frame_headers (asfparse, frame, skipsize);
     case ASF_PARSING_DATA:
-      GST_INFO_OBJECT (asfparse, "Parsing data object headers");
-      ret = gst_asf_parse_pull_data_header (asfparse);
-      if (ret != GST_FLOW_OK)
-        goto pause;
-      asfparse->parse_state = ASF_PARSING_PACKETS;
-
+      return gst_asf_parse_handle_frame_data_header (asfparse, frame, skipsize);
     case ASF_PARSING_PACKETS:
-      GST_INFO_OBJECT (asfparse, "Starting packet parsing");
-      GST_INFO_OBJECT (asfparse, "Broadcast mode %s",
-          asfparse->asfinfo->broadcast ? "on" : "off");
-      ret = gst_asf_parse_pull_packets (asfparse);
-      if (ret != GST_FLOW_OK)
-        goto pause;
-
-      /* test if all packets have been processed */
-      if (!asfparse->asfinfo->broadcast &&
-          asfparse->parsed_packets == asfparse->asfinfo->packets_count) {
-        GST_INFO_OBJECT (asfparse,
-            "All %" G_GUINT64_FORMAT " packets processed",
-            asfparse->parsed_packets);
-        asfparse->parse_state = ASF_PARSING_INDEXES;
-      }
-
+      return gst_asf_parse_handle_frame_packets (asfparse, frame, skipsize);
     case ASF_PARSING_INDEXES:
-      /* we currently don't care about indexes, so just push them forward */
-      GST_INFO_OBJECT (asfparse, "Starting indexes parsing");
-      ret = gst_asf_parse_pull_indexes (asfparse);
-      if (ret != GST_FLOW_OK)
-        goto pause;
+      return gst_asf_parse_handle_frame_indexes (asfparse, frame, skipsize);
     default:
       break;
   }
 
-pause:
-  {
-    const gchar *reason = gst_flow_get_name (ret);
-
-    GST_INFO_OBJECT (asfparse, "Pausing sinkpad task");
-    gst_pad_pause_task (pad);
-
-    if (ret == GST_FLOW_EOS) {
-      gst_pad_push_event (asfparse->srcpad, gst_event_new_eos ());
-    } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
-      GST_ELEMENT_ERROR (asfparse, STREAM, FAILED,
-          (NULL), ("streaming task paused, reason %s (%d)", reason, ret));
-      gst_pad_push_event (asfparse->srcpad, gst_event_new_eos ());
-    }
-  }
+  g_assert_not_reached ();
+  return GST_FLOW_ERROR;
 }
 
+
+#if 0
 static GstFlowReturn
-gst_asf_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
+gst_asf_parse_parse_packet (GstAsfParse * asfparse, GstBuffer * buffer)
 {
-  GstAsfParse *asfparse;
-  GstFlowReturn ret = GST_FLOW_OK;
+  GstAsfPacketInfo *packetinfo = asfparse->packetinfo;
 
-  asfparse = GST_ASF_PARSE (parent);
-  gst_adapter_push (asfparse->adapter, buffer);
+  if (!gst_asf_parse_packet (buffer, packetinfo, FALSE,
+          asfparse->asfinfo->packet_size))
+    goto error;
 
-  switch (asfparse->parse_state) {
-    case ASF_PARSING_HEADERS:
-      if (asfparse->headers_size == 0 &&
-          gst_adapter_available (asfparse->adapter) >= ASF_GUID_OBJSIZE_SIZE) {
-
-        /* we can peek at the object size */
-        asfparse->headers_size =
-            gst_asf_match_and_peek_obj_size (gst_adapter_map
-            (asfparse->adapter, ASF_GUID_OBJSIZE_SIZE),
-            &(guids[ASF_HEADER_OBJECT_INDEX]));
-        gst_adapter_unmap (asfparse->adapter);
-
-        if (asfparse->headers_size == 0) {
-          /* something is wrong, this probably ain't an ASF stream */
-          GST_ERROR_OBJECT (asfparse, "ASF starting identifier missing");
-          ret = GST_FLOW_ERROR;
-          goto end;
-        }
-      }
-      if (gst_adapter_available (asfparse->adapter) >= asfparse->headers_size) {
-        GstBuffer *headers = gst_adapter_take_buffer (asfparse->adapter,
-            asfparse->headers_size);
-        if (gst_asf_parse_headers (headers, asfparse->asfinfo)) {
-          ret = gst_asf_parse_push (asfparse, headers);
-          asfparse->parse_state = ASF_PARSING_DATA;
-        } else {
-          ret = GST_FLOW_ERROR;
-          GST_ERROR_OBJECT (asfparse, "Failed to parse headers");
-        }
-      }
-      break;
-    case ASF_PARSING_DATA:
-      if (asfparse->data_size == 0 &&
-          gst_adapter_available (asfparse->adapter) >= ASF_GUID_OBJSIZE_SIZE) {
-
-        /* we can peek at the object size */
-        asfparse->data_size =
-            gst_asf_match_and_peek_obj_size (gst_adapter_map
-            (asfparse->adapter, ASF_GUID_OBJSIZE_SIZE),
-            &(guids[ASF_DATA_OBJECT_INDEX]));
-        gst_adapter_unmap (asfparse->adapter);
-
-        if (asfparse->data_size == 0) {
-          /* something is wrong */
-          GST_ERROR_OBJECT (asfparse, "Unexpected object after headers, was "
-              "expecting a data object");
-          ret = GST_FLOW_ERROR;
-          goto end;
-        }
-      }
-      /* if we have received the full data object headers */
-      if (gst_adapter_available (asfparse->adapter) >= ASF_DATA_OBJECT_SIZE) {
-        ret = gst_asf_parse_parse_data_object (asfparse,
-            gst_adapter_take_buffer (asfparse->adapter, ASF_DATA_OBJECT_SIZE));
-        if (ret != GST_FLOW_OK) {
-          goto end;
-        }
-        asfparse->parse_state = ASF_PARSING_PACKETS;
-      }
-      break;
-    case ASF_PARSING_PACKETS:
-      g_assert (asfparse->asfinfo->packet_size);
-      while ((asfparse->asfinfo->broadcast ||
-              asfparse->parsed_packets < asfparse->asfinfo->packets_count) &&
-          gst_adapter_available (asfparse->adapter) >=
-          asfparse->asfinfo->packet_size) {
-        GstBuffer *packet = gst_adapter_take_buffer (asfparse->adapter,
-            asfparse->asfinfo->packet_size);
-        asfparse->parsed_packets++;
-        ret = gst_asf_parse_parse_packet (asfparse, packet);
-        if (ret != GST_FLOW_OK)
-          goto end;
-      }
-      if (!asfparse->asfinfo->broadcast &&
-          asfparse->parsed_packets >= asfparse->asfinfo->packets_count) {
-        GST_INFO_OBJECT (asfparse, "Finished parsing packets");
-        asfparse->parse_state = ASF_PARSING_INDEXES;
-      }
-      break;
-    case ASF_PARSING_INDEXES:
-      /* we currently don't care about any of those objects */
-      if (gst_adapter_available (asfparse->adapter) >= ASF_GUID_OBJSIZE_SIZE) {
-        guint64 obj_size;
-        /* we can peek at the object size */
-        obj_size = gst_asf_match_and_peek_obj_size (gst_adapter_map
-            (asfparse->adapter, ASF_GUID_OBJSIZE_SIZE), NULL);
-        gst_adapter_unmap (asfparse->adapter);
-        if (gst_adapter_available (asfparse->adapter) >= obj_size) {
-          GST_DEBUG_OBJECT (asfparse, "Skiping object");
-          ret = gst_asf_parse_push (asfparse,
-              gst_adapter_take_buffer (asfparse->adapter, obj_size));
-          if (ret != GST_FLOW_OK) {
-            goto end;
-          }
-        }
-      }
-      break;
-    default:
-      break;
+  GST_DEBUG_OBJECT (asfparse, "Received packet of length %" G_GUINT32_FORMAT
+      ", padding %" G_GUINT32_FORMAT ", send time %" G_GUINT32_FORMAT
+      ", duration %" G_GUINT16_FORMAT " and %s keyframe(s)",
+      packetinfo->packet_size, packetinfo->padding,
+      packetinfo->send_time, packetinfo->duration,
+      (packetinfo->has_keyframe) ? "with" : "without");
+
+  /* set gstbuffer fields */
+  if (!packetinfo->has_keyframe) {
+    GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
   }
+  GST_BUFFER_TIMESTAMP (buffer) = ((GstClockTime) packetinfo->send_time)
+      * GST_MSECOND;
+  GST_BUFFER_DURATION (buffer) = ((GstClockTime) packetinfo->duration)
+      * GST_MSECOND;
 
-end:
-  return ret;
+  return gst_asf_parse_push (asfparse, buffer);
+
+error:
+  GST_ERROR_OBJECT (asfparse, "Error while parsing data packet");
+  return GST_FLOW_ERROR;
 }
 
+#endif
+
 static void
 gst_asf_parse_finalize (GObject * object)
 {
   GstAsfParse *asfparse = GST_ASF_PARSE (object);
-  gst_adapter_clear (asfparse->adapter);
-  g_object_unref (G_OBJECT (asfparse->adapter));
-  gst_caps_unref (asfparse->outcaps);
   gst_asf_file_info_free (asfparse->asfinfo);
   g_free (asfparse->packetinfo);
   G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -529,16 +380,17 @@ gst_asf_parse_class_init (GstAsfParseClass * klass)
 {
   GObjectClass *gobject_class;
   GstElementClass *gstelement_class;
+  GstBaseParseClass *gstbaseparse_class;
 
   gobject_class = (GObjectClass *) klass;
   gstelement_class = (GstElementClass *) klass;
-
-  parent_class = g_type_class_peek_parent (klass);
+  gstbaseparse_class = (GstBaseParseClass *) klass;
 
   gobject_class->finalize = gst_asf_parse_finalize;
 
-  gstelement_class->change_state =
-      GST_DEBUG_FUNCPTR (gst_asf_parse_change_state);
+  gstbaseparse_class->start = gst_asf_parse_start;
+  gstbaseparse_class->stop = gst_asf_parse_stop;
+  gstbaseparse_class->handle_frame = gst_asf_parse_handle_frame;
 
   gst_element_class_add_pad_template (gstelement_class,
       gst_static_pad_template_get (&src_factory));
@@ -555,62 +407,8 @@ gst_asf_parse_class_init (GstAsfParseClass * klass)
 static void
 gst_asf_parse_init (GstAsfParse * asfparse)
 {
-  asfparse->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
-  gst_pad_set_chain_function (asfparse->sinkpad, gst_asf_parse_chain);
-  gst_pad_set_activate_function (asfparse->sinkpad,
-      gst_asf_parse_sink_activate);
-  gst_pad_set_activatemode_function (asfparse->sinkpad,
-      gst_asf_parse_sink_activate_mode);
-  gst_element_add_pad (GST_ELEMENT (asfparse), asfparse->sinkpad);
-
-  asfparse->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
-  gst_pad_use_fixed_caps (asfparse->srcpad);
-  gst_element_add_pad (GST_ELEMENT (asfparse), asfparse->srcpad);
-
-  asfparse->adapter = gst_adapter_new ();
-  asfparse->outcaps = gst_caps_new_empty_simple ("video/x-ms-asf");
   asfparse->asfinfo = gst_asf_file_info_new ();
   asfparse->packetinfo = g_new0 (GstAsfPacketInfo, 1);
-  gst_asf_parse_reset (asfparse);
-}
-
-static GstStateChangeReturn
-gst_asf_parse_change_state (GstElement * element, GstStateChange transition)
-{
-  GstAsfParse *asfparse;
-  GstStateChangeReturn ret;
-
-  asfparse = GST_ASF_PARSE (element);
-
-  switch (transition) {
-    case GST_STATE_CHANGE_READY_TO_PAUSED:
-      gst_asf_parse_reset (asfparse);
-      break;
-    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
-      break;
-    case GST_STATE_CHANGE_PAUSED_TO_READY:
-      break;
-    default:
-      break;
-  }
-
-  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-  if (ret == GST_STATE_CHANGE_FAILURE)
-    goto done;
-
-  switch (transition) {
-    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
-      break;
-    case GST_STATE_CHANGE_PAUSED_TO_READY:
-      break;
-    case GST_STATE_CHANGE_READY_TO_NULL:
-      break;
-    default:
-      break;
-  }
-
-done:
-  return ret;
 }
 
 gboolean
index 95c7f47..f01dd26 100644 (file)
@@ -23,6 +23,7 @@
 
 
 #include <gst/gst.h>
+#include <gst/base/gstbaseparse.h>
 #include <gst/base/gstadapter.h>
 #include <gst/base/gstbytereader.h>
 
@@ -54,29 +55,19 @@ typedef struct _GstAsfParse GstAsfParse;
 typedef struct _GstAsfParseClass GstAsfParseClass;
 
 struct _GstAsfParse {
-  GstElement element;
+  GstBaseParse baseparse;
 
   enum GstAsfParsingState parse_state;
 
-  GstAdapter *adapter;
-
-  GstPad *srcpad;
-  GstPad *sinkpad;
-  GstCaps *outcaps;
-
   guint64 parsed_packets;
 
-  guint64 offset; /* used in pull mode */
-
   /* parsed info */
   GstAsfFileInfo *asfinfo;
-  GstAsfPacketInfo *packetinfo; /* we keep it here to avoid allocs */
-  guint64 headers_size;
-  guint64 data_size;
+  GstAsfPacketInfo *packetinfo;
 };
 
 struct _GstAsfParseClass {
-  GstElementClass parent_class;
+  GstBaseParseClass parent_class;
 };
 
 GType gst_asf_parse_get_type(void);