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
This commit is contained in:
parent
6cf1f629a3
commit
04134671c9
@ -761,26 +761,36 @@ gst_asf_parse_file_properties_obj (GstByteReader * reader,
|
|||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_asf_parse_headers (GstBuffer * buffer, GstAsfFileInfo * file_info)
|
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;
|
gboolean ret = TRUE;
|
||||||
guint32 header_objects = 0;
|
guint32 header_objects = 0;
|
||||||
guint32 i;
|
guint32 i;
|
||||||
GstByteReader *reader;
|
GstByteReader *reader;
|
||||||
guint64 object_size;
|
guint64 object_size;
|
||||||
GstMapInfo map;
|
|
||||||
|
|
||||||
gst_buffer_map (buffer, &map, GST_MAP_READ);
|
object_size = gst_asf_match_and_peek_obj_size (data,
|
||||||
|
|
||||||
object_size = gst_asf_match_and_peek_obj_size (map.data,
|
|
||||||
&(guids[ASF_HEADER_OBJECT_INDEX]));
|
&(guids[ASF_HEADER_OBJECT_INDEX]));
|
||||||
if (object_size == 0) {
|
if (object_size == 0) {
|
||||||
GST_WARNING ("ASF: Cannot parse, header guid not found at the beginning "
|
GST_WARNING ("ASF: Cannot parse, header guid not found at the beginning "
|
||||||
" of data");
|
" of data");
|
||||||
gst_buffer_unmap (buffer, &map);
|
|
||||||
return FALSE;
|
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))
|
if (!gst_byte_reader_skip (reader, ASF_GUID_OBJSIZE_SIZE))
|
||||||
goto error;
|
goto error;
|
||||||
@ -818,7 +828,6 @@ error:
|
|||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
GST_WARNING ("ASF: Error while parsing headers");
|
GST_WARNING ("ASF: Error while parsing headers");
|
||||||
end:
|
end:
|
||||||
gst_buffer_unmap (buffer, &map);
|
|
||||||
gst_byte_reader_free (reader);
|
gst_byte_reader_free (reader);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -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,
|
guint64 gst_asf_match_and_peek_obj_size_buf (GstBuffer * buf,
|
||||||
const Guid * guid);
|
const Guid * guid);
|
||||||
gboolean gst_asf_parse_headers (GstBuffer * buffer, GstAsfFileInfo * file_info);
|
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
|
/* ASF tags
|
||||||
* found at http://msdn.microsoft.com/en-us/library/dd562330(VS.85).aspx
|
* found at http://msdn.microsoft.com/en-us/library/dd562330(VS.85).aspx
|
||||||
|
@ -42,99 +42,46 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
|
|||||||
GST_STATIC_CAPS ("video/x-ms-asf, parsed = (boolean) false")
|
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
|
#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
|
static gboolean
|
||||||
gst_asf_parse_reset (GstAsfParse * asfparse)
|
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);
|
gst_asf_file_info_reset (asfparse->asfinfo);
|
||||||
asfparse->parse_state = ASF_PARSING_HEADERS;
|
asfparse->parse_state = ASF_PARSING_HEADERS;
|
||||||
asfparse->headers_size = 0;
|
|
||||||
asfparse->data_size = 0;
|
|
||||||
asfparse->parsed_packets = 0;
|
asfparse->parsed_packets = 0;
|
||||||
asfparse->offset = 0;
|
|
||||||
|
/* ASF Obj header length */
|
||||||
|
gst_base_parse_set_min_frame_size (GST_BASE_PARSE_CAST (asfparse),
|
||||||
|
ASF_GUID_OBJSIZE_SIZE);
|
||||||
|
|
||||||
|
gst_base_parse_set_syncable (GST_BASE_PARSE_CAST (asfparse), FALSE);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_asf_parse_sink_activate (GstPad * sinkpad, GstObject * parent)
|
gst_asf_parse_stop (GstBaseParse * parse)
|
||||||
{
|
{
|
||||||
GstQuery *query;
|
GstAsfParse *asfparse = GST_ASF_PARSE_CAST (parse);
|
||||||
gboolean pull_mode;
|
gst_asf_file_info_reset (asfparse->asfinfo);
|
||||||
|
|
||||||
query = gst_query_new_scheduling ();
|
return TRUE;
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_asf_parse_sink_activate_mode (GstPad * pad, GstObject * parent,
|
|
||||||
GstPadMode mode, gboolean active)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_asf_parse_push (GstAsfParse * asfparse, GstBuffer * buf)
|
gst_asf_parse_parse_data_object (GstAsfParse * asfparse, guint8 * data,
|
||||||
{
|
gsize size)
|
||||||
return gst_pad_push (asfparse->srcpad, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstFlowReturn
|
|
||||||
gst_asf_parse_parse_data_object (GstAsfParse * asfparse, GstBuffer * buffer)
|
|
||||||
{
|
{
|
||||||
GstByteReader *reader;
|
GstByteReader *reader;
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
guint64 packet_count = 0;
|
guint64 packet_count = 0;
|
||||||
GstMapInfo map;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (asfparse, "Parsing data object");
|
GST_DEBUG_OBJECT (asfparse, "Parsing data object");
|
||||||
|
|
||||||
gst_buffer_map (buffer, &map, GST_MAP_READ);
|
reader = gst_byte_reader_new (data, size);
|
||||||
reader = gst_byte_reader_new (map.data, map.size);
|
|
||||||
/* skip to packet count */
|
/* skip to packet count */
|
||||||
if (!gst_byte_reader_skip (reader, 40))
|
if (!gst_byte_reader_skip (reader, 40))
|
||||||
goto error;
|
goto error;
|
||||||
@ -150,18 +97,241 @@ gst_asf_parse_parse_data_object (GstAsfParse * asfparse, GstBuffer * buffer)
|
|||||||
packet_count);
|
packet_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_buffer_unmap (buffer, &map);
|
|
||||||
gst_byte_reader_free (reader);
|
gst_byte_reader_free (reader);
|
||||||
return gst_asf_parse_push (asfparse, buffer);
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
ret = GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
GST_ERROR_OBJECT (asfparse, "Error while parsing data object headers");
|
GST_ERROR_OBJECT (asfparse, "Error while parsing data object headers");
|
||||||
gst_buffer_unmap (buffer, &map);
|
|
||||||
gst_byte_reader_free (reader);
|
gst_byte_reader_free (reader);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* reads the next object and pushes it through without parsing */
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_asf_parse_handle_frame_push_object (GstAsfParse * asfparse,
|
||||||
|
GstBaseParseFrame * frame, gint * skipsize, const Guid * guid)
|
||||||
|
{
|
||||||
|
GstBuffer *buffer = frame->buffer;
|
||||||
|
GstMapInfo map;
|
||||||
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
|
||||||
|
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, guid);
|
||||||
|
|
||||||
|
if (size == 0) {
|
||||||
|
GST_ERROR_OBJECT (asfparse, "GUID 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_handle_frame_headers (GstAsfParse * asfparse,
|
||||||
|
GstBaseParseFrame * frame, gint * skipsize)
|
||||||
|
{
|
||||||
|
GstBuffer *buffer = frame->buffer;
|
||||||
|
GstMapInfo map;
|
||||||
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
|
||||||
|
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_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_asf_parse_handle_frame_data_header (GstAsfParse * asfparse,
|
||||||
|
GstBaseParseFrame * frame, gint * skipsize)
|
||||||
|
{
|
||||||
|
GstBuffer *buffer = frame->buffer;
|
||||||
|
GstMapInfo map;
|
||||||
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_asf_parse_handle_frame_packets (GstAsfParse * asfparse,
|
||||||
|
GstBaseParseFrame * frame, gint * skipsize)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
asfparse->parsed_packets++;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
} 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 ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_asf_parse_handle_frame_indexes (GstAsfParse * asfparse,
|
||||||
|
GstBaseParseFrame * frame, gint * skipsize)
|
||||||
|
{
|
||||||
|
/* don't care about indexes, just push them forward */
|
||||||
|
return gst_asf_parse_handle_frame_push_object (asfparse, frame, skipsize,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_asf_parse_handle_frame (GstBaseParse * parse,
|
||||||
|
GstBaseParseFrame * frame, gint * skipsize)
|
||||||
|
{
|
||||||
|
GstAsfParse *asfparse = GST_ASF_PARSE_CAST (parse);
|
||||||
|
|
||||||
|
switch (asfparse->parse_state) {
|
||||||
|
case ASF_PARSING_HEADERS:
|
||||||
|
return gst_asf_parse_handle_frame_headers (asfparse, frame, skipsize);
|
||||||
|
case ASF_PARSING_DATA:
|
||||||
|
return gst_asf_parse_handle_frame_data_header (asfparse, frame, skipsize);
|
||||||
|
case ASF_PARSING_PACKETS:
|
||||||
|
return gst_asf_parse_handle_frame_packets (asfparse, frame, skipsize);
|
||||||
|
case ASF_PARSING_INDEXES:
|
||||||
|
return gst_asf_parse_handle_frame_indexes (asfparse, frame, skipsize);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert_not_reached ();
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_asf_parse_parse_packet (GstAsfParse * asfparse, GstBuffer * buffer)
|
gst_asf_parse_parse_packet (GstAsfParse * asfparse, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
@ -194,331 +364,12 @@ error:
|
|||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
#endif
|
||||||
gst_asf_parse_pull_headers (GstAsfParse * asfparse)
|
|
||||||
{
|
|
||||||
GstBuffer *guid_and_size = NULL;
|
|
||||||
GstBuffer *headers = NULL;
|
|
||||||
guint64 size;
|
|
||||||
GstFlowReturn ret;
|
|
||||||
GstMapInfo map;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
return gst_asf_parse_push (asfparse, headers);
|
|
||||||
|
|
||||||
leave:
|
|
||||||
if (headers)
|
|
||||||
gst_buffer_unref (headers);
|
|
||||||
if (guid_and_size)
|
|
||||||
gst_buffer_unref (guid_and_size);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstFlowReturn
|
|
||||||
gst_asf_parse_pull_data_header (GstAsfParse * asfparse)
|
|
||||||
{
|
|
||||||
GstBuffer *buf = NULL;
|
|
||||||
GstFlowReturn ret;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return gst_asf_parse_parse_data_object (asfparse, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstFlowReturn
|
|
||||||
gst_asf_parse_pull_packets (GstAsfParse * asfparse)
|
|
||||||
{
|
|
||||||
GstFlowReturn ret;
|
|
||||||
while (asfparse->asfinfo->broadcast ||
|
|
||||||
asfparse->parsed_packets < asfparse->asfinfo->packets_count) {
|
|
||||||
GstBuffer *packet;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
/* parse the packet */
|
|
||||||
ret = gst_asf_parse_parse_packet (asfparse, packet);
|
|
||||||
if (ret != GST_FLOW_OK)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return GST_FLOW_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstFlowReturn
|
|
||||||
gst_asf_parse_pull_indexes (GstAsfParse * asfparse)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_asf_parse_loop (GstPad * pad)
|
|
||||||
{
|
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
|
||||||
GstAsfParse *asfparse = GST_ASF_PARSE_CAST (GST_OBJECT_PARENT (pad));
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
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 ());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstFlowReturn
|
|
||||||
gst_asf_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
|
|
||||||
{
|
|
||||||
GstAsfParse *asfparse;
|
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
|
||||||
|
|
||||||
asfparse = GST_ASF_PARSE (parent);
|
|
||||||
gst_adapter_push (asfparse->adapter, buffer);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_asf_parse_finalize (GObject * object)
|
gst_asf_parse_finalize (GObject * object)
|
||||||
{
|
{
|
||||||
GstAsfParse *asfparse = GST_ASF_PARSE (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);
|
gst_asf_file_info_free (asfparse->asfinfo);
|
||||||
g_free (asfparse->packetinfo);
|
g_free (asfparse->packetinfo);
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
@ -529,16 +380,17 @@ gst_asf_parse_class_init (GstAsfParseClass * klass)
|
|||||||
{
|
{
|
||||||
GObjectClass *gobject_class;
|
GObjectClass *gobject_class;
|
||||||
GstElementClass *gstelement_class;
|
GstElementClass *gstelement_class;
|
||||||
|
GstBaseParseClass *gstbaseparse_class;
|
||||||
|
|
||||||
gobject_class = (GObjectClass *) klass;
|
gobject_class = (GObjectClass *) klass;
|
||||||
gstelement_class = (GstElementClass *) klass;
|
gstelement_class = (GstElementClass *) klass;
|
||||||
|
gstbaseparse_class = (GstBaseParseClass *) klass;
|
||||||
parent_class = g_type_class_peek_parent (klass);
|
|
||||||
|
|
||||||
gobject_class->finalize = gst_asf_parse_finalize;
|
gobject_class->finalize = gst_asf_parse_finalize;
|
||||||
|
|
||||||
gstelement_class->change_state =
|
gstbaseparse_class->start = gst_asf_parse_start;
|
||||||
GST_DEBUG_FUNCPTR (gst_asf_parse_change_state);
|
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_element_class_add_pad_template (gstelement_class,
|
||||||
gst_static_pad_template_get (&src_factory));
|
gst_static_pad_template_get (&src_factory));
|
||||||
@ -555,62 +407,8 @@ gst_asf_parse_class_init (GstAsfParseClass * klass)
|
|||||||
static void
|
static void
|
||||||
gst_asf_parse_init (GstAsfParse * asfparse)
|
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->asfinfo = gst_asf_file_info_new ();
|
||||||
asfparse->packetinfo = g_new0 (GstAsfPacketInfo, 1);
|
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
|
gboolean
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
#include <gst/base/gstbaseparse.h>
|
||||||
#include <gst/base/gstadapter.h>
|
#include <gst/base/gstadapter.h>
|
||||||
#include <gst/base/gstbytereader.h>
|
#include <gst/base/gstbytereader.h>
|
||||||
|
|
||||||
@ -54,29 +55,19 @@ typedef struct _GstAsfParse GstAsfParse;
|
|||||||
typedef struct _GstAsfParseClass GstAsfParseClass;
|
typedef struct _GstAsfParseClass GstAsfParseClass;
|
||||||
|
|
||||||
struct _GstAsfParse {
|
struct _GstAsfParse {
|
||||||
GstElement element;
|
GstBaseParse baseparse;
|
||||||
|
|
||||||
enum GstAsfParsingState parse_state;
|
enum GstAsfParsingState parse_state;
|
||||||
|
|
||||||
GstAdapter *adapter;
|
|
||||||
|
|
||||||
GstPad *srcpad;
|
|
||||||
GstPad *sinkpad;
|
|
||||||
GstCaps *outcaps;
|
|
||||||
|
|
||||||
guint64 parsed_packets;
|
guint64 parsed_packets;
|
||||||
|
|
||||||
guint64 offset; /* used in pull mode */
|
|
||||||
|
|
||||||
/* parsed info */
|
/* parsed info */
|
||||||
GstAsfFileInfo *asfinfo;
|
GstAsfFileInfo *asfinfo;
|
||||||
GstAsfPacketInfo *packetinfo; /* we keep it here to avoid allocs */
|
GstAsfPacketInfo *packetinfo;
|
||||||
guint64 headers_size;
|
|
||||||
guint64 data_size;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstAsfParseClass {
|
struct _GstAsfParseClass {
|
||||||
GstElementClass parent_class;
|
GstBaseParseClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_asf_parse_get_type(void);
|
GType gst_asf_parse_get_type(void);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user