gboolean res = TRUE;
guint old_rate;
- dec = GST_AUDIO_DECODER (gst_pad_get_parent (pad));
-
GST_DEBUG_OBJECT (dec, "setting src caps %" GST_PTR_FORMAT, caps);
+ GST_AUDIO_DECODER_STREAM_LOCK (dec);
+
/* parse caps here to check subclass;
* also makes us aware of output format */
if (!gst_caps_is_fixed (caps))
GST_DEBUG_OBJECT (dec, "caps: %" GST_PTR_FORMAT, caps);
+ GST_AUDIO_DECODER_STREAM_LOCK (dec);
/* 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 (klass->set_format)
res = klass->set_format (dec, caps);
- g_object_unref (dec);
+ GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
+
return res;
}
GstAudioDecoderContext *ctx;
gint samples = 0;
GstClockTime ts, next_ts;
+ gsize size;
+ GstFlowReturn ret = GST_FLOW_OK;
/* subclass should know what it is producing by now */
- g_return_val_if_fail (buf == NULL || GST_PAD_CAPS (dec->srcpad) != NULL,
+ g_return_val_if_fail (buf == NULL || gst_pad_has_current_caps (dec->srcpad),
GST_FLOW_ERROR);
/* subclass should not hand us no data */
- g_return_val_if_fail (buf == NULL || GST_BUFFER_SIZE (buf) > 0,
+ g_return_val_if_fail (buf == NULL || gst_buffer_get_size (buf) > 0,
GST_FLOW_ERROR);
/* no dummy calls please */
g_return_val_if_fail (frames != 0, GST_FLOW_ERROR);
priv = dec->priv;
ctx = &dec->priv->ctx;
+ size = buf ? gst_buffer_get_size (buf) : 0;
GST_LOG_OBJECT (dec, "accepting %d bytes == %d samples for %d frames",
- buf ? GST_BUFFER_SIZE (buf) : -1,
- buf ? GST_BUFFER_SIZE (buf) / ctx->info.bpf : -1, frames);
+ buf ? size : -1, buf ? size / ctx->info.bpf : -1, frames);
+ GST_AUDIO_DECODER_STREAM_LOCK (dec);
+
+ if (priv->pending_events) {
+ GList *pending_events, *l;
+
+ pending_events = priv->pending_events;
+ priv->pending_events = NULL;
+
+ GST_DEBUG_OBJECT (dec, "Pushing pending events");
+ for (l = priv->pending_events; l; l = l->next)
+ gst_pad_push_event (dec->srcpad, l->data);
+ g_list_free (pending_events);
+ }
+
/* output shoud be whole number of sample frames */
if (G_LIKELY (buf && ctx->info.bpf)) {
- if (GST_BUFFER_SIZE (buf) % ctx->info.bpf)
+ if (size % ctx->info.bpf)
goto wrong_buffer;
/* per channel least */
- samples = GST_BUFFER_SIZE (buf) / ctx->info.bpf;
+ samples = size / ctx->info.bpf;
}
/* frame and ts book-keeping */
wrong_buffer:
{
GST_ELEMENT_ERROR (dec, STREAM, ENCODE, (NULL),
- ("buffer size %d not a multiple of %d", GST_BUFFER_SIZE (buf),
- ctx->info.bpf));
+ ("buffer size %d not a multiple of %d", size, ctx->info.bpf));
gst_buffer_unref (buf);
- return GST_FLOW_ERROR;
+ ret = GST_FLOW_ERROR;
+ goto exit;
}
overflow:
{
gboolean handled = FALSE;
switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_NEWSEGMENT:
+ case GST_EVENT_SEGMENT:
{
- GstFormat format;
- gdouble rate, arate;
- gint64 start, stop, time;
- gboolean update;
+ GstSegment seg;
- gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
- &start, &stop, &time);
+ GST_AUDIO_DECODER_STREAM_LOCK (dec);
+ gst_event_copy_segment (event, &seg);
- if (format == GST_FORMAT_TIME) {
- GST_DEBUG_OBJECT (dec, "received TIME NEW_SEGMENT %" GST_TIME_FORMAT
- " -- %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT
- ", rate %g, applied_rate %g",
- GST_TIME_ARGS (start), GST_TIME_ARGS (stop), GST_TIME_ARGS (time),
- rate, arate);
+ if (seg.format == GST_FORMAT_TIME) {
+ GST_DEBUG_OBJECT (dec, "received TIME SEGMENT %" GST_PTR_FORMAT, &seg);
} else {
- GstFormat dformat = GST_FORMAT_TIME;
-
- GST_DEBUG_OBJECT (dec, "received NEW_SEGMENT %" G_GINT64_FORMAT
- " -- %" G_GINT64_FORMAT ", time %" G_GINT64_FORMAT
- ", rate %g, applied_rate %g", start, stop, time, rate, arate);
+ gint64 nstart;
+ GST_DEBUG_OBJECT (dec, "received SEGMENT %" GST_PTR_FORMAT, &seg);
/* handle newsegment resulting from legacy simple seeking */
/* note that we need to convert this whether or not enough data
* to handle initial newsegment */
/* as these are only estimates, stop is kept open-ended to avoid
* premature cutting */
GST_DEBUG_OBJECT (dec, "converted to TIME start %" GST_TIME_FORMAT,
- GST_TIME_ARGS (start));
- format = GST_FORMAT_TIME;
- time = start;
- stop = GST_CLOCK_TIME_NONE;
+ GST_TIME_ARGS (nstart));
+ seg.format = GST_FORMAT_TIME;
+ seg.start = nstart;
+ seg.time = nstart;
+ seg.stop = GST_CLOCK_TIME_NONE;
/* replace event */
gst_event_unref (event);
- event = gst_event_new_new_segment_full (update, rate, arate,
- GST_FORMAT_TIME, start, stop, time);
+ event = gst_event_new_segment (&seg);
} else {
GST_DEBUG_OBJECT (dec, "unsupported format; ignoring");
+ GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
break;
}
}
}
/* and follow along with segment */
- gst_segment_set_newsegment_full (&dec->segment, update, rate, arate,
- format, start, stop, time);
-
+ dec->segment = seg;
- gst_pad_push_event (dec->srcpad, event);
+ dec->priv->pending_events =
+ g_list_append (dec->priv->pending_events, event);
handled = TRUE;
+ GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
break;
}
break;
case GST_EVENT_EOS:
+ GST_AUDIO_DECODER_STREAM_LOCK (dec);
gst_audio_decoder_drain (dec);
+ GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
break;
+ case GST_EVENT_CAPS:
+ {
+ GstCaps *caps;
+
+ gst_event_parse_caps (event, &caps);
+ gst_audio_decoder_sink_setcaps (dec, caps);
+ gst_event_unref (event);
+ handled = TRUE;
+ break;
+ }
default:
break;
}
enc->priv->active = FALSE;
enc->priv->samples_in = 0;
enc->priv->bytes_out = 0;
- gst_audio_info_clear (&enc->priv->ctx.info);
+ gst_audio_info_init (&enc->priv->ctx.info);
memset (&enc->priv->ctx, 0, sizeof (enc->priv->ctx));
+
+ if (enc->priv->tags)
+ gst_tag_list_free (enc->priv->tags);
+ enc->priv->tags = NULL;
+
+ g_list_foreach (enc->priv->pending_events, (GFunc) gst_event_unref, NULL);
+ g_list_free (enc->priv->pending_events);
+ enc->priv->pending_events = NULL;
}
gst_segment_init (&enc->segment, GST_FORMAT_TIME);
ctx = &enc->priv->ctx;
/* subclass should know what it is producing by now */
- g_return_val_if_fail (GST_PAD_CAPS (enc->srcpad) != NULL, GST_FLOW_ERROR);
+ g_return_val_if_fail (gst_pad_has_current_caps (enc->srcpad), GST_FLOW_ERROR);
/* subclass should not hand us no data */
- g_return_val_if_fail (buf == NULL || GST_BUFFER_SIZE (buf) > 0,
+ g_return_val_if_fail (buf == NULL || gst_buffer_get_size (buf) > 0,
GST_FLOW_ERROR);
+ GST_AUDIO_ENCODER_STREAM_LOCK (enc);
+
+ if (G_UNLIKELY (enc->priv->tags)) {
+ GstTagList *tags;
+
+ /* add codec info to pending tags */
+ tags = enc->priv->tags;
+ /* no more pending */
+ enc->priv->tags = NULL;
+ gst_pb_utils_add_codec_description_to_tag_list (tags, GST_TAG_CODEC,
+ GST_PAD_CAPS (enc->srcpad));
+ gst_pb_utils_add_codec_description_to_tag_list (tags, GST_TAG_AUDIO_CODEC,
+ GST_PAD_CAPS (enc->srcpad));
+ GST_DEBUG_OBJECT (enc, "sending tags %" GST_PTR_FORMAT, tags);
+ gst_element_found_tags_for_pad (GST_ELEMENT (enc), enc->srcpad, tags);
+ }
+
GST_LOG_OBJECT (enc, "accepting %d bytes encoded data as %d samples",
- buf ? GST_BUFFER_SIZE (buf) : -1, samples);
+ buf ? gst_buffer_get_size (buf) : -1, samples);
/* mark subclass still alive and providing */
priv->got_data = TRUE;
wrong_buffer:
{
GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL),
- ("buffer size %d not a multiple of %d", GST_BUFFER_SIZE (buffer),
+ ("buffer size %d not a multiple of %d", gst_buffer_get_size (buffer),
ctx->info.bpf));
gst_buffer_unref (buffer);
- return GST_FLOW_ERROR;
+ ret = GST_FLOW_ERROR;
+ goto done;
}
}
g_return_val_if_fail (klass->set_format != NULL, FALSE);
ctx = &enc->priv->ctx;
- state = &ctx->info;
+ GST_AUDIO_ENCODER_STREAM_LOCK (enc);
+
GST_DEBUG_OBJECT (enc, "caps: %" GST_PTR_FORMAT, caps);
if (!gst_caps_is_fixed (caps))
/* reset partially for new segment */
gst_audio_encoder_reset (enc, FALSE);
/* and follow along with segment */
- gst_segment_set_newsegment_full (&enc->segment, update, rate, arate,
- format, start, stop, time);
+ enc->segment = seg;
+ GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
break;
}
break;
case GST_EVENT_EOS:
+ GST_AUDIO_ENCODER_STREAM_LOCK (enc);
gst_audio_encoder_drain (enc);
+ GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
break;
+ case GST_EVENT_TAG:
+ {
+ GstTagList *tags;
+
+ gst_event_parse_tag (event, &tags);
+ tags = gst_tag_list_copy (tags);
+ gst_event_unref (event);
+ gst_tag_list_remove_tag (tags, GST_TAG_CODEC);
+ gst_tag_list_remove_tag (tags, GST_TAG_AUDIO_CODEC);
+ event = gst_event_new_tag (tags);
+
+ GST_OBJECT_LOCK (enc);
+ enc->priv->pending_events =
+ g_list_append (enc->priv->pending_events, event);
+ GST_OBJECT_UNLOCK (enc);
+ handled = TRUE;
+ break;
+ }
+
+ case GST_EVENT_CAPS:
+ {
+ GstCaps *caps;
+
+ gst_event_parse_caps (event, &caps);
+ gst_audio_encoder_sink_setcaps (enc, caps);
+ gst_event_unref (event);
+ handled = TRUE;
+ break;
+ }
+
default:
break;
}