diff options
author | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2012-03-29 17:55:09 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2012-03-29 17:55:09 +0200 |
commit | a1c291ebb65ead218d432251880ae172f28b1a1b (patch) | |
tree | 0e065c28f8b38bf0f72af33f13e729950bcd4c05 /gst | |
parent | 88b833a925c73430e8e7f76fd48e48a27db273a4 (diff) |
mpegtsdemux: Revert to 0.10 state as this is unmergeable, also put it into the non-ported plugins again
Diffstat (limited to 'gst')
-rw-r--r-- | gst/mpegtsdemux/mpegtsbase.c | 265 | ||||
-rw-r--r-- | gst/mpegtsdemux/mpegtsbase.h | 5 | ||||
-rw-r--r-- | gst/mpegtsdemux/mpegtspacketizer.c | 235 | ||||
-rw-r--r-- | gst/mpegtsdemux/mpegtspacketizer.h | 9 | ||||
-rw-r--r-- | gst/mpegtsdemux/mpegtsparse.c | 62 | ||||
-rw-r--r-- | gst/mpegtsdemux/tsdemux.c | 209 |
6 files changed, 330 insertions, 455 deletions
diff --git a/gst/mpegtsdemux/mpegtsbase.c b/gst/mpegtsdemux/mpegtsbase.c index 863c5ec19..c3741bc8d 100644 --- a/gst/mpegtsdemux/mpegtsbase.c +++ b/gst/mpegtsdemux/mpegtsbase.c @@ -81,35 +81,22 @@ static void mpegts_base_dispose (GObject * object); static void mpegts_base_finalize (GObject * object); static void mpegts_base_free_program (MpegTSBaseProgram * program); static void mpegts_base_free_stream (MpegTSBaseStream * ptream); -static gboolean mpegts_base_sink_activate (GstPad * pad, GstObject * parent); -static gboolean mpegts_base_sink_activate_mode (GstPad * pad, - GstObject * parent, GstPadMode mode, gboolean active); -static GstFlowReturn mpegts_base_chain (GstPad * pad, GstObject * parent, - GstBuffer * buf); -static gboolean mpegts_base_sink_event (GstPad * pad, GstObject * parent, - GstEvent * event); +static gboolean mpegts_base_sink_activate (GstPad * pad); +static gboolean mpegts_base_sink_activate_pull (GstPad * pad, gboolean active); +static gboolean mpegts_base_sink_activate_push (GstPad * pad, gboolean active); +static GstFlowReturn mpegts_base_chain (GstPad * pad, GstBuffer * buf); +static gboolean mpegts_base_sink_event (GstPad * pad, GstEvent * event); static GstStateChangeReturn mpegts_base_change_state (GstElement * element, GstStateChange transition); - +static void _extra_init (GType type); static void mpegts_base_get_tags_from_sdt (MpegTSBase * base, GstStructure * sdt_info); static void mpegts_base_get_tags_from_eit (MpegTSBase * base, GstStructure * eit_info); -static void -_extra_init (void) -{ - QUARK_PROGRAMS = g_quark_from_string ("programs"); - QUARK_PROGRAM_NUMBER = g_quark_from_string ("program-number"); - QUARK_PID = g_quark_from_string ("pid"); - QUARK_PCR_PID = g_quark_from_string ("pcr-pid"); - QUARK_STREAMS = g_quark_from_string ("streams"); - QUARK_STREAM_TYPE = g_quark_from_string ("stream-type"); -} +GST_BOILERPLATE_FULL (MpegTSBase, mpegts_base, GstElement, GST_TYPE_ELEMENT, + _extra_init); -#define mpegts_base_parent_class parent_class -G_DEFINE_TYPE_WITH_CODE (MpegTSBase, mpegts_base, GST_TYPE_ELEMENT, - _extra_init ()); static const guint32 crc_tab[256] = { 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, @@ -171,6 +158,25 @@ mpegts_base_calc_crc32 (guint8 * data, guint datalen) } static void +_extra_init (GType type) +{ + QUARK_PROGRAMS = g_quark_from_string ("programs"); + QUARK_PROGRAM_NUMBER = g_quark_from_string ("program-number"); + QUARK_PID = g_quark_from_string ("pid"); + QUARK_PCR_PID = g_quark_from_string ("pcr-pid"); + QUARK_STREAMS = g_quark_from_string ("streams"); + QUARK_STREAM_TYPE = g_quark_from_string ("stream-type"); +} + +static void +mpegts_base_base_init (gpointer klass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_add_static_pad_template (element_class, &sink_template); +} + +static void mpegts_base_class_init (MpegTSBaseClass * klass) { GObjectClass *gobject_class; @@ -179,14 +185,12 @@ mpegts_base_class_init (MpegTSBaseClass * klass) element_class = GST_ELEMENT_CLASS (klass); element_class->change_state = mpegts_base_change_state; - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_template)); - gobject_class = G_OBJECT_CLASS (klass); gobject_class->set_property = mpegts_base_set_property; gobject_class->get_property = mpegts_base_get_property; gobject_class->dispose = mpegts_base_dispose; gobject_class->finalize = mpegts_base_finalize; + } static void @@ -222,20 +226,19 @@ mpegts_base_reset (MpegTSBase * base) base->upstream_live = FALSE; base->queried_latency = FALSE; - base->upstream_live = FALSE; - base->query_latency = FALSE; - if (klass->reset) klass->reset (base); } static void -mpegts_base_init (MpegTSBase * base) +mpegts_base_init (MpegTSBase * base, MpegTSBaseClass * klass) { base->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink"); gst_pad_set_activate_function (base->sinkpad, mpegts_base_sink_activate); - gst_pad_set_activatemode_function (base->sinkpad, - mpegts_base_sink_activate_mode); + gst_pad_set_activatepull_function (base->sinkpad, + mpegts_base_sink_activate_pull); + gst_pad_set_activatepush_function (base->sinkpad, + mpegts_base_sink_activate_push); gst_pad_set_chain_function (base->sinkpad, mpegts_base_chain); gst_pad_set_event_function (base->sinkpad, mpegts_base_sink_event); gst_element_add_pad (GST_ELEMENT (base), base->sinkpad); @@ -486,30 +489,21 @@ mpegts_base_free_program (MpegTSBaseProgram * program) /* FIXME : This is being called by tsdemux::find_timestamps() * We need to avoid re-entrant code like that */ -static gboolean -mpegts_base_stop_program (MpegTSBase * base, MpegTSBaseProgram * program) -{ - MpegTSBaseClass *klass = GST_MPEGTS_BASE_GET_CLASS (base); - - GST_DEBUG_OBJECT (base, "program_number : %d", program->program_number); - - if (klass->program_stopped) - klass->program_stopped (base, program); - - return TRUE; -} - void mpegts_base_remove_program (MpegTSBase * base, gint program_number) { MpegTSBaseProgram *program; + MpegTSBaseClass *klass = GST_MPEGTS_BASE_GET_CLASS (base); - program = - (MpegTSBaseProgram *) g_hash_table_lookup (base->programs, - GINT_TO_POINTER (program_number)); - if (program) - mpegts_base_stop_program (base, program); + GST_DEBUG_OBJECT (base, "program_number : %d", program_number); + if (klass->program_stopped) { + program = + (MpegTSBaseProgram *) g_hash_table_lookup (base->programs, + GINT_TO_POINTER (program_number)); + if (program) + klass->program_stopped (base, program); + } g_hash_table_remove (base->programs, GINT_TO_POINTER (program_number)); } @@ -1056,15 +1050,11 @@ mpegts_base_handle_psi (MpegTSBase * base, MpegTSPacketizerSection * section) /* table ids 0x70 - 0x73 do not have a crc */ if (G_LIKELY (section->table_id < 0x70 || section->table_id > 0x73)) { - GstMapInfo map; - - gst_buffer_map (section->buffer, &map, GST_MAP_READ); - if (G_UNLIKELY (mpegts_base_calc_crc32 (map.data, map.size) != 0)) { - gst_buffer_unmap (section->buffer, &map); + if (G_UNLIKELY (mpegts_base_calc_crc32 (GST_BUFFER_DATA (section->buffer), + GST_BUFFER_SIZE (section->buffer)) != 0)) { GST_WARNING_OBJECT (base, "bad crc in psi pid 0x%x", section->pid); return FALSE; } - gst_buffer_unmap (section->buffer, &map); } switch (section->table_id) { @@ -1199,7 +1189,7 @@ mpegts_base_get_tags_from_sdt (MpegTSBase * base, GstStructure * sdt_info) program = mpegts_base_get_program (base, program_number); if (program && !program->tags) { - program->tags = gst_tag_list_new (GST_TAG_ARTIST, + program->tags = gst_tag_list_new_full (GST_TAG_ARTIST, gst_structure_get_string (service, "name"), NULL); } } @@ -1240,33 +1230,27 @@ mpegts_base_get_tags_from_eit (MpegTSBase * base, GstStructure * eit_info) gst_structure_get_uint (event, "duration", &duration); program->event_id = event_id; - program->tags = gst_tag_list_new (GST_TAG_TITLE, + program->tags = gst_tag_list_new_full (GST_TAG_TITLE, title, GST_TAG_DURATION, duration * GST_SECOND, NULL); } } } } -static gboolean +static void remove_each_program (gpointer key, MpegTSBaseProgram * program, MpegTSBase * base) { /* First deactivate it */ mpegts_base_deactivate_program (base, program); - - /* Then stop it */ - mpegts_base_stop_program (base, program); - - /* And tell _foreach_remove() to remove it */ - return TRUE; + /* Then remove it */ + mpegts_base_remove_program (base, program->program_number); } static gboolean gst_mpegts_base_handle_eos (MpegTSBase * base) { - g_hash_table_foreach_remove (base->programs, (GHRFunc) remove_each_program, - base); - + g_hash_table_foreach (base->programs, (GHFunc) remove_each_program, base); /* finally remove */ return TRUE; } @@ -1284,27 +1268,37 @@ mpegts_base_flush (MpegTSBase * base) } static gboolean -mpegts_base_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) +mpegts_base_sink_event (GstPad * pad, GstEvent * event) { gboolean res = TRUE; - MpegTSBase *base = GST_MPEGTS_BASE (parent); + MpegTSBase *base = GST_MPEGTS_BASE (gst_object_get_parent (GST_OBJECT (pad))); GST_WARNING_OBJECT (base, "Got event %s", gst_event_type_get_name (GST_EVENT_TYPE (event))); switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEGMENT: - gst_event_copy_segment (event, &base->segment); - + case GST_EVENT_NEWSEGMENT: + { + gboolean update; + gdouble rate, applied_rate; + GstFormat format; + gint64 start, stop, position; + + gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate, + &format, &start, &stop, &position); + GST_DEBUG_OBJECT (base, + "Segment update:%d, rate:%f, applied_rate:%f, format:%s", update, + rate, applied_rate, gst_format_get_name (format)); + GST_DEBUG_OBJECT (base, + " start:%" G_GINT64_FORMAT ", stop:%" G_GINT64_FORMAT + ", position:%" G_GINT64_FORMAT, start, stop, position); + gst_segment_set_newsegment_full (&base->segment, update, rate, + applied_rate, format, start, stop, position); gst_event_unref (event); + } break; case GST_EVENT_EOS: res = gst_mpegts_base_handle_eos (base); - gst_event_unref (event); - break; - case GST_EVENT_CAPS: - /* FIXME, do something */ - gst_event_unref (event); break; case GST_EVENT_FLUSH_START: mpegts_packetizer_flush (base->packetizer); @@ -1321,7 +1315,7 @@ mpegts_base_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) gst_event_unref (event); } - GST_DEBUG ("Returning %d", res); + gst_object_unref (base); return res; } @@ -1357,7 +1351,7 @@ mpegts_base_push (MpegTSBase * base, MpegTSPacketizerPacket * packet, } static GstFlowReturn -mpegts_base_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) +mpegts_base_chain (GstPad * pad, GstBuffer * buf) { GstFlowReturn res = GST_FLOW_OK; MpegTSBase *base; @@ -1366,7 +1360,7 @@ mpegts_base_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) MpegTSPacketizer2 *packetizer; MpegTSPacketizerPacket packet; - base = GST_MPEGTS_BASE (parent); + base = GST_MPEGTS_BASE (gst_object_get_parent (GST_OBJECT (pad))); packetizer = base->packetizer; if (G_UNLIKELY (base->queried_latency == FALSE)) { @@ -1374,26 +1368,16 @@ mpegts_base_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) } mpegts_packetizer_push (base->packetizer, buf); - - while (res == GST_FLOW_OK) { - pret = mpegts_packetizer_next_packet (base->packetizer, &packet); - - /* If we don't have enough data, return */ - if (G_UNLIKELY (pret == PACKET_NEED_MORE)) - break; - - /* bad header, skip the packet */ + while (((pret = mpegts_packetizer_next_packet (base->packetizer, + &packet)) != PACKET_NEED_MORE) && res == GST_FLOW_OK) { if (G_UNLIKELY (pret == PACKET_BAD)) + /* bad header, skip the packet */ goto next; - GST_DEBUG ("Got packet (buffer:%p)", packet.buffer); - /* base PSI data */ if (packet.payload != NULL && mpegts_base_is_psi (base, &packet)) { MpegTSPacketizerSection section; - based = mpegts_packetizer_push_section (packetizer, &packet, §ion); - if (G_UNLIKELY (!based)) /* bad section data */ goto next; @@ -1401,28 +1385,26 @@ mpegts_base_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) if (G_LIKELY (section.complete)) { /* section complete */ based = mpegts_base_handle_psi (base, §ion); - - GST_DEBUG ("Unreffing section buffer %p", section.buffer); gst_buffer_unref (section.buffer); if (G_UNLIKELY (!based)) /* bad PSI table */ goto next; } - /* we need to push section packet downstream */ res = mpegts_base_push (base, &packet, §ion); + } else if (MPEGTS_BIT_IS_SET (base->is_pes, packet.pid)) { /* push the packet downstream */ res = mpegts_base_push (base, &packet, NULL); - } else { + } else gst_buffer_unref (packet.buffer); - } next: mpegts_packetizer_clear_packet (base->packetizer, &packet); } + gst_object_unref (base); return res; } @@ -1519,7 +1501,6 @@ mpegts_base_scan (MpegTSBase * base) } beach: - GST_DEBUG ("Returning %s", gst_flow_get_name (ret)); mpegts_packetizer_clear (base->packetizer); return ret; @@ -1535,7 +1516,6 @@ static void mpegts_base_loop (MpegTSBase * base) { GstFlowReturn ret = GST_FLOW_ERROR; - switch (base->mode) { case BASE_MODE_SCANNING: /* Find first sync point */ @@ -1551,7 +1531,7 @@ mpegts_base_loop (MpegTSBase * base) break; case BASE_MODE_STREAMING: { - GstBuffer *buf = NULL; + GstBuffer *buf; GST_DEBUG ("Pulling data from %" G_GUINT64_FORMAT, base->seek_offset); @@ -1559,8 +1539,8 @@ mpegts_base_loop (MpegTSBase * base) 100 * base->packetsize, &buf); if (G_UNLIKELY (ret != GST_FLOW_OK)) goto error; - base->seek_offset += gst_buffer_get_size (buf); - ret = mpegts_base_chain (base->sinkpad, GST_OBJECT_CAST (base), buf); + base->seek_offset += GST_BUFFER_SIZE (buf); + ret = mpegts_base_chain (base->sinkpad, buf); if (G_UNLIKELY (ret != GST_FLOW_OK)) goto error; } @@ -1575,9 +1555,8 @@ mpegts_base_loop (MpegTSBase * base) error: { const gchar *reason = gst_flow_get_name (ret); - GST_DEBUG_OBJECT (base, "Pausing task, reason %s", reason); - if (ret == GST_FLOW_EOS) { + if (ret == GST_FLOW_UNEXPECTED) { /* Push EOS downstream */ if (!GST_MPEGTS_BASE_GET_CLASS (base)->push_event (base, gst_event_new_eos ())) { @@ -1586,7 +1565,7 @@ error: ("got eos but no streams (yet)")); } - } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) { + } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_UNEXPECTED) { GST_ELEMENT_ERROR (base, STREAM, FAILED, (_("Internal data stream error.")), ("stream stopped, reason %s", reason)); @@ -1652,7 +1631,7 @@ mpegts_base_handle_seek_event (MpegTSBase * base, GstPad * pad, if (flush) { /* send a FLUSH_STOP for the sinkpad, since we need data for seeking */ GST_DEBUG_OBJECT (base, "sending flush stop"); - gst_pad_push_event (base->sinkpad, gst_event_new_flush_stop (TRUE)); + gst_pad_push_event (base->sinkpad, gst_event_new_flush_stop ()); /* And actually flush our pending data */ mpegts_base_flush (base); mpegts_packetizer_flush (base->packetizer); @@ -1681,7 +1660,7 @@ mpegts_base_handle_seek_event (MpegTSBase * base, GstPad * pad, GST_DEBUG_OBJECT (base, "sending flush stop"); //gst_pad_push_event (base->sinkpad, gst_event_new_flush_stop ()); GST_MPEGTS_BASE_GET_CLASS (base)->push_event (base, - gst_event_new_flush_stop (TRUE)); + gst_event_new_flush_stop ()); } //else done: @@ -1693,63 +1672,39 @@ push_mode: static gboolean -mpegts_base_sink_activate (GstPad * sinkpad, GstObject * parent) +mpegts_base_sink_activate (GstPad * pad) { - GstQuery *query; - gboolean pull_mode; - - query = gst_query_new_scheduling (); - - if (!gst_pad_peer_query (sinkpad, query)) { - gst_query_unref (query); - goto activate_push; - } - - pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL); - 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); + if (gst_pad_check_pull_range (pad)) { + GST_DEBUG_OBJECT (pad, "activating pull"); + return gst_pad_activate_pull (pad, TRUE); + } else { + GST_DEBUG_OBJECT (pad, "activating push"); + return gst_pad_activate_push (pad, TRUE); } } static gboolean -mpegts_base_sink_activate_mode (GstPad * pad, GstObject * parent, - GstPadMode mode, gboolean active) +mpegts_base_sink_activate_pull (GstPad * pad, gboolean active) { - gboolean res; - MpegTSBase *base = GST_MPEGTS_BASE (parent); + MpegTSBase *base = GST_MPEGTS_BASE (GST_OBJECT_PARENT (pad)); + if (active) { + base->mode = BASE_MODE_SCANNING; + base->packetizer->calculate_offset = TRUE; + return gst_pad_start_task (pad, (GstTaskFunction) mpegts_base_loop, base); + } else + return gst_pad_stop_task (pad); +} - switch (mode) { - case GST_PAD_MODE_PUSH: - base->mode = BASE_MODE_PUSHING; - base->packetizer->calculate_skew = TRUE; - res = TRUE; - break; - case GST_PAD_MODE_PULL: - if (active) { - base->mode = BASE_MODE_SCANNING; - base->packetizer->calculate_offset = TRUE; - res = - gst_pad_start_task (pad, (GstTaskFunction) mpegts_base_loop, base); - } else - res = gst_pad_stop_task (pad); - break; - default: - res = FALSE; - break; - } - return res; +static gboolean +mpegts_base_sink_activate_push (GstPad * pad, gboolean active) +{ + MpegTSBase *base = GST_MPEGTS_BASE (GST_OBJECT_PARENT (pad)); + base->mode = BASE_MODE_PUSHING; + base->packetizer->calculate_skew = TRUE; + return TRUE; } + static GstStateChangeReturn mpegts_base_change_state (GstElement * element, GstStateChange transition) { diff --git a/gst/mpegtsdemux/mpegtsbase.h b/gst/mpegtsdemux/mpegtsbase.h index 8521b5786..edce58d50 100644 --- a/gst/mpegtsdemux/mpegtsbase.h +++ b/gst/mpegtsdemux/mpegtsbase.h @@ -136,11 +136,6 @@ struct _MpegTSBase { /* Whether we queried the upstream latency or not */ gboolean queried_latency; - /* Whether upstream is live or not */ - gboolean upstream_live; - /* Whether we queried the upstream latency or not */ - gboolean query_latency; - /* Upstream segment */ GstSegment segment; }; diff --git a/gst/mpegtsdemux/mpegtspacketizer.c b/gst/mpegtsdemux/mpegtspacketizer.c index bf6e4afaf..6e0335a28 100644 --- a/gst/mpegtsdemux/mpegtspacketizer.c +++ b/gst/mpegtsdemux/mpegtspacketizer.c @@ -357,8 +357,6 @@ mpegts_packetizer_parse_packet (MpegTSPacketizer2 * packetizer, packet->data = data; - gst_buffer_unmap (packet->buffer, &packet->bufmap); - if (packet->adaptation_field_control & 0x02) if (!mpegts_packetizer_parse_adaptation_field_control (packetizer, packet)) return FALSE; @@ -375,19 +373,16 @@ static gboolean mpegts_packetizer_parse_section_header (MpegTSPacketizer2 * packetizer, MpegTSPacketizerStream * stream, MpegTSPacketizerSection * section) { - GstMapInfo map; guint8 tmp; guint8 *data, *crc_data; MpegTSPacketizerStreamSubtable *subtable; GSList *subtable_list = NULL; section->complete = TRUE; - /* get the section buffer, pass the ownership to the caller */ section->buffer = gst_adapter_take_buffer (stream->section_adapter, 3 + stream->section_length); - gst_buffer_map (section->buffer, &map, GST_MAP_READ); - data = map.data; + data = GST_BUFFER_DATA (section->buffer); GST_BUFFER_OFFSET (section->buffer) = stream->offset; section->table_id = *data++; @@ -423,7 +418,8 @@ mpegts_packetizer_parse_section_header (MpegTSPacketizer2 * packetizer, goto not_applicable; /* CRC is at the end of the section */ - crc_data = map.data + map.size - 4; + crc_data = + GST_BUFFER_DATA (section->buffer) + GST_BUFFER_SIZE (section->buffer) - 4; section->crc = GST_READ_UINT32_BE (crc_data); if (section->version_number == subtable->version_number && @@ -434,8 +430,6 @@ mpegts_packetizer_parse_section_header (MpegTSPacketizer2 * packetizer, subtable->crc = section->crc; stream->section_table_id = section->table_id; - gst_buffer_unmap (section->buffer, &map); - return TRUE; not_applicable: @@ -444,7 +438,6 @@ not_applicable: section->pid, section->table_id, section->subtable_extension, section->current_next_indicator, section->version_number, section->crc); section->complete = FALSE; - gst_buffer_unmap (section->buffer, &map); gst_buffer_unref (section->buffer); return TRUE; } @@ -498,7 +491,6 @@ mpegts_packetizer_parse_pat (MpegTSPacketizer2 * packetizer, MpegTSPacketizerSection * section) { GstStructure *pat_info = NULL; - GstMapInfo map; guint8 *data, *end; guint transport_stream_id; guint8 tmp; @@ -509,8 +501,7 @@ mpegts_packetizer_parse_pat (MpegTSPacketizer2 * packetizer, GstStructure *entry = NULL; gchar *struct_name; - gst_buffer_map (section->buffer, &map, GST_MAP_READ); - data = map.data; + data = GST_BUFFER_DATA (section->buffer); section->table_id = *data++; section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF; @@ -526,13 +517,11 @@ mpegts_packetizer_parse_pat (MpegTSPacketizer2 * packetizer, /* skip section_number and last_section_number */ data += 2; - pat_info = gst_structure_new_id (QUARK_PAT, + pat_info = gst_structure_id_new (QUARK_PAT, QUARK_TRANSPORT_STREAM_ID, G_TYPE_UINT, transport_stream_id, NULL); g_value_init (&entries, GST_TYPE_LIST); - /* stop at the CRC */ - end = map.data + map.size; - + end = GST_BUFFER_DATA (section->buffer) + GST_BUFFER_SIZE (section->buffer); while (data < end - 4) { program_number = GST_READ_UINT16_BE (data); data += 2; @@ -541,7 +530,7 @@ mpegts_packetizer_parse_pat (MpegTSPacketizer2 * packetizer, data += 2; struct_name = g_strdup_printf ("program-%d", program_number); - entry = gst_structure_new_empty (struct_name); + entry = gst_structure_new (struct_name, NULL); g_free (struct_name); gst_structure_id_set (entry, QUARK_PROGRAM_NUMBER, G_TYPE_UINT, program_number, QUARK_PID, G_TYPE_UINT, pmt_pid, NULL); @@ -555,8 +544,6 @@ mpegts_packetizer_parse_pat (MpegTSPacketizer2 * packetizer, gst_structure_id_set_value (pat_info, QUARK_PROGRAMS, &entries); g_value_unset (&entries); - gst_buffer_unmap (section->buffer, &map); - if (data != end - 4) { /* FIXME: check the CRC before parsing the packet */ GST_ERROR ("at the end of PAT data != end - 4"); @@ -573,7 +560,6 @@ mpegts_packetizer_parse_pmt (MpegTSPacketizer2 * packetizer, MpegTSPacketizerSection * section) { GstStructure *pmt = NULL; - GstMapInfo map; guint8 *data, *end; guint16 program_number; guint8 tmp; @@ -588,17 +574,15 @@ mpegts_packetizer_parse_pmt (MpegTSPacketizer2 * packetizer, GstStructure *stream_info = NULL; gchar *struct_name; - gst_buffer_map (section->buffer, &map, GST_MAP_READ); - data = map.data; - /* fixed header + CRC == 16 */ - if (map.size < 16) { + if (GST_BUFFER_SIZE (section->buffer) < 16) { GST_WARNING ("PID %d invalid PMT size %d", section->pid, section->section_length); goto error; } - end = map.data + map.size; + data = GST_BUFFER_DATA (section->buffer); + end = data + GST_BUFFER_SIZE (section->buffer); section->table_id = *data++; section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF; @@ -622,7 +606,7 @@ mpegts_packetizer_parse_pmt (MpegTSPacketizer2 * packetizer, program_info_length = GST_READ_UINT16_BE (data) & 0x0FFF; data += 2; - pmt = gst_structure_new_id (QUARK_PMT, + pmt = gst_structure_id_new (QUARK_PMT, QUARK_PROGRAM_NUMBER, G_TYPE_UINT, program_number, QUARK_PCR_PID, G_TYPE_UINT, pcr_pid, QUARK_VERSION_NUMBER, G_TYPE_UINT, section->version_number, NULL); @@ -669,7 +653,7 @@ mpegts_packetizer_parse_pmt (MpegTSPacketizer2 * packetizer, } struct_name = g_strdup_printf ("pid-%d", pid); - stream_info = gst_structure_new_empty (struct_name); + stream_info = gst_structure_new (struct_name, NULL); g_free (struct_name); gst_structure_id_set (stream_info, QUARK_PID, G_TYPE_UINT, pid, QUARK_STREAM_TYPE, G_TYPE_UINT, @@ -771,8 +755,6 @@ mpegts_packetizer_parse_pmt (MpegTSPacketizer2 * packetizer, gst_structure_id_set_value (pmt, QUARK_STREAMS, &programs); g_value_unset (&programs); - gst_buffer_unmap (section->buffer, &map); - g_assert (data == end - 4); return pmt; @@ -780,7 +762,6 @@ mpegts_packetizer_parse_pmt (MpegTSPacketizer2 * packetizer, error: if (pmt) gst_structure_free (pmt); - gst_buffer_unmap (section->buffer, &map); return NULL; } @@ -790,7 +771,6 @@ mpegts_packetizer_parse_nit (MpegTSPacketizer2 * packetizer, MpegTSPacketizerSection * section) { GstStructure *nit = NULL, *transport = NULL, *delivery_structure = NULL; - GstMapInfo map; guint8 *data, *end, *entry_begin; guint16 network_id, transport_stream_id, original_network_id; guint tmp; @@ -800,18 +780,15 @@ mpegts_packetizer_parse_nit (MpegTSPacketizer2 * packetizer, GValueArray *descriptors = NULL; GST_DEBUG ("NIT"); - - gst_buffer_map (section->buffer, &map, GST_MAP_READ); - data = map.data; - /* fixed header + CRC == 16 */ - if (map.size < 23) { + if (GST_BUFFER_SIZE (section->buffer) < 23) { GST_WARNING ("PID %d invalid NIT size %d", section->pid, section->section_length); goto error; } - end = map.data + map.size; + data = GST_BUFFER_DATA (section->buffer); + end = data + GST_BUFFER_SIZE (section->buffer); section->table_id = *data++; section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF; @@ -836,7 +813,7 @@ mpegts_packetizer_parse_nit (MpegTSPacketizer2 * packetizer, descriptors_loop_length = GST_READ_UINT16_BE (data) & 0x0FFF; data += 2; - nit = gst_structure_new_id (QUARK_NIT, + nit = gst_structure_id_new (QUARK_NIT, QUARK_NETWORK_ID, G_TYPE_UINT, network_id, QUARK_VERSION_NUMBER, G_TYPE_UINT, section->version_number, QUARK_CURRENT_NEXT_INDICATOR, G_TYPE_UINT, @@ -914,7 +891,7 @@ mpegts_packetizer_parse_nit (MpegTSPacketizer2 * packetizer, data += 2; transport_name = g_strdup_printf ("transport-%d", transport_stream_id); - transport = gst_structure_new_empty (transport_name); + transport = gst_structure_new (transport_name, NULL); g_free (transport_name); gst_structure_id_set (transport, QUARK_TRANSPORT_STREAM_ID, G_TYPE_UINT, transport_stream_id, @@ -1399,16 +1376,15 @@ mpegts_packetizer_parse_nit (MpegTSPacketizer2 * packetizer, } if (data != end - 4) { - GST_WARNING ("PID %d invalid NIT parsed %d length %" G_GSIZE_FORMAT, - section->pid, (gint) (data - map.data), map.size); + GST_WARNING ("PID %d invalid NIT parsed %d length %d", + section->pid, (gint) (data - GST_BUFFER_DATA (section->buffer)), + GST_BUFFER_SIZE (section->buffer)); goto error; } gst_structure_id_set_value (nit, QUARK_TRANSPORTS, &transports); g_value_unset (&transports); - gst_buffer_unmap (section->buffer, &map); - GST_DEBUG ("NIT %" GST_PTR_FORMAT, nit); return nit; @@ -1417,8 +1393,6 @@ error: if (nit) gst_structure_free (nit); - gst_buffer_unmap (section->buffer, &map); - if (GST_VALUE_HOLDS_LIST (&transports)) g_value_unset (&transports); @@ -1429,7 +1403,6 @@ GstStructure * mpegts_packetizer_parse_sdt (MpegTSPacketizer2 * packetizer, MpegTSPacketizerSection * section) { - GstMapInfo map; GstStructure *sdt = NULL, *service = NULL; guint8 *data, *end, *entry_begin; guint16 transport_stream_id, original_network_id, service_id; @@ -1443,18 +1416,15 @@ mpegts_packetizer_parse_sdt (MpegTSPacketizer2 * packetizer, GValue service_value = { 0 }; GST_DEBUG ("SDT"); - - gst_buffer_map (section->buffer, &map, GST_MAP_READ); - data = map.data; - /* fixed header + CRC == 16 */ - if (map.size < 14) { + if (GST_BUFFER_SIZE (section->buffer) < 14) { GST_WARNING ("PID %d invalid SDT size %d", section->pid, section->section_length); goto error; } - end = map.data + map.size; + data = GST_BUFFER_DATA (section->buffer); + end = data + GST_BUFFER_SIZE (section->buffer); section->table_id = *data++; section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF; @@ -1482,7 +1452,7 @@ mpegts_packetizer_parse_sdt (MpegTSPacketizer2 * packetizer, /* skip reserved byte */ data += 1; - sdt = gst_structure_new_id (QUARK_SDT, + sdt = gst_structure_id_new (QUARK_SDT, QUARK_TRANSPORT_STREAM_ID, G_TYPE_UINT, transport_stream_id, QUARK_VERSION_NUMBER, G_TYPE_UINT, section->version_number, QUARK_CURRENT_NEXT_INDICATOR, G_TYPE_UINT, @@ -1521,7 +1491,7 @@ mpegts_packetizer_parse_sdt (MpegTSPacketizer2 * packetizer, /* TODO send tag event down relevant pad for channel name and provider */ service_name = g_strdup_printf ("service-%d", service_id); - service = gst_structure_new_empty (service_name); + service = gst_structure_new (service_name, NULL); g_free (service_name); if (descriptors_loop_length) { @@ -1611,24 +1581,21 @@ mpegts_packetizer_parse_sdt (MpegTSPacketizer2 * packetizer, } if (data != end - 4) { - GST_WARNING ("PID %d invalid SDT parsed %d length %" G_GSIZE_FORMAT, - section->pid, (gint) (data - map.data), map.size); + GST_WARNING ("PID %d invalid SDT parsed %d length %d", + section->pid, (gint) (data - GST_BUFFER_DATA (section->buffer)), + GST_BUFFER_SIZE (section->buffer)); goto error; } gst_structure_id_set_value (sdt, QUARK_SERVICES, &services); g_value_unset (&services); - gst_buffer_unmap (section->buffer, &map); - return sdt; error: if (sdt) gst_structure_free (sdt); - gst_buffer_unmap (section->buffer, &map); - if (GST_VALUE_HOLDS_LIST (&services)) g_value_unset (&services); @@ -1647,7 +1614,6 @@ mpegts_packetizer_parse_eit (MpegTSPacketizer2 * packetizer, guint16 mjd; guint year, month, day, hour, minute, second; guint duration; - GstMapInfo map; guint8 *data, *end, *duration_ptr, *utc_ptr; guint16 descriptors_loop_length; GValue events = { 0 }; @@ -1656,17 +1622,15 @@ mpegts_packetizer_parse_eit (MpegTSPacketizer2 * packetizer, gchar *event_name; guint tmp; - gst_buffer_map (section->buffer, &map, GST_MAP_READ); - data = map.data; - /* fixed header + CRC == 16 */ - if (map.size < 18) { + if (GST_BUFFER_SIZE (section->buffer) < 18) { GST_WARNING ("PID %d invalid EIT size %d", section->pid, section->section_length); goto error; } - end = map.data + map.size; + data = GST_BUFFER_DATA (section->buffer); + end = data + GST_BUFFER_SIZE (section->buffer); section->table_id = *data++; section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF; @@ -1697,7 +1661,7 @@ mpegts_packetizer_parse_eit (MpegTSPacketizer2 * packetizer, last_table_id = *data; data += 1; - eit = gst_structure_new_id (QUARK_EIT, + eit = gst_structure_id_new (QUARK_EIT, QUARK_VERSION_NUMBER, G_TYPE_UINT, section->version_number, QUARK_CURRENT_NEXT_INDICATOR, G_TYPE_UINT, section->current_next_indicator, QUARK_SERVICE_ID, G_TYPE_UINT, @@ -2076,16 +2040,15 @@ mpegts_packetizer_parse_eit (MpegTSPacketizer2 * packetizer, } if (data != end - 4) { - GST_WARNING ("PID %d invalid EIT parsed %d length %" G_GSIZE_FORMAT, - section->pid, (gint) (data - map.data), map.size); + GST_WARNING ("PID %d invalid EIT parsed %d length %d", + section->pid, (gint) (data - GST_BUFFER_DATA (section->buffer)), + GST_BUFFER_SIZE (section->buffer)); goto error; } gst_structure_id_set_value (eit, QUARK_EVENTS, &events); g_value_unset (&events); - gst_buffer_unmap (section->buffer, &map); - GST_DEBUG ("EIT %" GST_PTR_FORMAT, eit); return eit; @@ -2094,8 +2057,6 @@ error: if (eit) gst_structure_free (eit); - gst_buffer_unmap (section->buffer, &map); - if (GST_VALUE_HOLDS_LIST (&events)) g_value_unset (&events); @@ -2109,22 +2070,18 @@ mpegts_packetizer_parse_tdt (MpegTSPacketizer2 * packetizer, GstStructure *tdt = NULL; guint16 mjd; guint year, month, day, hour, minute, second; - GstMapInfo map; guint8 *data, *end, *utc_ptr; GST_DEBUG ("TDT"); - - gst_buffer_map (section->buffer, &map, GST_MAP_READ); - data = map.data; - /* length always 8 */ - if (G_UNLIKELY (map.size != 8)) { + if (G_UNLIKELY (GST_BUFFER_SIZE (section->buffer) != 8)) { GST_WARNING ("PID %d invalid TDT size %d", section->pid, section->section_length); goto error; } - end = map.data + map.size; + data = GST_BUFFER_DATA (section->buffer); + end = data + GST_BUFFER_SIZE (section->buffer); section->table_id = *data++; section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF; @@ -2165,16 +2122,12 @@ mpegts_packetizer_parse_tdt (MpegTSPacketizer2 * packetizer, "hour", G_TYPE_UINT, hour, "minute", G_TYPE_UINT, minute, "second", G_TYPE_UINT, second, NULL); - gst_buffer_unmap (section->buffer, &map); - return tdt; error: if (tdt) gst_structure_free (tdt); - gst_buffer_unmap (section->buffer, &map); - return NULL; } @@ -2252,8 +2205,8 @@ mpegts_packetizer_push (MpegTSPacketizer2 * packetizer, GstBuffer * buffer) packetizer->offset = GST_BUFFER_OFFSET (buffer); } - GST_DEBUG ("Pushing %" G_GSIZE_FORMAT " byte from offset %" G_GUINT64_FORMAT, - gst_buffer_get_size (buffer), GST_BUFFER_OFFSET (buffer)); + GST_DEBUG ("Pushing %u byte from offset %" G_GUINT64_FORMAT, + GST_BUFFER_SIZE (buffer), GST_BUFFER_OFFSET (buffer)); gst_adapter_push (packetizer->adapter, buffer); } @@ -2348,82 +2301,74 @@ mpegts_packetizer_next_packet (MpegTSPacketizer2 * packetizer, packet->buffer = NULL; - /* Resync if needed */ if (G_UNLIKELY (!packetizer->know_packet_size)) { if (!mpegts_try_discover_packet_size (packetizer)) return PACKET_NEED_MORE; } while ((avail = packetizer->adapter->size) >= packetizer->packet_size) { - guint i; - GstBuffer *tmpbuf; - guint8 *bufdata; - packet->buffer = gst_adapter_take_buffer (packetizer->adapter, packetizer->packet_size); - gst_buffer_map (packet->buffer, &packet->bufmap, GST_MAP_READ); - - bufdata = packet->data_start = packet->bufmap.data; - /* M2TS packets don't start with the sync byte, all other variants do */ - if (packetizer->packet_size == MPEGTS_M2TS_PACKETSIZE) - packet->data_start += 4; - + if (packetizer->packet_size == MPEGTS_M2TS_PACKETSIZE) { + packet->data_start = GST_BUFFER_DATA (packet->buffer) + 4; + } else { + packet->data_start = GST_BUFFER_DATA (packet->buffer); + } /* ALL mpeg-ts variants contain 188 bytes of data. Those with bigger packet * sizes contain either extra data (timesync, FEC, ..) either before or after * the data */ packet->data_end = packet->data_start + 188; GST_BUFFER_OFFSET (packet->buffer) = packet->offset = packetizer->offset; GST_DEBUG ("offset %" G_GUINT64_FORMAT, packet->offset); - packetizer->offset += packetizer->packet_size; - GST_MEMDUMP ("buffer", bufdata, 16); + GST_MEMDUMP ("buffer", GST_BUFFER_DATA (packet->buffer), 16); GST_MEMDUMP ("data_start", packet->data_start, 16); GST_BUFFER_TIMESTAMP (packet->buffer) = gst_adapter_prev_timestamp (packetizer->adapter, NULL); /* Check sync byte */ - if (G_LIKELY (packet->data_start[0] == 0x47)) - goto got_valid_packet; - - GST_LOG ("Lost sync %d", packetizer->packet_size); - - /* Find the 0x47 in the buffer */ - for (i = 0; i < packetizer->packet_size; i++) - if (bufdata[i] == 0x47) - break; + if (G_UNLIKELY (packet->data_start[0] != 0x47)) { + guint i; + GstBuffer *tmpbuf; + + GST_LOG ("Lost sync %d", packetizer->packet_size); + /* Find the 0x47 in the buffer */ + for (i = 0; i < packetizer->packet_size; i++) + if (GST_BUFFER_DATA (packet->buffer)[i] == 0x47) + break; + if (G_UNLIKELY (i == packetizer->packet_size)) { + GST_ERROR ("REALLY lost the sync"); + gst_buffer_unref (packet->buffer); + goto done; + } - if (G_UNLIKELY (i == packetizer->packet_size)) { - GST_ERROR ("REALLY lost the sync"); - gst_buffer_unmap (packet->buffer, &packet->bufmap); - gst_buffer_unref (packet->buffer); - goto done; - } + if (packetizer->packet_size == MPEGTS_M2TS_PACKETSIZE) { + if (i >= 4) + i -= 4; + else + i += 188; + } - if (packetizer->packet_size == MPEGTS_M2TS_PACKETSIZE) { - if (i >= 4) - i -= 4; - else - i += 188; + /* Pop out the remaining data... */ + GST_BUFFER_DATA (packet->buffer) += i; + GST_BUFFER_SIZE (packet->buffer) -= i; + GST_BUFFER_OFFSET (packet->buffer) += i; + tmpbuf = + gst_adapter_take_buffer (packetizer->adapter, + packetizer->adapter->size); + /* ... and push everything back in */ + gst_adapter_push (packetizer->adapter, packet->buffer); + gst_adapter_push (packetizer->adapter, tmpbuf); + continue; } - /* Pop out the remaining data... */ - gst_buffer_resize (packet->buffer, i, packet->bufmap.size - i); - GST_BUFFER_OFFSET (packet->buffer) += i; - tmpbuf = - gst_adapter_take_buffer (packetizer->adapter, - packetizer->adapter->size); - /* ... and push everything back in */ - gst_adapter_push (packetizer->adapter, packet->buffer); - gst_adapter_push (packetizer->adapter, tmpbuf); + return mpegts_packetizer_parse_packet (packetizer, packet); } done: return PACKET_NEED_MORE; - -got_valid_packet: - return mpegts_packetizer_parse_packet (packetizer, packet); } MpegTSPacketizerPacketReturn @@ -2438,8 +2383,6 @@ void mpegts_packetizer_clear_packet (MpegTSPacketizer2 * packetizer, MpegTSPacketizerPacket * packet) { - GST_DEBUG ("packet:%p, buffer:%p", packet, packet->buffer); - memset (packet, 0, sizeof (MpegTSPacketizerPacket)); } @@ -2474,15 +2417,14 @@ mpegts_packetizer_push_section (MpegTSPacketizer2 * packetizer, if (packet->pid == 0x14) { table_id = data[0]; section->section_length = GST_READ_UINT24_BE (data) & 0x000FFF; - if (data - packet->bufmap.data + section->section_length + 3 > - packet->bufmap.size) { + if (data - GST_BUFFER_DATA (packet->buffer) + section->section_length + 3 > + GST_BUFFER_SIZE (packet->buffer)) { GST_WARNING ("PID %dd PSI section length extends past the end " "of the buffer", packet->pid); goto out; } - section->buffer = - gst_buffer_copy_region (packet->buffer, GST_BUFFER_COPY_ALL, - data - packet->bufmap.data, section->section_length + 3); + section->buffer = gst_buffer_create_sub (packet->buffer, + data - GST_BUFFER_DATA (packet->buffer), section->section_length + 3); section->table_id = table_id; section->complete = TRUE; res = TRUE; @@ -2493,8 +2435,8 @@ mpegts_packetizer_push_section (MpegTSPacketizer2 * packetizer, /* create a sub buffer from the start of the section (table_id and * section_length included) to the end */ - sub_buf = gst_buffer_copy_region (packet->buffer, GST_BUFFER_COPY_ALL, - data - packet->bufmap.data, packet->data_end - data); + sub_buf = gst_buffer_create_sub (packet->buffer, + data - GST_BUFFER_DATA (packet->buffer), packet->data_end - data); stream = packetizer->streams[packet->pid]; if (stream == NULL) { @@ -2518,11 +2460,10 @@ mpegts_packetizer_push_section (MpegTSPacketizer2 * packetizer, if (stream->continuity_counter != CONTINUITY_UNSET) { GST_DEBUG ("PID %d table_id %d sub_table_extension %d payload_unit_start_indicator set but section " - "not complete (last_continuity: %d continuity: %d sec len %d buffer %" - G_GSIZE_FORMAT " avail %" G_GSIZE_FORMAT, packet->pid, table_id, - subtable_extension, stream->continuity_counter, - packet->continuity_counter, section_length, - gst_buffer_get_size (sub_buf), stream->section_adapter->size); + "not complete (last_continuity: %d continuity: %d sec len %d buffer %d avail %d", + packet->pid, table_id, subtable_extension, stream->continuity_counter, + packet->continuity_counter, section_length, GST_BUFFER_SIZE (sub_buf), + stream->section_adapter->size); mpegts_packetizer_clear_section (packetizer, stream); } else { GST_DEBUG diff --git a/gst/mpegtsdemux/mpegtspacketizer.h b/gst/mpegtsdemux/mpegtspacketizer.h index 243d9561a..418da0847 100644 --- a/gst/mpegtsdemux/mpegtspacketizer.h +++ b/gst/mpegtsdemux/mpegtspacketizer.h @@ -124,12 +124,9 @@ typedef struct guint8 continuity_counter; guint8 *payload; - /* gst_buffer_map */ - GstMapInfo bufmap; - - guint8 *data_start; /* Location of 0x47 marker byte */ + guint8 *data_start; guint8 *data_end; - guint8 *data; /* Location of post-TS-header data */ + guint8 *data; guint8 afc_flags; guint64 pcr; @@ -179,7 +176,7 @@ MpegTSPacketizerPacketReturn mpegts_packetizer_next_packet (MpegTSPacketizer2 *p MpegTSPacketizerPacketReturn mpegts_packetizer_process_next_packet(MpegTSPacketizer2 * packetizer); void mpegts_packetizer_clear_packet (MpegTSPacketizer2 *packetizer, - MpegTSPacketizerPacket *packet); + MpegTSPacketizerPacket *packet); void mpegts_packetizer_remove_stream(MpegTSPacketizer2 *packetizer, gint16 pid); diff --git a/gst/mpegtsdemux/mpegtsparse.c b/gst/mpegtsdemux/mpegtsparse.c index 1c3f625b1..37b6da6e9 100644 --- a/gst/mpegtsdemux/mpegtsparse.c +++ b/gst/mpegtsdemux/mpegtsparse.c @@ -70,13 +70,13 @@ struct _MpegTSParsePad }; static GstStaticPadTemplate src_template = -GST_STATIC_PAD_TEMPLATE ("src_%u", GST_PAD_SRC, +GST_STATIC_PAD_TEMPLATE ("src%d", GST_PAD_SRC, GST_PAD_REQUEST, GST_STATIC_CAPS ("video/mpegts, " "systemstream = (boolean) true ") ); static GstStaticPadTemplate program_template = -GST_STATIC_PAD_TEMPLATE ("program_%u", GST_PAD_SRC, +GST_STATIC_PAD_TEMPLATE ("program_%d", GST_PAD_SRC, GST_PAD_SOMETIMES, GST_STATIC_CAPS ("video/mpegts, " "systemstream = (boolean) true ") ); @@ -113,14 +113,27 @@ static void mpegts_parse_reset_selected_programs (MpegTSParse2 * parse, static void mpegts_parse_pad_removed (GstElement * element, GstPad * pad); static GstPad *mpegts_parse_request_new_pad (GstElement * element, - GstPadTemplate * templ, const gchar * name, const GstCaps * caps); + GstPadTemplate * templ, const gchar * name); static void mpegts_parse_release_pad (GstElement * element, GstPad * pad); -static gboolean mpegts_parse_src_pad_query (GstPad * pad, GstObject * parent, - GstQuery * query); +static gboolean mpegts_parse_src_pad_query (GstPad * pad, GstQuery * query); static gboolean push_event (MpegTSBase * base, GstEvent * event); -#define mpegts_parse_parent_class parent_class -G_DEFINE_TYPE (MpegTSParse2, mpegts_parse, GST_TYPE_MPEGTS_BASE); +GST_BOILERPLATE (MpegTSParse2, mpegts_parse, MpegTSBase, GST_TYPE_MPEGTS_BASE); + +static void +mpegts_parse_base_init (gpointer klass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_add_static_pad_template (element_class, &src_template); + gst_element_class_add_static_pad_template (element_class, &program_template); + + gst_element_class_set_details_simple (element_class, + "MPEG transport stream parser", "Codec/Parser", + "Parses MPEG2 transport streams", + "Alessandro Decina <alessandro@nnva.org>, " + "Zaheer Abbas Merali <zaheerabbas at merali dot org>"); +} static void mpegts_parse_class_init (MpegTSParse2Class * klass) @@ -134,17 +147,6 @@ mpegts_parse_class_init (MpegTSParse2Class * klass) element_class->request_new_pad = mpegts_parse_request_new_pad; element_class->release_pad = mpegts_parse_release_pad; - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&program_template)); - - gst_element_class_set_details_simple (element_class, - "MPEG transport stream parser", "Codec/Parser", - "Parses MPEG2 transport streams", - "Alessandro Decina <alessandro@nnva.org>, " - "Zaheer Abbas Merali <zaheerabbas at merali dot org>"); - gobject_class = G_OBJECT_CLASS (klass); gobject_class->set_property = mpegts_parse_set_property; gobject_class->get_property = mpegts_parse_get_property; @@ -164,7 +166,7 @@ mpegts_parse_class_init (MpegTSParse2Class * klass) } static void -mpegts_parse_init (MpegTSParse2 * parse) +mpegts_parse_init (MpegTSParse2 * parse, MpegTSParse2Class * klass) { parse->need_sync_program_pads = FALSE; parse->program_numbers = g_strdup (""); @@ -222,7 +224,7 @@ mpegts_parse_activate_program (MpegTSParse2 * parse, gchar *pad_name; pad_name = - g_strdup_printf ("program_%u", + g_strdup_printf ("program_%d", ((MpegTSBaseProgram *) program)->program_number); tspad = mpegts_parse_create_tspad (parse, pad_name); @@ -425,7 +427,7 @@ mpegts_parse_pad_removed (GstElement * element, GstPad * pad) static GstPad * mpegts_parse_request_new_pad (GstElement * element, GstPadTemplate * template, - const gchar * unused, const GstCaps * caps) + const gchar * unused) { MpegTSParse2 *parse; gchar *name; @@ -437,7 +439,7 @@ mpegts_parse_request_new_pad (GstElement * element, GstPadTemplate * template, parse = GST_MPEGTS_PARSE (element); GST_OBJECT_LOCK (element); - name = g_strdup_printf ("src_%u", parse->req_pads++); + name = g_strdup_printf ("src%d", parse->req_pads++); GST_OBJECT_UNLOCK (element); pad = mpegts_parse_create_tspad (parse, name)->pad; @@ -507,7 +509,8 @@ mpegts_parse_tspad_push (MpegTSParse2 * parse, MpegTSParsePad * tspad, MpegTSBaseProgram *bp = (MpegTSBaseProgram *) tspad->program; pad_pids = bp->streams; if (bp->tags) { - gst_pad_push_event (tspad->pad, gst_event_new_tag (bp->tags)); + gst_element_found_tags_for_pad (GST_ELEMENT_CAST (parse), tspad->pad, + bp->tags); bp->tags = NULL; } } else { @@ -559,15 +562,9 @@ mpegts_parse_push (MpegTSBase * base, MpegTSPacketizerPacket * packet, mpegts_parse_sync_program_pads (parse); pid = packet->pid; - -#if 0 buffer = gst_buffer_make_metadata_writable (packet->buffer); - /* we have the same caps on all the src pads */ gst_buffer_set_caps (buffer, base->packetizer->caps); -#else - buffer = packet->buffer; -#endif GST_OBJECT_LOCK (parse); /* clear tspad->pushed on pads */ @@ -675,9 +672,9 @@ mpegts_parse_program_stopped (MpegTSBase * base, MpegTSBaseProgram * program) } static gboolean -mpegts_parse_src_pad_query (GstPad * pad, GstObject * parent, GstQuery * query) +mpegts_parse_src_pad_query (GstPad * pad, GstQuery * query) { - MpegTSParse2 *parse = GST_MPEGTS_PARSE (parent); + MpegTSParse2 *parse = GST_MPEGTS_PARSE (gst_pad_get_parent (pad)); gboolean res; switch (GST_QUERY_TYPE (query)) { @@ -700,8 +697,9 @@ mpegts_parse_src_pad_query (GstPad * pad, GstObject * parent, GstQuery * query) break; } default: - res = gst_pad_query_default (pad, parent, query); + res = gst_pad_query_default (pad, query); } + gst_object_unref (parse); return res; } diff --git a/gst/mpegtsdemux/tsdemux.c b/gst/mpegtsdemux/tsdemux.c index cf68672e2..e88a576e2 100644 --- a/gst/mpegtsdemux/tsdemux.c +++ b/gst/mpegtsdemux/tsdemux.c @@ -134,6 +134,8 @@ struct _TSDemuxStream guint current_size; /* Current data to be pushed out */ + GstBufferList *current; + GstBufferListIterator *currentit; GList *currentlist; /* Current PTS/DTS for this stream */ @@ -163,7 +165,7 @@ struct _TSDemuxStream "video/x-dirac;" \ "video/x-wmv," \ "wmvversion = (int) 3, " \ - "format = (string) WVC1" \ + "format = (fourcc) WVC1" \ ) #define AUDIO_CAPS \ @@ -225,6 +227,7 @@ enum /* Pad functions */ + /* mpegtsbase methods */ static void gst_ts_demux_program_started (MpegTSBase * base, MpegTSBaseProgram * program); @@ -248,9 +251,13 @@ static GstFlowReturn gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream); static gboolean push_event (MpegTSBase * base, GstEvent * event); +static void _extra_init (GType type); + +GST_BOILERPLATE_FULL (GstTSDemux, gst_ts_demux, MpegTSBase, + GST_TYPE_MPEGTS_BASE, _extra_init); static void -_extra_init (void) +_extra_init (GType type) { QUARK_TSDEMUX = g_quark_from_string ("tsdemux"); QUARK_PID = g_quark_from_string ("pid"); @@ -261,15 +268,29 @@ _extra_init (void) QUARK_OFFSET = g_quark_from_string ("offset"); } -#define gst_ts_demux_parent_class parent_class -G_DEFINE_TYPE_WITH_CODE (GstTSDemux, gst_ts_demux, GST_TYPE_MPEGTS_BASE, - _extra_init ()); +static void +gst_ts_demux_base_init (gpointer klass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_add_static_pad_template (element_class, &video_template); + gst_element_class_add_static_pad_template (element_class, &audio_template); + gst_element_class_add_static_pad_template (element_class, + &subpicture_template); + gst_element_class_add_static_pad_template (element_class, &private_template); + + gst_element_class_set_details_simple (element_class, + "MPEG transport stream demuxer", + "Codec/Demuxer", + "Demuxes MPEG2 transport streams", + "Zaheer Abbas Merali <zaheerabbas at merali dot org>\n" + "Edward Hervey <edward.hervey@collabora.co.uk>"); +} static void gst_ts_demux_class_init (GstTSDemuxClass * klass) { GObjectClass *gobject_class; - GstElementClass *element_class; MpegTSBaseClass *ts_class; gobject_class = G_OBJECT_CLASS (klass); @@ -286,22 +307,6 @@ gst_ts_demux_class_init (GstTSDemuxClass * klass) "Emit messages for every pcr/opcr/pts/dts", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - element_class = GST_ELEMENT_CLASS (klass); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&video_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&audio_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&subpicture_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&private_template)); - - gst_element_class_set_details_simple (element_class, - "MPEG transport stream demuxer", - "Codec/Demuxer", - "Demuxes MPEG2 transport streams", - "Zaheer Abbas Merali <zaheerabbas at merali dot org>\n" - "Edward Hervey <edward.hervey@collabora.co.uk>"); ts_class = GST_MPEGTS_BASE_CLASS (klass); ts_class->reset = GST_DEBUG_FUNCPTR (gst_ts_demux_reset); @@ -395,14 +400,14 @@ gst_ts_demux_srcpad_query_types (GstPad * pad) } static gboolean -gst_ts_demux_srcpad_query (GstPad * pad, GstObject * parent, GstQuery * query) +gst_ts_demux_srcpad_query (GstPad * pad, GstQuery * query) { gboolean res = TRUE; GstFormat format; GstTSDemux *demux; MpegTSBase *base; - demux = GST_TS_DEMUX (parent); + demux = GST_TS_DEMUX (gst_pad_get_parent (pad)); base = GST_MPEGTS_BASE (demux); switch (GST_QUERY_TYPE (query)) { @@ -479,9 +484,10 @@ gst_ts_demux_srcpad_query (GstPad * pad, GstObject * parent, GstQuery * query) break; } default: - res = gst_pad_query_default (pad, parent, query); + res = gst_pad_query_default (pad, query); } + gst_object_unref (demux); return res; } @@ -554,7 +560,7 @@ gst_ts_demux_do_seek (MpegTSBase * base, GstEvent * event) if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) { gst_element_post_message (GST_ELEMENT_CAST (demux), gst_message_new_segment_start (GST_OBJECT_CAST (demux), - demux->segment.format, demux->segment.stop)); + demux->segment.format, demux->segment.last_stop)); } done: @@ -562,10 +568,10 @@ done: } static gboolean -gst_ts_demux_srcpad_event (GstPad * pad, GstObject * parent, GstEvent * event) +gst_ts_demux_srcpad_event (GstPad * pad, GstEvent * event) { gboolean res = TRUE; - GstTSDemux *demux = GST_TS_DEMUX (parent); + GstTSDemux *demux = GST_TS_DEMUX (gst_pad_get_parent (pad)); GST_DEBUG_OBJECT (pad, "Got event %s", gst_event_type_get_name (GST_EVENT_TYPE (event))); @@ -578,9 +584,10 @@ gst_ts_demux_srcpad_event (GstPad * pad, GstObject * parent, GstEvent * event) gst_event_unref (event); break; default: - res = gst_pad_event_default (pad, parent, event); + res = gst_pad_event_default (pad, event); } + gst_object_unref (demux); return res; } @@ -601,8 +608,6 @@ push_event (MpegTSBase * base, GstEvent * event) } } - gst_event_unref (event); - return TRUE; } @@ -681,7 +686,7 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream, GST_LOG ("ac3 audio"); template = gst_static_pad_template_get (&audio_template); name = g_strdup_printf ("audio_%04x", bstream->pid); - caps = gst_caps_new_empty_simple ("audio/x-ac3"); + caps = gst_caps_new_simple ("audio/x-ac3", NULL); g_free (desc); break; } @@ -692,7 +697,7 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream, GST_LOG ("ac3 audio"); template = gst_static_pad_template_get (&audio_template); name = g_strdup_printf ("audio_%04x", bstream->pid); - caps = gst_caps_new_empty_simple ("audio/x-eac3"); + caps = gst_caps_new_simple ("audio/x-eac3", NULL); g_free (desc); break; } @@ -702,7 +707,7 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream, GST_LOG ("teletext"); template = gst_static_pad_template_get (&private_template); name = g_strdup_printf ("private_%04x", bstream->pid); - caps = gst_caps_new_empty_simple ("private/teletext"); + caps = gst_caps_new_simple ("private/teletext", NULL); g_free (desc); break; } @@ -713,7 +718,7 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream, GST_LOG ("subtitling"); template = gst_static_pad_template_get (&private_template); name = g_strdup_printf ("private_%04x", bstream->pid); - caps = gst_caps_new_empty_simple ("subpicture/x-dvb"); + caps = gst_caps_new_simple ("subpicture/x-dvb", NULL); g_free (desc); break; } @@ -806,7 +811,7 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream, /* dirac in hex */ template = gst_static_pad_template_get (&video_template); name = g_strdup_printf ("video_%04x", bstream->pid); - caps = gst_caps_new_empty_simple ("video/x-dirac"); + caps = gst_caps_new_simple ("video/x-dirac", NULL); } } g_free (desc); @@ -826,7 +831,8 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream, name = g_strdup_printf ("video_%04x", bstream->pid); caps = gst_caps_new_simple ("video/x-wmv", "wmvversion", G_TYPE_INT, 3, - "format", G_TYPE_STRING, "WVC1", NULL); + "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('W', 'V', 'C', '1'), + NULL); } } g_free (desc); @@ -857,6 +863,7 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream, name = g_strdup_printf ("audio_%04x", bstream->pid); caps = gst_caps_new_simple ("audio/x-eac3", NULL); } + } g_free (desc); @@ -871,7 +878,7 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream, if (desc) { template = gst_static_pad_template_get (&audio_template); name = g_strdup_printf ("audio_%04x", bstream->pid); - caps = gst_caps_new_empty_simple ("audio/x-eac3"); + caps = gst_caps_new_simple ("audio/x-eac3", NULL); g_free (desc); break; } @@ -888,60 +895,58 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream, g_free (desc); template = gst_static_pad_template_get (&audio_template); name = g_strdup_printf ("audio_%04x", bstream->pid); - caps = gst_caps_new_empty_simple ("audio/x-ac3"); + caps = gst_caps_new_simple ("audio/x-ac3", NULL); break; } case ST_BD_AUDIO_EAC3: template = gst_static_pad_template_get (&audio_template); name = g_strdup_printf ("audio_%04x", bstream->pid); - caps = gst_caps_new_empty_simple ("audio/x-eac3"); + caps = gst_caps_new_simple ("audio/x-eac3", NULL); break; case ST_PS_AUDIO_DTS: template = gst_static_pad_template_get (&audio_template); name = g_strdup_printf ("audio_%04x", bstream->pid); - caps = gst_caps_new_empty_simple ("audio/x-dts"); + caps = gst_caps_new_simple ("audio/x-dts", NULL); break; case ST_PS_AUDIO_LPCM: template = gst_static_pad_template_get (&audio_template); name = g_strdup_printf ("audio_%04x", bstream->pid); - caps = gst_caps_new_empty_simple ("audio/x-lpcm"); + caps = gst_caps_new_simple ("audio/x-lpcm", NULL); break; case ST_BD_AUDIO_LPCM: template = gst_static_pad_template_get (&audio_template); name = g_strdup_printf ("audio_%04x", bstream->pid); - caps = gst_caps_new_empty_simple ("audio/x-private-ts-lpcm"); + caps = gst_caps_new_simple ("audio/x-private-ts-lpcm", NULL); break; case ST_PS_DVD_SUBPICTURE: template = gst_static_pad_template_get (&subpicture_template); name = g_strdup_printf ("subpicture_%04x", bstream->pid); - caps = gst_caps_new_empty_simple ("video/x-dvd-subpicture"); + caps = gst_caps_new_simple ("video/x-dvd-subpicture", NULL); break; case ST_BD_PGS_SUBPICTURE: template = gst_static_pad_template_get (&subpicture_template); name = g_strdup_printf ("subpicture_%04x", bstream->pid); - caps = gst_caps_new_empty_simple ("subpicture/x-pgs"); + caps = gst_caps_new_simple ("subpicture/x-pgs", NULL); break; default: GST_WARNING ("Non-media stream (stream_type:0x%x). Not creating pad", bstream->stream_type); break; } - if (template && name && caps) { GST_LOG ("stream:%p creating pad with name %s and caps %s", stream, name, gst_caps_to_string (caps)); pad = gst_pad_new_from_template (template, name); - gst_pad_set_active (pad, TRUE); gst_pad_use_fixed_caps (pad); gst_pad_set_caps (pad, caps); + gst_pad_set_query_type_function (pad, gst_ts_demux_srcpad_query_types); gst_pad_set_query_function (pad, gst_ts_demux_srcpad_query); gst_pad_set_event_function (pad, gst_ts_demux_srcpad_event); } if (name) g_free (name); - if (template) - gst_object_unref (template); + if (caps) gst_caps_unref (caps); @@ -1002,6 +1007,7 @@ activate_pad_for_stream (GstTSDemux * tsdemux, TSDemuxStream * stream) if (stream->pad) { GST_DEBUG_OBJECT (tsdemux, "Activating pad %s:%s for stream %p", GST_DEBUG_PAD_NAME (stream->pad), stream); + gst_pad_set_active (stream->pad, TRUE); gst_element_add_pad ((GstElement *) tsdemux, stream->pad); stream->active = TRUE; GST_DEBUG_OBJECT (stream->pad, "done adding pad"); @@ -1097,7 +1103,7 @@ gst_ts_demux_record_pcr (GstTSDemux * demux, TSDemuxStream * stream, if (G_UNLIKELY (demux->emit_statistics)) { GstStructure *st; - st = gst_structure_new_id_empty (QUARK_TSDEMUX); + st = gst_structure_id_empty_new (QUARK_TSDEMUX); gst_structure_id_set (st, QUARK_PID, G_TYPE_UINT, bs->pid, QUARK_OFFSET, G_TYPE_UINT64, offset, QUARK_PCR, G_TYPE_UINT64, pcr, @@ -1121,7 +1127,7 @@ gst_ts_demux_record_opcr (GstTSDemux * demux, TSDemuxStream * stream, if (G_UNLIKELY (demux->emit_statistics)) { GstStructure *st; - st = gst_structure_new_id_empty (QUARK_TSDEMUX); + st = gst_structure_id_empty_new (QUARK_TSDEMUX); gst_structure_id_set (st, QUARK_PID, G_TYPE_UINT, bs->pid, QUARK_OFFSET, G_TYPE_UINT64, offset, @@ -1167,7 +1173,7 @@ gst_ts_demux_record_pts (GstTSDemux * demux, TSDemuxStream * stream, if (G_UNLIKELY (demux->emit_statistics)) { GstStructure *st; - st = gst_structure_new_id_empty (QUARK_TSDEMUX); + st = gst_structure_id_empty_new (QUARK_TSDEMUX); gst_structure_id_set (st, QUARK_PID, G_TYPE_UINT, bs->pid, QUARK_OFFSET, G_TYPE_UINT64, offset, QUARK_PTS, G_TYPE_UINT64, pts, @@ -1212,7 +1218,7 @@ gst_ts_demux_record_dts (GstTSDemux * demux, TSDemuxStream * stream, if (G_UNLIKELY (demux->emit_statistics)) { GstStructure *st; - st = gst_structure_new_id_empty (QUARK_TSDEMUX); + st = gst_structure_id_empty_new (QUARK_TSDEMUX); gst_structure_id_set (st, QUARK_PID, G_TYPE_UINT, bs->pid, QUARK_OFFSET, G_TYPE_UINT64, offset, QUARK_DTS, G_TYPE_UINT64, dts, @@ -1227,22 +1233,20 @@ gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream) { MpegTSBase *base = (MpegTSBase *) demux; PESHeader header; - GstBuffer *buf = stream->pendingbuffers[0]; GstFlowReturn res = GST_FLOW_OK; gint offset = 0; - GstMapInfo map; + guint8 *data; + guint32 length; guint64 bufferoffset; PESParsingResult parseres; - GstClockTime origts; - - gst_buffer_map (buf, &map, GST_MAP_READ); - bufferoffset = GST_BUFFER_OFFSET (buf); - origts = GST_BUFFER_TIMESTAMP (buf); - GST_MEMDUMP ("Header buffer", map.data, MIN (map.size, 32)); + data = GST_BUFFER_DATA (stream->pendingbuffers[0]); + length = GST_BUFFER_SIZE (stream->pendingbuffers[0]); + bufferoffset = GST_BUFFER_OFFSET (stream->pendingbuffers[0]); - parseres = mpegts_parse_pes_header (map.data, map.size, &header, &offset); + GST_MEMDUMP ("Header buffer", data, MIN (length, 32)); + parseres = mpegts_parse_pes_header (data, length, &header, &offset); if (G_UNLIKELY (parseres == PES_PARSING_NEED_MORE)) goto discont; if (G_UNLIKELY (parseres == PES_PARSING_BAD)) { @@ -1272,25 +1276,27 @@ gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream) GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (stream->pendingbuffers[0]))); } - if (header.DTS != -1) - gst_ts_demux_record_dts (demux, stream, header.DTS, bufferoffset); - - gst_buffer_unmap (buf, &map); - /* Remove PES headers */ GST_DEBUG ("Moving data forward by %d bytes (packet_size:%d, have:%d)", header.header_size, header.packet_length, GST_BUFFER_SIZE (stream->pendingbuffers[0])); stream->expected_size = header.packet_length; - gst_buffer_resize (buf, header.header_size, map.size - header.header_size); + GST_BUFFER_DATA (stream->pendingbuffers[0]) += header.header_size; + GST_BUFFER_SIZE (stream->pendingbuffers[0]) -= header.header_size; /* FIXME : responsible for switching to PENDING_PACKET_BUFFER and * creating the bufferlist */ if (1) { /* Append to the buffer list */ - if (G_UNLIKELY (stream->currentlist == NULL)) { + if (G_UNLIKELY (stream->current == NULL)) { guint8 i; + /* Create a new bufferlist */ + stream->current = gst_buffer_list_new (); + stream->currentit = gst_buffer_list_iterate (stream->current); + stream->currentlist = NULL; + gst_buffer_list_iterator_add_group (stream->currentit); + /* Push pending buffers into the list */ for (i = stream->nbpending; i; i--) stream->currentlist = @@ -1317,19 +1323,14 @@ gst_ts_demux_queue_data (GstTSDemux * demux, TSDemuxStream * stream, MpegTSPacketizerPacket * packet) { GstBuffer *buf; - GstMapInfo map; GST_DEBUG ("state:%d", stream->state); buf = packet->buffer; - gst_buffer_map (buf, &map, GST_MAP_READ); - - GST_DEBUG ("Resizing buffer to %d (size:%d) (Was %" G_GSIZE_FORMAT - " bytes long)", (int) (packet->payload - map.data), - (int) (packet->data_end - packet->payload), map.size); - gst_buffer_resize (buf, packet->payload - map.data, - packet->data_end - packet->payload); - gst_buffer_unmap (buf, &map); + /* HACK : Instead of creating a new buffer, we just modify the data/size + * of the buffer to point to the payload */ + GST_BUFFER_DATA (buf) = packet->payload; + GST_BUFFER_SIZE (buf) = packet->data_end - packet->payload; if (stream->state == PENDING_PACKET_EMPTY) { if (G_UNLIKELY (!packet->payload_unit_start_indicator)) { @@ -1338,6 +1339,10 @@ gst_ts_demux_queue_data (GstTSDemux * demux, TSDemuxStream * stream, } else { GST_LOG ("EMPTY=>HEADER"); stream->state = PENDING_PACKET_HEADER; + if (stream->pad) { + GST_DEBUG ("Setting pad caps on buffer %p", buf); + gst_buffer_set_caps (buf, GST_PAD_CAPS (stream->pad)); + } } } @@ -1391,7 +1396,6 @@ calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream) lowest_pts = pstream->dts; } } - if (GST_CLOCK_TIME_IS_VALID (lowest_pts)) firstts = mpegts_packetizer_pts_to_ts (base->packetizer, lowest_pts); GST_DEBUG ("lowest_pts %" G_GUINT64_FORMAT " => clocktime %" GST_TIME_FORMAT, @@ -1403,7 +1407,10 @@ calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream) if (demux->segment.format == GST_FORMAT_TIME) { GST_DEBUG ("Re-using segment " SEGMENT_FORMAT, SEGMENT_ARGS (demux->segment)); - demux->update_segment = gst_event_new_segment (&demux->segment); + demux->update_segment = + gst_event_new_new_segment_full (TRUE, demux->segment.rate, + demux->segment.applied_rate, GST_FORMAT_TIME, demux->segment.start, + firstts, demux->segment.time); GST_EVENT_SRC (demux->update_segment) = gst_object_ref (demux); } demux->calculate_update_segment = FALSE; @@ -1412,7 +1419,9 @@ calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream) if (!demux->segment_event) { GST_DEBUG ("Calculating actual segment"); /* FIXME : Set proper values */ - demux->segment_event = gst_event_new_segment (&demux->segment); + demux->segment_event = + gst_event_new_new_segment_full (FALSE, 1.0, 1.0, GST_FORMAT_TIME, + firstts, GST_CLOCK_TIME_NONE, firstts); GST_EVENT_SRC (demux->segment_event) = gst_object_ref (demux); } @@ -1436,7 +1445,6 @@ static GstFlowReturn gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream) { GstFlowReturn res = GST_FLOW_OK; - GList *tmp; MpegTSBaseStream *bs = (MpegTSBaseStream *) stream; /* MpegTSBase *base = (MpegTSBase*) demux; */ GstBuffer *firstbuffer = NULL; @@ -1446,7 +1454,7 @@ gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream) "stream:%p, pid:0x%04x stream_type:%d state:%d", stream, bs->pid, bs->stream_type, stream->state); - if (G_UNLIKELY (stream->currentlist == NULL)) { + if (G_UNLIKELY (stream->current == NULL)) { GST_LOG ("stream->current == NULL"); goto beach; } @@ -1465,7 +1473,8 @@ gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream) if (G_UNLIKELY (stream->pad == NULL)) { g_list_foreach (stream->currentlist, (GFunc) gst_buffer_unref, NULL); g_list_free (stream->currentlist); - stream->currentlist = NULL; + gst_buffer_list_iterator_free (stream->currentit); + gst_buffer_list_unref (stream->current); goto beach; } @@ -1473,26 +1482,10 @@ gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream) calculate_and_push_newsegment (demux, stream); /* We have a confirmed buffer, let's push it out */ - GST_LOG_OBJECT (stream->pad, "Putting pending data into buffer list"); + GST_LOG_OBJECT (stream->pad, "Putting pending data into GstBufferList"); stream->currentlist = g_list_reverse (stream->currentlist); - buf = (GstBuffer *) stream->currentlist->data; - - ts = GST_BUFFER_TIMESTAMP (buf); - - GST_DEBUG_OBJECT (stream->pad, - "ts %" GST_TIME_FORMAT " delta %" GST_TIME_FORMAT " stream->pts %" - GST_TIME_FORMAT, GST_TIME_ARGS (ts), GST_TIME_ARGS (demux->pts_delta), - GST_TIME_ARGS (stream->pts)); - - if (GST_CLOCK_TIME_IS_VALID (demux->pts_delta) - && GST_CLOCK_TIME_IS_VALID (stream->pts) - && !GST_CLOCK_TIME_IS_VALID (ts)) { - ts = stream->pts - demux->pts_delta; - } - - for (tmp = stream->currentlist->next; tmp; tmp = tmp->next) { - buf = gst_buffer_append (buf, (GstBuffer *) tmp->data); - } + gst_buffer_list_iterator_add_list (stream->currentit, stream->currentlist); + gst_buffer_list_iterator_free (stream->currentit); firstbuffer = gst_buffer_list_get (stream->current, 0, 0); @@ -1507,7 +1500,7 @@ gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream) "Pushing buffer list with timestamp: %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (firstbuffer))); - res = gst_pad_push (stream->pad, buf); + res = gst_pad_push_list (stream->pad, stream->current); GST_DEBUG_OBJECT (stream->pad, "Returned %s", gst_flow_get_name (res)); res = tsdemux_combine_flows (demux, stream, res); GST_DEBUG_OBJECT (stream->pad, "combined %s", gst_flow_get_name (res)); @@ -1531,10 +1524,8 @@ gst_ts_demux_handle_packet (GstTSDemux * demux, TSDemuxStream * stream, { GstFlowReturn res = GST_FLOW_OK; -#if 0 GST_DEBUG ("buffer:%p, data:%p", GST_BUFFER_DATA (packet->buffer), packet->data); -#endif GST_LOG ("pid 0x%04x pusi:%d, afc:%d, cont:%d, payload:%p", packet->pid, packet->payload_unit_start_indicator, @@ -1542,8 +1533,8 @@ gst_ts_demux_handle_packet (GstTSDemux * demux, TSDemuxStream * stream, packet->continuity_counter, packet->payload); if (section) { - GST_DEBUG ("section complete:%d, buffer size %" G_GSIZE_FORMAT, - section->complete, gst_buffer_get_size (section->buffer)); + GST_DEBUG ("section complete:%d, buffer size %d", + section->complete, GST_BUFFER_SIZE (section->buffer)); gst_buffer_unref (packet->buffer); return res; } @@ -1590,8 +1581,6 @@ gst_ts_demux_push (MpegTSBase * base, MpegTSPacketizerPacket * packet, TSDemuxStream *stream = NULL; GstFlowReturn res = GST_FLOW_OK; - GST_DEBUG ("packet->buffer %p", packet->buffer); - if (G_LIKELY (demux->program)) { stream = (TSDemuxStream *) demux->program->streams[packet->pid]; |