diff --git a/gst-libs/gst/audio/gstaudiodecoder.c b/gst-libs/gst/audio/gstaudiodecoder.c index 630b5c085b..c6cd0070df 100644 --- a/gst-libs/gst/audio/gstaudiodecoder.c +++ b/gst-libs/gst/audio/gstaudiodecoder.c @@ -247,6 +247,7 @@ struct _GstAudioDecoderPrivate gint error_count; /* codec id tag */ GstTagList *taglist; + gboolean taglist_changed; /* whether circumstances allow output aggregation */ gint agg; @@ -477,6 +478,7 @@ gst_audio_decoder_reset (GstAudioDecoder * dec, gboolean full) gst_tag_list_free (dec->priv->taglist); dec->priv->taglist = NULL; } + dec->priv->taglist_changed = FALSE; gst_segment_init (&dec->input_segment, GST_FORMAT_TIME); gst_segment_init (&dec->output_segment, GST_FORMAT_TIME); @@ -706,11 +708,12 @@ gst_audio_decoder_sink_setcaps (GstAudioDecoder * dec, GstCaps * caps) /* NOTE pbutils only needed here */ /* TODO maybe (only) upstream demuxer/parser etc should handle this ? */ #if 0 - if (dec->priv->taglist) - gst_tag_list_free (dec->priv->taglist); - dec->priv->taglist = gst_tag_list_new (); + if (!dec->priv->taglist) + dec->priv->taglist = gst_tag_list_new (); + dec->priv->taglist = gst_tag_list_make_writable (dec->priv->taglist); gst_pb_utils_add_codec_description_to_tag_list (dec->priv->taglist, GST_TAG_AUDIO_CODEC, caps); + dec->priv->taglist_changed = TRUE; #endif if (klass->set_format) @@ -1070,14 +1073,12 @@ gst_audio_decoder_finish_frame (GstAudioDecoder * dec, GstBuffer * buf, } /* delayed one-shot stuff until confirmed data */ - if (priv->taglist) { + if (priv->taglist && priv->taglist_changed) { GST_DEBUG_OBJECT (dec, "codec tag %" GST_PTR_FORMAT, priv->taglist); - if (gst_tag_list_is_empty (priv->taglist)) { - gst_tag_list_free (priv->taglist); - } else { - gst_audio_decoder_push_event (dec, gst_event_new_tag (priv->taglist)); - } - priv->taglist = NULL; + if (!gst_tag_list_is_empty (priv->taglist)) + gst_audio_decoder_push_event (dec, + gst_event_new_tag (gst_tag_list_ref (priv->taglist))); + priv->taglist_changed = FALSE; } buf = gst_buffer_make_writable (buf); @@ -2862,7 +2863,8 @@ gst_audio_decoder_merge_tags (GstAudioDecoder * dec, otags = dec->priv->taglist; dec->priv->taglist = gst_tag_list_merge (dec->priv->taglist, tags, mode); if (otags) - gst_tag_list_free (otags); + gst_tag_list_unref (otags); + dec->priv->taglist_changed = TRUE; GST_AUDIO_DECODER_STREAM_UNLOCK (dec); } diff --git a/gst-libs/gst/audio/gstaudioencoder.c b/gst-libs/gst/audio/gstaudioencoder.c index 303ef9410e..6e71394329 100644 --- a/gst-libs/gst/audio/gstaudioencoder.c +++ b/gst-libs/gst/audio/gstaudioencoder.c @@ -255,6 +255,7 @@ struct _GstAudioEncoderPrivate /* pending tags */ GstTagList *tags; + gboolean tags_changed; /* pending serialized sink events, will be sent from finish_frame() */ GList *pending_events; }; @@ -467,6 +468,7 @@ gst_audio_encoder_reset (GstAudioEncoder * enc, gboolean full) if (enc->priv->tags) gst_tag_list_free (enc->priv->tags); enc->priv->tags = NULL; + enc->priv->tags_changed = FALSE; g_list_foreach (enc->priv->pending_events, (GFunc) gst_event_unref, NULL); g_list_free (enc->priv->pending_events); @@ -641,24 +643,26 @@ gst_audio_encoder_finish_frame (GstAudioEncoder * enc, GstBuffer * buf, } /* send after pending events, which likely includes newsegment event */ - if (G_UNLIKELY (enc->priv->tags)) { - GstTagList *tags; + if (G_UNLIKELY (enc->priv->tags && enc->priv->tags_changed)) { #if 0 GstCaps *caps; #endif /* add codec info to pending tags */ - tags = enc->priv->tags; - /* no more pending */ - enc->priv->tags = NULL; #if 0 + if (!enc->priv->tags) + enc->priv->tags = gst_tag_list_new (); + enc->priv->tags = gst_tag_list_make_writable (enc->priv->tags); caps = gst_pad_get_current_caps (enc->srcpad); - gst_pb_utils_add_codec_description_to_tag_list (tags, GST_TAG_CODEC, caps); - gst_pb_utils_add_codec_description_to_tag_list (tags, GST_TAG_AUDIO_CODEC, - caps); + gst_pb_utils_add_codec_description_to_tag_list (enc->priv->tags, + GST_TAG_CODEC, caps); + gst_pb_utils_add_codec_description_to_tag_list (enc->priv->tags, + GST_TAG_AUDIO_CODEC, caps); #endif - GST_DEBUG_OBJECT (enc, "sending tags %" GST_PTR_FORMAT, tags); - gst_audio_encoder_push_event (enc, gst_event_new_tag (tags)); + GST_DEBUG_OBJECT (enc, "sending tags %" GST_PTR_FORMAT, enc->priv->tags); + gst_audio_encoder_push_event (enc, + gst_event_new_tag (gst_tag_list_ref (enc->priv->tags))); + enc->priv->tags_changed = FALSE; } /* remove corresponding samples from input */ @@ -1962,6 +1966,7 @@ gst_audio_encoder_activate (GstAudioEncoder * enc, gboolean active) if (enc->priv->tags) gst_tag_list_free (enc->priv->tags); enc->priv->tags = gst_tag_list_new_empty (); + enc->priv->tags_changed = FALSE; if (!enc->priv->active && klass->start) result = klass->start (enc); @@ -2502,14 +2507,15 @@ gst_audio_encoder_merge_tags (GstAudioEncoder * enc, g_return_if_fail (GST_IS_AUDIO_ENCODER (enc)); g_return_if_fail (tags == NULL || GST_IS_TAG_LIST (tags)); - GST_OBJECT_LOCK (enc); + GST_AUDIO_ENCODER_STREAM_LOCK (enc); if (tags) GST_DEBUG_OBJECT (enc, "merging tags %" GST_PTR_FORMAT, tags); otags = enc->priv->tags; enc->priv->tags = gst_tag_list_merge (enc->priv->tags, tags, mode); if (otags) - gst_tag_list_free (otags); - GST_OBJECT_UNLOCK (enc); + gst_tag_list_unref (otags); + enc->priv->tags_changed = TRUE; + GST_AUDIO_ENCODER_STREAM_UNLOCK (enc); } static gboolean