2 * Copyright (C) 2008 David Schleef <ds@schleef.org>
3 * Copyright (C) 2011 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>.
4 * Copyright (C) 2011 Nokia Corporation. All rights reserved.
5 * Contact: Stefan Kost <stefan.kost@nokia.com>
6 * Copyright (C) 2012 Collabora Ltd.
7 * Author : Edward Hervey <edward@collabora.com>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
26 * SECTION:gstvideoencoder
27 * @short_description: Base class for video encoders
30 * This base class is for video encoders turning raw video into
33 * GstVideoEncoder and subclass should cooperate as follows.
36 * <itemizedlist><title>Configuration</title>
38 * Initially, GstVideoEncoder calls @start when the encoder element
39 * is activated, which allows subclass to perform any global setup.
42 * GstVideoEncoder calls @set_format to inform subclass of the format
43 * of input video data that it is about to receive. Subclass should
44 * setup for encoding and configure base class as appropriate
45 * (e.g. latency). While unlikely, it might be called more than once,
46 * if changing input parameters require reconfiguration. Baseclass
47 * will ensure that processing of current configuration is finished.
50 * GstVideoEncoder calls @stop at end of all processing.
56 * <title>Data processing</title>
58 * Base class collects input data and metadata into a frame and hands
59 * this to subclass' @handle_frame.
62 * If codec processing results in encoded data, subclass should call
63 * @gst_video_encoder_finish_frame to have encoded data pushed
67 * If implemented, baseclass calls subclass @pre_push just prior to
68 * pushing to allow subclasses to modify some metadata on the buffer.
69 * If it returns GST_FLOW_OK, the buffer is pushed downstream.
72 * GstVideoEncoderClass will handle both srcpad and sinkpad events.
73 * Sink events will be passed to subclass if @event callback has been
79 * <itemizedlist><title>Shutdown phase</title>
81 * GstVideoEncoder class calls @stop to inform the subclass that data
82 * parsing will be stopped.
88 * Subclass is responsible for providing pad template caps for
89 * source and sink pads. The pads need to be named "sink" and "src". It should
90 * also be able to provide fixed src pad caps in @getcaps by the time it calls
91 * @gst_video_encoder_finish_frame.
93 * Things that subclass need to take care of:
95 * <listitem><para>Provide pad templates</para></listitem>
97 * Provide source pad caps before pushing the first buffer
100 * Accept data in @handle_frame and provide encoded results to
101 * @gst_video_encoder_finish_frame.
113 * * Calculate actual latency based on input/output timestamp/frame_number
114 * and if it exceeds the recorded one, save it and emit a GST_MESSAGE_LATENCY
117 #include <gst/video/video.h>
118 #include "gstvideoencoder.h"
119 #include "gstvideoutils.h"
120 #include "gstvideoutilsprivate.h"
122 #include <gst/video/gstvideometa.h>
123 #include <gst/video/gstvideopool.h>
127 GST_DEBUG_CATEGORY (videoencoder_debug);
128 #define GST_CAT_DEFAULT videoencoder_debug
130 #define GST_VIDEO_ENCODER_GET_PRIVATE(obj) \
131 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_VIDEO_ENCODER, \
132 GstVideoEncoderPrivate))
134 struct _GstVideoEncoderPrivate
136 guint64 presentation_frame_number;
137 int distance_from_sync;
139 /* FIXME : (and introduce a context ?) */
145 GList *current_frame_events;
148 gboolean new_headers; /* Whether new headers were just set */
150 GList *force_key_unit; /* List of pending forced keyunits */
152 guint32 system_frame_number;
154 GList *frames; /* Protected with OBJECT_LOCK */
155 GstVideoCodecState *input_state;
156 GstVideoCodecState *output_state;
157 gboolean output_state_changed;
162 GstAllocator *allocator;
163 GstAllocationParams params;
165 /* upstream stream tags (global tags are passed through as-is) */
166 GstTagList *upstream_tags;
170 GstTagMergeMode tags_merge_mode;
172 gboolean tags_changed;
174 GstClockTime min_pts;
175 /* adjustment needed on pts, dts, segment start and stop to accomodate
177 GstClockTime time_adjustment;
180 typedef struct _ForcedKeyUnitEvent ForcedKeyUnitEvent;
181 struct _ForcedKeyUnitEvent
183 GstClockTime running_time;
184 gboolean pending; /* TRUE if this was requested already */
185 gboolean all_headers;
191 forced_key_unit_event_free (ForcedKeyUnitEvent * evt)
193 g_slice_free (ForcedKeyUnitEvent, evt);
196 static ForcedKeyUnitEvent *
197 forced_key_unit_event_new (GstClockTime running_time, gboolean all_headers,
200 ForcedKeyUnitEvent *evt = g_slice_new0 (ForcedKeyUnitEvent);
202 evt->running_time = running_time;
203 evt->all_headers = all_headers;
209 static GstElementClass *parent_class = NULL;
210 static void gst_video_encoder_class_init (GstVideoEncoderClass * klass);
211 static void gst_video_encoder_init (GstVideoEncoder * enc,
212 GstVideoEncoderClass * klass);
214 static void gst_video_encoder_finalize (GObject * object);
216 static gboolean gst_video_encoder_setcaps (GstVideoEncoder * enc,
218 static GstCaps *gst_video_encoder_sink_getcaps (GstVideoEncoder * encoder,
220 static gboolean gst_video_encoder_src_event (GstPad * pad, GstObject * parent,
222 static gboolean gst_video_encoder_sink_event (GstPad * pad, GstObject * parent,
224 static GstFlowReturn gst_video_encoder_chain (GstPad * pad, GstObject * parent,
226 static GstStateChangeReturn gst_video_encoder_change_state (GstElement *
227 element, GstStateChange transition);
228 static gboolean gst_video_encoder_sink_query (GstPad * pad, GstObject * parent,
230 static gboolean gst_video_encoder_src_query (GstPad * pad, GstObject * parent,
232 static GstVideoCodecFrame *gst_video_encoder_new_frame (GstVideoEncoder *
233 encoder, GstBuffer * buf, GstClockTime pts, GstClockTime dts,
234 GstClockTime duration);
236 static gboolean gst_video_encoder_sink_event_default (GstVideoEncoder * encoder,
238 static gboolean gst_video_encoder_src_event_default (GstVideoEncoder * encoder,
240 static gboolean gst_video_encoder_decide_allocation_default (GstVideoEncoder *
241 encoder, GstQuery * query);
242 static gboolean gst_video_encoder_propose_allocation_default (GstVideoEncoder *
243 encoder, GstQuery * query);
244 static gboolean gst_video_encoder_negotiate_default (GstVideoEncoder * encoder);
245 static gboolean gst_video_encoder_negotiate_unlocked (GstVideoEncoder *
248 static gboolean gst_video_encoder_sink_query_default (GstVideoEncoder * encoder,
250 static gboolean gst_video_encoder_src_query_default (GstVideoEncoder * encoder,
253 static gboolean gst_video_encoder_transform_meta_default (GstVideoEncoder *
254 encoder, GstVideoCodecFrame * frame, GstMeta * meta);
256 /* we can't use G_DEFINE_ABSTRACT_TYPE because we need the klass in the _init
257 * method to get to the padtemplates */
259 gst_video_encoder_get_type (void)
261 static volatile gsize type = 0;
263 if (g_once_init_enter (&type)) {
265 static const GTypeInfo info = {
266 sizeof (GstVideoEncoderClass),
269 (GClassInitFunc) gst_video_encoder_class_init,
272 sizeof (GstVideoEncoder),
274 (GInstanceInitFunc) gst_video_encoder_init,
276 const GInterfaceInfo preset_interface_info = {
277 NULL, /* interface_init */
278 NULL, /* interface_finalize */
279 NULL /* interface_data */
282 _type = g_type_register_static (GST_TYPE_ELEMENT,
283 "GstVideoEncoder", &info, G_TYPE_FLAG_ABSTRACT);
284 g_type_add_interface_static (_type, GST_TYPE_PRESET,
285 &preset_interface_info);
286 g_once_init_leave (&type, _type);
292 gst_video_encoder_class_init (GstVideoEncoderClass * klass)
294 GObjectClass *gobject_class;
295 GstElementClass *gstelement_class;
297 gobject_class = G_OBJECT_CLASS (klass);
298 gstelement_class = GST_ELEMENT_CLASS (klass);
300 GST_DEBUG_CATEGORY_INIT (videoencoder_debug, "videoencoder", 0,
301 "Base Video Encoder");
303 parent_class = g_type_class_peek_parent (klass);
305 g_type_class_add_private (klass, sizeof (GstVideoEncoderPrivate));
307 gobject_class->finalize = gst_video_encoder_finalize;
309 gstelement_class->change_state =
310 GST_DEBUG_FUNCPTR (gst_video_encoder_change_state);
312 klass->sink_event = gst_video_encoder_sink_event_default;
313 klass->src_event = gst_video_encoder_src_event_default;
314 klass->propose_allocation = gst_video_encoder_propose_allocation_default;
315 klass->decide_allocation = gst_video_encoder_decide_allocation_default;
316 klass->negotiate = gst_video_encoder_negotiate_default;
317 klass->sink_query = gst_video_encoder_sink_query_default;
318 klass->src_query = gst_video_encoder_src_query_default;
319 klass->transform_meta = gst_video_encoder_transform_meta_default;
323 _flush_events (GstPad * pad, GList * events)
327 for (tmp = events; tmp; tmp = tmp->next) {
328 if (GST_EVENT_TYPE (tmp->data) != GST_EVENT_EOS &&
329 GST_EVENT_TYPE (tmp->data) != GST_EVENT_SEGMENT &&
330 GST_EVENT_IS_STICKY (tmp->data)) {
331 gst_pad_store_sticky_event (pad, GST_EVENT_CAST (tmp->data));
333 gst_event_unref (tmp->data);
335 g_list_free (events);
341 gst_video_encoder_reset (GstVideoEncoder * encoder, gboolean hard)
343 GstVideoEncoderPrivate *priv = encoder->priv;
346 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
348 priv->presentation_frame_number = 0;
349 priv->distance_from_sync = 0;
351 g_list_foreach (priv->force_key_unit, (GFunc) forced_key_unit_event_free,
353 g_list_free (priv->force_key_unit);
354 priv->force_key_unit = NULL;
356 priv->drained = TRUE;
361 priv->time_adjustment = GST_CLOCK_TIME_NONE;
364 gst_segment_init (&encoder->input_segment, GST_FORMAT_TIME);
365 gst_segment_init (&encoder->output_segment, GST_FORMAT_TIME);
367 if (priv->input_state)
368 gst_video_codec_state_unref (priv->input_state);
369 priv->input_state = NULL;
370 if (priv->output_state)
371 gst_video_codec_state_unref (priv->output_state);
372 priv->output_state = NULL;
374 if (priv->upstream_tags) {
375 gst_tag_list_unref (priv->upstream_tags);
376 priv->upstream_tags = NULL;
379 gst_tag_list_unref (priv->tags);
381 priv->tags_merge_mode = GST_TAG_MERGE_APPEND;
382 priv->tags_changed = FALSE;
384 g_list_foreach (priv->headers, (GFunc) gst_event_unref, NULL);
385 g_list_free (priv->headers);
386 priv->headers = NULL;
387 priv->new_headers = FALSE;
389 if (priv->allocator) {
390 gst_object_unref (priv->allocator);
391 priv->allocator = NULL;
394 g_list_foreach (priv->current_frame_events, (GFunc) gst_event_unref, NULL);
395 g_list_free (priv->current_frame_events);
396 priv->current_frame_events = NULL;
401 for (l = priv->frames; l; l = l->next) {
402 GstVideoCodecFrame *frame = l->data;
404 frame->events = _flush_events (encoder->srcpad, frame->events);
406 priv->current_frame_events = _flush_events (encoder->srcpad,
407 encoder->priv->current_frame_events);
410 g_list_foreach (priv->frames, (GFunc) gst_video_codec_frame_unref, NULL);
411 g_list_free (priv->frames);
414 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
419 /* Always call reset() in one way or another after this */
421 gst_video_encoder_flush (GstVideoEncoder * encoder)
423 GstVideoEncoderClass *klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
426 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
428 ret = klass->flush (encoder);
430 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
435 gst_video_encoder_init (GstVideoEncoder * encoder, GstVideoEncoderClass * klass)
437 GstVideoEncoderPrivate *priv;
438 GstPadTemplate *pad_template;
441 GST_DEBUG_OBJECT (encoder, "gst_video_encoder_init");
443 priv = encoder->priv = GST_VIDEO_ENCODER_GET_PRIVATE (encoder);
446 gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink");
447 g_return_if_fail (pad_template != NULL);
449 encoder->sinkpad = pad = gst_pad_new_from_template (pad_template, "sink");
451 gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_video_encoder_chain));
452 gst_pad_set_event_function (pad,
453 GST_DEBUG_FUNCPTR (gst_video_encoder_sink_event));
454 gst_pad_set_query_function (pad,
455 GST_DEBUG_FUNCPTR (gst_video_encoder_sink_query));
456 gst_element_add_pad (GST_ELEMENT (encoder), encoder->sinkpad);
459 gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "src");
460 g_return_if_fail (pad_template != NULL);
462 encoder->srcpad = pad = gst_pad_new_from_template (pad_template, "src");
464 gst_pad_set_query_function (pad,
465 GST_DEBUG_FUNCPTR (gst_video_encoder_src_query));
466 gst_pad_set_event_function (pad,
467 GST_DEBUG_FUNCPTR (gst_video_encoder_src_event));
468 gst_element_add_pad (GST_ELEMENT (encoder), encoder->srcpad);
470 gst_segment_init (&encoder->input_segment, GST_FORMAT_TIME);
471 gst_segment_init (&encoder->output_segment, GST_FORMAT_TIME);
473 g_rec_mutex_init (&encoder->stream_lock);
475 priv->headers = NULL;
476 priv->new_headers = FALSE;
478 priv->min_latency = 0;
479 priv->max_latency = 0;
480 priv->min_pts = GST_CLOCK_TIME_NONE;
481 priv->time_adjustment = GST_CLOCK_TIME_NONE;
483 gst_video_encoder_reset (encoder, TRUE);
487 gst_video_encoded_video_convert (gint64 bytes, gint64 time,
488 GstFormat src_format, gint64 src_value, GstFormat * dest_format,
491 gboolean res = FALSE;
493 g_return_val_if_fail (dest_format != NULL, FALSE);
494 g_return_val_if_fail (dest_value != NULL, FALSE);
496 if (G_UNLIKELY (src_format == *dest_format || src_value == 0 ||
499 *dest_value = src_value;
503 if (bytes <= 0 || time <= 0) {
504 GST_DEBUG ("not enough metadata yet to convert");
508 switch (src_format) {
509 case GST_FORMAT_BYTES:
510 switch (*dest_format) {
511 case GST_FORMAT_TIME:
512 *dest_value = gst_util_uint64_scale (src_value, time, bytes);
519 case GST_FORMAT_TIME:
520 switch (*dest_format) {
521 case GST_FORMAT_BYTES:
522 *dest_value = gst_util_uint64_scale (src_value, bytes, time);
530 GST_DEBUG ("unhandled conversion from %d to %d", src_format,
540 * gst_video_encoder_set_headers:
541 * @encoder: a #GstVideoEncoder
542 * @headers: (transfer full) (element-type GstBuffer): a list of #GstBuffer containing the codec header
544 * Set the codec headers to be sent downstream whenever requested.
547 gst_video_encoder_set_headers (GstVideoEncoder * video_encoder, GList * headers)
549 GST_VIDEO_ENCODER_STREAM_LOCK (video_encoder);
551 GST_DEBUG_OBJECT (video_encoder, "new headers %p", headers);
552 if (video_encoder->priv->headers) {
553 g_list_foreach (video_encoder->priv->headers, (GFunc) gst_buffer_unref,
555 g_list_free (video_encoder->priv->headers);
557 video_encoder->priv->headers = headers;
558 video_encoder->priv->new_headers = TRUE;
560 GST_VIDEO_ENCODER_STREAM_UNLOCK (video_encoder);
563 static GstVideoCodecState *
564 _new_output_state (GstCaps * caps, GstVideoCodecState * reference)
566 GstVideoCodecState *state;
568 state = g_slice_new0 (GstVideoCodecState);
569 state->ref_count = 1;
570 gst_video_info_init (&state->info);
571 gst_video_info_set_format (&state->info, GST_VIDEO_FORMAT_ENCODED, 0, 0);
576 GstVideoInfo *tgt, *ref;
579 ref = &reference->info;
581 /* Copy over extra fields from reference state */
582 tgt->interlace_mode = ref->interlace_mode;
583 tgt->flags = ref->flags;
584 tgt->width = ref->width;
585 tgt->height = ref->height;
586 tgt->chroma_site = ref->chroma_site;
587 tgt->colorimetry = ref->colorimetry;
588 tgt->par_n = ref->par_n;
589 tgt->par_d = ref->par_d;
590 tgt->fps_n = ref->fps_n;
591 tgt->fps_d = ref->fps_d;
593 GST_VIDEO_INFO_MULTIVIEW_MODE (tgt) = GST_VIDEO_INFO_MULTIVIEW_MODE (ref);
594 GST_VIDEO_INFO_MULTIVIEW_FLAGS (tgt) = GST_VIDEO_INFO_MULTIVIEW_FLAGS (ref);
600 static GstVideoCodecState *
601 _new_input_state (GstCaps * caps)
603 GstVideoCodecState *state;
605 state = g_slice_new0 (GstVideoCodecState);
606 state->ref_count = 1;
607 gst_video_info_init (&state->info);
608 if (G_UNLIKELY (!gst_video_info_from_caps (&state->info, caps)))
610 state->caps = gst_caps_ref (caps);
616 g_slice_free (GstVideoCodecState, state);
622 gst_video_encoder_setcaps (GstVideoEncoder * encoder, GstCaps * caps)
624 GstVideoEncoderClass *encoder_class;
625 GstVideoCodecState *state;
628 encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);
630 /* subclass should do something here ... */
631 g_return_val_if_fail (encoder_class->set_format != NULL, FALSE);
633 GST_DEBUG_OBJECT (encoder, "setcaps %" GST_PTR_FORMAT, caps);
635 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
637 if (encoder->priv->input_state) {
638 GST_DEBUG_OBJECT (encoder,
639 "Checking if caps changed old %" GST_PTR_FORMAT " new %" GST_PTR_FORMAT,
640 encoder->priv->input_state->caps, caps);
641 if (gst_caps_is_equal (encoder->priv->input_state->caps, caps))
642 goto caps_not_changed;
645 state = _new_input_state (caps);
646 if (G_UNLIKELY (!state))
649 if (encoder->priv->input_state
650 && gst_video_info_is_equal (&state->info,
651 &encoder->priv->input_state->info)) {
652 gst_video_codec_state_unref (state);
653 goto caps_not_changed;
656 if (encoder_class->reset) {
657 GST_FIXME_OBJECT (encoder, "GstVideoEncoder::reset() is deprecated");
658 encoder_class->reset (encoder, TRUE);
661 /* and subclass should be ready to configure format at any time around */
662 ret = encoder_class->set_format (encoder, state);
664 if (encoder->priv->input_state)
665 gst_video_codec_state_unref (encoder->priv->input_state);
666 encoder->priv->input_state = state;
668 gst_video_codec_state_unref (state);
671 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
674 GST_WARNING_OBJECT (encoder, "rejected caps %" GST_PTR_FORMAT, caps);
680 GST_DEBUG_OBJECT (encoder, "Caps did not change - ignore");
681 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
688 GST_WARNING_OBJECT (encoder, "Failed to parse caps");
689 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
695 * gst_video_encoder_proxy_getcaps:
696 * @enc: a #GstVideoEncoder
697 * @caps: (allow-none): initial caps
698 * @filter: (allow-none): filter caps
700 * Returns caps that express @caps (or sink template caps if @caps == NULL)
701 * restricted to resolution/format/... combinations supported by downstream
702 * elements (e.g. muxers).
704 * Returns: (transfer full): a #GstCaps owned by caller
707 gst_video_encoder_proxy_getcaps (GstVideoEncoder * encoder, GstCaps * caps,
710 return __gst_video_element_proxy_getcaps (GST_ELEMENT_CAST (encoder),
711 GST_VIDEO_ENCODER_SINK_PAD (encoder),
712 GST_VIDEO_ENCODER_SRC_PAD (encoder), caps, filter);
716 gst_video_encoder_sink_getcaps (GstVideoEncoder * encoder, GstCaps * filter)
718 GstVideoEncoderClass *klass;
721 klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
724 caps = klass->getcaps (encoder, filter);
726 caps = gst_video_encoder_proxy_getcaps (encoder, NULL, filter);
728 GST_LOG_OBJECT (encoder, "Returning caps %" GST_PTR_FORMAT, caps);
734 gst_video_encoder_decide_allocation_default (GstVideoEncoder * encoder,
737 GstAllocator *allocator = NULL;
738 GstAllocationParams params;
739 gboolean update_allocator;
741 /* we got configuration from our peer or the decide_allocation method,
743 if (gst_query_get_n_allocation_params (query) > 0) {
744 /* try the allocator */
745 gst_query_parse_nth_allocation_param (query, 0, &allocator, ¶ms);
746 update_allocator = TRUE;
749 gst_allocation_params_init (¶ms);
750 update_allocator = FALSE;
753 if (update_allocator)
754 gst_query_set_nth_allocation_param (query, 0, allocator, ¶ms);
756 gst_query_add_allocation_param (query, allocator, ¶ms);
758 gst_object_unref (allocator);
764 gst_video_encoder_propose_allocation_default (GstVideoEncoder * encoder,
772 gst_query_parse_allocation (query, &caps, NULL);
777 if (!gst_video_info_from_caps (&info, caps))
780 size = GST_VIDEO_INFO_SIZE (&info);
782 if (gst_query_get_n_allocation_pools (query) == 0) {
783 GstStructure *structure;
784 GstAllocator *allocator = NULL;
785 GstAllocationParams params = { 0, 15, 0, 0 };
787 if (gst_query_get_n_allocation_params (query) > 0)
788 gst_query_parse_nth_allocation_param (query, 0, &allocator, ¶ms);
790 gst_query_add_allocation_param (query, allocator, ¶ms);
792 pool = gst_video_buffer_pool_new ();
794 structure = gst_buffer_pool_get_config (pool);
795 gst_buffer_pool_config_set_params (structure, caps, size, 0, 0);
796 gst_buffer_pool_config_set_allocator (structure, allocator, ¶ms);
799 gst_object_unref (allocator);
801 if (!gst_buffer_pool_set_config (pool, structure))
804 gst_query_add_allocation_pool (query, pool, size, 0, 0);
805 gst_object_unref (pool);
806 gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
814 GST_ERROR_OBJECT (encoder, "failed to set config");
815 gst_object_unref (pool);
821 gst_video_encoder_sink_query_default (GstVideoEncoder * encoder,
824 GstPad *pad = GST_VIDEO_ENCODER_SINK_PAD (encoder);
825 gboolean res = FALSE;
827 switch (GST_QUERY_TYPE (query)) {
830 GstCaps *filter, *caps;
832 gst_query_parse_caps (query, &filter);
833 caps = gst_video_encoder_sink_getcaps (encoder, filter);
834 gst_query_set_caps_result (query, caps);
835 gst_caps_unref (caps);
839 case GST_QUERY_ALLOCATION:
841 GstVideoEncoderClass *klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
843 if (klass->propose_allocation)
844 res = klass->propose_allocation (encoder, query);
848 res = gst_pad_query_default (pad, GST_OBJECT (encoder), query);
855 gst_video_encoder_sink_query (GstPad * pad, GstObject * parent,
858 GstVideoEncoder *encoder;
859 GstVideoEncoderClass *encoder_class;
860 gboolean ret = FALSE;
862 encoder = GST_VIDEO_ENCODER (parent);
863 encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);
865 GST_DEBUG_OBJECT (encoder, "received query %d, %s", GST_QUERY_TYPE (query),
866 GST_QUERY_TYPE_NAME (query));
868 if (encoder_class->sink_query)
869 ret = encoder_class->sink_query (encoder, query);
875 gst_video_encoder_finalize (GObject * object)
877 GstVideoEncoder *encoder;
879 GST_DEBUG_OBJECT (object, "finalize");
881 encoder = GST_VIDEO_ENCODER (object);
882 g_rec_mutex_clear (&encoder->stream_lock);
884 if (encoder->priv->allocator) {
885 gst_object_unref (encoder->priv->allocator);
886 encoder->priv->allocator = NULL;
889 G_OBJECT_CLASS (parent_class)->finalize (object);
893 gst_video_encoder_push_event (GstVideoEncoder * encoder, GstEvent * event)
895 switch (GST_EVENT_TYPE (event)) {
896 case GST_EVENT_SEGMENT:
900 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
902 gst_event_copy_segment (event, &segment);
904 GST_DEBUG_OBJECT (encoder, "segment %" GST_SEGMENT_FORMAT, &segment);
906 if (segment.format != GST_FORMAT_TIME) {
907 GST_DEBUG_OBJECT (encoder, "received non TIME segment");
908 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
912 if (encoder->priv->time_adjustment != GST_CLOCK_TIME_NONE) {
913 segment.start += encoder->priv->time_adjustment;
914 if (GST_CLOCK_TIME_IS_VALID (segment.stop)) {
915 segment.stop += encoder->priv->time_adjustment;
919 encoder->output_segment = segment;
920 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
922 gst_event_unref (event);
923 event = gst_event_new_segment (&encoder->output_segment);
931 return gst_pad_push_event (encoder->srcpad, event);
935 gst_video_encoder_create_merged_tags_event (GstVideoEncoder * enc)
937 GstTagList *merged_tags;
939 GST_LOG_OBJECT (enc, "upstream : %" GST_PTR_FORMAT, enc->priv->upstream_tags);
940 GST_LOG_OBJECT (enc, "encoder : %" GST_PTR_FORMAT, enc->priv->tags);
941 GST_LOG_OBJECT (enc, "mode : %d", enc->priv->tags_merge_mode);
944 gst_tag_list_merge (enc->priv->upstream_tags, enc->priv->tags,
945 enc->priv->tags_merge_mode);
947 GST_DEBUG_OBJECT (enc, "merged : %" GST_PTR_FORMAT, merged_tags);
949 if (merged_tags == NULL)
952 if (gst_tag_list_is_empty (merged_tags)) {
953 gst_tag_list_unref (merged_tags);
957 return gst_event_new_tag (merged_tags);
961 gst_video_encoder_check_and_push_tags (GstVideoEncoder * encoder)
963 if (encoder->priv->tags_changed) {
964 GstEvent *tags_event;
966 tags_event = gst_video_encoder_create_merged_tags_event (encoder);
968 if (tags_event != NULL)
969 gst_video_encoder_push_event (encoder, tags_event);
971 encoder->priv->tags_changed = FALSE;
976 gst_video_encoder_sink_event_default (GstVideoEncoder * encoder,
979 GstVideoEncoderClass *encoder_class;
980 gboolean ret = FALSE;
982 encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);
984 switch (GST_EVENT_TYPE (event)) {
989 gst_event_parse_caps (event, &caps);
990 ret = gst_video_encoder_setcaps (encoder, caps);
992 gst_event_unref (event);
998 GstFlowReturn flow_ret;
1000 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1002 if (encoder_class->finish) {
1003 flow_ret = encoder_class->finish (encoder);
1005 flow_ret = GST_FLOW_OK;
1008 if (encoder->priv->current_frame_events) {
1011 for (l = g_list_last (encoder->priv->current_frame_events); l;
1012 l = g_list_previous (l)) {
1013 GstEvent *event = GST_EVENT (l->data);
1015 gst_video_encoder_push_event (encoder, event);
1018 g_list_free (encoder->priv->current_frame_events);
1019 encoder->priv->current_frame_events = NULL;
1021 gst_video_encoder_check_and_push_tags (encoder);
1023 ret = (flow_ret == GST_FLOW_OK);
1024 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1027 case GST_EVENT_SEGMENT:
1031 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1033 gst_event_copy_segment (event, &segment);
1035 GST_DEBUG_OBJECT (encoder, "segment %" GST_SEGMENT_FORMAT, &segment);
1037 if (segment.format != GST_FORMAT_TIME) {
1038 GST_DEBUG_OBJECT (encoder, "received non TIME newsegment");
1039 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1043 encoder->input_segment = segment;
1045 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1048 case GST_EVENT_CUSTOM_DOWNSTREAM:
1050 if (gst_video_event_is_force_key_unit (event)) {
1051 GstClockTime running_time;
1052 gboolean all_headers;
1055 if (gst_video_event_parse_downstream_force_key_unit (event,
1056 NULL, NULL, &running_time, &all_headers, &count)) {
1057 ForcedKeyUnitEvent *fevt;
1059 GST_OBJECT_LOCK (encoder);
1060 fevt = forced_key_unit_event_new (running_time, all_headers, count);
1061 encoder->priv->force_key_unit =
1062 g_list_append (encoder->priv->force_key_unit, fevt);
1063 GST_OBJECT_UNLOCK (encoder);
1065 GST_DEBUG_OBJECT (encoder,
1066 "force-key-unit event: running-time %" GST_TIME_FORMAT
1067 ", all_headers %d, count %u",
1068 GST_TIME_ARGS (running_time), all_headers, count);
1070 gst_event_unref (event);
1076 case GST_EVENT_STREAM_START:
1078 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1079 /* Flush upstream tags after a STREAM_START */
1080 GST_DEBUG_OBJECT (encoder, "STREAM_START, clearing upstream tags");
1081 if (encoder->priv->upstream_tags) {
1082 gst_tag_list_unref (encoder->priv->upstream_tags);
1083 encoder->priv->upstream_tags = NULL;
1084 encoder->priv->tags_changed = TRUE;
1086 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1093 gst_event_parse_tag (event, &tags);
1095 if (gst_tag_list_get_scope (tags) == GST_TAG_SCOPE_STREAM) {
1096 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1097 if (encoder->priv->upstream_tags != tags) {
1098 tags = gst_tag_list_copy (tags);
1100 /* FIXME: make generic based on GST_TAG_FLAG_ENCODED */
1101 gst_tag_list_remove_tag (tags, GST_TAG_CODEC);
1102 gst_tag_list_remove_tag (tags, GST_TAG_AUDIO_CODEC);
1103 gst_tag_list_remove_tag (tags, GST_TAG_VIDEO_CODEC);
1104 gst_tag_list_remove_tag (tags, GST_TAG_SUBTITLE_CODEC);
1105 gst_tag_list_remove_tag (tags, GST_TAG_CONTAINER_FORMAT);
1106 gst_tag_list_remove_tag (tags, GST_TAG_BITRATE);
1107 gst_tag_list_remove_tag (tags, GST_TAG_NOMINAL_BITRATE);
1108 gst_tag_list_remove_tag (tags, GST_TAG_MAXIMUM_BITRATE);
1109 gst_tag_list_remove_tag (tags, GST_TAG_MINIMUM_BITRATE);
1110 gst_tag_list_remove_tag (tags, GST_TAG_ENCODER);
1111 gst_tag_list_remove_tag (tags, GST_TAG_ENCODER_VERSION);
1113 if (encoder->priv->upstream_tags)
1114 gst_tag_list_unref (encoder->priv->upstream_tags);
1115 encoder->priv->upstream_tags = tags;
1116 GST_INFO_OBJECT (encoder, "upstream tags: %" GST_PTR_FORMAT, tags);
1118 gst_event_unref (event);
1119 event = gst_video_encoder_create_merged_tags_event (encoder);
1120 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1126 case GST_EVENT_FLUSH_STOP:{
1127 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1128 gst_video_encoder_flush (encoder);
1129 gst_segment_init (&encoder->input_segment, GST_FORMAT_TIME);
1130 gst_segment_init (&encoder->output_segment, GST_FORMAT_TIME);
1131 gst_video_encoder_reset (encoder, FALSE);
1132 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1139 /* Forward non-serialized events and EOS/FLUSH_STOP immediately.
1140 * For EOS this is required because no buffer or serialized event
1141 * will come after EOS and nothing could trigger another
1142 * _finish_frame() call. *
1143 * If the subclass handles sending of EOS manually it can simply
1144 * not chain up to the parent class' event handler
1146 * For FLUSH_STOP this is required because it is expected
1147 * to be forwarded immediately and no buffers are queued anyway.
1150 if (!GST_EVENT_IS_SERIALIZED (event)
1151 || GST_EVENT_TYPE (event) == GST_EVENT_EOS
1152 || GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
1153 ret = gst_video_encoder_push_event (encoder, event);
1155 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1156 encoder->priv->current_frame_events =
1157 g_list_prepend (encoder->priv->current_frame_events, event);
1158 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1167 gst_video_encoder_sink_event (GstPad * pad, GstObject * parent,
1170 GstVideoEncoder *enc;
1171 GstVideoEncoderClass *klass;
1172 gboolean ret = TRUE;
1174 enc = GST_VIDEO_ENCODER (parent);
1175 klass = GST_VIDEO_ENCODER_GET_CLASS (enc);
1177 GST_DEBUG_OBJECT (enc, "received event %d, %s", GST_EVENT_TYPE (event),
1178 GST_EVENT_TYPE_NAME (event));
1180 if (klass->sink_event)
1181 ret = klass->sink_event (enc, event);
1187 gst_video_encoder_src_event_default (GstVideoEncoder * encoder,
1190 gboolean ret = FALSE;
1192 switch (GST_EVENT_TYPE (event)) {
1193 case GST_EVENT_CUSTOM_UPSTREAM:
1195 if (gst_video_event_is_force_key_unit (event)) {
1196 GstClockTime running_time;
1197 gboolean all_headers;
1200 if (gst_video_event_parse_upstream_force_key_unit (event,
1201 &running_time, &all_headers, &count)) {
1202 ForcedKeyUnitEvent *fevt;
1204 GST_OBJECT_LOCK (encoder);
1205 fevt = forced_key_unit_event_new (running_time, all_headers, count);
1206 encoder->priv->force_key_unit =
1207 g_list_append (encoder->priv->force_key_unit, fevt);
1208 GST_OBJECT_UNLOCK (encoder);
1210 GST_DEBUG_OBJECT (encoder,
1211 "force-key-unit event: running-time %" GST_TIME_FORMAT
1212 ", all_headers %d, count %u",
1213 GST_TIME_ARGS (running_time), all_headers, count);
1215 gst_event_unref (event);
1227 gst_pad_event_default (encoder->srcpad, GST_OBJECT_CAST (encoder),
1234 gst_video_encoder_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
1236 GstVideoEncoder *encoder;
1237 GstVideoEncoderClass *klass;
1238 gboolean ret = FALSE;
1240 encoder = GST_VIDEO_ENCODER (parent);
1241 klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
1243 GST_LOG_OBJECT (encoder, "handling event: %" GST_PTR_FORMAT, event);
1245 if (klass->src_event)
1246 ret = klass->src_event (encoder, event);
1252 gst_video_encoder_src_query_default (GstVideoEncoder * enc, GstQuery * query)
1254 GstPad *pad = GST_VIDEO_ENCODER_SRC_PAD (enc);
1255 GstVideoEncoderPrivate *priv;
1260 GST_LOG_OBJECT (enc, "handling query: %" GST_PTR_FORMAT, query);
1262 switch (GST_QUERY_TYPE (query)) {
1263 case GST_QUERY_CONVERT:
1265 GstFormat src_fmt, dest_fmt;
1266 gint64 src_val, dest_val;
1268 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
1270 gst_video_encoded_video_convert (priv->bytes, priv->time, src_fmt,
1271 src_val, &dest_fmt, &dest_val);
1274 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1277 case GST_QUERY_LATENCY:
1280 GstClockTime min_latency, max_latency;
1282 res = gst_pad_peer_query (enc->sinkpad, query);
1284 gst_query_parse_latency (query, &live, &min_latency, &max_latency);
1285 GST_DEBUG_OBJECT (enc, "Peer latency: live %d, min %"
1286 GST_TIME_FORMAT " max %" GST_TIME_FORMAT, live,
1287 GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
1289 GST_OBJECT_LOCK (enc);
1290 min_latency += priv->min_latency;
1291 if (max_latency == GST_CLOCK_TIME_NONE
1292 || enc->priv->max_latency == GST_CLOCK_TIME_NONE)
1293 max_latency = GST_CLOCK_TIME_NONE;
1295 max_latency += enc->priv->max_latency;
1296 GST_OBJECT_UNLOCK (enc);
1298 gst_query_set_latency (query, live, min_latency, max_latency);
1303 res = gst_pad_query_default (pad, GST_OBJECT (enc), query);
1308 GST_DEBUG_OBJECT (enc, "query failed");
1313 gst_video_encoder_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
1315 GstVideoEncoder *encoder;
1316 GstVideoEncoderClass *encoder_class;
1317 gboolean ret = FALSE;
1319 encoder = GST_VIDEO_ENCODER (parent);
1320 encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);
1322 GST_DEBUG_OBJECT (encoder, "received query %d, %s", GST_QUERY_TYPE (query),
1323 GST_QUERY_TYPE_NAME (query));
1325 if (encoder_class->src_query)
1326 ret = encoder_class->src_query (encoder, query);
1331 static GstVideoCodecFrame *
1332 gst_video_encoder_new_frame (GstVideoEncoder * encoder, GstBuffer * buf,
1333 GstClockTime pts, GstClockTime dts, GstClockTime duration)
1335 GstVideoEncoderPrivate *priv = encoder->priv;
1336 GstVideoCodecFrame *frame;
1338 frame = g_slice_new0 (GstVideoCodecFrame);
1340 frame->ref_count = 1;
1342 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1343 frame->system_frame_number = priv->system_frame_number;
1344 priv->system_frame_number++;
1346 frame->presentation_frame_number = priv->presentation_frame_number;
1347 priv->presentation_frame_number++;
1348 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1350 frame->events = priv->current_frame_events;
1351 priv->current_frame_events = NULL;
1352 frame->input_buffer = buf;
1355 frame->duration = duration;
1356 frame->abidata.ABI.ts = pts;
1362 static GstFlowReturn
1363 gst_video_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
1365 GstVideoEncoder *encoder;
1366 GstVideoEncoderPrivate *priv;
1367 GstVideoEncoderClass *klass;
1368 GstVideoCodecFrame *frame;
1369 GstClockTime pts, duration;
1370 GstFlowReturn ret = GST_FLOW_OK;
1371 guint64 start, stop, cstart, cstop;
1373 encoder = GST_VIDEO_ENCODER (parent);
1374 priv = encoder->priv;
1375 klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
1377 g_return_val_if_fail (klass->handle_frame != NULL, GST_FLOW_ERROR);
1379 if (!encoder->priv->input_state)
1380 goto not_negotiated;
1382 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1384 pts = GST_BUFFER_PTS (buf);
1385 duration = GST_BUFFER_DURATION (buf);
1387 GST_LOG_OBJECT (encoder,
1388 "received buffer of size %" G_GSIZE_FORMAT " with PTS %" GST_TIME_FORMAT
1389 ", DTS %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT,
1390 gst_buffer_get_size (buf), GST_TIME_ARGS (pts),
1391 GST_TIME_ARGS (GST_BUFFER_DTS (buf)), GST_TIME_ARGS (duration));
1394 if (GST_CLOCK_TIME_IS_VALID (duration))
1395 stop = start + duration;
1397 stop = GST_CLOCK_TIME_NONE;
1399 /* Drop buffers outside of segment */
1400 if (!gst_segment_clip (&encoder->input_segment,
1401 GST_FORMAT_TIME, start, stop, &cstart, &cstop)) {
1402 GST_DEBUG_OBJECT (encoder, "clipping to segment dropped frame");
1403 gst_buffer_unref (buf);
1407 if (GST_CLOCK_TIME_IS_VALID (cstop))
1408 duration = cstop - cstart;
1410 duration = GST_CLOCK_TIME_NONE;
1412 if (priv->min_pts != GST_CLOCK_TIME_NONE
1413 && priv->time_adjustment == GST_CLOCK_TIME_NONE) {
1414 if (cstart < priv->min_pts) {
1415 priv->time_adjustment = priv->min_pts - cstart;
1419 if (priv->time_adjustment != GST_CLOCK_TIME_NONE) {
1420 cstart += priv->time_adjustment;
1423 /* incoming DTS is not really relevant and does not make sense anyway,
1424 * so pass along _NONE and maybe come up with something better later on */
1425 frame = gst_video_encoder_new_frame (encoder, buf, cstart,
1426 GST_CLOCK_TIME_NONE, duration);
1428 GST_OBJECT_LOCK (encoder);
1429 if (priv->force_key_unit) {
1430 ForcedKeyUnitEvent *fevt = NULL;
1431 GstClockTime running_time;
1435 gst_segment_to_running_time (&encoder->output_segment, GST_FORMAT_TIME,
1438 for (l = priv->force_key_unit; l; l = l->next) {
1439 ForcedKeyUnitEvent *tmp = l->data;
1441 /* Skip pending keyunits */
1445 /* Simple case, keyunit ASAP */
1446 if (tmp->running_time == GST_CLOCK_TIME_NONE) {
1451 /* Event for before this frame */
1452 if (tmp->running_time <= running_time) {
1459 fevt->frame_id = frame->system_frame_number;
1460 GST_DEBUG_OBJECT (encoder,
1461 "Forcing a key unit at running time %" GST_TIME_FORMAT,
1462 GST_TIME_ARGS (running_time));
1463 GST_VIDEO_CODEC_FRAME_SET_FORCE_KEYFRAME (frame);
1464 if (fevt->all_headers)
1465 GST_VIDEO_CODEC_FRAME_SET_FORCE_KEYFRAME_HEADERS (frame);
1466 fevt->pending = TRUE;
1469 GST_OBJECT_UNLOCK (encoder);
1471 gst_video_codec_frame_ref (frame);
1472 priv->frames = g_list_append (priv->frames, frame);
1474 /* new data, more finish needed */
1475 priv->drained = FALSE;
1477 GST_LOG_OBJECT (encoder, "passing frame pfn %d to subclass",
1478 frame->presentation_frame_number);
1480 ret = klass->handle_frame (encoder, frame);
1483 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1490 GST_ELEMENT_ERROR (encoder, CORE, NEGOTIATION, (NULL),
1491 ("encoder not initialized"));
1492 gst_buffer_unref (buf);
1493 return GST_FLOW_NOT_NEGOTIATED;
1497 static GstStateChangeReturn
1498 gst_video_encoder_change_state (GstElement * element, GstStateChange transition)
1500 GstVideoEncoder *encoder;
1501 GstVideoEncoderClass *encoder_class;
1502 GstStateChangeReturn ret;
1504 encoder = GST_VIDEO_ENCODER (element);
1505 encoder_class = GST_VIDEO_ENCODER_GET_CLASS (element);
1507 switch (transition) {
1508 case GST_STATE_CHANGE_NULL_TO_READY:
1509 /* open device/library if needed */
1510 if (encoder_class->open && !encoder_class->open (encoder))
1513 case GST_STATE_CHANGE_READY_TO_PAUSED:
1514 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1515 gst_video_encoder_reset (encoder, TRUE);
1516 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1518 /* Initialize device/library if needed */
1519 if (encoder_class->start && !encoder_class->start (encoder))
1526 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1528 switch (transition) {
1529 case GST_STATE_CHANGE_PAUSED_TO_READY:{
1530 gboolean stopped = TRUE;
1532 if (encoder_class->stop)
1533 stopped = encoder_class->stop (encoder);
1535 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1536 gst_video_encoder_reset (encoder, TRUE);
1537 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1543 case GST_STATE_CHANGE_READY_TO_NULL:
1544 /* close device/library if needed */
1545 if (encoder_class->close && !encoder_class->close (encoder))
1558 GST_ELEMENT_ERROR (encoder, LIBRARY, INIT, (NULL),
1559 ("Failed to open encoder"));
1560 return GST_STATE_CHANGE_FAILURE;
1565 GST_ELEMENT_ERROR (encoder, LIBRARY, INIT, (NULL),
1566 ("Failed to start encoder"));
1567 return GST_STATE_CHANGE_FAILURE;
1572 GST_ELEMENT_ERROR (encoder, LIBRARY, INIT, (NULL),
1573 ("Failed to stop encoder"));
1574 return GST_STATE_CHANGE_FAILURE;
1579 GST_ELEMENT_ERROR (encoder, LIBRARY, INIT, (NULL),
1580 ("Failed to close encoder"));
1581 return GST_STATE_CHANGE_FAILURE;
1586 gst_video_encoder_negotiate_default (GstVideoEncoder * encoder)
1588 GstVideoEncoderClass *klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
1589 GstAllocator *allocator;
1590 GstAllocationParams params;
1591 gboolean ret = TRUE;
1592 GstVideoCodecState *state = encoder->priv->output_state;
1593 GstVideoInfo *info = &state->info;
1594 GstQuery *query = NULL;
1595 GstVideoCodecFrame *frame;
1598 g_return_val_if_fail (state->caps != NULL, FALSE);
1600 if (encoder->priv->output_state_changed) {
1601 state->caps = gst_caps_make_writable (state->caps);
1604 gst_caps_set_simple (state->caps, "width", G_TYPE_INT, info->width,
1605 "height", G_TYPE_INT, info->height,
1606 "pixel-aspect-ratio", GST_TYPE_FRACTION,
1607 info->par_n, info->par_d, NULL);
1608 if (info->flags & GST_VIDEO_FLAG_VARIABLE_FPS && info->fps_n != 0) {
1609 /* variable fps with a max-framerate */
1610 gst_caps_set_simple (state->caps, "framerate", GST_TYPE_FRACTION, 0, 1,
1611 "max-framerate", GST_TYPE_FRACTION, info->fps_n, info->fps_d, NULL);
1613 /* no variable fps or no max-framerate */
1614 gst_caps_set_simple (state->caps, "framerate", GST_TYPE_FRACTION,
1615 info->fps_n, info->fps_d, NULL);
1617 if (state->codec_data)
1618 gst_caps_set_simple (state->caps, "codec_data", GST_TYPE_BUFFER,
1619 state->codec_data, NULL);
1621 if (GST_VIDEO_INFO_MULTIVIEW_MODE (info) != GST_VIDEO_MULTIVIEW_MODE_NONE) {
1622 const gchar *caps_mview_mode =
1623 gst_video_multiview_mode_to_caps_string (GST_VIDEO_INFO_MULTIVIEW_MODE
1626 gst_caps_set_simple (state->caps, "multiview-mode", G_TYPE_STRING,
1627 caps_mview_mode, "multiview-flags", GST_TYPE_VIDEO_MULTIVIEW_FLAGSET,
1628 GST_VIDEO_INFO_MULTIVIEW_FLAGS (info), GST_FLAG_SET_MASK_EXACT, NULL);
1630 encoder->priv->output_state_changed = FALSE;
1633 /* Push all pending pre-caps events of the oldest frame before
1635 frame = encoder->priv->frames ? encoder->priv->frames->data : NULL;
1636 if (frame || encoder->priv->current_frame_events) {
1640 events = &frame->events;
1642 events = &encoder->priv->current_frame_events;
1645 for (l = g_list_last (*events); l;) {
1646 GstEvent *event = GST_EVENT (l->data);
1649 if (GST_EVENT_TYPE (event) < GST_EVENT_CAPS) {
1650 gst_video_encoder_push_event (encoder, event);
1653 *events = g_list_delete_link (*events, tmp);
1660 prevcaps = gst_pad_get_current_caps (encoder->srcpad);
1661 if (!prevcaps || !gst_caps_is_equal (prevcaps, state->caps))
1662 ret = gst_pad_set_caps (encoder->srcpad, state->caps);
1666 gst_caps_unref (prevcaps);
1671 query = gst_query_new_allocation (state->caps, TRUE);
1672 if (!gst_pad_peer_query (encoder->srcpad, query)) {
1673 GST_DEBUG_OBJECT (encoder, "didn't get downstream ALLOCATION hints");
1676 g_assert (klass->decide_allocation != NULL);
1677 ret = klass->decide_allocation (encoder, query);
1679 GST_DEBUG_OBJECT (encoder, "ALLOCATION (%d) params: %" GST_PTR_FORMAT, ret,
1683 goto no_decide_allocation;
1685 /* we got configuration from our peer or the decide_allocation method,
1687 if (gst_query_get_n_allocation_params (query) > 0) {
1688 gst_query_parse_nth_allocation_param (query, 0, &allocator, ¶ms);
1691 gst_allocation_params_init (¶ms);
1694 if (encoder->priv->allocator)
1695 gst_object_unref (encoder->priv->allocator);
1696 encoder->priv->allocator = allocator;
1697 encoder->priv->params = params;
1701 gst_query_unref (query);
1706 no_decide_allocation:
1708 GST_WARNING_OBJECT (encoder, "Subclass failed to decide allocation");
1714 gst_video_encoder_negotiate_unlocked (GstVideoEncoder * encoder)
1716 GstVideoEncoderClass *klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
1717 gboolean ret = TRUE;
1719 if (G_LIKELY (klass->negotiate))
1720 ret = klass->negotiate (encoder);
1726 * gst_video_encoder_negotiate:
1727 * @encoder: a #GstVideoEncoder
1729 * Negotiate with downstream elements to currently configured #GstVideoCodecState.
1730 * Unmark GST_PAD_FLAG_NEED_RECONFIGURE in any case. But mark it again if
1733 * Returns: #TRUE if the negotiation succeeded, else #FALSE.
1736 gst_video_encoder_negotiate (GstVideoEncoder * encoder)
1738 GstVideoEncoderClass *klass;
1739 gboolean ret = TRUE;
1741 g_return_val_if_fail (GST_IS_VIDEO_ENCODER (encoder), FALSE);
1742 g_return_val_if_fail (encoder->priv->output_state, FALSE);
1744 klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
1746 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1747 gst_pad_check_reconfigure (encoder->srcpad);
1748 if (klass->negotiate) {
1749 ret = klass->negotiate (encoder);
1751 gst_pad_mark_reconfigure (encoder->srcpad);
1753 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1759 * gst_video_encoder_allocate_output_buffer:
1760 * @encoder: a #GstVideoEncoder
1761 * @size: size of the buffer
1763 * Helper function that allocates a buffer to hold an encoded video frame
1764 * for @encoder's current #GstVideoCodecState.
1766 * Returns: (transfer full): allocated buffer
1769 gst_video_encoder_allocate_output_buffer (GstVideoEncoder * encoder, gsize size)
1772 gboolean needs_reconfigure = FALSE;
1774 g_return_val_if_fail (size > 0, NULL);
1776 GST_DEBUG ("alloc src buffer");
1778 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1779 needs_reconfigure = gst_pad_check_reconfigure (encoder->srcpad);
1780 if (G_UNLIKELY (encoder->priv->output_state_changed
1781 || (encoder->priv->output_state && needs_reconfigure))) {
1782 if (!gst_video_encoder_negotiate_unlocked (encoder)) {
1783 GST_DEBUG_OBJECT (encoder, "Failed to negotiate, fallback allocation");
1784 gst_pad_mark_reconfigure (encoder->srcpad);
1790 gst_buffer_new_allocate (encoder->priv->allocator, size,
1791 &encoder->priv->params);
1793 GST_INFO_OBJECT (encoder, "couldn't allocate output buffer");
1797 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1802 buffer = gst_buffer_new_allocate (NULL, size, NULL);
1804 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1810 * gst_video_encoder_allocate_output_frame:
1811 * @encoder: a #GstVideoEncoder
1812 * @frame: a #GstVideoCodecFrame
1813 * @size: size of the buffer
1815 * Helper function that allocates a buffer to hold an encoded video frame for @encoder's
1816 * current #GstVideoCodecState. Subclass should already have configured video
1817 * state and set src pad caps.
1819 * The buffer allocated here is owned by the frame and you should only
1820 * keep references to the frame, not the buffer.
1822 * Returns: %GST_FLOW_OK if an output buffer could be allocated
1825 gst_video_encoder_allocate_output_frame (GstVideoEncoder *
1826 encoder, GstVideoCodecFrame * frame, gsize size)
1828 gboolean needs_reconfigure = FALSE;
1830 g_return_val_if_fail (frame->output_buffer == NULL, GST_FLOW_ERROR);
1832 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1833 needs_reconfigure = gst_pad_check_reconfigure (encoder->srcpad);
1834 if (G_UNLIKELY (encoder->priv->output_state_changed
1835 || (encoder->priv->output_state && needs_reconfigure))) {
1836 if (!gst_video_encoder_negotiate_unlocked (encoder)) {
1837 GST_DEBUG_OBJECT (encoder, "Failed to negotiate, fallback allocation");
1838 gst_pad_mark_reconfigure (encoder->srcpad);
1842 GST_LOG_OBJECT (encoder, "alloc buffer size %" G_GSIZE_FORMAT, size);
1844 frame->output_buffer =
1845 gst_buffer_new_allocate (encoder->priv->allocator, size,
1846 &encoder->priv->params);
1848 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1850 return frame->output_buffer ? GST_FLOW_OK : GST_FLOW_ERROR;
1854 gst_video_encoder_release_frame (GstVideoEncoder * enc,
1855 GstVideoCodecFrame * frame)
1859 /* unref once from the list */
1860 link = g_list_find (enc->priv->frames, frame);
1862 gst_video_codec_frame_unref (frame);
1863 enc->priv->frames = g_list_delete_link (enc->priv->frames, link);
1865 /* unref because this function takes ownership */
1866 gst_video_codec_frame_unref (frame);
1870 gst_video_encoder_transform_meta_default (GstVideoEncoder *
1871 encoder, GstVideoCodecFrame * frame, GstMeta * meta)
1873 const GstMetaInfo *info = meta->info;
1874 const gchar *const *tags;
1876 tags = gst_meta_api_type_get_tags (info->api);
1878 if (!tags || (g_strv_length ((gchar **) tags) == 1
1879 && gst_meta_api_type_has_tag (info->api,
1880 g_quark_from_string (GST_META_TAG_VIDEO_STR))))
1888 GstVideoEncoder *encoder;
1889 GstVideoCodecFrame *frame;
1893 foreach_metadata (GstBuffer * inbuf, GstMeta ** meta, gpointer user_data)
1895 CopyMetaData *data = user_data;
1896 GstVideoEncoder *encoder = data->encoder;
1897 GstVideoEncoderClass *klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
1898 GstVideoCodecFrame *frame = data->frame;
1899 const GstMetaInfo *info = (*meta)->info;
1900 gboolean do_copy = FALSE;
1902 if (gst_meta_api_type_has_tag (info->api, _gst_meta_tag_memory)) {
1903 /* never call the transform_meta with memory specific metadata */
1904 GST_DEBUG_OBJECT (encoder, "not copying memory specific metadata %s",
1905 g_type_name (info->api));
1907 } else if (klass->transform_meta) {
1908 do_copy = klass->transform_meta (encoder, frame, *meta);
1909 GST_DEBUG_OBJECT (encoder, "transformed metadata %s: copy: %d",
1910 g_type_name (info->api), do_copy);
1913 /* we only copy metadata when the subclass implemented a transform_meta
1914 * function and when it returns %TRUE */
1916 GstMetaTransformCopy copy_data = { FALSE, 0, -1 };
1917 GST_DEBUG_OBJECT (encoder, "copy metadata %s", g_type_name (info->api));
1918 /* simply copy then */
1919 info->transform_func (frame->output_buffer, *meta, inbuf,
1920 _gst_meta_transform_copy, ©_data);
1926 * gst_video_encoder_finish_frame:
1927 * @encoder: a #GstVideoEncoder
1928 * @frame: (transfer full): an encoded #GstVideoCodecFrame
1930 * @frame must have a valid encoded data buffer, whose metadata fields
1931 * are then appropriately set according to frame data or no buffer at
1932 * all if the frame should be dropped.
1933 * It is subsequently pushed downstream or provided to @pre_push.
1934 * In any case, the frame is considered finished and released.
1936 * After calling this function the output buffer of the frame is to be
1937 * considered read-only. This function will also change the metadata
1940 * Returns: a #GstFlowReturn resulting from sending data downstream
1943 gst_video_encoder_finish_frame (GstVideoEncoder * encoder,
1944 GstVideoCodecFrame * frame)
1946 GstVideoEncoderPrivate *priv = encoder->priv;
1947 GstFlowReturn ret = GST_FLOW_OK;
1948 GstVideoEncoderClass *encoder_class;
1950 gboolean send_headers = FALSE;
1951 gboolean discont = (frame->presentation_frame_number == 0);
1953 gboolean needs_reconfigure = FALSE;
1955 encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);
1957 GST_LOG_OBJECT (encoder,
1958 "finish frame fpn %d", frame->presentation_frame_number);
1960 GST_LOG_OBJECT (encoder, "frame PTS %" GST_TIME_FORMAT
1961 ", DTS %" GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts),
1962 GST_TIME_ARGS (frame->dts));
1964 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1966 needs_reconfigure = gst_pad_check_reconfigure (encoder->srcpad);
1967 if (G_UNLIKELY (priv->output_state_changed || (priv->output_state
1968 && needs_reconfigure))) {
1969 if (!gst_video_encoder_negotiate_unlocked (encoder)) {
1970 gst_pad_mark_reconfigure (encoder->srcpad);
1971 if (GST_PAD_IS_FLUSHING (encoder->srcpad))
1972 ret = GST_FLOW_FLUSHING;
1974 ret = GST_FLOW_NOT_NEGOTIATED;
1979 if (G_UNLIKELY (priv->output_state == NULL))
1980 goto no_output_state;
1982 /* Push all pending events that arrived before this frame */
1983 for (l = priv->frames; l; l = l->next) {
1984 GstVideoCodecFrame *tmp = l->data;
1989 for (k = g_list_last (tmp->events); k; k = k->prev)
1990 gst_video_encoder_push_event (encoder, k->data);
1991 g_list_free (tmp->events);
1999 gst_video_encoder_check_and_push_tags (encoder);
2001 /* no buffer data means this frame is skipped/dropped */
2002 if (!frame->output_buffer) {
2003 GST_DEBUG_OBJECT (encoder, "skipping frame %" GST_TIME_FORMAT,
2004 GST_TIME_ARGS (frame->pts));
2008 if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame) && priv->force_key_unit) {
2009 GstClockTime stream_time, running_time;
2011 ForcedKeyUnitEvent *fevt = NULL;
2015 gst_segment_to_running_time (&encoder->output_segment, GST_FORMAT_TIME,
2018 GST_OBJECT_LOCK (encoder);
2019 for (l = priv->force_key_unit; l; l = l->next) {
2020 ForcedKeyUnitEvent *tmp = l->data;
2022 /* Skip non-pending keyunits */
2026 /* Exact match using the frame id */
2027 if (frame->system_frame_number == tmp->frame_id) {
2032 /* Simple case, keyunit ASAP */
2033 if (tmp->running_time == GST_CLOCK_TIME_NONE) {
2038 /* Event for before this frame */
2039 if (tmp->running_time <= running_time) {
2046 priv->force_key_unit = g_list_remove (priv->force_key_unit, fevt);
2048 GST_OBJECT_UNLOCK (encoder);
2052 gst_segment_to_stream_time (&encoder->output_segment, GST_FORMAT_TIME,
2055 ev = gst_video_event_new_downstream_force_key_unit
2056 (frame->pts, stream_time, running_time,
2057 fevt->all_headers, fevt->count);
2059 gst_video_encoder_push_event (encoder, ev);
2061 if (fevt->all_headers)
2062 send_headers = TRUE;
2064 GST_DEBUG_OBJECT (encoder,
2065 "Forced key unit: running-time %" GST_TIME_FORMAT
2066 ", all_headers %d, count %u",
2067 GST_TIME_ARGS (running_time), fevt->all_headers, fevt->count);
2068 forced_key_unit_event_free (fevt);
2072 if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)) {
2073 priv->distance_from_sync = 0;
2074 GST_BUFFER_FLAG_UNSET (frame->output_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2075 /* For keyframes, DTS = PTS, if encoder doesn't decide otherwise */
2076 if (!GST_CLOCK_TIME_IS_VALID (frame->dts)) {
2077 frame->dts = frame->pts;
2080 GST_BUFFER_FLAG_SET (frame->output_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2083 /* DTS is expected monotone ascending,
2084 * so a good guess is the lowest unsent PTS (all being OK) */
2086 GstClockTime min_ts = GST_CLOCK_TIME_NONE;
2087 GstVideoCodecFrame *oframe = NULL;
2088 gboolean seen_none = FALSE;
2090 /* some maintenance regardless */
2091 for (l = priv->frames; l; l = l->next) {
2092 GstVideoCodecFrame *tmp = l->data;
2094 if (!GST_CLOCK_TIME_IS_VALID (tmp->abidata.ABI.ts)) {
2099 if (!GST_CLOCK_TIME_IS_VALID (min_ts) || tmp->abidata.ABI.ts < min_ts) {
2100 min_ts = tmp->abidata.ABI.ts;
2104 /* save a ts if needed */
2105 if (oframe && oframe != frame) {
2106 oframe->abidata.ABI.ts = frame->abidata.ABI.ts;
2109 /* and set if needed */
2110 if (!GST_CLOCK_TIME_IS_VALID (frame->dts) && !seen_none) {
2111 frame->dts = min_ts;
2112 GST_DEBUG_OBJECT (encoder,
2113 "no valid DTS, using oldest PTS %" GST_TIME_FORMAT,
2114 GST_TIME_ARGS (frame->pts));
2118 frame->distance_from_sync = priv->distance_from_sync;
2119 priv->distance_from_sync++;
2121 GST_BUFFER_PTS (frame->output_buffer) = frame->pts;
2122 GST_BUFFER_DTS (frame->output_buffer) = frame->dts;
2123 GST_BUFFER_DURATION (frame->output_buffer) = frame->duration;
2125 /* update rate estimate */
2126 priv->bytes += gst_buffer_get_size (frame->output_buffer);
2127 if (GST_CLOCK_TIME_IS_VALID (frame->duration)) {
2128 priv->time += frame->duration;
2130 /* better none than nothing valid */
2131 priv->time = GST_CLOCK_TIME_NONE;
2134 if (G_UNLIKELY (send_headers || priv->new_headers)) {
2135 GList *tmp, *copy = NULL;
2137 GST_DEBUG_OBJECT (encoder, "Sending headers");
2139 /* First make all buffers metadata-writable */
2140 for (tmp = priv->headers; tmp; tmp = tmp->next) {
2141 GstBuffer *tmpbuf = GST_BUFFER (tmp->data);
2143 copy = g_list_append (copy, gst_buffer_make_writable (tmpbuf));
2145 g_list_free (priv->headers);
2146 priv->headers = copy;
2148 for (tmp = priv->headers; tmp; tmp = tmp->next) {
2149 GstBuffer *tmpbuf = GST_BUFFER (tmp->data);
2151 priv->bytes += gst_buffer_get_size (tmpbuf);
2152 if (G_UNLIKELY (discont)) {
2153 GST_LOG_OBJECT (encoder, "marking discont");
2154 GST_BUFFER_FLAG_SET (tmpbuf, GST_BUFFER_FLAG_DISCONT);
2158 gst_pad_push (encoder->srcpad, gst_buffer_ref (tmpbuf));
2160 priv->new_headers = FALSE;
2163 if (G_UNLIKELY (discont)) {
2164 GST_LOG_OBJECT (encoder, "marking discont");
2165 GST_BUFFER_FLAG_SET (frame->output_buffer, GST_BUFFER_FLAG_DISCONT);
2168 if (encoder_class->pre_push)
2169 ret = encoder_class->pre_push (encoder, frame);
2171 if (encoder_class->transform_meta) {
2172 if (G_LIKELY (frame->input_buffer)) {
2175 data.encoder = encoder;
2177 gst_buffer_foreach_meta (frame->input_buffer, foreach_metadata, &data);
2179 GST_WARNING_OBJECT (encoder,
2180 "Can't copy metadata because input frame disappeared");
2184 /* Get an additional ref to the buffer, which is going to be pushed
2185 * downstream, the original ref is owned by the frame */
2186 buffer = gst_buffer_ref (frame->output_buffer);
2188 /* Release frame so the buffer is writable when we push it downstream
2189 * if possible, i.e. if the subclass does not hold additional references
2192 gst_video_encoder_release_frame (encoder, frame);
2195 if (ret == GST_FLOW_OK)
2196 ret = gst_pad_push (encoder->srcpad, buffer);
2201 gst_video_encoder_release_frame (encoder, frame);
2203 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2210 gst_video_encoder_release_frame (encoder, frame);
2211 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2212 GST_ERROR_OBJECT (encoder, "Output state was not configured");
2213 return GST_FLOW_ERROR;
2218 * gst_video_encoder_get_output_state:
2219 * @encoder: a #GstVideoEncoder
2221 * Get the current #GstVideoCodecState
2223 * Returns: (transfer full): #GstVideoCodecState describing format of video data.
2225 GstVideoCodecState *
2226 gst_video_encoder_get_output_state (GstVideoEncoder * encoder)
2228 GstVideoCodecState *state;
2230 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2231 state = gst_video_codec_state_ref (encoder->priv->output_state);
2232 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2238 * gst_video_encoder_set_output_state:
2239 * @encoder: a #GstVideoEncoder
2240 * @caps: (transfer full): the #GstCaps to use for the output
2241 * @reference: (allow-none) (transfer none): An optional reference @GstVideoCodecState
2243 * Creates a new #GstVideoCodecState with the specified caps as the output state
2245 * Any previously set output state on @encoder will be replaced by the newly
2248 * The specified @caps should not contain any resolution, pixel-aspect-ratio,
2249 * framerate, codec-data, .... Those should be specified instead in the returned
2250 * #GstVideoCodecState.
2252 * If the subclass wishes to copy over existing fields (like pixel aspect ratio,
2253 * or framerate) from an existing #GstVideoCodecState, it can be provided as a
2256 * If the subclass wishes to override some fields from the output state (like
2257 * pixel-aspect-ratio or framerate) it can do so on the returned #GstVideoCodecState.
2259 * The new output state will only take effect (set on pads and buffers) starting
2260 * from the next call to #gst_video_encoder_finish_frame().
2262 * Returns: (transfer full): the newly configured output state.
2264 GstVideoCodecState *
2265 gst_video_encoder_set_output_state (GstVideoEncoder * encoder, GstCaps * caps,
2266 GstVideoCodecState * reference)
2268 GstVideoEncoderPrivate *priv = encoder->priv;
2269 GstVideoCodecState *state;
2271 g_return_val_if_fail (caps != NULL, NULL);
2273 state = _new_output_state (caps, reference);
2275 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2276 if (priv->output_state)
2277 gst_video_codec_state_unref (priv->output_state);
2278 priv->output_state = gst_video_codec_state_ref (state);
2280 priv->output_state_changed = TRUE;
2281 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2287 * gst_video_encoder_set_latency:
2288 * @encoder: a #GstVideoEncoder
2289 * @min_latency: minimum latency
2290 * @max_latency: maximum latency
2292 * Informs baseclass of encoding latency.
2295 gst_video_encoder_set_latency (GstVideoEncoder * encoder,
2296 GstClockTime min_latency, GstClockTime max_latency)
2298 g_return_if_fail (GST_CLOCK_TIME_IS_VALID (min_latency));
2299 g_return_if_fail (max_latency >= min_latency);
2301 GST_OBJECT_LOCK (encoder);
2302 encoder->priv->min_latency = min_latency;
2303 encoder->priv->max_latency = max_latency;
2304 GST_OBJECT_UNLOCK (encoder);
2306 gst_element_post_message (GST_ELEMENT_CAST (encoder),
2307 gst_message_new_latency (GST_OBJECT_CAST (encoder)));
2311 * gst_video_encoder_get_latency:
2312 * @encoder: a #GstVideoEncoder
2313 * @min_latency: (out) (allow-none): address of variable in which to store the
2314 * configured minimum latency, or %NULL
2315 * @max_latency: (out) (allow-none): address of variable in which to store the
2316 * configured maximum latency, or %NULL
2318 * Query the configured encoding latency. Results will be returned via
2319 * @min_latency and @max_latency.
2322 gst_video_encoder_get_latency (GstVideoEncoder * encoder,
2323 GstClockTime * min_latency, GstClockTime * max_latency)
2325 GST_OBJECT_LOCK (encoder);
2327 *min_latency = encoder->priv->min_latency;
2329 *max_latency = encoder->priv->max_latency;
2330 GST_OBJECT_UNLOCK (encoder);
2334 * gst_video_encoder_get_oldest_frame:
2335 * @encoder: a #GstVideoEncoder
2337 * Get the oldest unfinished pending #GstVideoCodecFrame
2339 * Returns: (transfer full): oldest unfinished pending #GstVideoCodecFrame
2341 GstVideoCodecFrame *
2342 gst_video_encoder_get_oldest_frame (GstVideoEncoder * encoder)
2344 GstVideoCodecFrame *frame = NULL;
2346 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2347 if (encoder->priv->frames)
2348 frame = gst_video_codec_frame_ref (encoder->priv->frames->data);
2349 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2351 return (GstVideoCodecFrame *) frame;
2355 * gst_video_encoder_get_frame:
2356 * @encoder: a #GstVideoEnccoder
2357 * @frame_number: system_frame_number of a frame
2359 * Get a pending unfinished #GstVideoCodecFrame
2361 * Returns: (transfer full): pending unfinished #GstVideoCodecFrame identified by @frame_number.
2363 GstVideoCodecFrame *
2364 gst_video_encoder_get_frame (GstVideoEncoder * encoder, int frame_number)
2367 GstVideoCodecFrame *frame = NULL;
2369 GST_DEBUG_OBJECT (encoder, "frame_number : %d", frame_number);
2371 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2372 for (g = encoder->priv->frames; g; g = g->next) {
2373 GstVideoCodecFrame *tmp = g->data;
2375 if (tmp->system_frame_number == frame_number) {
2376 frame = gst_video_codec_frame_ref (tmp);
2380 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2386 * gst_video_encoder_get_frames:
2387 * @encoder: a #GstVideoEncoder
2389 * Get all pending unfinished #GstVideoCodecFrame
2391 * Returns: (transfer full) (element-type GstVideoCodecFrame): pending unfinished #GstVideoCodecFrame.
2394 gst_video_encoder_get_frames (GstVideoEncoder * encoder)
2398 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2399 frames = g_list_copy (encoder->priv->frames);
2400 g_list_foreach (frames, (GFunc) gst_video_codec_frame_ref, NULL);
2401 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2407 * gst_video_encoder_merge_tags:
2408 * @encoder: a #GstVideoEncoder
2409 * @tags: (allow-none): a #GstTagList to merge, or NULL to unset
2410 * previously-set tags
2411 * @mode: the #GstTagMergeMode to use, usually #GST_TAG_MERGE_REPLACE
2413 * Sets the video encoder tags and how they should be merged with any
2414 * upstream stream tags. This will override any tags previously-set
2415 * with gst_video_encoder_merge_tags().
2417 * Note that this is provided for convenience, and the subclass is
2418 * not required to use this and can still do tag handling on its own.
2423 gst_video_encoder_merge_tags (GstVideoEncoder * encoder,
2424 const GstTagList * tags, GstTagMergeMode mode)
2426 g_return_if_fail (GST_IS_VIDEO_ENCODER (encoder));
2427 g_return_if_fail (tags == NULL || GST_IS_TAG_LIST (tags));
2428 g_return_if_fail (tags == NULL || mode != GST_TAG_MERGE_UNDEFINED);
2430 GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2431 if (encoder->priv->tags != tags) {
2432 if (encoder->priv->tags) {
2433 gst_tag_list_unref (encoder->priv->tags);
2434 encoder->priv->tags = NULL;
2435 encoder->priv->tags_merge_mode = GST_TAG_MERGE_APPEND;
2438 encoder->priv->tags = gst_tag_list_ref ((GstTagList *) tags);
2439 encoder->priv->tags_merge_mode = mode;
2442 GST_DEBUG_OBJECT (encoder, "setting encoder tags to %" GST_PTR_FORMAT,
2444 encoder->priv->tags_changed = TRUE;
2446 GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2450 * gst_video_encoder_get_allocator:
2451 * @encoder: a #GstVideoEncoder
2452 * @allocator: (out) (allow-none) (transfer full): the #GstAllocator
2454 * @params: (out) (allow-none) (transfer full): the
2455 * #GstAllocatorParams of @allocator
2457 * Lets #GstVideoEncoder sub-classes to know the memory @allocator
2458 * used by the base class and its @params.
2460 * Unref the @allocator after use it.
2463 gst_video_encoder_get_allocator (GstVideoEncoder * encoder,
2464 GstAllocator ** allocator, GstAllocationParams * params)
2466 g_return_if_fail (GST_IS_VIDEO_ENCODER (encoder));
2469 *allocator = encoder->priv->allocator ?
2470 gst_object_ref (encoder->priv->allocator) : NULL;
2473 *params = encoder->priv->params;
2477 * gst_video_encoder_set_min_pts:
2478 * @encoder: a #GstVideoEncoder
2479 * @min_pts: minimal PTS that will be passed to handle_frame
2481 * Request minimal value for PTS passed to handle_frame.
2483 * For streams with reordered frames this can be used to ensure that there
2484 * is enough time to accomodate first DTS, which may be less than first PTS
2489 gst_video_encoder_set_min_pts (GstVideoEncoder * encoder, GstClockTime min_pts)
2491 g_return_if_fail (GST_IS_VIDEO_ENCODER (encoder));
2492 encoder->priv->min_pts = min_pts;
2493 encoder->priv->time_adjustment = GST_CLOCK_TIME_NONE;