From 6094ec27b17cd69f43e5e5c86b6bcad9f92d1f96 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Wed, 15 Feb 2012 11:06:57 -0300 Subject: [PATCH 1/5] tsdemux: Minor refactoring/code cleaning ... add some debugging symbols in the mean time. --- gst/mpegtsdemux/mpegtsbase.c | 23 +++++------ gst/mpegtsdemux/mpegtspacketizer.c | 31 ++++++++------- gst/mpegtsdemux/tsdemux.c | 62 +++++++++++++++--------------- 3 files changed, 58 insertions(+), 58 deletions(-) diff --git a/gst/mpegtsdemux/mpegtsbase.c b/gst/mpegtsdemux/mpegtsbase.c index 99b5ea7bf2..363eeaf479 100644 --- a/gst/mpegtsdemux/mpegtsbase.c +++ b/gst/mpegtsdemux/mpegtsbase.c @@ -639,6 +639,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; @@ -689,7 +690,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; @@ -839,7 +840,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)) { @@ -870,19 +870,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; */ @@ -1266,8 +1263,7 @@ mpegts_base_chain (GstPad * pad, GstBuffer * buf) } mpegts_packetizer_push (base->packetizer, buf); - while (((pret = - mpegts_packetizer_next_packet (base->packetizer, + 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 */ @@ -1319,8 +1315,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 25d75cfa84..d88fd19193 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) @@ -396,7 +397,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); @@ -521,6 +522,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; @@ -565,6 +568,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; @@ -2159,13 +2163,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", @@ -2200,10 +2205,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; @@ -2235,6 +2240,7 @@ mpegts_packetizer_next_packet (MpegTSPacketizer2 * packetizer, while ((avail = packetizer->adapter->size) >= packetizer->packet_size) { packet->buffer = gst_adapter_take_buffer (packetizer->adapter, packetizer->packet_size); + /* M2TS packets don't start with the sync byte, all other variants do */ if (packetizer->packet_size == MPEGTS_M2TS_PACKETSIZE) { packet->data_start = GST_BUFFER_DATA (packet->buffer) + 4; @@ -2347,7 +2353,6 @@ mpegts_packetizer_push_section (MpegTSPacketizer2 * packetizer, 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) { stream = mpegts_packetizer_stream_new (); @@ -2356,7 +2361,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; @@ -2481,7 +2486,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 166089ba5b..03814b6d46 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 */ @@ -1363,10 +1363,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; @@ -1375,8 +1375,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; @@ -1412,10 +1413,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; @@ -1428,8 +1428,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; @@ -1587,16 +1588,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++; @@ -1605,7 +1605,6 @@ find_timestamps (MpegTSBase * base, guint64 initoff, guint64 * offset) done = FALSE; i = 1; - *offset = base->seek_offset; /* Search for the first PCRs */ @@ -1617,7 +1616,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; @@ -1628,9 +1627,9 @@ find_timestamps (MpegTSBase * base, guint64 initoff, guint64 * offset) if (G_UNLIKELY (!gst_pad_query_peer_duration (base->sinkpad, &format, &total_bytes) || format != GST_FORMAT_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); @@ -1640,10 +1639,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; @@ -1654,10 +1654,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"); @@ -1669,6 +1667,7 @@ find_timestamps (MpegTSBase * base, guint64 initoff, guint64 * offset) gst_segment_set_duration (&demux->segment, GST_FORMAT_TIME, demux->last_pcr.gsttime - demux->first_pcr.gsttime); demux->duration = demux->last_pcr.gsttime - demux->first_pcr.gsttime; + GST_DEBUG ("Done, duration:%" GST_TIME_FORMAT, GST_TIME_ARGS (demux->duration)); @@ -1726,8 +1725,7 @@ process_pcr (MpegTSBase * base, guint64 initoff, TSPcrOffset * pcroffset, for (i = 0; (i < 20) && (nbpcr < numpcr); i++) { guint offset, 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)) From cda0d3aed881018c4a39273613f7644742705ece Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Tue, 14 Feb 2012 11:44:48 -0300 Subject: [PATCH 2/5] tsdemux: Add AAC latm support --- gst/mpegtsdemux/gstmpegdefs.h | 3 ++- gst/mpegtsdemux/tsdemux.c | 20 ++++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) 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/tsdemux.c b/gst/mpegtsdemux/tsdemux.c index 03814b6d46..7049c816ed 100644 --- a/gst/mpegtsdemux/tsdemux.c +++ b/gst/mpegtsdemux/tsdemux.c @@ -149,7 +149,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 }, " \ @@ -256,14 +256,11 @@ 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, &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_add_static_pad_template (element_class, &private_template); gst_element_class_set_details_simple (element_class, "MPEG transport stream demuxer", @@ -1080,13 +1077,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); From 1182dd0c1ba3e97d197d145dcdb0feeb76f6cd1e Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Wed, 15 Feb 2012 10:32:17 -0300 Subject: [PATCH 3/5] tsdemux: Avoid throwing FLOW_ERROR on last PCR processing error In the case of scanning last pcr, errors are not critical, so we keep the stream flowing. --- gst/mpegtsdemux/tsdemux.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/gst/mpegtsdemux/tsdemux.c b/gst/mpegtsdemux/tsdemux.c index 7049c816ed..0fd86f98f2 100644 --- a/gst/mpegtsdemux/tsdemux.c +++ b/gst/mpegtsdemux/tsdemux.c @@ -1697,7 +1697,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]; @@ -1708,8 +1708,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; From b3592ebda868fd183304789d8448c21abe517fe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 16 Feb 2012 00:30:05 +0000 Subject: [PATCH 4/5] mve: don't return a boolean for a GstFlowReturn fixes playback. --- gst/mve/gstmvedemux.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/gst/mve/gstmvedemux.c b/gst/mve/gstmvedemux.c index 8a0cc5ce83..85d61229a6 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,9 @@ gst_mve_demux_base_init (GstMveDemuxClass * klass) GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - 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_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", From 2ce709cf4a4d46b058218a965885cecfa1568b1f Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Thu, 16 Feb 2012 01:12:58 -0300 Subject: [PATCH 5/5] wrappercamerabinsrc: Put source in NULL when it fails changing state When source is being reset to change caps, check the return of the state syncing function to avoid leaving the source in an unconsistent state. --- gst/camerabin2/gstwrappercamerabinsrc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gst/camerabin2/gstwrappercamerabinsrc.c b/gst/camerabin2/gstwrappercamerabinsrc.c index 2b45342550..944cd2c2ed 100644 --- a/gst/camerabin2/gstwrappercamerabinsrc.c +++ b/gst/camerabin2/gstwrappercamerabinsrc.c @@ -162,7 +162,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);