summaryrefslogtreecommitdiff
path: root/gst/asfmux
diff options
context:
space:
mode:
authorThiago Santos <ts.santos@sisa.samsung.com>2013-12-10 10:34:02 -0300
committerThiago Santos <ts.santos@sisa.samsung.com>2013-12-14 03:56:44 -0300
commit04134671c930cc2c6ba04d5980c4d2155b07e677 (patch)
tree6c09f89c42736bcbbdf4a8456b62872ee3df048d /gst/asfmux
parent6cf1f629a34340a2c60871b6940f5b76e27c7e5f (diff)
downloadgstreamer-plugins-bad-04134671c930cc2c6ba04d5980c4d2155b07e677.tar.gz
asfparse: port to baseparse
asfparse was not really functional after the port to 1.0 Now porting it to baseparse to get it working again
Diffstat (limited to 'gst/asfmux')
-rw-r--r--gst/asfmux/gstasfobjects.c23
-rw-r--r--gst/asfmux/gstasfobjects.h1
-rw-r--r--gst/asfmux/gstasfparse.c642
-rw-r--r--gst/asfmux/gstasfparse.h17
4 files changed, 241 insertions, 442 deletions
diff --git a/gst/asfmux/gstasfobjects.c b/gst/asfmux/gstasfobjects.c
index b8ec94d2a..df4f69c34 100644
--- a/gst/asfmux/gstasfobjects.c
+++ b/gst/asfmux/gstasfobjects.c
@@ -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;
}
diff --git a/gst/asfmux/gstasfobjects.h b/gst/asfmux/gstasfobjects.h
index 0c1e20262..fd8e97cac 100644
--- a/gst/asfmux/gstasfobjects.h
+++ b/gst/asfmux/gstasfobjects.h
@@ -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
diff --git a/gst/asfmux/gstasfparse.c b/gst/asfmux/gstasfparse.c
index 55bfe1d19..bd23a7921 100644
--- a/gst/asfmux/gstasfparse.c
+++ b/gst/asfmux/gstasfparse.c
@@ -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
diff --git a/gst/asfmux/gstasfparse.h b/gst/asfmux/gstasfparse.h
index 95c7f4763..f01dd2683 100644
--- a/gst/asfmux/gstasfparse.h
+++ b/gst/asfmux/gstasfparse.h
@@ -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);