diff --git a/gst/asfmux/gstasfobjects.c b/gst/asfmux/gstasfobjects.c index df4f69c347..b9de741c6f 100644 --- a/gst/asfmux/gstasfobjects.c +++ b/gst/asfmux/gstasfobjects.c @@ -543,6 +543,21 @@ gst_asf_parse_single_payload (GstByteReader * reader, gboolean * has_keyframe) gboolean gst_asf_parse_packet (GstBuffer * buffer, GstAsfPacketInfo * packet, gboolean trust_delta_flag, guint packet_size) +{ + gboolean ret; + GstMapInfo map; + + gst_buffer_map (buffer, &map, GST_MAP_READ); + ret = gst_asf_parse_packet_from_data (map.data, map.size, buffer, packet, + trust_delta_flag, packet_size); + gst_buffer_unmap (buffer, &map); + + return ret; +} + +gboolean +gst_asf_parse_packet_from_data (guint8 * data, gsize size, GstBuffer * buffer, + GstAsfPacketInfo * packet, gboolean trust_delta_flag, guint packet_size) { /* Might be useful in future: guint8 rep_data_len_type; @@ -565,16 +580,14 @@ gst_asf_parse_packet (GstBuffer * buffer, GstAsfPacketInfo * packet, gboolean has_keyframe; GstMapInfo map; - if (packet_size != 0 && gst_buffer_get_size (buffer) != packet_size) { + if (packet_size != 0 && size != packet_size) { GST_WARNING ("ASF packets should be aligned with buffers"); return FALSE; } - gst_buffer_map (buffer, &map, GST_MAP_READ); - reader = gst_byte_reader_new (map.data, map.size); + reader = gst_byte_reader_new (data, size); - GST_LOG ("Starting packet parsing, size: %" G_GSIZE_FORMAT, - gst_buffer_get_size (buffer)); + GST_LOG ("Starting packet parsing, size: %" G_GSIZE_FORMAT, size); if (!gst_byte_reader_get_uint8 (reader, &first)) goto error; @@ -700,7 +713,6 @@ gst_asf_parse_packet (GstBuffer * buffer, GstAsfPacketInfo * packet, packet->seq_field_type = seq_len_type; packet->err_cor_len = err_length; - 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 fd8e97cac5..eea98599e7 100644 --- a/gst/asfmux/gstasfobjects.h +++ b/gst/asfmux/gstasfobjects.h @@ -110,6 +110,8 @@ guint16 gst_asf_put_subpayload (guint8 * buf, AsfPayload * payload, gboolean gst_asf_parse_packet (GstBuffer * buffer, GstAsfPacketInfo * packet, gboolean trust_delta_flag, guint packet_size); +gboolean gst_asf_parse_packet_from_data (guint8 * data, gsize size, GstBuffer * buffer, GstAsfPacketInfo * packet, + gboolean trust_delta_flag, guint packet_size); guint64 gst_asf_match_and_peek_obj_size (const guint8 * data, const Guid * guid); guint64 gst_asf_match_and_peek_obj_size_buf (GstBuffer * buf, diff --git a/gst/asfmux/gstasfparse.c b/gst/asfmux/gstasfparse.c index bd23a79218..fe869e8cb5 100644 --- a/gst/asfmux/gstasfparse.c +++ b/gst/asfmux/gstasfparse.c @@ -107,6 +107,47 @@ error: return ret; } +static GstFlowReturn +gst_asf_parse_parse_packet (GstAsfParse * asfparse, GstBaseParseFrame * frame, + GstMapInfo * map) +{ + GstBuffer *buffer = frame->buffer; + GstAsfPacketInfo *packetinfo = asfparse->packetinfo; + + /* gst_asf_parse_packet_* won't accept size larger than the packet size, so we assume + * it will always be packet_size here */ + g_return_val_if_fail (map->size >= asfparse->asfinfo->packet_size, + GST_FLOW_ERROR); + + if (!gst_asf_parse_packet_from_data (map->data, + asfparse->asfinfo->packet_size, buffer, packetinfo, FALSE, + asfparse->asfinfo->packet_size)) + goto error; + + 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; + + return GST_FLOW_OK; + +error: + GST_ERROR_OBJECT (asfparse, "Error while parsing data packet"); + return GST_FLOW_ERROR; +} + + /* reads the next object and pushes it through without parsing */ static GstFlowReturn gst_asf_parse_handle_frame_push_object (GstAsfParse * asfparse, @@ -268,25 +309,30 @@ gst_asf_parse_handle_frame_packets (GstAsfParse * asfparse, 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); + ret = gst_asf_parse_parse_packet (asfparse, frame, &map); + + gst_buffer_unmap (buffer, &map); + + if (ret == GST_FLOW_OK) { + 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); @@ -330,42 +376,6 @@ gst_asf_parse_handle_frame (GstBaseParse * parse, return GST_FLOW_ERROR; } - -#if 0 -static GstFlowReturn -gst_asf_parse_parse_packet (GstAsfParse * asfparse, GstBuffer * buffer) -{ - GstAsfPacketInfo *packetinfo = asfparse->packetinfo; - - if (!gst_asf_parse_packet (buffer, packetinfo, FALSE, - asfparse->asfinfo->packet_size)) - goto error; - - 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; - - 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) {