diff --git a/gst/camerabin2/gstwrappercamerabinsrc.c b/gst/camerabin2/gstwrappercamerabinsrc.c index 3bc047108d..cef902d875 100644 --- a/gst/camerabin2/gstwrappercamerabinsrc.c +++ b/gst/camerabin2/gstwrappercamerabinsrc.c @@ -163,7 +163,10 @@ gst_wrapper_camera_bin_reset_video_src_caps (GstWrapperCameraBinSrc * self, self->drop_newseg = TRUE; GST_DEBUG_OBJECT (self, "Bringing source up"); - gst_element_sync_state_with_parent (self->src_vid_src); + if (!gst_element_sync_state_with_parent (self->src_vid_src)) { + GST_WARNING_OBJECT (self, "Failed to reset source caps"); + gst_element_set_state (self->src_vid_src, GST_STATE_NULL); + } if (clock) { gst_element_set_clock (self->src_vid_src, clock); diff --git a/gst/mpegtsdemux/gstmpegdefs.h b/gst/mpegtsdemux/gstmpegdefs.h index be6209aaf7..66f922b715 100644 --- a/gst/mpegtsdemux/gstmpegdefs.h +++ b/gst/mpegtsdemux/gstmpegdefs.h @@ -151,8 +151,9 @@ #define ST_DSMCC_D 0x0d /* later extensions */ -#define ST_AUDIO_AAC 0x0f +#define ST_AUDIO_AAC_ADTS 0x0f #define ST_VIDEO_MPEG4 0x10 +#define ST_AUDIO_AAC_LATM 0x11 #define ST_VIDEO_H264 0x1b /* Un-official Dirac extension */ diff --git a/gst/mpegtsdemux/mpegtsbase.c b/gst/mpegtsdemux/mpegtsbase.c index bb200df743..129e9dd1e6 100644 --- a/gst/mpegtsdemux/mpegtsbase.c +++ b/gst/mpegtsdemux/mpegtsbase.c @@ -645,6 +645,7 @@ mpegts_base_activate_program (MpegTSBase * base, MpegTSBaseProgram * program, /* activate new pmt */ if (program->pmt_info) gst_structure_free (program->pmt_info); + program->pmt_info = gst_structure_copy (pmt_info); program->pmt_pid = pmt_pid; program->pcr_pid = pcr_pid; @@ -695,7 +696,7 @@ mpegts_base_is_psi (MpegTSBase * base, MpegTSPacketizerPacket * packet) if (MPEGTS_BIT_IS_SET (base->known_psi, packet->pid)) retval = TRUE; - /* check is it is a pes pid */ + /* check if it is a pes pid */ if (MPEGTS_BIT_IS_SET (base->is_pes, packet->pid)) return FALSE; @@ -845,7 +846,6 @@ mpegts_base_apply_pmt (MpegTSBase * base, { MpegTSBaseProgram *program, *old_program; guint program_number; - gboolean deactivate_old_program = FALSE; /* FIXME : not so sure this is valid anymore */ if (G_UNLIKELY (base->seen_pat == FALSE)) { @@ -876,19 +876,16 @@ mpegts_base_apply_pmt (MpegTSBase * base, program = mpegts_base_new_program (base, program_number, pmt_pid); g_hash_table_insert (base->programs, GINT_TO_POINTER (program_number), program); - deactivate_old_program = TRUE; + + /* Desactivate the old program */ + mpegts_base_deactivate_program (base, old_program); + mpegts_base_free_program (old_program); } else program = old_program; /* First activate program */ mpegts_base_activate_program (base, program, pmt_pid, pmt_info); - if (deactivate_old_program) { - /* deactivate old pmt */ ; - mpegts_base_deactivate_program (base, old_program); - mpegts_base_free_program (old_program); - } - /* if (program->pmt_info) */ /* gst_structure_free (program->pmt_info); */ /* program->pmt_info = NULL; */ @@ -1359,8 +1356,9 @@ mpegts_base_scan (MpegTSBase * base) /* Find initial sync point */ for (i = 0; i < 10; i++) { - GST_DEBUG ("Grabbing %d => %d", - i * 50 * MPEGTS_MAX_PACKETSIZE, 50 * MPEGTS_MAX_PACKETSIZE); + GST_DEBUG ("Grabbing %d => %d", i * 50 * MPEGTS_MAX_PACKETSIZE, + 50 * MPEGTS_MAX_PACKETSIZE); + ret = gst_pad_pull_range (base->sinkpad, i * 50 * MPEGTS_MAX_PACKETSIZE, 50 * MPEGTS_MAX_PACKETSIZE, &buf); if (G_UNLIKELY (ret != GST_FLOW_OK)) diff --git a/gst/mpegtsdemux/mpegtspacketizer.c b/gst/mpegtsdemux/mpegtspacketizer.c index 148e5410af..f16514ba0d 100644 --- a/gst/mpegtsdemux/mpegtspacketizer.c +++ b/gst/mpegtsdemux/mpegtspacketizer.c @@ -1,7 +1,7 @@ /* - * mpegtspacketizer.c - + * mpegtspacketizer.c - * Copyright (C) 2007, 2008 Alessandro Decina, Zaheer Merali - * + * * Authors: * Zaheer Merali * Alessandro Decina @@ -78,6 +78,7 @@ static gchar *get_encoding_and_convert (const gchar * text, guint length); #define MAX_CONTINUITY 15 #define VERSION_NUMBER_UNSET 255 #define TABLE_ID_UNSET 0xFF +#define PACKET_SYNC_BYTE 0x47 static gint mpegts_packetizer_stream_subtable_compare (gconstpointer a, gconstpointer b) @@ -403,7 +404,7 @@ mpegts_packetizer_parse_descriptors (MpegTSPacketizer2 * packetizer, /* include length */ desc = g_string_new_len ((gchar *) data - 2, length + 2); data += length; - /* G_TYPE_GSTING is a GBoxed type and is used so properly marshalled from python */ + /* G_TYPE_GSTRING is a GBoxed type and is used so properly marshalled from python */ g_value_init (&value, G_TYPE_GSTRING); g_value_take_boxed (&value, desc); g_value_array_append (descriptors, &value); @@ -537,6 +538,8 @@ mpegts_packetizer_parse_pmt (MpegTSPacketizer2 * packetizer, program_number = GST_READ_UINT16_BE (data); data += 2; + GST_DEBUG ("Parsing %d Program Map Table", program_number); + tmp = *data++; section->version_number = (tmp >> 1) & 0x1F; section->current_next_indicator = tmp & 0x01; @@ -581,6 +584,7 @@ mpegts_packetizer_parse_pmt (MpegTSPacketizer2 * packetizer, * bytes) plus the CRC */ while (data <= end - 4 - 5) { stream_type = *data++; + GST_DEBUG ("Stream type 0x%02x found", stream_type); pid = GST_READ_UINT16_BE (data) & 0x1FFF; data += 2; @@ -2206,13 +2210,14 @@ mpegts_try_discover_packet_size (MpegTSPacketizer2 * packetizer) /* find first sync byte */ pos = -1; for (i = 0; i < MPEGTS_MAX_PACKETSIZE; i++) { - if (dest[i] == 0x47) { + if (dest[i] == PACKET_SYNC_BYTE) { for (j = 0; j < 4; j++) { guint packetsize = psizes[j]; /* check each of the packet size possibilities in turn */ - if (dest[i] == 0x47 && dest[i + packetsize] == 0x47 && - dest[i + packetsize * 2] == 0x47 && - dest[i + packetsize * 3] == 0x47) { + if (dest[i] == PACKET_SYNC_BYTE + && dest[i + packetsize] == PACKET_SYNC_BYTE + && dest[i + packetsize * 2] == PACKET_SYNC_BYTE + && dest[i + packetsize * 3] == PACKET_SYNC_BYTE) { packetizer->know_packet_size = TRUE; packetizer->packet_size = packetsize; packetizer->caps = gst_caps_new_simple ("video/mpegts", @@ -2247,10 +2252,10 @@ mpegts_try_discover_packet_size (MpegTSPacketizer2 * packetizer) GST_DEBUG ("Flushing out %d bytes", pos); gst_adapter_flush (packetizer->adapter, pos); packetizer->offset += pos; - } else if (!packetizer->know_packet_size) { - /* drop invalid data and move to the next possible packets */ - gst_adapter_flush (packetizer->adapter, MPEGTS_MAX_PACKETSIZE); } + } else { + /* drop invalid data and move to the next possible packets */ + GST_DEBUG ("Could not determine packet size"); } return packetizer->know_packet_size; @@ -2406,7 +2411,6 @@ mpegts_packetizer_push_section (MpegTSPacketizer2 * packetizer, sub_buf = gst_buffer_copy_region (packet->buffer, GST_BUFFER_COPY_ALL, data - packet->bufmap.data, packet->data_end - data); - stream = packetizer->streams[packet->pid]; if (stream == NULL) { stream = mpegts_packetizer_stream_new (); @@ -2415,7 +2419,7 @@ mpegts_packetizer_push_section (MpegTSPacketizer2 * packetizer, if (packet->payload_unit_start_indicator) { table_id = *data++; - /* subtable_extension should be read from 4th and 5th bytes only if + /* subtable_extension should be read from 4th and 5th bytes only if * section_syntax_indicator is 1 */ if ((data[0] & 0x80) == 0) subtable_extension = 0; @@ -2541,7 +2545,7 @@ _init_local (void) * @is_multibyte: Location where information whether it's a multibyte encoding * or not is stored * @returns: Name of encoding or NULL of encoding could not be detected. - * + * * The returned string should be freed with g_free () when no longer needed. */ static gchar * diff --git a/gst/mpegtsdemux/tsdemux.c b/gst/mpegtsdemux/tsdemux.c index 70b464a640..f3a32d4b97 100644 --- a/gst/mpegtsdemux/tsdemux.c +++ b/gst/mpegtsdemux/tsdemux.c @@ -44,7 +44,7 @@ #include "payload_parsers.h" #include "pesparse.h" -/* +/* * tsdemux * * See TODO for explanations on improvements needed @@ -56,7 +56,7 @@ #define TABLE_ID_UNSET 0xFF /* Size of the pendingbuffers array. */ -#define TS_MAX_PENDING_BUFFERS 256 +#define TS_MAX_PENDING_BUFFERS 256 #define PCR_WRAP_SIZE_128KBPS (((gint64)1490)*(1024*1024)) /* small PCR for wrap detection */ @@ -147,7 +147,7 @@ struct _TSDemuxStream "mpegversion = (int) 1;" \ "audio/mpeg, " \ "mpegversion = (int) 4, " \ - "stream-format = (string) adts; " \ + "stream-format = (string) {adts, loas}; " \ "audio/x-lpcm, " \ "width = (int) { 16, 20, 24 }, " \ "rate = (int) { 48000, 96000 }, " \ @@ -1085,13 +1085,20 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream, case ST_DSMCC_D: MPEGTS_BIT_UNSET (base->is_pes, bstream->pid); break; - case ST_AUDIO_AAC: /* ADTS */ + case ST_AUDIO_AAC_ADTS: template = gst_static_pad_template_get (&audio_template); name = g_strdup_printf ("audio_%04x", bstream->pid); caps = gst_caps_new_simple ("audio/mpeg", "mpegversion", G_TYPE_INT, 4, "stream-format", G_TYPE_STRING, "adts", NULL); break; + case ST_AUDIO_AAC_LATM: + template = gst_static_pad_template_get (&audio_template); + name = g_strdup_printf ("audio_%04x", bstream->pid); + caps = gst_caps_new_simple ("audio/mpeg", + "mpegversion", G_TYPE_INT, 4, + "stream-format", G_TYPE_STRING, "loas", NULL); + break; case ST_VIDEO_MPEG4: template = gst_static_pad_template_get (&video_template); name = g_strdup_printf ("video_%04x", bstream->pid); @@ -1369,10 +1376,10 @@ process_section (MpegTSBase * base) MpegTSPacketizerPacket packet; MpegTSPacketizerPacketReturn pret; - while ((!done) - && ((pret = - mpegts_packetizer_next_packet (base->packetizer, - &packet)) != PACKET_NEED_MORE)) { + while ((!done) && + ((pret = mpegts_packetizer_next_packet (base->packetizer, &packet)) + != PACKET_NEED_MORE)) { + if (G_UNLIKELY (pret == PACKET_BAD)) /* bad header, skip the packet */ goto next; @@ -1381,8 +1388,9 @@ process_section (MpegTSBase * base) if (packet.payload != NULL && mpegts_base_is_psi (base, &packet)) { MpegTSPacketizerSection section; - based = - mpegts_packetizer_push_section (base->packetizer, &packet, §ion); + based = mpegts_packetizer_push_section (base->packetizer, &packet, + §ion); + if (G_UNLIKELY (!based)) /* bad section data */ goto next; @@ -1419,10 +1427,9 @@ process_pes (MpegTSBase * base, TSPcrOffset * pcroffset) GstTSDemux *demux = GST_TS_DEMUX (base); guint16 pcr_pid = 0; - while ((!done) - && ((pret = - mpegts_packetizer_next_packet (base->packetizer, - &packet)) != PACKET_NEED_MORE)) { + while ((!done) && + ((pret = mpegts_packetizer_next_packet (base->packetizer, &packet)) + != PACKET_NEED_MORE)) { if (G_UNLIKELY (pret == PACKET_BAD)) /* bad header, skip the packet */ goto next; @@ -1435,8 +1442,9 @@ process_pes (MpegTSBase * base, TSPcrOffset * pcroffset) if (packet.payload != NULL && mpegts_base_is_psi (base, &packet)) { MpegTSPacketizerSection section; - based = - mpegts_packetizer_push_section (base->packetizer, &packet, §ion); + based = mpegts_packetizer_push_section (base->packetizer, &packet, + §ion); + if (G_UNLIKELY (!based)) /* bad section data */ goto next; @@ -1593,16 +1601,15 @@ find_timestamps (MpegTSBase * base, guint64 initoff, guint64 * offset) GST_DEBUG ("Scanning for timestamps"); - /* Flush what remained from before */ - mpegts_packetizer_clear (base->packetizer); + /* Start scanning from now PAT offset */ - /* Start scanning from know PAT offset */ while (!done) { - ret = - gst_pad_pull_range (base->sinkpad, i * 50 * MPEGTS_MAX_PACKETSIZE, + ret = gst_pad_pull_range (base->sinkpad, i * 50 * MPEGTS_MAX_PACKETSIZE, 50 * MPEGTS_MAX_PACKETSIZE, &buf); + if (ret != GST_FLOW_OK) goto beach; + mpegts_packetizer_push (base->packetizer, buf); done = process_section (base); i++; @@ -1611,7 +1618,6 @@ find_timestamps (MpegTSBase * base, guint64 initoff, guint64 * offset) done = FALSE; i = 1; - *offset = base->seek_offset; /* Search for the first PCRs */ @@ -1623,7 +1629,7 @@ find_timestamps (MpegTSBase * base, guint64 initoff, guint64 * offset) } mpegts_packetizer_clear (base->packetizer); - /* Remove current program so we ensure looking for a PAT when scanning the + /* Remove current program so we ensure looking for a PAT when scanning * for the final PCR */ gst_structure_free (base->pat); base->pat = NULL; @@ -1634,9 +1640,9 @@ find_timestamps (MpegTSBase * base, guint64 initoff, guint64 * offset) if (G_UNLIKELY (!gst_pad_peer_query_duration (base->sinkpad, GST_FORMAT_BYTES, &total_bytes))) { GST_WARNING_OBJECT (base, "Couldn't get upstream size in bytes"); - ret = GST_FLOW_ERROR; mpegts_packetizer_clear (base->packetizer); - return ret; + + return GST_FLOW_ERROR; } GST_DEBUG ("Upstream is %" G_GINT64_FORMAT " bytes", total_bytes); @@ -1646,10 +1652,11 @@ find_timestamps (MpegTSBase * base, guint64 initoff, guint64 * offset) GST_DEBUG ("Scanning for last sync point between:%" G_GINT64_FORMAT " and the end:%" G_GINT64_FORMAT, scan_offset, total_bytes); + while ((!done) && (scan_offset < total_bytes)) { - ret = - gst_pad_pull_range (base->sinkpad, - scan_offset, 50 * MPEGTS_MAX_PACKETSIZE, &buf); + ret = gst_pad_pull_range (base->sinkpad, scan_offset, + 50 * MPEGTS_MAX_PACKETSIZE, &buf); + if (ret != GST_FLOW_OK) goto beach; @@ -1660,10 +1667,8 @@ find_timestamps (MpegTSBase * base, guint64 initoff, guint64 * offset) mpegts_packetizer_clear (base->packetizer); - GST_DEBUG ("Searching PCR"); - ret = - process_pcr (base, scan_offset - 50 * MPEGTS_MAX_PACKETSIZE, &final, 10, - FALSE); + ret = process_pcr (base, scan_offset - 50 * MPEGTS_MAX_PACKETSIZE, &final, + 10, FALSE); if (ret != GST_FLOW_OK) { GST_DEBUG ("Problem getting last PCRs"); @@ -1699,7 +1704,7 @@ process_pcr (MpegTSBase * base, guint64 initoff, TSPcrOffset * pcroffset, GstFlowReturn ret = GST_FLOW_OK; MpegTSBaseProgram *program; GstBuffer *buf; - guint nbpcr, i = 0; + guint i, nbpcr = 0; guint32 pcrmask, pcrpattern; guint64 pcrs[50]; guint64 pcroffs[50]; @@ -1710,8 +1715,12 @@ process_pcr (MpegTSBase * base, guint64 initoff, TSPcrOffset * pcroffset, /* Get the program */ program = demux->program; - if (G_UNLIKELY (program == NULL)) - return GST_FLOW_ERROR; + if (G_UNLIKELY (program == NULL)) { + GST_DEBUG ("No program set, can not keep processing pcr"); + + ret = GST_FLOW_ERROR; + goto beach; + } /* First find the first X PCR */ nbpcr = 0; @@ -1733,8 +1742,7 @@ process_pcr (MpegTSBase * base, guint64 initoff, TSPcrOffset * pcroffset, GstMapInfo map; gsize size; - ret = - gst_pad_pull_range (base->sinkpad, + ret = gst_pad_pull_range (base->sinkpad, initoff + i * 500 * base->packetsize, 500 * base->packetsize, &buf); if (G_UNLIKELY (ret != GST_FLOW_OK)) diff --git a/gst/mve/gstmvedemux.c b/gst/mve/gstmvedemux.c index a101a9059d..9851e68eb3 100644 --- a/gst/mve/gstmvedemux.c +++ b/gst/mve/gstmvedemux.c @@ -713,7 +713,7 @@ gst_mve_audio_init (GstMveDemux * mve, guint8 version, const guint8 * data, if (gst_mve_add_stream (mve, stream, list)) return gst_pad_push_event (mve->audio_stream->pad, gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, - 0, GST_CLOCK_TIME_NONE, 0)); + 0, GST_CLOCK_TIME_NONE, 0)) ? GST_FLOW_OK : GST_FLOW_ERROR; else return GST_FLOW_OK; } @@ -866,7 +866,7 @@ gst_mve_timer_create (GstMveDemux * mve, const guint8 * data, guint16 len, if (gst_mve_add_stream (mve, s, list)) return gst_pad_push_event (s->pad, gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, - 0, GST_CLOCK_TIME_NONE, 0)); + 0, GST_CLOCK_TIME_NONE, 0)) ? GST_FLOW_OK : GST_FLOW_ERROR; else return GST_FLOW_OK; } @@ -1090,12 +1090,10 @@ gst_mve_demux_base_init (GstMveDemuxClass * klass) GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&vidsrc_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&audsrc_template)); + gst_element_class_add_static_pad_template (element_class, &sink_template); + gst_element_class_add_static_pad_template (element_class, &vidsrc_template); + gst_element_class_add_static_pad_template (element_class, &audsrc_template); + gst_element_class_set_details_simple (element_class, "MVE Demuxer", "Codec/Demuxer", "Demultiplex an Interplay movie (MVE) stream into audio and video",