diff --git a/Android.mk b/Android.mk index d858ab8eab..73aed2ca2d 100644 --- a/Android.mk +++ b/Android.mk @@ -8,6 +8,7 @@ GST_PLUGINS_BAD_BUILT_SOURCES := \ pkgconfig/gstreamer-plugins-bad-0.10.pc \ gst-libs/gst/baseparse/Android.mk \ gst-libs/gst/basecamerabinsrc/Android.mk \ + gst-libs/gst/codecparsers/Android.mk \ gst-libs/gst/interfaces/Android.mk \ gst/h264parse/Android.mk \ gst/videoparsers/Android.mk \ @@ -102,6 +103,7 @@ CONFIGURE_TARGETS += gst-plugins-bad-configure -include $(GST_PLUGINS_BAD_TOP)/gst-libs/gst/baseparse/Android.mk -include $(GST_PLUGINS_BAD_TOP)/gst-libs/gst/basecamerabinsrc/Android.mk +-include $(GST_PLUGINS_BAD_TOP)/gst-libs/gst/codecparsers/Android.mk -include $(GST_PLUGINS_BAD_TOP)/gst-libs/gst/interfaces/Android.mk -include $(GST_PLUGINS_BAD_TOP)/gst/h264parse/Android.mk -include $(GST_PLUGINS_BAD_TOP)/gst/audiobuffer/Android.mk diff --git a/ext/celt/gstceltenc.c b/ext/celt/gstceltenc.c index 9e6944df0f..c2011b31cc 100644 --- a/ext/celt/gstceltenc.c +++ b/ext/celt/gstceltenc.c @@ -494,7 +494,7 @@ gst_celt_enc_src_query (GstPad * pad, GstQuery * query) GstClockTime min_latency, max_latency; gint64 latency; - if ((res = gst_pad_peer_query (pad, query))) { + if ((res = gst_pad_peer_query (enc->sinkpad, query))) { gst_query_parse_latency (query, &live, &min_latency, &max_latency); latency = gst_celt_enc_get_latency (enc); @@ -820,7 +820,7 @@ gst_celt_enc_encode (GstCeltEnc * enc, gboolean flush) } if (flush && gst_adapter_available (enc->adapter) % bytes != 0) { - guint diff = gst_adapter_available (enc->adapter) % bytes; + guint diff = bytes - gst_adapter_available (enc->adapter) % bytes; GstBuffer *buf = gst_buffer_new_and_alloc (diff); memset (GST_BUFFER_DATA (buf), 0, diff); diff --git a/ext/kate/gstkatetiger.c b/ext/kate/gstkatetiger.c index 4dd7ef2395..134469fe91 100644 --- a/ext/kate/gstkatetiger.c +++ b/ext/kate/gstkatetiger.c @@ -121,7 +121,8 @@ enum ARG_DEFAULT_BACKGROUND_RED, ARG_DEFAULT_BACKGROUND_GREEN, ARG_DEFAULT_BACKGROUND_BLUE, - ARG_DEFAULT_BACKGROUND_ALPHA + ARG_DEFAULT_BACKGROUND_ALPHA, + ARG_SILENT }; static GstStaticPadTemplate kate_sink_factory = @@ -294,6 +295,12 @@ gst_kate_tiger_class_init (GstKateTigerClass * klass) "Default background color (alpha component, between 0 and 255) to render text with", 0, 255, 255, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /* FIXME 0.11: rename to "visible" or "text-visible" or "render-text" */ + g_object_class_install_property (gobject_class, ARG_SILENT, + g_param_spec_boolean ("silent", "silent", + "Whether to render the stream", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_kate_tiger_change_state); } @@ -353,6 +360,7 @@ gst_kate_tiger_init (GstKateTiger * tiger, GstKateTigerClass * gclass) tiger->default_background_g = 0; tiger->default_background_b = 0; tiger->default_background_a = 0; + tiger->silent = FALSE; tiger->video_width = 0; tiger->video_height = 0; @@ -488,6 +496,9 @@ gst_kate_tiger_set_property (GObject * object, guint prop_id, tiger->default_background_a = g_value_get_int (value); gst_kate_tiger_update_default_background_color (tiger); break; + case ARG_SILENT: + tiger->silent = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -542,6 +553,9 @@ gst_kate_tiger_get_property (GObject * object, guint prop_id, case ARG_DEFAULT_BACKGROUND_ALPHA: g_value_set_int (value, tiger->default_background_a); break; + case ARG_SILENT: + g_value_set_boolean (value, tiger->silent); + break; default: if (!gst_kate_util_decoder_base_get_property (&tiger->decoder, object, prop_id, value, pspec)) { @@ -767,7 +781,7 @@ gst_kate_tiger_video_chain (GstPad * pad, GstBuffer * buf) } /* if there nothing to draw, we can just push the video buffer as is */ - if (ret > 0) + if (ret > 0 || tiger->silent) goto pass; /* there is something to draw, so first make the buffer writable */ diff --git a/ext/kate/gstkatetiger.h b/ext/kate/gstkatetiger.h index d3880b32bf..0947da4cff 100644 --- a/ext/kate/gstkatetiger.h +++ b/ext/kate/gstkatetiger.h @@ -88,6 +88,7 @@ struct _GstKateTiger guchar default_background_g; guchar default_background_b; guchar default_background_a; + gboolean silent; gint video_width; gint video_height; diff --git a/ext/opus/gstopusenc.c b/ext/opus/gstopusenc.c index 75ccaaa573..51ae5c2a37 100644 --- a/ext/opus/gstopusenc.c +++ b/ext/opus/gstopusenc.c @@ -270,7 +270,7 @@ gst_opus_enc_sink_setcaps (GstPad * pad, GstCaps * caps) gst_caps_unref (otherpadcaps); } - GST_ERROR_OBJECT (pad, "channels=%d rate=%d frame-size=%d", + GST_DEBUG_OBJECT (pad, "channels=%d rate=%d frame-size=%d", enc->n_channels, enc->sample_rate, enc->frame_size); switch (enc->frame_size) { case 2: @@ -296,7 +296,7 @@ gst_opus_enc_sink_setcaps (GstPad * pad, GstCaps * caps) return FALSE; break; } - GST_ERROR ("frame_samples %d", enc->frame_samples); + GST_DEBUG_OBJECT (pad, "frame_samples %d", enc->frame_samples); gst_opus_enc_setup (enc); @@ -534,7 +534,7 @@ gst_opus_enc_src_query (GstPad * pad, GstQuery * query) GstClockTime min_latency, max_latency; gint64 latency; - if ((res = gst_pad_peer_query (pad, query))) { + if ((res = gst_pad_peer_query (enc->sinkpad, query))) { gst_query_parse_latency (query, &live, &min_latency, &max_latency); latency = gst_opus_enc_get_latency (enc); @@ -807,7 +807,7 @@ gst_opus_enc_encode (GstOpusEnc * enc, gboolean flush) (enc->bitrate * enc->frame_samples / enc->sample_rate + 4) / 8; if (flush && gst_adapter_available (enc->adapter) % bytes != 0) { - guint diff = gst_adapter_available (enc->adapter) % bytes; + guint diff = bytes - gst_adapter_available (enc->adapter) % bytes; GstBuffer *buf = gst_buffer_new_and_alloc (diff); memset (GST_BUFFER_DATA (buf), 0, diff); diff --git a/ext/resindvd/resindvdsrc.c b/ext/resindvd/resindvdsrc.c index e4bdd7eec6..a0059fdaac 100644 --- a/ext/resindvd/resindvdsrc.c +++ b/ext/resindvd/resindvdsrc.c @@ -2400,7 +2400,7 @@ rsn_dvdsrc_src_event (GstBaseSrc * basesrc, GstEvent * event) GST_LOG_OBJECT (src, "handling seek event"); gst_event_parse_seek (event, NULL, NULL, &flags, NULL, NULL, NULL, NULL); - src->flushing_seek = !!(flags & GST_SEEK_FLAG_FLUSH); + src->flushing_seek = ! !(flags & GST_SEEK_FLAG_FLUSH); GST_DEBUG_OBJECT (src, "%s seek event", src->flushing_seek ? "flushing" : "non-flushing"); @@ -2759,7 +2759,12 @@ rsn_dvdsrc_do_seek (GstBaseSrc * bsrc, GstSegment * segment) if (dvdnav_current_title_info (src->dvdnav, &title, &x) == DVDNAV_STATUS_OK) { if (segment->start + 1 == x) { - dvdnav_prev_pg_search (src->dvdnav); + /* if already on the first part, don't try to get before it */ + if (segment->start == 0) { + dvdnav_part_play (src->dvdnav, title, 1); + } else { + dvdnav_prev_pg_search (src->dvdnav); + } ret = TRUE; src->discont = TRUE; } else if (segment->start == x + 1) { diff --git a/gst-libs/gst/codecparsers/gstmpegvideoparser.c b/gst-libs/gst/codecparsers/gstmpegvideoparser.c index 399e834767..2d762fbaaa 100644 --- a/gst-libs/gst/codecparsers/gstmpegvideoparser.c +++ b/gst-libs/gst/codecparsers/gstmpegvideoparser.c @@ -319,7 +319,7 @@ scan_for_start_codes (const GstByteReader * reader, guint offset, guint size) * Returns: a #GList of #GstMpegVideoTypeOffsetSize */ GList * -gst_mpeg_video_parse (guint8 * data, gsize size, guint offset) +gst_mpeg_video_parse (const guint8 * data, gsize size, guint offset) { gint off, rsize; GstByteReader br; @@ -385,7 +385,7 @@ gst_mpeg_video_parse (guint8 * data, gsize size, guint offset) */ gboolean gst_mpeg_video_parse_sequence_header (GstMpegVideoSequenceHdr * seqhdr, - guint8 * data, gsize size, guint offset) + const guint8 * data, gsize size, guint offset) { GstBitReader br; @@ -414,7 +414,7 @@ gst_mpeg_video_parse_sequence_header (GstMpegVideoSequenceHdr * seqhdr, */ gboolean gst_mpeg_video_parse_sequence_extension (GstMpegVideoSequenceExt * seqext, - guint8 * data, gsize size, guint offset) + const guint8 * data, gsize size, guint offset) { GstBitReader br; @@ -482,7 +482,7 @@ gst_mpeg_video_parse_sequence_extension (GstMpegVideoSequenceExt * seqext, */ gboolean gst_mpeg_video_parse_quant_matrix_extension (GstMpegVideoQuantMatrixExt * quant, - guint8 * data, gsize size, guint offset) + const guint8 * data, gsize size, guint offset) { guint8 i; GstBitReader br; @@ -556,7 +556,7 @@ failed: */ gboolean gst_mpeg_video_parse_picture_extension (GstMpegVideoPictureExt * ext, - guint8 * data, gsize size, guint offset) + const guint8 * data, gsize size, guint offset) { GstBitReader br; @@ -657,7 +657,7 @@ failed: */ gboolean gst_mpeg_video_parse_picture_header (GstMpegVideoPictureHdr * hdr, - guint8 * data, gsize size, guint offset) + const guint8 * data, gsize size, guint offset) { GstBitReader br; @@ -728,7 +728,7 @@ failed: * Returns: %TRUE if the gop could be parsed correctly, %FALSE otherwize. */ gboolean -gst_mpeg_video_parse_gop (GstMpegVideoGop * gop, guint8 * data, +gst_mpeg_video_parse_gop (GstMpegVideoGop * gop, const guint8 * data, gsize size, guint offset) { GstBitReader br; diff --git a/gst-libs/gst/codecparsers/gstmpegvideoparser.h b/gst-libs/gst/codecparsers/gstmpegvideoparser.h index a212a94445..444092ef41 100644 --- a/gst-libs/gst/codecparsers/gstmpegvideoparser.h +++ b/gst-libs/gst/codecparsers/gstmpegvideoparser.h @@ -375,25 +375,25 @@ struct _GstMpegVideoTypeOffsetSize gint size; }; -GList *gst_mpeg_video_parse (guint8 * data, gsize size, guint offset); +GList *gst_mpeg_video_parse (const guint8 * data, gsize size, guint offset); gboolean gst_mpeg_video_parse_sequence_header (GstMpegVideoSequenceHdr * params, - guint8 * data, gsize size, guint offset); + const guint8 * data, gsize size, guint offset); gboolean gst_mpeg_video_parse_picture_header (GstMpegVideoPictureHdr* hdr, - guint8 * data, gsize size, guint offset); + const guint8 * data, gsize size, guint offset); gboolean gst_mpeg_video_parse_picture_extension (GstMpegVideoPictureExt *ext, - guint8 * data, gsize size, guint offset); + const guint8 * data, gsize size, guint offset); gboolean gst_mpeg_video_parse_gop (GstMpegVideoGop * gop, - guint8 * data, gsize size, guint offset); + const guint8 * data, gsize size, guint offset); gboolean gst_mpeg_video_parse_sequence_extension (GstMpegVideoSequenceExt * seqext, - guint8 * data, gsize size, guint offset); + const guint8 * data, gsize size, guint offset); gboolean gst_mpeg_video_parse_quant_matrix_extension (GstMpegVideoQuantMatrixExt * quant, - guint8 * data, gsize size, guint offset); + const guint8 * data, gsize size, guint offset); G_END_DECLS diff --git a/gst/adpcmdec/adpcmdec.c b/gst/adpcmdec/adpcmdec.c index 08a3e914cc..0fcfeb03f1 100644 --- a/gst/adpcmdec/adpcmdec.c +++ b/gst/adpcmdec/adpcmdec.c @@ -199,21 +199,21 @@ adpcmdec_sink_setcaps (GstPad * pad, GstCaps * caps) * *===================================================================== */ -static int AdaptationTable[] = { +static const int AdaptationTable[] = { 230, 230, 230, 230, 307, 409, 512, 614, 768, 614, 512, 409, 307, 230, 230, 230 }; -static int AdaptCoeff1[] = { +static const int AdaptCoeff1[] = { 256, 512, 0, 192, 240, 460, 392 }; -static int AdaptCoeff2[] = { +static const int AdaptCoeff2[] = { 0, -256, 0, 64, 0, -208, -232 }; static gint16 -read_sample (guint8 * data) +read_sample (const guint8 * data) { guint16 val = data[0] | (data[1] << 8); return *((gint16 *) & val); @@ -225,7 +225,7 @@ read_sample (guint8 * data) All buffer lengths have been verified by the caller */ static gboolean -adpcmdec_decode_ms_block (ADPCMDec * dec, int n_samples, guint8 * data, +adpcmdec_decode_ms_block (ADPCMDec * dec, int n_samples, const guint8 * data, gint16 * samples) { gint16 pred[2]; @@ -298,11 +298,11 @@ adpcmdec_decode_ms_block (ADPCMDec * dec, int n_samples, guint8 * data, return TRUE; } -static int ima_indx_adjust[16] = { +static const int ima_indx_adjust[16] = { -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8, }; -static int ima_step_size[89] = { +static const int ima_step_size[89] = { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, @@ -318,7 +318,7 @@ static int ima_step_size[89] = { All buffer lengths have been verified by the caller */ static gboolean -adpcmdec_decode_ima_block (ADPCMDec * dec, int n_samples, guint8 * data, +adpcmdec_decode_ima_block (ADPCMDec * dec, int n_samples, const guint8 * data, gint16 * samples) { gint16 stepindex[2]; @@ -378,7 +378,7 @@ adpcmdec_decode_ima_block (ADPCMDec * dec, int n_samples, guint8 * data, } static GstFlowReturn -adpcmdec_decode_block (ADPCMDec * dec, guint8 * data, int blocksize) +adpcmdec_decode_block (ADPCMDec * dec, const guint8 * data, int blocksize) { gboolean res; GstBuffer *outbuf = NULL; diff --git a/gst/adpcmenc/adpcmenc.c b/gst/adpcmenc/adpcmenc.c index 49e0550617..5f6a244248 100644 --- a/gst/adpcmenc/adpcmenc.c +++ b/gst/adpcmenc/adpcmenc.c @@ -66,11 +66,11 @@ static GstStaticPadTemplate adpcmenc_src_template = #define DEFAULT_ADPCM_BLOCK_SIZE 1024 #define DEFAULT_ADPCM_LAYOUT LAYOUT_ADPCM_DVI -static int ima_indx_adjust[16] = { +static const int ima_indx_adjust[16] = { -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8, }; -static int ima_step_size[89] = { +static const int ima_step_size[89] = { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, @@ -302,7 +302,8 @@ adpcmenc_encode_ima_sample (gint16 sample, gint16 * prev_sample, } static gboolean -adpcmenc_encode_ima_block (ADPCMEnc * enc, gint16 * samples, guint8 * outbuf) +adpcmenc_encode_ima_block (ADPCMEnc * enc, const gint16 * samples, + guint8 * outbuf) { const int HEADER_SIZE = 4; gint16 prev_sample[2] = { 0, 0 }; @@ -368,7 +369,7 @@ adpcmenc_encode_ima_block (ADPCMEnc * enc, gint16 * samples, guint8 * outbuf) } static GstFlowReturn -adpcmenc_encode_block (ADPCMEnc * enc, gint16 * samples, int blocksize) +adpcmenc_encode_block (ADPCMEnc * enc, const gint16 * samples, int blocksize) { gboolean res; GstBuffer *outbuf = NULL; diff --git a/gst/autoconvert/gstautoconvert.c b/gst/autoconvert/gstautoconvert.c index 0cf7e08745..df094d85b9 100644 --- a/gst/autoconvert/gstautoconvert.c +++ b/gst/autoconvert/gstautoconvert.c @@ -1277,14 +1277,10 @@ gst_auto_convert_sink_getcaps (GstPad * pad) if (element_caps) { if (!gst_caps_is_any (element_caps) && !gst_caps_is_empty (element_caps)) { - GstCaps *tmpcaps = NULL; - - tmpcaps = gst_caps_union (caps, element_caps); - gst_caps_unref (caps); - caps = tmpcaps; - + gst_caps_merge (caps, element_caps); + } else { + gst_caps_unref (element_caps); } - gst_caps_unref (element_caps); } gst_object_unref (element); @@ -1298,11 +1294,7 @@ gst_auto_convert_sink_getcaps (GstPad * pad) if (static_caps && !gst_caps_is_any (static_caps) && !gst_caps_is_empty (static_caps)) { - GstCaps *tmpcaps = NULL; - - tmpcaps = gst_caps_union (caps, static_caps); - gst_caps_unref (caps); - caps = tmpcaps; + gst_caps_merge (caps, static_caps); } } } diff --git a/gst/camerabin2/gstcamerabin2.c b/gst/camerabin2/gstcamerabin2.c index eebf12041d..62f29a1b26 100644 --- a/gst/camerabin2/gstcamerabin2.c +++ b/gst/camerabin2/gstcamerabin2.c @@ -243,7 +243,7 @@ static guint camerabin_signals[LAST_SIGNAL]; #define DEFAULT_MODE MODE_IMAGE #define DEFAULT_LOCATION "cap_%d" -#define DEFAULT_POST_PREVIEWS TRUE +#define DEFAULT_POST_PREVIEWS FALSE #define DEFAULT_MUTE_AUDIO FALSE #define DEFAULT_IDLE TRUE #define DEFAULT_FLAGS 0 @@ -957,6 +957,7 @@ static void gst_camera_bin_handle_message (GstBin * bin, GstMessage * message) { GstCameraBin2 *camerabin = GST_CAMERA_BIN2_CAST (bin); + gboolean dec_counter = FALSE; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ELEMENT:{ @@ -964,7 +965,6 @@ gst_camera_bin_handle_message (GstBin * bin, GstMessage * message) const gchar *filename; if (gst_structure_has_name (structure, "GstMultiFileSink")) { - GST_CAMERA_BIN2_PROCESSING_DEC (GST_CAMERA_BIN2_CAST (bin)); filename = gst_structure_get_string (structure, "filename"); GST_DEBUG_OBJECT (bin, "Got file save message from multifilesink, " "image %s has been saved", filename); @@ -972,6 +972,7 @@ gst_camera_bin_handle_message (GstBin * bin, GstMessage * message) gst_image_capture_bin_post_image_done (GST_CAMERA_BIN2_CAST (bin), filename); } + dec_counter = TRUE; } else if (gst_structure_has_name (structure, "preview-image")) { GValue *value; gchar *location = NULL; @@ -1001,7 +1002,7 @@ gst_camera_bin_handle_message (GstBin * bin, GstMessage * message) } GST_LOG_OBJECT (bin, "received preview-image message"); - GST_CAMERA_BIN2_PROCESSING_DEC (GST_CAMERA_BIN2_CAST (bin)); + dec_counter = TRUE; } } break; @@ -1014,10 +1015,10 @@ gst_camera_bin_handle_message (GstBin * bin, GstMessage * message) /* some capturing failed */ GST_WARNING_OBJECT (bin, "Capture failed, reason: %s - %s", err->message, debug); - GST_CAMERA_BIN2_PROCESSING_DEC (GST_CAMERA_BIN2_CAST (bin)); if (camerabin->post_previews) { gst_camera_bin_skip_next_preview (camerabin); } + dec_counter = TRUE; } } break; @@ -1025,8 +1026,8 @@ gst_camera_bin_handle_message (GstBin * bin, GstMessage * message) GstElement *src = GST_ELEMENT (GST_MESSAGE_SRC (message)); if (src == GST_CAMERA_BIN2_CAST (bin)->videosink) { GST_DEBUG_OBJECT (bin, "EOS from video branch"); - GST_CAMERA_BIN2_PROCESSING_DEC (GST_CAMERA_BIN2_CAST (bin)); gst_video_capture_bin_post_video_done (GST_CAMERA_BIN2_CAST (bin)); + dec_counter = TRUE; } } break; @@ -1035,6 +1036,9 @@ gst_camera_bin_handle_message (GstBin * bin, GstMessage * message) } if (message) GST_BIN_CLASS (parent_class)->handle_message (bin, message); + + if (dec_counter) + GST_CAMERA_BIN2_PROCESSING_DEC (camerabin); } /* diff --git a/gst/dtmf/gstdtmfsrc.c b/gst/dtmf/gstdtmfsrc.c index 7492b151e7..929147fe07 100644 --- a/gst/dtmf/gstdtmfsrc.c +++ b/gst/dtmf/gstdtmfsrc.c @@ -110,6 +110,12 @@ * gst_element_send_event (pipeline, event); * * + * When a DTMF tone actually starts or stop, a "dtmf-event-processed" + * element #GstMessage with the same fields as the "dtmf-event" + * #GstEvent that was used to request the event. Also, if any event + * has not been processed when the element goes from the PAUSED to the + * READY state, then a "dtmf-event-dropped" message is posted on the + * #GstBus in the order that they were received. */ #ifdef HAVE_CONFIG_H @@ -324,6 +330,9 @@ gst_dtmf_src_handle_dtmf_event (GstDTMFSrc * dtmfsrc, gboolean start; gint method; GstClockTime last_stop; + gint event_number; + gint event_volume; + gboolean correct_order; if (!gst_structure_get_int (event_structure, "type", &event_type) || !gst_structure_get_boolean (event_structure, "start", &start) || @@ -336,22 +345,25 @@ gst_dtmf_src_handle_dtmf_event (GstDTMFSrc * dtmfsrc, } } + if (start) + if (!gst_structure_get_int (event_structure, "number", &event_number) || + !gst_structure_get_int (event_structure, "volume", &event_volume)) + goto failure; + GST_OBJECT_LOCK (dtmfsrc); if (gst_structure_get_clock_time (event_structure, "last-stop", &last_stop)) dtmfsrc->last_stop = last_stop; else dtmfsrc->last_stop = GST_CLOCK_TIME_NONE; + correct_order = (start != dtmfsrc->last_event_was_start); + dtmfsrc->last_event_was_start = start; GST_OBJECT_UNLOCK (dtmfsrc); + if (!correct_order) + goto failure; + if (start) { - gint event_number; - gint event_volume; - - if (!gst_structure_get_int (event_structure, "number", &event_number) || - !gst_structure_get_int (event_structure, "volume", &event_volume)) - goto failure; - GST_DEBUG_OBJECT (dtmfsrc, "Received start event %d with volume %d", event_number, event_volume); gst_dtmf_src_add_start_event (dtmfsrc, event_number, event_volume); @@ -625,6 +637,35 @@ gst_dtmf_src_create_next_tone_packet (GstDTMFSrc * dtmfsrc, return buf; } +static void +gst_dtmf_src_post_message (GstDTMFSrc * dtmfsrc, const gchar * message_name, + GstDTMFSrcEvent * event) +{ + GstStructure *s = NULL; + + switch (event->event_type) { + case DTMF_EVENT_TYPE_START: + s = gst_structure_new (message_name, + "type", G_TYPE_INT, 1, + "method", G_TYPE_INT, 2, + "start", G_TYPE_BOOLEAN, TRUE, + "number", G_TYPE_INT, event->event_number, + "volume", G_TYPE_INT, event->volume, NULL); + break; + case DTMF_EVENT_TYPE_STOP: + s = gst_structure_new (message_name, + "type", G_TYPE_INT, 1, "method", G_TYPE_INT, 2, + "start", G_TYPE_BOOLEAN, FALSE, NULL); + break; + case DTMF_EVENT_TYPE_PAUSE_TASK: + return; + } + + if (s) + gst_element_post_message (GST_ELEMENT (dtmfsrc), + gst_message_new_element (GST_OBJECT (dtmfsrc), s)); +} + static GstFlowReturn gst_dtmf_src_create (GstBaseSrc * basesrc, guint64 offset, guint length, GstBuffer ** buffer) @@ -650,6 +691,7 @@ gst_dtmf_src_create (GstBaseSrc * basesrc, guint64 offset, case DTMF_EVENT_TYPE_STOP: GST_WARNING_OBJECT (dtmfsrc, "Received a DTMF stop event when already stopped"); + gst_dtmf_src_post_message (dtmfsrc, "dtmf-event-dropped", event); break; case DTMF_EVENT_TYPE_START: gst_dtmf_prepare_timestamps (dtmfsrc); @@ -657,6 +699,8 @@ gst_dtmf_src_create (GstBaseSrc * basesrc, guint64 offset, event->packet_count = 0; dtmfsrc->last_event = event; event = NULL; + gst_dtmf_src_post_message (dtmfsrc, "dtmf-event-processed", + dtmfsrc->last_event); break; case DTMF_EVENT_TYPE_PAUSE_TASK: /* @@ -684,10 +728,12 @@ gst_dtmf_src_create (GstBaseSrc * basesrc, guint64 offset, case DTMF_EVENT_TYPE_START: GST_WARNING_OBJECT (dtmfsrc, "Received two consecutive DTMF start events"); + gst_dtmf_src_post_message (dtmfsrc, "dtmf-event-dropped", event); break; case DTMF_EVENT_TYPE_STOP: g_slice_free (GstDTMFSrcEvent, dtmfsrc->last_event); dtmfsrc->last_event = NULL; + gst_dtmf_src_post_message (dtmfsrc, "dtmf-event-processed", event); break; case DTMF_EVENT_TYPE_PAUSE_TASK: /* @@ -853,9 +899,11 @@ gst_dtmf_src_change_state (GstElement * element, GstStateChange transition) event = g_async_queue_try_pop (dtmfsrc->event_queue); while (event != NULL) { + gst_dtmf_src_post_message (dtmfsrc, "dtmf-event-dropped", event); g_slice_free (GstDTMFSrcEvent, event); event = g_async_queue_try_pop (dtmfsrc->event_queue); } + dtmfsrc->last_event_was_start = FALSE; dtmfsrc->timestamp = 0; no_preroll = TRUE; break; @@ -878,9 +926,11 @@ gst_dtmf_src_change_state (GstElement * element, GstStateChange transition) event = g_async_queue_try_pop (dtmfsrc->event_queue); while (event != NULL) { + gst_dtmf_src_post_message (dtmfsrc, "dtmf-event-dropped", event); g_slice_free (GstDTMFSrcEvent, event); event = g_async_queue_try_pop (dtmfsrc->event_queue); } + dtmfsrc->last_event_was_start = FALSE; break; default: diff --git a/gst/dtmf/gstdtmfsrc.h b/gst/dtmf/gstdtmfsrc.h index cda5840a5f..ce69bf4115 100644 --- a/gst/dtmf/gstdtmfsrc.h +++ b/gst/dtmf/gstdtmfsrc.h @@ -74,6 +74,7 @@ struct _GstDTMFSrc GstBaseSrc parent; GAsyncQueue *event_queue; GstDTMFSrcEvent *last_event; + gboolean last_event_was_start; guint16 interval; GstClockTime timestamp; diff --git a/gst/dtmf/gstrtpdtmfsrc.c b/gst/dtmf/gstrtpdtmfsrc.c index 8f07cafc4a..ee8703563d 100644 --- a/gst/dtmf/gstrtpdtmfsrc.c +++ b/gst/dtmf/gstrtpdtmfsrc.c @@ -108,7 +108,13 @@ * gst_element_send_event (pipeline, event); * * - */ + * When a DTMF tone actually starts or stop, a "dtmf-event-processed" + * element #GstMessage with the same fields as the "dtmf-event" + * #GstEvent that was used to request the event. Also, if any event + * has not been processed when the element goes from the PAUSED to the + * READY state, then a "dtmf-event-dropped" message is posted on the + * #GstBus in the order that they were received. + */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -335,6 +341,9 @@ gst_rtp_dtmf_src_handle_dtmf_event (GstRTPDTMFSrc * dtmfsrc, gboolean start; gint method; GstClockTime last_stop; + gint event_number; + gint event_volume; + gboolean correct_order; if (!gst_structure_get_int (event_structure, "type", &event_type) || !gst_structure_get_boolean (event_structure, "start", &start) || @@ -347,17 +356,24 @@ gst_rtp_dtmf_src_handle_dtmf_event (GstRTPDTMFSrc * dtmfsrc, } } + if (start) + if (!gst_structure_get_int (event_structure, "number", &event_number) || + !gst_structure_get_int (event_structure, "volume", &event_volume)) + goto failure; + GST_OBJECT_LOCK (dtmfsrc); if (gst_structure_get_clock_time (event_structure, "last-stop", &last_stop)) dtmfsrc->last_stop = last_stop; else dtmfsrc->last_stop = GST_CLOCK_TIME_NONE; + correct_order = (start != dtmfsrc->last_event_was_start); + dtmfsrc->last_event_was_start = start; GST_OBJECT_UNLOCK (dtmfsrc); - if (start) { - gint event_number; - gint event_volume; + if (!correct_order) + goto failure; + if (start) { if (!gst_structure_get_int (event_structure, "number", &event_number) || !gst_structure_get_int (event_structure, "volume", &event_volume)) goto failure; @@ -644,6 +660,37 @@ gst_rtp_dtmf_src_create_next_rtp_packet (GstRTPDTMFSrc * dtmfsrc) return buf; } + +static void +gst_dtmf_src_post_message (GstRTPDTMFSrc * dtmfsrc, const gchar * message_name, + GstRTPDTMFSrcEvent * event) +{ + GstStructure *s = NULL; + + switch (event->event_type) { + case RTP_DTMF_EVENT_TYPE_START: + s = gst_structure_new (message_name, + "type", G_TYPE_INT, 1, + "method", G_TYPE_INT, 1, + "start", G_TYPE_BOOLEAN, TRUE, + "number", G_TYPE_INT, event->payload->event, + "volume", G_TYPE_INT, event->payload->volume, NULL); + break; + case RTP_DTMF_EVENT_TYPE_STOP: + s = gst_structure_new (message_name, + "type", G_TYPE_INT, 1, "method", G_TYPE_INT, 1, + "start", G_TYPE_BOOLEAN, FALSE, NULL); + break; + case RTP_DTMF_EVENT_TYPE_PAUSE_TASK: + return; + } + + if (s) + gst_element_post_message (GST_ELEMENT (dtmfsrc), + gst_message_new_element (GST_OBJECT (dtmfsrc), s)); +} + + static GstFlowReturn gst_rtp_dtmf_src_create (GstBaseSrc * basesrc, guint64 offset, guint length, GstBuffer ** buffer) @@ -668,6 +715,7 @@ gst_rtp_dtmf_src_create (GstBaseSrc * basesrc, guint64 offset, case RTP_DTMF_EVENT_TYPE_STOP: GST_WARNING_OBJECT (dtmfsrc, "Received a DTMF stop event when already stopped"); + gst_dtmf_src_post_message (dtmfsrc, "dtmf-event-dropped", event); break; case RTP_DTMF_EVENT_TYPE_START: @@ -678,6 +726,7 @@ gst_rtp_dtmf_src_create (GstBaseSrc * basesrc, guint64 offset, if (!gst_rtp_dtmf_prepare_timestamps (dtmfsrc)) goto no_clock; + gst_dtmf_src_post_message (dtmfsrc, "dtmf-event-processed", event); dtmfsrc->payload = event->payload; event->payload = NULL; break; @@ -711,6 +760,7 @@ gst_rtp_dtmf_src_create (GstBaseSrc * basesrc, guint64 offset, case RTP_DTMF_EVENT_TYPE_START: GST_WARNING_OBJECT (dtmfsrc, "Received two consecutive DTMF start events"); + gst_dtmf_src_post_message (dtmfsrc, "dtmf-event-dropped", event); break; case RTP_DTMF_EVENT_TYPE_STOP: @@ -718,6 +768,7 @@ gst_rtp_dtmf_src_create (GstBaseSrc * basesrc, guint64 offset, dtmfsrc->last_packet = TRUE; /* Set the redundancy on the last packet */ dtmfsrc->redundancy_count = dtmfsrc->packet_redundancy; + gst_dtmf_src_post_message (dtmfsrc, "dtmf-event-processed", event); break; case RTP_DTMF_EVENT_TYPE_PAUSE_TASK: @@ -1004,8 +1055,11 @@ gst_rtp_dtmf_src_change_state (GstElement * element, GstStateChange transition) gst_rtp_dtmf_src_ready_to_paused (dtmfsrc); /* Flushing the event queue */ - while ((event = g_async_queue_try_pop (dtmfsrc->event_queue)) != NULL) + while ((event = g_async_queue_try_pop (dtmfsrc->event_queue)) != NULL) { + gst_dtmf_src_post_message (dtmfsrc, "dtmf-event-dropped", event); gst_rtp_dtmf_src_event_free (event); + } + dtmfsrc->last_event_was_start = FALSE; no_preroll = TRUE; break; @@ -1025,8 +1079,11 @@ gst_rtp_dtmf_src_change_state (GstElement * element, GstStateChange transition) case GST_STATE_CHANGE_PAUSED_TO_READY: /* Flushing the event queue */ - while ((event = g_async_queue_try_pop (dtmfsrc->event_queue)) != NULL) + while ((event = g_async_queue_try_pop (dtmfsrc->event_queue)) != NULL) { + gst_dtmf_src_post_message (dtmfsrc, "dtmf-event-dropped", event); gst_rtp_dtmf_src_event_free (event); + } + dtmfsrc->last_event_was_start = FALSE; /* Indicate that we don't do PRE_ROLL */ break; diff --git a/gst/dtmf/gstrtpdtmfsrc.h b/gst/dtmf/gstrtpdtmfsrc.h index 9be9df69cb..5bc0e3ea65 100644 --- a/gst/dtmf/gstrtpdtmfsrc.h +++ b/gst/dtmf/gstrtpdtmfsrc.h @@ -93,6 +93,7 @@ struct _GstRTPDTMFSrc guint16 ptime; guint16 packet_redundancy; guint32 clock_rate; + gboolean last_event_was_start; GstClockTime last_stop; diff --git a/gst/mpegdemux/gstpesfilter.c b/gst/mpegdemux/gstpesfilter.c index 18d503608c..23b205a590 100644 --- a/gst/mpegdemux/gstpesfilter.c +++ b/gst/mpegdemux/gstpesfilter.c @@ -168,7 +168,7 @@ gst_pes_filter_parse (GstPESFilter * filter) avail = MIN (avail, filter->length + 6); } - if (avail < 7) + if (avail < 6) goto need_more_data; /* read more data, either the whole packet if there is a length @@ -202,6 +202,8 @@ gst_pes_filter_parse (GstPESFilter * filter) break; } + if (datalen == 0) + goto need_more_data; filter->pts = filter->dts = -1; /* stuffing bits, first two bits are '10' for mpeg2 pes so this code is diff --git a/gst/mpegdemux/mpegtspacketizer.c b/gst/mpegdemux/mpegtspacketizer.c index a9a69c9d3c..118a3acc5b 100644 --- a/gst/mpegdemux/mpegtspacketizer.c +++ b/gst/mpegdemux/mpegtspacketizer.c @@ -2197,6 +2197,12 @@ mpegts_packetizer_push_section (MpegTSPacketizer * packetizer, if (packet->pid == 0x14) { table_id = data[0]; section->section_length = GST_READ_UINT24_BE (data) & 0x000FFF; + 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_create_sub (packet->buffer, data - GST_BUFFER_DATA (packet->buffer), section->section_length + 3); section->table_id = table_id; diff --git a/tests/check/elements/camerabin2.c b/tests/check/elements/camerabin2.c index 2c1bbb1dbe..b310b8654a 100644 --- a/tests/check/elements/camerabin2.c +++ b/tests/check/elements/camerabin2.c @@ -379,7 +379,7 @@ setup_wrappercamerabinsrc_videotestsrc (void) g_object_set (G_OBJECT (audiosrc), "is-live", TRUE, NULL); g_object_set (G_OBJECT (src), "video-source", testsrc, NULL); g_object_set (G_OBJECT (camera), "camera-source", src, "preview-caps", - preview_caps, "audio-source", audiosrc, NULL); + preview_caps, "post-previews", TRUE, "audio-source", audiosrc, NULL); gst_object_unref (src); gst_object_unref (testsrc); gst_object_unref (audiosrc); diff --git a/tests/check/libs/mpegvideoparser.c b/tests/check/libs/mpegvideoparser.c index 414a45e232..e5a2358a2a 100644 --- a/tests/check/libs/mpegvideoparser.c +++ b/tests/check/libs/mpegvideoparser.c @@ -23,7 +23,7 @@ #include /* actually seq + gop */ -static guint8 mpeg2_seq[] = { +static const guint8 mpeg2_seq[] = { 0x00, 0x00, 0x01, 0xb3, 0x02, 0x00, 0x18, 0x15, 0xff, 0xff, 0xe0, 0x28, 0x00, 0x00, 0x01, 0xb3, 0x78, 0x04, 0x38, 0x37, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x01, 0xb5, 0x14, 0x8a, 0x00, 0x11, 0x03, 0x71, @@ -31,7 +31,7 @@ static guint8 mpeg2_seq[] = { 0x00, 0x00, 0x01, 0x03, 0x00, 0x08, 0x00, 0x00 }; -static guint8 mis_identified_datas[] = { +static const guint8 mis_identified_datas[] = { 0x00, 0x00, 0x01, 0x1f, 0x4a, 0xf4, 0xd4, 0xd8, 0x08, 0x23, 0xdd, 0x7c, 0xd3, 0x75, 0x21, 0x43, 0x85, 0x31, 0x43, 0x04, 0x24, 0x30, 0x18, 0x43, 0xba, 0x1a, 0x50, 0x60, 0xbb, 0x53, 0x56, 0x80, 0x41, @@ -85,7 +85,8 @@ GST_START_TEST (test_mpeg_parse) assert_equals_int (ordercode[i], typeoffsz->type); } - g_list_free_full (list, (GDestroyNotify) g_free); + g_list_foreach (list, (GFunc) g_free, NULL); + g_list_free (list); } GST_END_TEST; @@ -115,7 +116,8 @@ GST_START_TEST (test_mpeg_parse_sequence_header) assert_equals_int (seqhdr.vbv_buffer_size_value, 512); fail_unless (seqhdr.constrained_parameters_flag == FALSE); - g_list_free_full (list, (GDestroyNotify) g_free); + g_list_foreach (list, (GFunc) g_free, NULL); + g_list_free (list); } GST_END_TEST; @@ -145,7 +147,8 @@ GST_START_TEST (test_mpeg_parse_sequence_extension) assert_equals_int (seqext.fps_n_ext, 3); assert_equals_int (seqext.fps_d_ext, 2); - g_list_free_full (list, (GDestroyNotify) g_free); + g_list_foreach (list, (GFunc) g_free, NULL); + g_list_free (list); } GST_END_TEST; @@ -154,7 +157,7 @@ GST_START_TEST (test_mis_identified_datas) { GList *list, *tmp; GstMpegVideoTypeOffsetSize *typeoffsz; - guint8 *data = mis_identified_datas; + const guint8 *data = mis_identified_datas; list = gst_mpeg_video_parse (mis_identified_datas, sizeof (mis_identified_datas), 0); @@ -168,7 +171,8 @@ GST_START_TEST (test_mis_identified_datas) assert_equals_int (data[typeoffsz->offset - 2], 1); } - g_list_free_full (list, (GDestroyNotify) g_free); + g_list_foreach (list, (GFunc) g_free, NULL); + g_list_free (list); } GST_END_TEST;