2 * Copyright (C) 2011 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>.
3 * Copyright (C) 2011 Nokia Corporation. All rights reserved.
4 * Contact: Stefan Kost <stefan.kost@nokia.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
23 * SECTION:gstaudioencoder
24 * @short_description: Base class for audio encoders
25 * @see_also: #GstBaseTransform
27 * This base class is for audio encoders turning raw audio samples into
30 * GstAudioEncoder and subclass should cooperate as follows.
33 * <itemizedlist><title>Configuration</title>
35 * Initially, GstAudioEncoder calls @start when the encoder element
36 * is activated, which allows subclass to perform any global setup.
39 * GstAudioEncoder calls @set_format to inform subclass of the format
40 * of input audio data that it is about to receive. Subclass should
41 * setup for encoding and configure various base class parameters
42 * appropriately, notably those directing desired input data handling.
43 * While unlikely, it might be called more than once, if changing input
44 * parameters require reconfiguration.
47 * GstAudioEncoder calls @stop at end of all processing.
51 * As of configuration stage, and throughout processing, GstAudioEncoder
52 * maintains various parameters that provide required context,
53 * e.g. describing the format of input audio data.
54 * Conversely, subclass can and should configure these context parameters
55 * to inform base class of its expectation w.r.t. buffer handling.
58 * <title>Data processing</title>
60 * Base class gathers input sample data (as directed by the context's
61 * frame_samples and frame_max) and provides this to subclass' @handle_frame.
64 * If codec processing results in encoded data, subclass should call
65 * gst_audio_encoder_finish_frame() to have encoded data pushed
66 * downstream. Alternatively, it might also call
67 * gst_audio_encoder_finish_frame() (with a NULL buffer and some number of
68 * dropped samples) to indicate dropped (non-encoded) samples.
71 * Just prior to actually pushing a buffer downstream,
72 * it is passed to @pre_push.
75 * During the parsing process GstAudioEncoderClass will handle both
76 * srcpad and sinkpad events. Sink events will be passed to subclass
77 * if @event callback has been provided.
82 * <itemizedlist><title>Shutdown phase</title>
84 * GstAudioEncoder class calls @stop to inform the subclass that data
85 * parsing will be stopped.
91 * Subclass is responsible for providing pad template caps for
92 * source and sink pads. The pads need to be named "sink" and "src". It also
93 * needs to set the fixed caps on srcpad, when the format is ensured. This
94 * is typically when base class calls subclass' @set_format function, though
95 * it might be delayed until calling @gst_audio_encoder_finish_frame.
97 * In summary, above process should have subclass concentrating on
98 * codec data processing while leaving other matters to base class,
99 * such as most notably timestamp handling. While it may exert more control
100 * in this area (see e.g. @pre_push), it is very much not recommended.
102 * In particular, base class will either favor tracking upstream timestamps
103 * (at the possible expense of jitter) or aim to arrange for a perfect stream of
104 * output timestamps, depending on #GstAudioEncoder:perfect-timestamp.
105 * However, in the latter case, the input may not be so perfect or ideal, which
106 * is handled as follows. An input timestamp is compared with the expected
107 * timestamp as dictated by input sample stream and if the deviation is less
108 * than #GstAudioEncoder:tolerance, the deviation is discarded.
109 * Otherwise, it is considered a discontuinity and subsequent output timestamp
110 * is resynced to the new position after performing configured discontinuity
111 * processing. In the non-perfect-timestamp case, an upstream variation
112 * exceeding tolerance only leads to marking DISCONT on subsequent outgoing
113 * (while timestamps are adjusted to upstream regardless of variation).
114 * While DISCONT is also marked in the perfect-timestamp case, this one
115 * optionally (see #GstAudioEncoder:hard-resync)
116 * performs some additional steps, such as clipping of (early) input samples
117 * or draining all currently remaining input data, depending on the direction
118 * of the discontuinity.
120 * If perfect timestamps are arranged, it is also possible to request baseclass
121 * (usually set by subclass) to provide additional buffer metadata (in OFFSET
122 * and OFFSET_END) fields according to granule defined semantics currently
123 * needed by oggmux. Specifically, OFFSET is set to granulepos (= sample count
124 * including buffer) and OFFSET_END to corresponding timestamp (as determined
125 * by same sample count and sample rate).
127 * Things that subclass need to take care of:
129 * <listitem><para>Provide pad templates</para></listitem>
131 * Set source pad caps when appropriate
134 * Inform base class of buffer processing needs using context's
135 * frame_samples and frame_bytes.
138 * Set user-configurable properties to sane defaults for format and
139 * implementing codec at hand, e.g. those controlling timestamp behaviour
140 * and discontinuity processing.
143 * Accept data in @handle_frame and provide encoded results to
144 * gst_audio_encoder_finish_frame().
154 #include "gstaudioencoder.h"
155 #include "gstaudioutilsprivate.h"
156 #include <gst/base/gstadapter.h>
157 #include <gst/audio/audio.h>
158 #include <gst/pbutils/descriptions.h>
164 GST_DEBUG_CATEGORY_STATIC (gst_audio_encoder_debug);
165 #define GST_CAT_DEFAULT gst_audio_encoder_debug
167 #define GST_AUDIO_ENCODER_GET_PRIVATE(obj) \
168 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_AUDIO_ENCODER, \
169 GstAudioEncoderPrivate))
180 #define DEFAULT_PERFECT_TS FALSE
181 #define DEFAULT_GRANULE FALSE
182 #define DEFAULT_HARD_RESYNC FALSE
183 #define DEFAULT_TOLERANCE 40000000
184 #define DEFAULT_HARD_MIN FALSE
185 #define DEFAULT_DRAINABLE TRUE
187 typedef struct _GstAudioEncoderContext
190 /* last negotiated input caps */
192 /* last negotiated input info */
197 GstCaps *allocation_caps;
198 gboolean output_caps_changed;
199 gint frame_samples_min, frame_samples_max;
202 /* MT-protected (with LOCK) */
203 GstClockTime min_latency;
204 GstClockTime max_latency;
207 gboolean new_headers;
209 GstAllocator *allocator;
210 GstAllocationParams params;
211 } GstAudioEncoderContext;
213 struct _GstAudioEncoderPrivate
215 /* activation status */
218 /* input base/first ts as basis for output ts;
219 * kept nearly constant for perfect_ts,
220 * otherwise resyncs to upstream ts */
221 GstClockTime base_ts;
222 /* corresponding base granulepos */
224 /* input samples processed and sent downstream so far (w.r.t. base_ts) */
227 /* currently collected sample data */
229 /* offset in adapter up to which already supplied to encoder */
231 /* mark outgoing discont */
233 /* to guess duration of drained data */
234 GstClockTime last_duration;
236 /* subclass provided data in processing round */
238 /* subclass gave all it could already */
240 /* subclass currently being forcibly drained */
242 /* need to handle changed input caps */
245 /* output bps estimatation */
246 /* global in samples seen */
248 /* global bytes sent out */
251 /* context storage */
252 GstAudioEncoderContext ctx;
257 gboolean hard_resync;
262 /* upstream stream tags (global tags are passed through as-is) */
263 GstTagList *upstream_tags;
267 GstTagMergeMode tags_merge_mode;
269 gboolean tags_changed;
271 /* pending serialized sink events, will be sent from finish_frame() */
272 GList *pending_events;
276 static GstElementClass *parent_class = NULL;
278 static void gst_audio_encoder_class_init (GstAudioEncoderClass * klass);
279 static void gst_audio_encoder_init (GstAudioEncoder * parse,
280 GstAudioEncoderClass * klass);
283 gst_audio_encoder_get_type (void)
285 static GType audio_encoder_type = 0;
287 if (!audio_encoder_type) {
288 static const GTypeInfo audio_encoder_info = {
289 sizeof (GstAudioEncoderClass),
290 (GBaseInitFunc) NULL,
291 (GBaseFinalizeFunc) NULL,
292 (GClassInitFunc) gst_audio_encoder_class_init,
295 sizeof (GstAudioEncoder),
297 (GInstanceInitFunc) gst_audio_encoder_init,
299 const GInterfaceInfo preset_interface_info = {
300 NULL, /* interface_init */
301 NULL, /* interface_finalize */
302 NULL /* interface_data */
305 audio_encoder_type = g_type_register_static (GST_TYPE_ELEMENT,
306 "GstAudioEncoder", &audio_encoder_info, G_TYPE_FLAG_ABSTRACT);
308 g_type_add_interface_static (audio_encoder_type, GST_TYPE_PRESET,
309 &preset_interface_info);
311 return audio_encoder_type;
314 static void gst_audio_encoder_finalize (GObject * object);
315 static void gst_audio_encoder_reset (GstAudioEncoder * enc, gboolean full);
317 static void gst_audio_encoder_set_property (GObject * object,
318 guint prop_id, const GValue * value, GParamSpec * pspec);
319 static void gst_audio_encoder_get_property (GObject * object,
320 guint prop_id, GValue * value, GParamSpec * pspec);
322 static gboolean gst_audio_encoder_sink_activate_mode (GstPad * pad,
323 GstObject * parent, GstPadMode mode, gboolean active);
325 static GstCaps *gst_audio_encoder_getcaps_default (GstAudioEncoder * enc,
328 static gboolean gst_audio_encoder_sink_event_default (GstAudioEncoder * enc,
330 static gboolean gst_audio_encoder_src_event_default (GstAudioEncoder * enc,
332 static gboolean gst_audio_encoder_sink_event (GstPad * pad, GstObject * parent,
334 static gboolean gst_audio_encoder_src_event (GstPad * pad, GstObject * parent,
336 static gboolean gst_audio_encoder_sink_setcaps (GstAudioEncoder * enc,
338 static GstFlowReturn gst_audio_encoder_chain (GstPad * pad, GstObject * parent,
340 static gboolean gst_audio_encoder_src_query (GstPad * pad, GstObject * parent,
342 static gboolean gst_audio_encoder_sink_query (GstPad * pad, GstObject * parent,
344 static GstStateChangeReturn gst_audio_encoder_change_state (GstElement *
345 element, GstStateChange transition);
347 static gboolean gst_audio_encoder_decide_allocation_default (GstAudioEncoder *
348 enc, GstQuery * query);
349 static gboolean gst_audio_encoder_propose_allocation_default (GstAudioEncoder *
350 enc, GstQuery * query);
351 static gboolean gst_audio_encoder_negotiate_default (GstAudioEncoder * enc);
352 static gboolean gst_audio_encoder_negotiate_unlocked (GstAudioEncoder * enc);
354 static gboolean gst_audio_encoder_transform_meta_default (GstAudioEncoder *
355 encoder, GstBuffer * outbuf, GstMeta * meta, GstBuffer * inbuf);
357 static gboolean gst_audio_encoder_sink_query_default (GstAudioEncoder * encoder,
359 static gboolean gst_audio_encoder_src_query_default (GstAudioEncoder * encoder,
363 gst_audio_encoder_class_init (GstAudioEncoderClass * klass)
365 GObjectClass *gobject_class;
366 GstElementClass *gstelement_class;
368 gobject_class = G_OBJECT_CLASS (klass);
369 gstelement_class = GST_ELEMENT_CLASS (klass);
370 parent_class = g_type_class_peek_parent (klass);
372 GST_DEBUG_CATEGORY_INIT (gst_audio_encoder_debug, "audioencoder", 0,
373 "audio encoder base class");
375 g_type_class_add_private (klass, sizeof (GstAudioEncoderPrivate));
377 gobject_class->set_property = gst_audio_encoder_set_property;
378 gobject_class->get_property = gst_audio_encoder_get_property;
380 gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_audio_encoder_finalize);
383 g_object_class_install_property (gobject_class, PROP_PERFECT_TS,
384 g_param_spec_boolean ("perfect-timestamp", "Perfect Timestamps",
385 "Favour perfect timestamps over tracking upstream timestamps",
386 DEFAULT_PERFECT_TS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
387 g_object_class_install_property (gobject_class, PROP_GRANULE,
388 g_param_spec_boolean ("mark-granule", "Granule Marking",
389 "Apply granule semantics to buffer metadata (implies perfect-timestamp)",
390 DEFAULT_GRANULE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
391 g_object_class_install_property (gobject_class, PROP_HARD_RESYNC,
392 g_param_spec_boolean ("hard-resync", "Hard Resync",
393 "Perform clipping and sample flushing upon discontinuity",
394 DEFAULT_HARD_RESYNC, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
395 g_object_class_install_property (gobject_class, PROP_TOLERANCE,
396 g_param_spec_int64 ("tolerance", "Tolerance",
397 "Consider discontinuity if timestamp jitter/imperfection exceeds tolerance (ns)",
398 0, G_MAXINT64, DEFAULT_TOLERANCE,
399 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
401 gstelement_class->change_state =
402 GST_DEBUG_FUNCPTR (gst_audio_encoder_change_state);
404 klass->getcaps = gst_audio_encoder_getcaps_default;
405 klass->sink_event = gst_audio_encoder_sink_event_default;
406 klass->src_event = gst_audio_encoder_src_event_default;
407 klass->sink_query = gst_audio_encoder_sink_query_default;
408 klass->src_query = gst_audio_encoder_src_query_default;
409 klass->propose_allocation = gst_audio_encoder_propose_allocation_default;
410 klass->decide_allocation = gst_audio_encoder_decide_allocation_default;
411 klass->negotiate = gst_audio_encoder_negotiate_default;
412 klass->transform_meta = gst_audio_encoder_transform_meta_default;
416 gst_audio_encoder_init (GstAudioEncoder * enc, GstAudioEncoderClass * bclass)
418 GstPadTemplate *pad_template;
420 GST_DEBUG_OBJECT (enc, "gst_audio_encoder_init");
422 enc->priv = GST_AUDIO_ENCODER_GET_PRIVATE (enc);
424 /* only push mode supported */
426 gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "sink");
427 g_return_if_fail (pad_template != NULL);
428 enc->sinkpad = gst_pad_new_from_template (pad_template, "sink");
429 gst_pad_set_event_function (enc->sinkpad,
430 GST_DEBUG_FUNCPTR (gst_audio_encoder_sink_event));
431 gst_pad_set_query_function (enc->sinkpad,
432 GST_DEBUG_FUNCPTR (gst_audio_encoder_sink_query));
433 gst_pad_set_chain_function (enc->sinkpad,
434 GST_DEBUG_FUNCPTR (gst_audio_encoder_chain));
435 gst_pad_set_activatemode_function (enc->sinkpad,
436 GST_DEBUG_FUNCPTR (gst_audio_encoder_sink_activate_mode));
437 gst_element_add_pad (GST_ELEMENT (enc), enc->sinkpad);
439 GST_DEBUG_OBJECT (enc, "sinkpad created");
441 /* and we don't mind upstream traveling stuff that much ... */
443 gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "src");
444 g_return_if_fail (pad_template != NULL);
445 enc->srcpad = gst_pad_new_from_template (pad_template, "src");
446 gst_pad_set_event_function (enc->srcpad,
447 GST_DEBUG_FUNCPTR (gst_audio_encoder_src_event));
448 gst_pad_set_query_function (enc->srcpad,
449 GST_DEBUG_FUNCPTR (gst_audio_encoder_src_query));
450 gst_pad_use_fixed_caps (enc->srcpad);
451 gst_element_add_pad (GST_ELEMENT (enc), enc->srcpad);
452 GST_DEBUG_OBJECT (enc, "src created");
454 enc->priv->adapter = gst_adapter_new ();
456 g_rec_mutex_init (&enc->stream_lock);
458 /* property default */
459 enc->priv->granule = DEFAULT_GRANULE;
460 enc->priv->perfect_ts = DEFAULT_PERFECT_TS;
461 enc->priv->hard_resync = DEFAULT_HARD_RESYNC;
462 enc->priv->tolerance = DEFAULT_TOLERANCE;
463 enc->priv->hard_min = DEFAULT_HARD_MIN;
464 enc->priv->drainable = DEFAULT_DRAINABLE;
467 enc->priv->ctx.min_latency = 0;
468 enc->priv->ctx.max_latency = 0;
469 gst_audio_encoder_reset (enc, TRUE);
470 GST_DEBUG_OBJECT (enc, "init ok");
474 gst_audio_encoder_reset (GstAudioEncoder * enc, gboolean full)
476 GST_AUDIO_ENCODER_STREAM_LOCK (enc);
478 GST_LOG_OBJECT (enc, "reset full %d", full);
481 enc->priv->active = FALSE;
482 enc->priv->samples_in = 0;
483 enc->priv->bytes_out = 0;
485 g_list_foreach (enc->priv->ctx.headers, (GFunc) gst_buffer_unref, NULL);
486 g_list_free (enc->priv->ctx.headers);
487 enc->priv->ctx.headers = NULL;
488 enc->priv->ctx.new_headers = FALSE;
490 if (enc->priv->ctx.allocator)
491 gst_object_unref (enc->priv->ctx.allocator);
492 enc->priv->ctx.allocator = NULL;
494 gst_caps_replace (&enc->priv->ctx.input_caps, NULL);
495 gst_caps_replace (&enc->priv->ctx.caps, NULL);
496 gst_caps_replace (&enc->priv->ctx.allocation_caps, NULL);
498 memset (&enc->priv->ctx, 0, sizeof (enc->priv->ctx));
499 gst_audio_info_init (&enc->priv->ctx.info);
501 if (enc->priv->upstream_tags) {
502 gst_tag_list_unref (enc->priv->upstream_tags);
503 enc->priv->upstream_tags = NULL;
506 gst_tag_list_unref (enc->priv->tags);
507 enc->priv->tags = NULL;
508 enc->priv->tags_merge_mode = GST_TAG_MERGE_APPEND;
509 enc->priv->tags_changed = FALSE;
511 g_list_foreach (enc->priv->pending_events, (GFunc) gst_event_unref, NULL);
512 g_list_free (enc->priv->pending_events);
513 enc->priv->pending_events = NULL;
516 gst_segment_init (&enc->input_segment, GST_FORMAT_TIME);
517 gst_segment_init (&enc->output_segment, GST_FORMAT_TIME);
519 gst_adapter_clear (enc->priv->adapter);
520 enc->priv->got_data = FALSE;
521 enc->priv->drained = TRUE;
522 enc->priv->offset = 0;
523 enc->priv->base_ts = GST_CLOCK_TIME_NONE;
524 enc->priv->base_gp = -1;
525 enc->priv->samples = 0;
526 enc->priv->discont = FALSE;
528 GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
532 gst_audio_encoder_finalize (GObject * object)
534 GstAudioEncoder *enc = GST_AUDIO_ENCODER (object);
536 g_object_unref (enc->priv->adapter);
538 g_rec_mutex_clear (&enc->stream_lock);
540 G_OBJECT_CLASS (parent_class)->finalize (object);
543 static GstStateChangeReturn
544 gst_audio_encoder_change_state (GstElement * element, GstStateChange transition)
546 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
547 GstAudioEncoder *enc = GST_AUDIO_ENCODER (element);
548 GstAudioEncoderClass *klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
550 switch (transition) {
551 case GST_STATE_CHANGE_NULL_TO_READY:
553 if (!klass->open (enc))
560 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
562 switch (transition) {
563 case GST_STATE_CHANGE_READY_TO_NULL:
565 if (!klass->close (enc))
576 GST_ELEMENT_ERROR (enc, LIBRARY, INIT, (NULL), ("Failed to open codec"));
577 return GST_STATE_CHANGE_FAILURE;
581 GST_ELEMENT_ERROR (enc, LIBRARY, INIT, (NULL), ("Failed to close codec"));
582 return GST_STATE_CHANGE_FAILURE;
587 gst_audio_encoder_push_event (GstAudioEncoder * enc, GstEvent * event)
589 switch (GST_EVENT_TYPE (event)) {
590 case GST_EVENT_SEGMENT:{
593 GST_AUDIO_ENCODER_STREAM_LOCK (enc);
594 gst_event_copy_segment (event, &seg);
596 GST_DEBUG_OBJECT (enc, "starting segment %" GST_SEGMENT_FORMAT, &seg);
598 enc->output_segment = seg;
599 GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
606 return gst_pad_push_event (enc->srcpad, event);
610 gst_audio_encoder_push_pending_events (GstAudioEncoder * enc)
612 GstAudioEncoderPrivate *priv = enc->priv;
614 if (priv->pending_events) {
615 GList *pending_events, *l;
617 pending_events = priv->pending_events;
618 priv->pending_events = NULL;
620 GST_DEBUG_OBJECT (enc, "Pushing pending events");
621 for (l = pending_events; l; l = l->next)
622 gst_audio_encoder_push_event (enc, l->data);
623 g_list_free (pending_events);
628 gst_audio_encoder_create_merged_tags_event (GstAudioEncoder * enc)
630 GstTagList *merged_tags;
632 GST_LOG_OBJECT (enc, "upstream : %" GST_PTR_FORMAT, enc->priv->upstream_tags);
633 GST_LOG_OBJECT (enc, "encoder : %" GST_PTR_FORMAT, enc->priv->tags);
634 GST_LOG_OBJECT (enc, "mode : %d", enc->priv->tags_merge_mode);
637 gst_tag_list_merge (enc->priv->upstream_tags, enc->priv->tags,
638 enc->priv->tags_merge_mode);
640 GST_DEBUG_OBJECT (enc, "merged : %" GST_PTR_FORMAT, merged_tags);
642 if (merged_tags == NULL)
645 if (gst_tag_list_is_empty (merged_tags)) {
646 gst_tag_list_unref (merged_tags);
650 /* add codec info to pending tags */
652 caps = gst_pad_get_current_caps (enc->srcpad);
653 gst_pb_utils_add_codec_description_to_tag_list (merged_tags,
654 GST_TAG_AUDIO_CODEC, caps);
657 return gst_event_new_tag (merged_tags);
661 gst_audio_encoder_check_and_push_pending_tags (GstAudioEncoder * enc)
663 if (enc->priv->tags_changed) {
664 GstEvent *tags_event;
666 tags_event = gst_audio_encoder_create_merged_tags_event (enc);
668 if (tags_event != NULL)
669 gst_audio_encoder_push_event (enc, tags_event);
671 enc->priv->tags_changed = FALSE;
677 gst_audio_encoder_transform_meta_default (GstAudioEncoder *
678 encoder, GstBuffer * outbuf, GstMeta * meta, GstBuffer * inbuf)
680 const GstMetaInfo *info = meta->info;
681 const gchar *const *tags;
683 tags = gst_meta_api_type_get_tags (info->api);
685 if (!tags || (g_strv_length ((gchar **) tags) == 1
686 && gst_meta_api_type_has_tag (info->api,
687 g_quark_from_string (GST_META_TAG_AUDIO_STR))))
695 GstAudioEncoder *encoder;
700 foreach_metadata (GstBuffer * inbuf, GstMeta ** meta, gpointer user_data)
702 CopyMetaData *data = user_data;
703 GstAudioEncoder *encoder = data->encoder;
704 GstAudioEncoderClass *klass = GST_AUDIO_ENCODER_GET_CLASS (encoder);
705 GstBuffer *outbuf = data->outbuf;
706 const GstMetaInfo *info = (*meta)->info;
707 gboolean do_copy = FALSE;
709 if (gst_meta_api_type_has_tag (info->api, _gst_meta_tag_memory)) {
710 /* never call the transform_meta with memory specific metadata */
711 GST_DEBUG_OBJECT (encoder, "not copying memory specific metadata %s",
712 g_type_name (info->api));
714 } else if (klass->transform_meta) {
715 do_copy = klass->transform_meta (encoder, outbuf, *meta, inbuf);
716 GST_DEBUG_OBJECT (encoder, "transformed metadata %s: copy: %d",
717 g_type_name (info->api), do_copy);
720 /* we only copy metadata when the subclass implemented a transform_meta
721 * function and when it returns %TRUE */
723 GstMetaTransformCopy copy_data = { FALSE, 0, -1 };
724 GST_DEBUG_OBJECT (encoder, "copy metadata %s", g_type_name (info->api));
725 /* simply copy then */
726 info->transform_func (outbuf, *meta, inbuf,
727 _gst_meta_transform_copy, ©_data);
733 * gst_audio_encoder_finish_frame:
734 * @enc: a #GstAudioEncoder
735 * @buffer: encoded data
736 * @samples: number of samples (per channel) represented by encoded data
738 * Collects encoded data and pushes encoded data downstream.
739 * Source pad caps must be set when this is called.
741 * If @samples < 0, then best estimate is all samples provided to encoder
742 * (subclass) so far. @buf may be NULL, in which case next number of @samples
743 * are considered discarded, e.g. as a result of discontinuous transmission,
744 * and a discontinuity is marked.
746 * Note that samples received in gst_audio_encoder_handle_frame()
747 * may be invalidated by a call to this function.
749 * Returns: a #GstFlowReturn that should be escalated to caller (of caller)
752 gst_audio_encoder_finish_frame (GstAudioEncoder * enc, GstBuffer * buf,
755 GstAudioEncoderClass *klass;
756 GstAudioEncoderPrivate *priv;
757 GstAudioEncoderContext *ctx;
758 GstFlowReturn ret = GST_FLOW_OK;
759 gboolean needs_reconfigure = FALSE;
760 GstBuffer *inbuf = NULL;
762 klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
764 ctx = &enc->priv->ctx;
766 /* subclass should not hand us no data */
767 g_return_val_if_fail (buf == NULL || gst_buffer_get_size (buf) > 0,
770 /* subclass should know what it is producing by now */
774 GST_AUDIO_ENCODER_STREAM_LOCK (enc);
777 "accepting %" G_GSIZE_FORMAT " bytes encoded data as %d samples",
778 buf ? gst_buffer_get_size (buf) : -1, samples);
780 needs_reconfigure = gst_pad_check_reconfigure (enc->srcpad);
781 if (G_UNLIKELY (ctx->output_caps_changed || needs_reconfigure)) {
782 if (!gst_audio_encoder_negotiate_unlocked (enc)) {
783 gst_pad_mark_reconfigure (enc->srcpad);
784 if (GST_PAD_IS_FLUSHING (enc->srcpad))
785 ret = GST_FLOW_FLUSHING;
787 ret = GST_FLOW_NOT_NEGOTIATED;
792 /* mark subclass still alive and providing */
794 priv->got_data = TRUE;
796 gst_audio_encoder_push_pending_events (enc);
798 /* send after pending events, which likely includes segment event */
799 gst_audio_encoder_check_and_push_pending_tags (enc);
801 /* remove corresponding samples from input */
803 samples = (enc->priv->offset / ctx->info.bpf);
805 if (G_LIKELY (samples)) {
806 /* track upstream ts if so configured */
807 if (!enc->priv->perfect_ts) {
808 guint64 ts, distance;
810 ts = gst_adapter_prev_pts (priv->adapter, &distance);
811 g_assert (distance % ctx->info.bpf == 0);
812 distance /= ctx->info.bpf;
813 GST_LOG_OBJECT (enc, "%" G_GUINT64_FORMAT " samples past prev_ts %"
814 GST_TIME_FORMAT, distance, GST_TIME_ARGS (ts));
815 GST_LOG_OBJECT (enc, "%" G_GUINT64_FORMAT " samples past base_ts %"
816 GST_TIME_FORMAT, priv->samples, GST_TIME_ARGS (priv->base_ts));
817 /* when draining adapter might be empty and no ts to offer */
818 if (GST_CLOCK_TIME_IS_VALID (ts) && ts != priv->base_ts) {
819 GstClockTimeDiff diff;
820 GstClockTime old_ts, next_ts;
822 /* passed into another buffer;
823 * mild check for discontinuity and only mark if so */
825 gst_util_uint64_scale (distance, GST_SECOND, ctx->info.rate);
826 old_ts = priv->base_ts +
827 gst_util_uint64_scale (priv->samples, GST_SECOND, ctx->info.rate);
828 diff = GST_CLOCK_DIFF (next_ts, old_ts);
829 GST_LOG_OBJECT (enc, "ts diff %d ms", (gint) (diff / GST_MSECOND));
830 /* only mark discontinuity if beyond tolerance */
831 if (G_UNLIKELY (diff < -enc->priv->tolerance ||
832 diff > enc->priv->tolerance)) {
833 GST_DEBUG_OBJECT (enc, "marked discont");
834 priv->discont = TRUE;
836 if (diff > GST_SECOND / ctx->info.rate / 2 ||
837 diff < -GST_SECOND / ctx->info.rate / 2) {
838 GST_LOG_OBJECT (enc, "new upstream ts %" GST_TIME_FORMAT
839 " at distance %" G_GUINT64_FORMAT, GST_TIME_ARGS (ts), distance);
840 /* re-sync to upstream ts */
842 priv->samples = distance;
844 GST_LOG_OBJECT (enc, "new upstream ts only introduces jitter");
848 /* advance sample view */
849 if (G_UNLIKELY (samples * ctx->info.bpf > priv->offset)) {
850 guint avail = gst_adapter_available (priv->adapter);
852 if (G_LIKELY (!priv->force)) {
853 /* we should have received EOS to enable force */
857 if (avail > 0 && samples * ctx->info.bpf >= avail) {
858 inbuf = gst_adapter_take_buffer_fast (priv->adapter, avail);
859 gst_adapter_clear (priv->adapter);
860 } else if (avail > 0) {
862 gst_adapter_take_buffer_fast (priv->adapter,
863 samples * ctx->info.bpf);
867 guint avail = gst_adapter_available (priv->adapter);
871 gst_adapter_take_buffer_fast (priv->adapter,
872 samples * ctx->info.bpf);
874 priv->offset -= samples * ctx->info.bpf;
875 /* avoid subsequent stray prev_ts */
876 if (G_UNLIKELY (gst_adapter_available (priv->adapter) == 0))
877 gst_adapter_clear (priv->adapter);
879 /* sample count advanced below after buffer handling */
883 if (G_LIKELY (buf)) {
886 /* Pushing headers first */
887 if (G_UNLIKELY (priv->ctx.new_headers)) {
890 GST_DEBUG_OBJECT (enc, "Sending headers");
892 for (tmp = priv->ctx.headers; tmp; tmp = tmp->next) {
893 GstBuffer *tmpbuf = gst_buffer_ref (tmp->data);
895 tmpbuf = gst_buffer_make_writable (tmpbuf);
896 size = gst_buffer_get_size (tmpbuf);
898 if (G_UNLIKELY (priv->discont)) {
899 GST_LOG_OBJECT (enc, "marking discont");
900 GST_BUFFER_FLAG_SET (tmpbuf, GST_BUFFER_FLAG_DISCONT);
901 priv->discont = FALSE;
904 /* Ogg codecs like Vorbis use offset/offset-end in a special
905 * way and both should be 0 for these codecs */
906 if (priv->base_gp >= 0) {
907 GST_BUFFER_OFFSET (tmpbuf) = 0;
908 GST_BUFFER_OFFSET_END (tmpbuf) = 0;
910 GST_BUFFER_OFFSET (tmpbuf) = priv->bytes_out;
911 GST_BUFFER_OFFSET_END (tmpbuf) = priv->bytes_out + size;
914 priv->bytes_out += size;
916 gst_pad_push (enc->srcpad, tmpbuf);
918 priv->ctx.new_headers = FALSE;
921 size = gst_buffer_get_size (buf);
923 GST_LOG_OBJECT (enc, "taking %" G_GSIZE_FORMAT " bytes for output", size);
924 buf = gst_buffer_make_writable (buf);
927 if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (priv->base_ts))) {
928 /* FIXME ? lookahead could lead to weird ts and duration ?
929 * (particularly if not in perfect mode) */
930 /* mind sample rounding and produce perfect output */
931 GST_BUFFER_TIMESTAMP (buf) = priv->base_ts +
932 gst_util_uint64_scale (priv->samples - ctx->lookahead, GST_SECOND,
934 GST_BUFFER_DTS (buf) = GST_BUFFER_TIMESTAMP (buf);
935 GST_DEBUG_OBJECT (enc, "out samples %d", samples);
936 if (G_LIKELY (samples > 0)) {
937 priv->samples += samples;
938 GST_BUFFER_DURATION (buf) = priv->base_ts +
939 gst_util_uint64_scale (priv->samples - ctx->lookahead, GST_SECOND,
940 ctx->info.rate) - GST_BUFFER_TIMESTAMP (buf);
941 priv->last_duration = GST_BUFFER_DURATION (buf);
943 /* duration forecast in case of handling remainder;
944 * the last one is probably like the previous one ... */
945 GST_BUFFER_DURATION (buf) = priv->last_duration;
947 if (priv->base_gp >= 0) {
949 /* FIXME: in longer run, muxer should take care of this ... */
950 /* offset_end = granulepos for ogg muxer */
951 GST_BUFFER_OFFSET_END (buf) = priv->base_gp + priv->samples -
952 enc->priv->ctx.lookahead;
953 /* offset = timestamp corresponding to granulepos for ogg muxer */
954 GST_BUFFER_OFFSET (buf) =
955 GST_FRAMES_TO_CLOCK_TIME (GST_BUFFER_OFFSET_END (buf),
958 GST_BUFFER_OFFSET (buf) = priv->bytes_out;
959 GST_BUFFER_OFFSET_END (buf) = priv->bytes_out + size;
963 if (klass->transform_meta) {
964 if (G_LIKELY (inbuf)) {
969 gst_buffer_foreach_meta (inbuf, foreach_metadata, &data);
971 GST_WARNING_OBJECT (enc,
972 "Can't copy metadata because input buffer disappeared");
976 priv->bytes_out += size;
978 if (G_UNLIKELY (priv->discont)) {
979 GST_LOG_OBJECT (enc, "marking discont");
980 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
981 priv->discont = FALSE;
984 if (klass->pre_push) {
985 /* last chance for subclass to do some dirty stuff */
986 ret = klass->pre_push (enc, &buf);
987 if (ret != GST_FLOW_OK || !buf) {
988 GST_DEBUG_OBJECT (enc, "subclass returned %s, buf %p",
989 gst_flow_get_name (ret), buf);
992 gst_buffer_unref (buf);
998 "pushing buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
999 ", duration %" GST_TIME_FORMAT, size,
1000 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
1001 GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
1003 ret = gst_pad_push (enc->srcpad, buf);
1004 GST_LOG_OBJECT (enc, "buffer pushed: %s", gst_flow_get_name (ret));
1006 /* merely advance samples, most work for that already done above */
1007 priv->samples += samples;
1012 gst_buffer_unref (inbuf);
1014 GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
1021 GST_ELEMENT_ERROR (enc, STREAM, ENCODE, ("no caps set"), (NULL));
1023 gst_buffer_unref (buf);
1024 return GST_FLOW_ERROR;
1028 GST_ELEMENT_ERROR (enc, STREAM, ENCODE,
1029 ("received more encoded samples %d than provided %d as inputs",
1030 samples, priv->offset / ctx->info.bpf), (NULL));
1032 gst_buffer_unref (buf);
1033 ret = GST_FLOW_ERROR;
1034 /* no way we can let this pass */
1035 g_assert_not_reached ();
1041 /* adapter tracking idea:
1042 * - start of adapter corresponds with what has already been encoded
1043 * (i.e. really returned by encoder subclass)
1044 * - start + offset is what needs to be fed to subclass next */
1045 static GstFlowReturn
1046 gst_audio_encoder_push_buffers (GstAudioEncoder * enc, gboolean force)
1048 GstAudioEncoderClass *klass;
1049 GstAudioEncoderPrivate *priv;
1050 GstAudioEncoderContext *ctx;
1053 GstFlowReturn ret = GST_FLOW_OK;
1055 klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
1057 g_return_val_if_fail (klass->handle_frame != NULL, GST_FLOW_ERROR);
1060 ctx = &enc->priv->ctx;
1062 while (ret == GST_FLOW_OK) {
1065 av = gst_adapter_available (priv->adapter);
1067 g_assert (priv->offset <= av);
1071 ctx->frame_samples_min >
1072 0 ? ctx->frame_samples_min * ctx->info.bpf : av;
1073 GST_LOG_OBJECT (enc, "available: %d, needed: %d, force: %d", av, need,
1076 if ((need > av) || !av) {
1077 if (G_UNLIKELY (force)) {
1084 priv->force = FALSE;
1087 if (ctx->frame_samples_max > 0)
1088 need = MIN (av, ctx->frame_samples_max * ctx->info.bpf);
1090 if (ctx->frame_samples_min == ctx->frame_samples_max) {
1091 /* if we have some extra metadata,
1092 * provide for integer multiple of frames to allow for better granularity
1094 if (ctx->frame_samples_min > 0 && need) {
1095 if (ctx->frame_max > 1)
1096 need = need * MIN ((av / need), ctx->frame_max);
1097 else if (ctx->frame_max == 0)
1098 need = need * (av / need);
1102 priv->got_data = FALSE;
1103 if (G_LIKELY (need)) {
1106 data = gst_adapter_map (priv->adapter, priv->offset + need);
1108 gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
1109 (gpointer) data, priv->offset + need, priv->offset, need, NULL, NULL);
1110 } else if (!priv->drainable) {
1111 GST_DEBUG_OBJECT (enc, "non-drainable and no more data");
1115 GST_LOG_OBJECT (enc, "providing subclass with %d bytes at offset %d",
1116 need, priv->offset);
1118 /* mark this already as consumed,
1119 * which it should be when subclass gives us data in exchange for samples */
1120 priv->offset += need;
1121 priv->samples_in += need / ctx->info.bpf;
1123 /* subclass might not want to be bothered with leftover data,
1124 * so take care of that here if so, otherwise pass along */
1125 if (G_UNLIKELY (priv->force && priv->hard_min && buf)) {
1126 GST_DEBUG_OBJECT (enc, "bypassing subclass with leftover");
1127 ret = gst_audio_encoder_finish_frame (enc, NULL, -1);
1129 ret = klass->handle_frame (enc, buf);
1132 if (G_LIKELY (buf)) {
1133 gst_buffer_unref (buf);
1134 gst_adapter_unmap (priv->adapter);
1138 /* no data to feed, no leftover provided, then bail out */
1139 if (G_UNLIKELY (!buf && !priv->got_data)) {
1140 priv->drained = TRUE;
1141 GST_LOG_OBJECT (enc, "no more data drained from subclass");
1149 static GstFlowReturn
1150 gst_audio_encoder_drain (GstAudioEncoder * enc)
1152 GST_DEBUG_OBJECT (enc, "draining");
1153 if (enc->priv->drained)
1156 GST_DEBUG_OBJECT (enc, "... really");
1157 return gst_audio_encoder_push_buffers (enc, TRUE);
1162 gst_audio_encoder_set_base_gp (GstAudioEncoder * enc)
1166 if (!enc->priv->granule)
1169 /* use running time for granule */
1170 /* incoming data is clipped, so a valid input should yield a valid output */
1171 ts = gst_segment_to_running_time (&enc->input_segment, GST_FORMAT_TIME,
1172 enc->priv->base_ts);
1173 if (GST_CLOCK_TIME_IS_VALID (ts)) {
1174 enc->priv->base_gp =
1175 GST_CLOCK_TIME_TO_FRAMES (enc->priv->base_ts, enc->priv->ctx.info.rate);
1176 GST_DEBUG_OBJECT (enc, "new base gp %" G_GINT64_FORMAT, enc->priv->base_gp);
1178 /* should reasonably have a valid base,
1179 * otherwise start at 0 if we did not already start there earlier */
1180 if (enc->priv->base_gp < 0) {
1181 enc->priv->base_gp = 0;
1182 GST_DEBUG_OBJECT (enc, "new base gp %" G_GINT64_FORMAT,
1183 enc->priv->base_gp);
1188 static GstFlowReturn
1189 gst_audio_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
1191 GstAudioEncoder *enc;
1192 GstAudioEncoderPrivate *priv;
1193 GstAudioEncoderContext *ctx;
1194 GstFlowReturn ret = GST_FLOW_OK;
1198 enc = GST_AUDIO_ENCODER (parent);
1201 ctx = &enc->priv->ctx;
1203 GST_AUDIO_ENCODER_STREAM_LOCK (enc);
1205 if (G_UNLIKELY (priv->do_caps)) {
1206 GstCaps *caps = gst_pad_get_current_caps (enc->sinkpad);
1208 goto not_negotiated;
1209 if (!gst_audio_encoder_sink_setcaps (enc, caps)) {
1210 gst_caps_unref (caps);
1211 goto not_negotiated;
1213 gst_caps_unref (caps);
1214 priv->do_caps = FALSE;
1217 /* should know what is coming by now */
1219 goto not_negotiated;
1221 size = gst_buffer_get_size (buffer);
1223 GST_LOG_OBJECT (enc,
1224 "received buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
1225 ", duration %" GST_TIME_FORMAT, size,
1226 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
1227 GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
1229 /* input shoud be whole number of sample frames */
1230 if (size % ctx->info.bpf)
1233 #ifndef GST_DISABLE_GST_DEBUG
1235 GstClockTime duration;
1236 GstClockTimeDiff diff;
1238 /* verify buffer duration */
1239 duration = gst_util_uint64_scale (size, GST_SECOND,
1240 ctx->info.rate * ctx->info.bpf);
1241 diff = GST_CLOCK_DIFF (duration, GST_BUFFER_DURATION (buffer));
1242 if (GST_BUFFER_DURATION (buffer) != GST_CLOCK_TIME_NONE &&
1243 (diff > GST_SECOND / ctx->info.rate / 2 ||
1244 diff < -GST_SECOND / ctx->info.rate / 2)) {
1245 GST_DEBUG_OBJECT (enc, "incoming buffer had incorrect duration %"
1246 GST_TIME_FORMAT ", expected duration %" GST_TIME_FORMAT,
1247 GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)),
1248 GST_TIME_ARGS (duration));
1253 discont = GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT);
1254 if (G_UNLIKELY (discont)) {
1255 GST_LOG_OBJECT (buffer, "marked discont");
1256 enc->priv->discont = discont;
1259 /* clip to segment */
1260 buffer = gst_audio_buffer_clip (buffer, &enc->input_segment, ctx->info.rate,
1262 if (G_UNLIKELY (!buffer)) {
1263 GST_DEBUG_OBJECT (buffer, "no data after clipping to segment");
1267 size = gst_buffer_get_size (buffer);
1269 GST_LOG_OBJECT (enc,
1270 "buffer after segment clipping has size %" G_GSIZE_FORMAT " with ts %"
1271 GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT, size,
1272 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
1273 GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
1275 if (!GST_CLOCK_TIME_IS_VALID (priv->base_ts)) {
1276 priv->base_ts = GST_BUFFER_TIMESTAMP (buffer);
1277 GST_DEBUG_OBJECT (enc, "new base ts %" GST_TIME_FORMAT,
1278 GST_TIME_ARGS (priv->base_ts));
1279 gst_audio_encoder_set_base_gp (enc);
1282 /* check for continuity;
1283 * checked elsewhere in non-perfect case */
1284 if (enc->priv->perfect_ts) {
1285 GstClockTimeDiff diff = 0;
1286 GstClockTime next_ts = 0;
1288 if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
1289 GST_CLOCK_TIME_IS_VALID (priv->base_ts)) {
1292 samples = priv->samples +
1293 gst_adapter_available (priv->adapter) / ctx->info.bpf;
1294 next_ts = priv->base_ts +
1295 gst_util_uint64_scale (samples, GST_SECOND, ctx->info.rate);
1296 GST_LOG_OBJECT (enc, "buffer is %" G_GUINT64_FORMAT
1297 " samples past base_ts %" GST_TIME_FORMAT
1298 ", expected ts %" GST_TIME_FORMAT, samples,
1299 GST_TIME_ARGS (priv->base_ts), GST_TIME_ARGS (next_ts));
1300 diff = GST_CLOCK_DIFF (next_ts, GST_BUFFER_TIMESTAMP (buffer));
1301 GST_LOG_OBJECT (enc, "ts diff %d ms", (gint) (diff / GST_MSECOND));
1302 /* if within tolerance,
1303 * discard buffer ts and carry on producing perfect stream,
1304 * otherwise clip or resync to ts */
1305 if (G_UNLIKELY (diff < -enc->priv->tolerance ||
1306 diff > enc->priv->tolerance)) {
1307 GST_DEBUG_OBJECT (enc, "marked discont");
1312 /* do some fancy tweaking in hard resync case */
1313 if (discont && enc->priv->hard_resync) {
1317 GST_WARNING_OBJECT (enc, "Buffer is older than expected ts %"
1318 GST_TIME_FORMAT ". Clipping buffer", GST_TIME_ARGS (next_ts));
1321 GST_CLOCK_TIME_TO_FRAMES (-diff, ctx->info.rate) * ctx->info.bpf;
1322 if (diff_bytes >= size) {
1323 gst_buffer_unref (buffer);
1326 buffer = gst_buffer_make_writable (buffer);
1327 gst_buffer_resize (buffer, diff_bytes, size - diff_bytes);
1329 GST_BUFFER_TIMESTAMP (buffer) += diff;
1330 /* care even less about duration after this */
1332 /* drain stuff prior to resync */
1333 gst_audio_encoder_drain (enc);
1337 /* now re-sync ts */
1338 priv->base_ts += diff;
1339 gst_audio_encoder_set_base_gp (enc);
1340 priv->discont |= discont;
1344 gst_adapter_push (enc->priv->adapter, buffer);
1345 /* new stuff, so we can push subclass again */
1346 enc->priv->drained = FALSE;
1348 ret = gst_audio_encoder_push_buffers (enc, FALSE);
1351 GST_LOG_OBJECT (enc, "chain leaving");
1353 GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
1360 GST_ELEMENT_ERROR (enc, CORE, NEGOTIATION, (NULL),
1361 ("encoder not initialized"));
1362 gst_buffer_unref (buffer);
1363 ret = GST_FLOW_NOT_NEGOTIATED;
1368 GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL),
1369 ("buffer size %" G_GSIZE_FORMAT " not a multiple of %d",
1370 gst_buffer_get_size (buffer), ctx->info.bpf));
1371 gst_buffer_unref (buffer);
1372 ret = GST_FLOW_ERROR;
1378 gst_audio_encoder_sink_setcaps (GstAudioEncoder * enc, GstCaps * caps)
1380 GstAudioEncoderClass *klass;
1381 GstAudioEncoderContext *ctx;
1383 gboolean res = TRUE;
1386 klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
1388 /* subclass must do something here ... */
1389 g_return_val_if_fail (klass->set_format != NULL, FALSE);
1391 ctx = &enc->priv->ctx;
1393 GST_AUDIO_ENCODER_STREAM_LOCK (enc);
1395 GST_DEBUG_OBJECT (enc, "caps: %" GST_PTR_FORMAT, caps);
1397 if (!gst_caps_is_fixed (caps))
1400 if (enc->priv->ctx.input_caps
1401 && gst_caps_is_equal (enc->priv->ctx.input_caps, caps))
1404 if (!gst_audio_info_from_caps (&state, caps))
1407 if (enc->priv->ctx.input_caps && gst_audio_info_is_equal (&state, &ctx->info))
1410 /* adjust ts tracking to new sample rate */
1411 old_rate = GST_AUDIO_INFO_RATE (&ctx->info);
1412 if (GST_CLOCK_TIME_IS_VALID (enc->priv->base_ts) && old_rate) {
1413 enc->priv->base_ts +=
1414 GST_FRAMES_TO_CLOCK_TIME (enc->priv->samples, old_rate);
1415 enc->priv->samples = 0;
1418 /* drain any pending old data stuff */
1419 gst_audio_encoder_drain (enc);
1421 /* context defaults */
1422 /* FIXME 2.0: This is quite unexpected behaviour. We should never
1423 * just reset *settings* of a subclass inside the base class */
1424 enc->priv->ctx.frame_samples_min = 0;
1425 enc->priv->ctx.frame_samples_max = 0;
1426 enc->priv->ctx.frame_max = 0;
1427 enc->priv->ctx.lookahead = 0;
1429 if (klass->set_format)
1430 res = klass->set_format (enc, &state);
1434 gst_caps_replace (&enc->priv->ctx.input_caps, caps);
1436 /* invalidate state to ensure no casual carrying on */
1437 GST_DEBUG_OBJECT (enc, "subclass did not accept format");
1438 gst_audio_info_init (&state);
1444 GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
1450 GST_DEBUG_OBJECT (enc, "new audio format identical to configured format");
1457 GST_WARNING_OBJECT (enc, "rejected caps %" GST_PTR_FORMAT, caps);
1464 * gst_audio_encoder_proxy_getcaps:
1465 * @enc: a #GstAudioEncoder
1466 * @caps: (allow-none): initial caps
1467 * @filter: (allow-none): filter caps
1469 * Returns caps that express @caps (or sink template caps if @caps == NULL)
1470 * restricted to channel/rate combinations supported by downstream elements
1473 * Returns: (transfer full): a #GstCaps owned by caller
1476 gst_audio_encoder_proxy_getcaps (GstAudioEncoder * enc, GstCaps * caps,
1479 return __gst_audio_element_proxy_getcaps (GST_ELEMENT_CAST (enc),
1480 GST_AUDIO_ENCODER_SINK_PAD (enc), GST_AUDIO_ENCODER_SRC_PAD (enc),
1485 gst_audio_encoder_getcaps_default (GstAudioEncoder * enc, GstCaps * filter)
1489 caps = gst_audio_encoder_proxy_getcaps (enc, NULL, filter);
1490 GST_LOG_OBJECT (enc, "returning caps %" GST_PTR_FORMAT, caps);
1496 _flush_events (GstPad * pad, GList * events)
1500 for (tmp = events; tmp; tmp = tmp->next) {
1501 if (GST_EVENT_TYPE (tmp->data) != GST_EVENT_EOS &&
1502 GST_EVENT_TYPE (tmp->data) != GST_EVENT_SEGMENT &&
1503 GST_EVENT_IS_STICKY (tmp->data)) {
1504 gst_pad_store_sticky_event (pad, GST_EVENT_CAST (tmp->data));
1506 gst_event_unref (tmp->data);
1508 g_list_free (events);
1514 gst_audio_encoder_sink_event_default (GstAudioEncoder * enc, GstEvent * event)
1516 GstAudioEncoderClass *klass;
1519 klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
1521 switch (GST_EVENT_TYPE (event)) {
1522 case GST_EVENT_SEGMENT:
1526 gst_event_copy_segment (event, &seg);
1528 if (seg.format == GST_FORMAT_TIME) {
1529 GST_DEBUG_OBJECT (enc, "received TIME SEGMENT %" GST_SEGMENT_FORMAT,
1532 GST_DEBUG_OBJECT (enc, "received SEGMENT %" GST_SEGMENT_FORMAT, &seg);
1533 GST_DEBUG_OBJECT (enc, "unsupported format; ignoring");
1538 GST_AUDIO_ENCODER_STREAM_LOCK (enc);
1539 /* finish current segment */
1540 gst_audio_encoder_drain (enc);
1541 /* reset partially for new segment */
1542 gst_audio_encoder_reset (enc, FALSE);
1543 /* and follow along with segment */
1544 enc->input_segment = seg;
1546 enc->priv->pending_events =
1547 g_list_append (enc->priv->pending_events, event);
1548 GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
1554 case GST_EVENT_FLUSH_START:
1555 res = gst_audio_encoder_push_event (enc, event);
1558 case GST_EVENT_FLUSH_STOP:
1559 GST_AUDIO_ENCODER_STREAM_LOCK (enc);
1560 /* discard any pending stuff */
1561 /* TODO route through drain ?? */
1562 if (!enc->priv->drained && klass->flush)
1564 /* and get (re)set for the sequel */
1565 gst_audio_encoder_reset (enc, FALSE);
1567 enc->priv->pending_events = _flush_events (enc->srcpad,
1568 enc->priv->pending_events);
1569 GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
1571 res = gst_audio_encoder_push_event (enc, event);
1575 GST_AUDIO_ENCODER_STREAM_LOCK (enc);
1576 gst_audio_encoder_drain (enc);
1578 /* check for pending events and tags */
1579 gst_audio_encoder_push_pending_events (enc);
1580 gst_audio_encoder_check_and_push_pending_tags (enc);
1582 GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
1584 /* forward immediately because no buffer or serialized event
1585 * will come after EOS and nothing could trigger another
1586 * _finish_frame() call. */
1587 res = gst_audio_encoder_push_event (enc, event);
1590 case GST_EVENT_CAPS:
1594 gst_event_parse_caps (event, &caps);
1595 enc->priv->do_caps = TRUE;
1597 gst_event_unref (event);
1601 case GST_EVENT_STREAM_START:
1603 GST_AUDIO_ENCODER_STREAM_LOCK (enc);
1604 /* Flush upstream tags after a STREAM_START */
1605 GST_DEBUG_OBJECT (enc, "received STREAM_START. Clearing taglist");
1606 if (enc->priv->upstream_tags) {
1607 gst_tag_list_unref (enc->priv->upstream_tags);
1608 enc->priv->upstream_tags = NULL;
1609 enc->priv->tags_changed = TRUE;
1611 GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
1612 res = gst_audio_encoder_push_event (enc, event);
1620 gst_event_parse_tag (event, &tags);
1622 if (gst_tag_list_get_scope (tags) == GST_TAG_SCOPE_STREAM) {
1623 GST_AUDIO_ENCODER_STREAM_LOCK (enc);
1624 if (enc->priv->upstream_tags != tags) {
1625 tags = gst_tag_list_copy (tags);
1627 /* FIXME: make generic based on GST_TAG_FLAG_ENCODED */
1628 gst_tag_list_remove_tag (tags, GST_TAG_CODEC);
1629 gst_tag_list_remove_tag (tags, GST_TAG_AUDIO_CODEC);
1630 gst_tag_list_remove_tag (tags, GST_TAG_VIDEO_CODEC);
1631 gst_tag_list_remove_tag (tags, GST_TAG_SUBTITLE_CODEC);
1632 gst_tag_list_remove_tag (tags, GST_TAG_CONTAINER_FORMAT);
1633 gst_tag_list_remove_tag (tags, GST_TAG_BITRATE);
1634 gst_tag_list_remove_tag (tags, GST_TAG_NOMINAL_BITRATE);
1635 gst_tag_list_remove_tag (tags, GST_TAG_MAXIMUM_BITRATE);
1636 gst_tag_list_remove_tag (tags, GST_TAG_MINIMUM_BITRATE);
1637 gst_tag_list_remove_tag (tags, GST_TAG_ENCODER);
1638 gst_tag_list_remove_tag (tags, GST_TAG_ENCODER_VERSION);
1640 if (enc->priv->upstream_tags)
1641 gst_tag_list_unref (enc->priv->upstream_tags);
1642 enc->priv->upstream_tags = tags;
1643 GST_INFO_OBJECT (enc, "upstream stream tags: %" GST_PTR_FORMAT, tags);
1645 gst_event_unref (event);
1646 event = gst_audio_encoder_create_merged_tags_event (enc);
1647 GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
1649 /* No tags, go out of here instead of fall through */
1658 /* Forward non-serialized events immediately. */
1659 if (!GST_EVENT_IS_SERIALIZED (event)) {
1661 gst_pad_event_default (enc->sinkpad, GST_OBJECT_CAST (enc), event);
1663 GST_AUDIO_ENCODER_STREAM_LOCK (enc);
1664 enc->priv->pending_events =
1665 g_list_append (enc->priv->pending_events, event);
1666 GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
1675 gst_audio_encoder_sink_event (GstPad * pad, GstObject * parent,
1678 GstAudioEncoder *enc;
1679 GstAudioEncoderClass *klass;
1682 enc = GST_AUDIO_ENCODER (parent);
1683 klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
1685 GST_DEBUG_OBJECT (enc, "received event %d, %s", GST_EVENT_TYPE (event),
1686 GST_EVENT_TYPE_NAME (event));
1688 if (klass->sink_event)
1689 ret = klass->sink_event (enc, event);
1691 gst_event_unref (event);
1695 GST_DEBUG_OBJECT (enc, "event result %d", ret);
1701 gst_audio_encoder_sink_query_default (GstAudioEncoder * enc, GstQuery * query)
1703 GstPad *pad = GST_AUDIO_ENCODER_SINK_PAD (enc);
1704 gboolean res = FALSE;
1706 switch (GST_QUERY_TYPE (query)) {
1707 case GST_QUERY_FORMATS:
1709 gst_query_set_formats (query, 3,
1710 GST_FORMAT_TIME, GST_FORMAT_BYTES, GST_FORMAT_DEFAULT);
1714 case GST_QUERY_CONVERT:
1716 GstFormat src_fmt, dest_fmt;
1717 gint64 src_val, dest_val;
1719 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
1720 if (!(res = gst_audio_info_convert (&enc->priv->ctx.info,
1721 src_fmt, src_val, dest_fmt, &dest_val)))
1723 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1727 case GST_QUERY_CAPS:
1729 GstCaps *filter, *caps;
1730 GstAudioEncoderClass *klass;
1732 gst_query_parse_caps (query, &filter);
1734 klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
1735 if (klass->getcaps) {
1736 caps = klass->getcaps (enc, filter);
1737 gst_query_set_caps_result (query, caps);
1738 gst_caps_unref (caps);
1743 case GST_QUERY_ALLOCATION:
1745 GstAudioEncoderClass *klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
1747 if (klass->propose_allocation)
1748 res = klass->propose_allocation (enc, query);
1752 res = gst_pad_query_default (pad, GST_OBJECT (enc), query);
1761 gst_audio_encoder_sink_query (GstPad * pad, GstObject * parent,
1764 GstAudioEncoder *encoder;
1765 GstAudioEncoderClass *encoder_class;
1766 gboolean ret = FALSE;
1768 encoder = GST_AUDIO_ENCODER (parent);
1769 encoder_class = GST_AUDIO_ENCODER_GET_CLASS (encoder);
1771 GST_DEBUG_OBJECT (encoder, "received query %d, %s", GST_QUERY_TYPE (query),
1772 GST_QUERY_TYPE_NAME (query));
1774 if (encoder_class->sink_query)
1775 ret = encoder_class->sink_query (encoder, query);
1781 gst_audio_encoder_src_event_default (GstAudioEncoder * enc, GstEvent * event)
1785 switch (GST_EVENT_TYPE (event)) {
1787 res = gst_pad_event_default (enc->srcpad, GST_OBJECT_CAST (enc), event);
1794 gst_audio_encoder_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
1796 GstAudioEncoder *enc;
1797 GstAudioEncoderClass *klass;
1800 enc = GST_AUDIO_ENCODER (parent);
1801 klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
1803 GST_DEBUG_OBJECT (enc, "received event %d, %s", GST_EVENT_TYPE (event),
1804 GST_EVENT_TYPE_NAME (event));
1806 if (klass->src_event)
1807 ret = klass->src_event (enc, event);
1809 gst_event_unref (event);
1817 gst_audio_encoder_decide_allocation_default (GstAudioEncoder * enc,
1820 GstAllocator *allocator = NULL;
1821 GstAllocationParams params;
1822 gboolean update_allocator;
1824 /* we got configuration from our peer or the decide_allocation method,
1826 if (gst_query_get_n_allocation_params (query) > 0) {
1827 /* try the allocator */
1828 gst_query_parse_nth_allocation_param (query, 0, &allocator, ¶ms);
1829 update_allocator = TRUE;
1832 gst_allocation_params_init (¶ms);
1833 update_allocator = FALSE;
1836 if (update_allocator)
1837 gst_query_set_nth_allocation_param (query, 0, allocator, ¶ms);
1839 gst_query_add_allocation_param (query, allocator, ¶ms);
1841 gst_object_unref (allocator);
1847 gst_audio_encoder_propose_allocation_default (GstAudioEncoder * enc,
1854 * gst_audio_encoded_audio_convert:
1855 * @fmt: audio format of the encoded audio
1856 * @bytes: number of encoded bytes
1857 * @samples: number of encoded samples
1858 * @src_format: source format
1859 * @src_value: source value
1860 * @dest_format: destination format
1861 * @dest_value: destination format
1863 * Helper function to convert @src_value in @src_format to @dest_value in
1864 * @dest_format for encoded audio data. Conversion is possible between
1865 * BYTE and TIME format by using estimated bitrate based on
1866 * @samples and @bytes (and @fmt).
1868 /* FIXME: make gst_audio_encoded_audio_convert() public? */
1870 gst_audio_encoded_audio_convert (GstAudioInfo * fmt,
1871 gint64 bytes, gint64 samples, GstFormat src_format,
1872 gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
1874 gboolean res = FALSE;
1876 g_return_val_if_fail (dest_format != NULL, FALSE);
1877 g_return_val_if_fail (dest_value != NULL, FALSE);
1879 if (G_UNLIKELY (src_format == *dest_format || src_value == 0 ||
1882 *dest_value = src_value;
1886 if (samples == 0 || bytes == 0 || fmt->rate == 0) {
1887 GST_DEBUG ("not enough metadata yet to convert");
1893 switch (src_format) {
1894 case GST_FORMAT_BYTES:
1895 switch (*dest_format) {
1896 case GST_FORMAT_TIME:
1897 *dest_value = gst_util_uint64_scale (src_value,
1898 GST_SECOND * samples, bytes);
1905 case GST_FORMAT_TIME:
1906 switch (*dest_format) {
1907 case GST_FORMAT_BYTES:
1908 *dest_value = gst_util_uint64_scale (src_value, bytes,
1909 samples * GST_SECOND);
1924 /* FIXME ? are any of these queries (other than latency) an encoder's business
1925 * also, the conversion stuff might seem to make sense, but seems to not mind
1926 * segment stuff etc at all
1927 * Supposedly that's backward compatibility ... */
1929 gst_audio_encoder_src_query_default (GstAudioEncoder * enc, GstQuery * query)
1931 GstPad *pad = GST_AUDIO_ENCODER_SRC_PAD (enc);
1932 gboolean res = FALSE;
1934 GST_LOG_OBJECT (enc, "handling query: %" GST_PTR_FORMAT, query);
1936 switch (GST_QUERY_TYPE (query)) {
1937 case GST_QUERY_POSITION:
1939 GstFormat fmt, req_fmt;
1942 if ((res = gst_pad_peer_query (enc->sinkpad, query))) {
1943 GST_LOG_OBJECT (enc, "returning peer response");
1947 gst_query_parse_position (query, &req_fmt, NULL);
1948 fmt = GST_FORMAT_TIME;
1949 if (!(res = gst_pad_peer_query_position (enc->sinkpad, fmt, &pos)))
1953 gst_pad_peer_query_convert (enc->sinkpad, fmt, pos, req_fmt,
1955 gst_query_set_position (query, req_fmt, val);
1959 case GST_QUERY_DURATION:
1961 GstFormat fmt, req_fmt;
1964 if ((res = gst_pad_peer_query (enc->sinkpad, query))) {
1965 GST_LOG_OBJECT (enc, "returning peer response");
1969 gst_query_parse_duration (query, &req_fmt, NULL);
1970 fmt = GST_FORMAT_TIME;
1971 if (!(res = gst_pad_peer_query_duration (enc->sinkpad, fmt, &dur)))
1975 gst_pad_peer_query_convert (enc->sinkpad, fmt, dur, req_fmt,
1977 gst_query_set_duration (query, req_fmt, val);
1981 case GST_QUERY_FORMATS:
1983 gst_query_set_formats (query, 2, GST_FORMAT_TIME, GST_FORMAT_BYTES);
1987 case GST_QUERY_CONVERT:
1989 GstFormat src_fmt, dest_fmt;
1990 gint64 src_val, dest_val;
1992 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
1993 if (!(res = gst_audio_encoded_audio_convert (&enc->priv->ctx.info,
1994 enc->priv->bytes_out, enc->priv->samples_in, src_fmt, src_val,
1995 &dest_fmt, &dest_val)))
1997 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
2000 case GST_QUERY_LATENCY:
2002 if ((res = gst_pad_peer_query (enc->sinkpad, query))) {
2004 GstClockTime min_latency, max_latency;
2006 gst_query_parse_latency (query, &live, &min_latency, &max_latency);
2007 GST_DEBUG_OBJECT (enc, "Peer latency: live %d, min %"
2008 GST_TIME_FORMAT " max %" GST_TIME_FORMAT, live,
2009 GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
2011 GST_OBJECT_LOCK (enc);
2012 /* add our latency */
2013 min_latency += enc->priv->ctx.min_latency;
2014 if (max_latency == -1 || enc->priv->ctx.max_latency == -1)
2017 max_latency += enc->priv->ctx.max_latency;
2018 GST_OBJECT_UNLOCK (enc);
2020 gst_query_set_latency (query, live, min_latency, max_latency);
2025 res = gst_pad_query_default (pad, GST_OBJECT (enc), query);
2033 gst_audio_encoder_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
2035 GstAudioEncoder *encoder;
2036 GstAudioEncoderClass *encoder_class;
2037 gboolean ret = FALSE;
2039 encoder = GST_AUDIO_ENCODER (parent);
2040 encoder_class = GST_AUDIO_ENCODER_GET_CLASS (encoder);
2042 GST_DEBUG_OBJECT (encoder, "received query %d, %s", GST_QUERY_TYPE (query),
2043 GST_QUERY_TYPE_NAME (query));
2045 if (encoder_class->src_query)
2046 ret = encoder_class->src_query (encoder, query);
2053 gst_audio_encoder_set_property (GObject * object, guint prop_id,
2054 const GValue * value, GParamSpec * pspec)
2056 GstAudioEncoder *enc;
2058 enc = GST_AUDIO_ENCODER (object);
2061 case PROP_PERFECT_TS:
2062 if (enc->priv->granule && !g_value_get_boolean (value))
2063 GST_WARNING_OBJECT (enc, "perfect-timestamp can not be set FALSE "
2064 "while granule handling is enabled");
2066 enc->priv->perfect_ts = g_value_get_boolean (value);
2068 case PROP_HARD_RESYNC:
2069 enc->priv->hard_resync = g_value_get_boolean (value);
2071 case PROP_TOLERANCE:
2072 enc->priv->tolerance = g_value_get_int64 (value);
2075 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2081 gst_audio_encoder_get_property (GObject * object, guint prop_id,
2082 GValue * value, GParamSpec * pspec)
2084 GstAudioEncoder *enc;
2086 enc = GST_AUDIO_ENCODER (object);
2089 case PROP_PERFECT_TS:
2090 g_value_set_boolean (value, enc->priv->perfect_ts);
2093 g_value_set_boolean (value, enc->priv->granule);
2095 case PROP_HARD_RESYNC:
2096 g_value_set_boolean (value, enc->priv->hard_resync);
2098 case PROP_TOLERANCE:
2099 g_value_set_int64 (value, enc->priv->tolerance);
2102 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2108 gst_audio_encoder_activate (GstAudioEncoder * enc, gboolean active)
2110 GstAudioEncoderClass *klass;
2111 gboolean result = TRUE;
2113 klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
2115 g_return_val_if_fail (!enc->priv->granule || enc->priv->perfect_ts, FALSE);
2117 GST_DEBUG_OBJECT (enc, "activate %d", active);
2120 /* arrange clean state */
2121 gst_audio_encoder_reset (enc, TRUE);
2123 if (!enc->priv->active && klass->start)
2124 result = klass->start (enc);
2126 /* We must make sure streaming has finished before resetting things
2127 * and calling the ::stop vfunc */
2128 GST_PAD_STREAM_LOCK (enc->sinkpad);
2129 GST_PAD_STREAM_UNLOCK (enc->sinkpad);
2131 if (enc->priv->active && klass->stop)
2132 result = klass->stop (enc);
2135 gst_audio_encoder_reset (enc, TRUE);
2137 GST_DEBUG_OBJECT (enc, "activate return: %d", result);
2143 gst_audio_encoder_sink_activate_mode (GstPad * pad, GstObject * parent,
2144 GstPadMode mode, gboolean active)
2146 gboolean result = TRUE;
2147 GstAudioEncoder *enc;
2149 enc = GST_AUDIO_ENCODER (parent);
2151 GST_DEBUG_OBJECT (enc, "sink activate push %d", active);
2153 result = gst_audio_encoder_activate (enc, active);
2156 enc->priv->active = active;
2158 GST_DEBUG_OBJECT (enc, "sink activate push return: %d", result);
2164 * gst_audio_encoder_get_audio_info:
2165 * @enc: a #GstAudioEncoder
2167 * Returns: a #GstAudioInfo describing the input audio format
2170 gst_audio_encoder_get_audio_info (GstAudioEncoder * enc)
2172 g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), NULL);
2174 return &enc->priv->ctx.info;
2178 * gst_audio_encoder_set_frame_samples_min:
2179 * @enc: a #GstAudioEncoder
2180 * @num: number of samples per frame
2182 * Sets number of samples (per channel) subclass needs to be handed,
2183 * at least or will be handed all available if 0.
2185 * If an exact number of samples is required, gst_audio_encoder_set_frame_samples_max()
2186 * must be called with the same number.
2188 * Note: This value will be reset to 0 every time before
2189 * GstAudioEncoder::set_format() is called.
2192 gst_audio_encoder_set_frame_samples_min (GstAudioEncoder * enc, gint num)
2194 g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));
2196 enc->priv->ctx.frame_samples_min = num;
2197 GST_LOG_OBJECT (enc, "set to %d", num);
2201 * gst_audio_encoder_get_frame_samples_min:
2202 * @enc: a #GstAudioEncoder
2204 * Returns: currently minimum requested samples per frame
2207 gst_audio_encoder_get_frame_samples_min (GstAudioEncoder * enc)
2209 g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), 0);
2211 return enc->priv->ctx.frame_samples_min;
2215 * gst_audio_encoder_set_frame_samples_max:
2216 * @enc: a #GstAudioEncoder
2217 * @num: number of samples per frame
2219 * Sets number of samples (per channel) subclass needs to be handed,
2220 * at most or will be handed all available if 0.
2222 * If an exact number of samples is required, gst_audio_encoder_set_frame_samples_min()
2223 * must be called with the same number.
2225 * Note: This value will be reset to 0 every time before
2226 * GstAudioEncoder::set_format() is called.
2229 gst_audio_encoder_set_frame_samples_max (GstAudioEncoder * enc, gint num)
2231 g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));
2233 enc->priv->ctx.frame_samples_max = num;
2234 GST_LOG_OBJECT (enc, "set to %d", num);
2238 * gst_audio_encoder_get_frame_samples_max:
2239 * @enc: a #GstAudioEncoder
2241 * Returns: currently maximum requested samples per frame
2244 gst_audio_encoder_get_frame_samples_max (GstAudioEncoder * enc)
2246 g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), 0);
2248 return enc->priv->ctx.frame_samples_max;
2252 * gst_audio_encoder_set_frame_max:
2253 * @enc: a #GstAudioEncoder
2254 * @num: number of frames
2256 * Sets max number of frames accepted at once (assumed minimally 1).
2257 * Requires @frame_samples_min and @frame_samples_max to be the equal.
2259 * Note: This value will be reset to 0 every time before
2260 * GstAudioEncoder::set_format() is called.
2263 gst_audio_encoder_set_frame_max (GstAudioEncoder * enc, gint num)
2265 g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));
2267 enc->priv->ctx.frame_max = num;
2268 GST_LOG_OBJECT (enc, "set to %d", num);
2272 * gst_audio_encoder_get_frame_max:
2273 * @enc: a #GstAudioEncoder
2275 * Returns: currently configured maximum handled frames
2278 gst_audio_encoder_get_frame_max (GstAudioEncoder * enc)
2280 g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), 0);
2282 return enc->priv->ctx.frame_max;
2286 * gst_audio_encoder_set_lookahead:
2287 * @enc: a #GstAudioEncoder
2290 * Sets encoder lookahead (in units of input rate samples)
2292 * Note: This value will be reset to 0 every time before
2293 * GstAudioEncoder::set_format() is called.
2296 gst_audio_encoder_set_lookahead (GstAudioEncoder * enc, gint num)
2298 g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));
2300 enc->priv->ctx.lookahead = num;
2301 GST_LOG_OBJECT (enc, "set to %d", num);
2305 * gst_audio_encoder_get_lookahead:
2306 * @enc: a #GstAudioEncoder
2308 * Returns: currently configured encoder lookahead
2311 gst_audio_encoder_get_lookahead (GstAudioEncoder * enc)
2313 g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), 0);
2315 return enc->priv->ctx.lookahead;
2319 * gst_audio_encoder_set_latency:
2320 * @enc: a #GstAudioEncoder
2321 * @min: minimum latency
2322 * @max: maximum latency
2324 * Sets encoder latency.
2327 gst_audio_encoder_set_latency (GstAudioEncoder * enc,
2328 GstClockTime min, GstClockTime max)
2330 g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));
2331 g_return_if_fail (GST_CLOCK_TIME_IS_VALID (min));
2332 g_return_if_fail (min <= max);
2334 GST_OBJECT_LOCK (enc);
2335 enc->priv->ctx.min_latency = min;
2336 enc->priv->ctx.max_latency = max;
2337 GST_OBJECT_UNLOCK (enc);
2339 GST_LOG_OBJECT (enc, "set to %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT,
2340 GST_TIME_ARGS (min), GST_TIME_ARGS (max));
2342 /* post latency message on the bus */
2343 gst_element_post_message (GST_ELEMENT (enc),
2344 gst_message_new_latency (GST_OBJECT (enc)));
2348 * gst_audio_encoder_get_latency:
2349 * @enc: a #GstAudioEncoder
2350 * @min: (out) (allow-none): a pointer to storage to hold minimum latency
2351 * @max: (out) (allow-none): a pointer to storage to hold maximum latency
2353 * Sets the variables pointed to by @min and @max to the currently configured
2357 gst_audio_encoder_get_latency (GstAudioEncoder * enc,
2358 GstClockTime * min, GstClockTime * max)
2360 g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));
2362 GST_OBJECT_LOCK (enc);
2364 *min = enc->priv->ctx.min_latency;
2366 *max = enc->priv->ctx.max_latency;
2367 GST_OBJECT_UNLOCK (enc);
2371 * gst_audio_encoder_set_headers:
2372 * @enc: a #GstAudioEncoder
2373 * @headers: (transfer full) (element-type Gst.Buffer): a list of
2374 * #GstBuffer containing the codec header
2376 * Set the codec headers to be sent downstream whenever requested.
2379 gst_audio_encoder_set_headers (GstAudioEncoder * enc, GList * headers)
2381 GST_DEBUG_OBJECT (enc, "new headers %p", headers);
2383 if (enc->priv->ctx.headers) {
2384 g_list_foreach (enc->priv->ctx.headers, (GFunc) gst_buffer_unref, NULL);
2385 g_list_free (enc->priv->ctx.headers);
2387 enc->priv->ctx.headers = headers;
2388 enc->priv->ctx.new_headers = TRUE;
2392 * gst_audio_encoder_set_allocation_caps:
2393 * @enc: a #GstAudioEncoder
2394 * @allocation_caps: (allow-none): a #GstCaps or %NULL
2396 * Sets a caps in allocation query which are different from the set
2397 * pad's caps. Use this function before calling
2398 * gst_audio_encoder_negotiate(). Setting to %NULL the allocation
2399 * query will use the caps from the pad.
2404 gst_audio_encoder_set_allocation_caps (GstAudioEncoder * enc,
2405 GstCaps * allocation_caps)
2407 g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));
2409 gst_caps_replace (&enc->priv->ctx.allocation_caps, allocation_caps);
2413 * gst_audio_encoder_set_mark_granule:
2414 * @enc: a #GstAudioEncoder
2415 * @enabled: new state
2417 * Enable or disable encoder granule handling.
2422 gst_audio_encoder_set_mark_granule (GstAudioEncoder * enc, gboolean enabled)
2424 g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));
2426 GST_LOG_OBJECT (enc, "enabled: %d", enabled);
2428 GST_OBJECT_LOCK (enc);
2429 enc->priv->granule = enabled;
2430 GST_OBJECT_UNLOCK (enc);
2434 * gst_audio_encoder_get_mark_granule:
2435 * @enc: a #GstAudioEncoder
2437 * Queries if the encoder will handle granule marking.
2439 * Returns: TRUE if granule marking is enabled.
2444 gst_audio_encoder_get_mark_granule (GstAudioEncoder * enc)
2448 g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), FALSE);
2450 GST_OBJECT_LOCK (enc);
2451 result = enc->priv->granule;
2452 GST_OBJECT_UNLOCK (enc);
2458 * gst_audio_encoder_set_perfect_timestamp:
2459 * @enc: a #GstAudioEncoder
2460 * @enabled: new state
2462 * Enable or disable encoder perfect output timestamp preference.
2467 gst_audio_encoder_set_perfect_timestamp (GstAudioEncoder * enc,
2470 g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));
2472 GST_LOG_OBJECT (enc, "enabled: %d", enabled);
2474 GST_OBJECT_LOCK (enc);
2475 enc->priv->perfect_ts = enabled;
2476 GST_OBJECT_UNLOCK (enc);
2480 * gst_audio_encoder_get_perfect_timestamp:
2481 * @enc: a #GstAudioEncoder
2483 * Queries encoder perfect timestamp behaviour.
2485 * Returns: TRUE if perfect timestamp setting enabled.
2490 gst_audio_encoder_get_perfect_timestamp (GstAudioEncoder * enc)
2494 g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), FALSE);
2496 GST_OBJECT_LOCK (enc);
2497 result = enc->priv->perfect_ts;
2498 GST_OBJECT_UNLOCK (enc);
2504 * gst_audio_encoder_set_hard_sync:
2505 * @enc: a #GstAudioEncoder
2506 * @enabled: new state
2508 * Sets encoder hard resync handling.
2513 gst_audio_encoder_set_hard_resync (GstAudioEncoder * enc, gboolean enabled)
2515 g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));
2517 GST_LOG_OBJECT (enc, "enabled: %d", enabled);
2519 GST_OBJECT_LOCK (enc);
2520 enc->priv->hard_resync = enabled;
2521 GST_OBJECT_UNLOCK (enc);
2525 * gst_audio_encoder_get_hard_sync:
2526 * @enc: a #GstAudioEncoder
2528 * Queries encoder's hard resync setting.
2530 * Returns: TRUE if hard resync is enabled.
2535 gst_audio_encoder_get_hard_resync (GstAudioEncoder * enc)
2539 g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), FALSE);
2541 GST_OBJECT_LOCK (enc);
2542 result = enc->priv->hard_resync;
2543 GST_OBJECT_UNLOCK (enc);
2549 * gst_audio_encoder_set_tolerance:
2550 * @enc: a #GstAudioEncoder
2551 * @tolerance: new tolerance
2553 * Configures encoder audio jitter tolerance threshold.
2558 gst_audio_encoder_set_tolerance (GstAudioEncoder * enc, GstClockTime tolerance)
2560 g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));
2562 GST_OBJECT_LOCK (enc);
2563 enc->priv->tolerance = tolerance;
2564 GST_OBJECT_UNLOCK (enc);
2566 GST_LOG_OBJECT (enc, "set to %" GST_TIME_FORMAT, GST_TIME_ARGS (tolerance));
2570 * gst_audio_encoder_get_tolerance:
2571 * @enc: a #GstAudioEncoder
2573 * Queries current audio jitter tolerance threshold.
2575 * Returns: encoder audio jitter tolerance threshold.
2580 gst_audio_encoder_get_tolerance (GstAudioEncoder * enc)
2582 GstClockTime result;
2584 g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), 0);
2586 GST_OBJECT_LOCK (enc);
2587 result = enc->priv->tolerance;
2588 GST_OBJECT_UNLOCK (enc);
2594 * gst_audio_encoder_set_hard_min:
2595 * @enc: a #GstAudioEncoder
2596 * @enabled: new state
2598 * Configures encoder hard minimum handling. If enabled, subclass
2599 * will never be handed less samples than it configured, which otherwise
2600 * might occur near end-of-data handling. Instead, the leftover samples
2601 * will simply be discarded.
2606 gst_audio_encoder_set_hard_min (GstAudioEncoder * enc, gboolean enabled)
2608 g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));
2610 GST_OBJECT_LOCK (enc);
2611 enc->priv->hard_min = enabled;
2612 GST_OBJECT_UNLOCK (enc);
2616 * gst_audio_encoder_get_hard_min:
2617 * @enc: a #GstAudioEncoder
2619 * Queries encoder hard minimum handling.
2621 * Returns: TRUE if hard minimum handling is enabled.
2626 gst_audio_encoder_get_hard_min (GstAudioEncoder * enc)
2630 g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), 0);
2632 GST_OBJECT_LOCK (enc);
2633 result = enc->priv->hard_min;
2634 GST_OBJECT_UNLOCK (enc);
2640 * gst_audio_encoder_set_drainable:
2641 * @enc: a #GstAudioEncoder
2642 * @enabled: new state
2644 * Configures encoder drain handling. If drainable, subclass might
2645 * be handed a NULL buffer to have it return any leftover encoded data.
2646 * Otherwise, it is not considered so capable and will only ever be passed
2652 gst_audio_encoder_set_drainable (GstAudioEncoder * enc, gboolean enabled)
2654 g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));
2656 GST_OBJECT_LOCK (enc);
2657 enc->priv->drainable = enabled;
2658 GST_OBJECT_UNLOCK (enc);
2662 * gst_audio_encoder_get_drainable:
2663 * @enc: a #GstAudioEncoder
2665 * Queries encoder drain handling.
2667 * Returns: TRUE if drainable handling is enabled.
2672 gst_audio_encoder_get_drainable (GstAudioEncoder * enc)
2676 g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), 0);
2678 GST_OBJECT_LOCK (enc);
2679 result = enc->priv->drainable;
2680 GST_OBJECT_UNLOCK (enc);
2686 * gst_audio_encoder_merge_tags:
2687 * @enc: a #GstAudioEncoder
2688 * @tags: (allow-none): a #GstTagList to merge, or NULL to unset
2689 * previously-set tags
2690 * @mode: the #GstTagMergeMode to use, usually #GST_TAG_MERGE_REPLACE
2692 * Sets the audio encoder tags and how they should be merged with any
2693 * upstream stream tags. This will override any tags previously-set
2694 * with gst_audio_encoder_merge_tags().
2696 * Note that this is provided for convenience, and the subclass is
2697 * not required to use this and can still do tag handling on its own.
2702 gst_audio_encoder_merge_tags (GstAudioEncoder * enc,
2703 const GstTagList * tags, GstTagMergeMode mode)
2705 g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));
2706 g_return_if_fail (tags == NULL || GST_IS_TAG_LIST (tags));
2707 g_return_if_fail (tags == NULL || mode != GST_TAG_MERGE_UNDEFINED);
2709 GST_AUDIO_ENCODER_STREAM_LOCK (enc);
2710 if (enc->priv->tags != tags) {
2711 if (enc->priv->tags) {
2712 gst_tag_list_unref (enc->priv->tags);
2713 enc->priv->tags = NULL;
2714 enc->priv->tags_merge_mode = GST_TAG_MERGE_APPEND;
2717 enc->priv->tags = gst_tag_list_ref ((GstTagList *) tags);
2718 enc->priv->tags_merge_mode = mode;
2721 GST_DEBUG_OBJECT (enc, "setting encoder tags to %" GST_PTR_FORMAT, tags);
2722 enc->priv->tags_changed = TRUE;
2724 GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
2728 gst_audio_encoder_negotiate_default (GstAudioEncoder * enc)
2730 GstAudioEncoderClass *klass;
2731 gboolean res = TRUE;
2732 GstQuery *query = NULL;
2733 GstAllocator *allocator;
2734 GstAllocationParams params;
2735 GstCaps *caps, *prevcaps;
2737 g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), FALSE);
2738 g_return_val_if_fail (GST_IS_CAPS (enc->priv->ctx.caps), FALSE);
2740 klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
2742 caps = enc->priv->ctx.caps;
2743 if (enc->priv->ctx.allocation_caps == NULL)
2744 enc->priv->ctx.allocation_caps = gst_caps_ref (caps);
2746 GST_DEBUG_OBJECT (enc, "Setting srcpad caps %" GST_PTR_FORMAT, caps);
2748 if (enc->priv->pending_events) {
2749 GList **pending_events, *l;
2751 pending_events = &enc->priv->pending_events;
2753 GST_DEBUG_OBJECT (enc, "Pushing pending events");
2754 for (l = *pending_events; l;) {
2755 GstEvent *event = GST_EVENT (l->data);
2758 if (GST_EVENT_TYPE (event) < GST_EVENT_CAPS) {
2759 gst_audio_encoder_push_event (enc, l->data);
2762 *pending_events = g_list_delete_link (*pending_events, tmp);
2769 prevcaps = gst_pad_get_current_caps (enc->srcpad);
2770 if (!prevcaps || !gst_caps_is_equal (prevcaps, caps))
2771 res = gst_pad_set_caps (enc->srcpad, caps);
2773 gst_caps_unref (prevcaps);
2777 enc->priv->ctx.output_caps_changed = FALSE;
2779 query = gst_query_new_allocation (enc->priv->ctx.allocation_caps, TRUE);
2780 if (!gst_pad_peer_query (enc->srcpad, query)) {
2781 GST_DEBUG_OBJECT (enc, "didn't get downstream ALLOCATION hints");
2784 g_assert (klass->decide_allocation != NULL);
2785 res = klass->decide_allocation (enc, query);
2787 GST_DEBUG_OBJECT (enc, "ALLOCATION (%d) params: %" GST_PTR_FORMAT, res,
2791 goto no_decide_allocation;
2793 /* we got configuration from our peer or the decide_allocation method,
2795 if (gst_query_get_n_allocation_params (query) > 0) {
2796 gst_query_parse_nth_allocation_param (query, 0, &allocator, ¶ms);
2799 gst_allocation_params_init (¶ms);
2802 if (enc->priv->ctx.allocator)
2803 gst_object_unref (enc->priv->ctx.allocator);
2804 enc->priv->ctx.allocator = allocator;
2805 enc->priv->ctx.params = params;
2809 gst_query_unref (query);
2814 no_decide_allocation:
2816 GST_WARNING_OBJECT (enc, "Subclass failed to decide allocation");
2822 gst_audio_encoder_negotiate_unlocked (GstAudioEncoder * enc)
2824 GstAudioEncoderClass *klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
2825 gboolean ret = TRUE;
2827 if (G_LIKELY (klass->negotiate))
2828 ret = klass->negotiate (enc);
2834 * gst_audio_encoder_negotiate:
2835 * @enc: a #GstAudioEncoder
2837 * Negotiate with downstream elements to currently configured #GstCaps.
2838 * Unmark GST_PAD_FLAG_NEED_RECONFIGURE in any case. But mark it again if
2841 * Returns: #TRUE if the negotiation succeeded, else #FALSE.
2844 gst_audio_encoder_negotiate (GstAudioEncoder * enc)
2846 GstAudioEncoderClass *klass;
2847 gboolean ret = TRUE;
2849 g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), FALSE);
2851 klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
2853 GST_AUDIO_ENCODER_STREAM_LOCK (enc);
2854 gst_pad_check_reconfigure (enc->srcpad);
2855 if (klass->negotiate) {
2856 ret = klass->negotiate (enc);
2858 gst_pad_mark_reconfigure (enc->srcpad);
2860 GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
2866 * gst_audio_encoder_set_output_format:
2867 * @enc: a #GstAudioEncoder
2868 * @caps: (transfer none): #GstCaps
2870 * Configure output caps on the srcpad of @enc.
2872 * Returns: %TRUE on success.
2875 gst_audio_encoder_set_output_format (GstAudioEncoder * enc, GstCaps * caps)
2877 gboolean res = TRUE;
2878 GstCaps *templ_caps;
2880 GST_DEBUG_OBJECT (enc, "Setting srcpad caps %" GST_PTR_FORMAT, caps);
2882 GST_AUDIO_ENCODER_STREAM_LOCK (enc);
2883 if (!gst_caps_is_fixed (caps))
2886 /* Only allow caps that are a subset of the template caps */
2887 templ_caps = gst_pad_get_pad_template_caps (enc->srcpad);
2888 if (!gst_caps_is_subset (caps, templ_caps)) {
2889 gst_caps_unref (templ_caps);
2892 gst_caps_unref (templ_caps);
2894 gst_caps_replace (&enc->priv->ctx.caps, caps);
2895 enc->priv->ctx.output_caps_changed = TRUE;
2898 GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
2905 GST_WARNING_OBJECT (enc, "refused caps %" GST_PTR_FORMAT, caps);
2912 * gst_audio_encoder_allocate_output_buffer:
2913 * @enc: a #GstAudioEncoder
2914 * @size: size of the buffer
2916 * Helper function that allocates a buffer to hold an encoded audio frame
2917 * for @enc's current output format.
2919 * Returns: (transfer full): allocated buffer
2922 gst_audio_encoder_allocate_output_buffer (GstAudioEncoder * enc, gsize size)
2924 GstBuffer *buffer = NULL;
2925 gboolean needs_reconfigure = FALSE;
2927 g_return_val_if_fail (size > 0, NULL);
2929 GST_DEBUG ("alloc src buffer");
2931 GST_AUDIO_ENCODER_STREAM_LOCK (enc);
2933 needs_reconfigure = gst_pad_check_reconfigure (enc->srcpad);
2934 if (G_UNLIKELY (enc->priv->ctx.output_caps_changed || (enc->priv->ctx.caps
2935 && needs_reconfigure))) {
2936 if (!gst_audio_encoder_negotiate_unlocked (enc)) {
2937 GST_INFO_OBJECT (enc, "Failed to negotiate, fallback allocation");
2938 gst_pad_mark_reconfigure (enc->srcpad);
2944 gst_buffer_new_allocate (enc->priv->ctx.allocator, size,
2945 &enc->priv->ctx.params);
2947 GST_INFO_OBJECT (enc, "couldn't allocate output buffer");
2951 GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
2956 buffer = gst_buffer_new_allocate (NULL, size, NULL);
2957 GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
2963 * gst_audio_encoder_get_allocator:
2964 * @enc: a #GstAudioEncoder
2965 * @allocator: (out) (allow-none) (transfer full): the #GstAllocator
2967 * @params: (out) (allow-none) (transfer full): the
2968 * #GstAllocatorParams of @allocator
2970 * Lets #GstAudioEncoder sub-classes to know the memory @allocator
2971 * used by the base class and its @params.
2973 * Unref the @allocator after use it.
2976 gst_audio_encoder_get_allocator (GstAudioEncoder * enc,
2977 GstAllocator ** allocator, GstAllocationParams * params)
2979 g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));
2982 *allocator = enc->priv->ctx.allocator ?
2983 gst_object_ref (enc->priv->ctx.allocator) : NULL;
2986 *params = enc->priv->ctx.params;