Bump GLib requirement to >= 2.62
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-base / gst-libs / gst / video / gstvideoencoder.c
1 /* GStreamer
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>
8  *
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.
13  *
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.
18  *
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.
23  */
24
25 /**
26  * SECTION:gstvideoencoder
27  * @title: GstVideoEncoder
28  * @short_description: Base class for video encoders
29  *
30  * This base class is for video encoders turning raw video into
31  * encoded video data.
32  *
33  * GstVideoEncoder and subclass should cooperate as follows.
34  *
35  * ## Configuration
36  *
37  *   * Initially, GstVideoEncoder calls @start when the encoder element
38  *     is activated, which allows subclass to perform any global setup.
39  *   * GstVideoEncoder calls @set_format to inform subclass of the format
40  *     of input video data that it is about to receive.  Subclass should
41  *     setup for encoding and configure base class as appropriate
42  *     (e.g. latency). While unlikely, it might be called more than once,
43  *     if changing input parameters require reconfiguration.  Baseclass
44  *     will ensure that processing of current configuration is finished.
45  *   * GstVideoEncoder calls @stop at end of all processing.
46  *
47  * ## Data processing
48  *
49  *     * Base class collects input data and metadata into a frame and hands
50  *       this to subclass' @handle_frame.
51  *
52  *     * If codec processing results in encoded data, subclass should call
53  *       @gst_video_encoder_finish_frame to have encoded data pushed
54  *       downstream.
55  *
56  *     * If implemented, baseclass calls subclass @pre_push just prior to
57  *       pushing to allow subclasses to modify some metadata on the buffer.
58  *       If it returns GST_FLOW_OK, the buffer is pushed downstream.
59  *
60  *     * GstVideoEncoderClass will handle both srcpad and sinkpad events.
61  *       Sink events will be passed to subclass if @event callback has been
62  *       provided.
63  *
64  * ## Shutdown phase
65  *
66  *   * GstVideoEncoder class calls @stop to inform the subclass that data
67  *     parsing will be stopped.
68  *
69  * Subclass is responsible for providing pad template caps for
70  * source and sink pads. The pads need to be named "sink" and "src". It should
71  * also be able to provide fixed src pad caps in @getcaps by the time it calls
72  * @gst_video_encoder_finish_frame.
73  *
74  * Things that subclass need to take care of:
75  *
76  *   * Provide pad templates
77  *   * Provide source pad caps before pushing the first buffer
78  *   * Accept data in @handle_frame and provide encoded results to
79  *      @gst_video_encoder_finish_frame.
80  *
81  *
82  * The #GstVideoEncoder:qos property will enable the Quality-of-Service
83  * features of the encoder which gather statistics about the real-time
84  * performance of the downstream elements. If enabled, subclasses can
85  * use gst_video_encoder_get_max_encode_time() to check if input frames
86  * are already late and drop them right away to give a chance to the
87  * pipeline to catch up.
88  */
89
90 #ifdef HAVE_CONFIG_H
91 #include "config.h"
92 #endif
93
94 /* TODO
95  *
96  * * Calculate actual latency based on input/output timestamp/frame_number
97  *   and if it exceeds the recorded one, save it and emit a GST_MESSAGE_LATENCY
98  */
99
100 #include <gst/video/video.h>
101 #include "gstvideoencoder.h"
102 #include "gstvideoutils.h"
103 #include "gstvideoutilsprivate.h"
104
105 #include <gst/video/gstvideometa.h>
106 #include <gst/video/gstvideopool.h>
107
108 #include <string.h>
109
110 GST_DEBUG_CATEGORY (videoencoder_debug);
111 #define GST_CAT_DEFAULT videoencoder_debug
112
113 /* properties */
114
115 #define DEFAULT_QOS                 FALSE
116 #define DEFAULT_MIN_FORCE_KEY_UNIT_INTERVAL 0
117
118 enum
119 {
120   PROP_0,
121   PROP_QOS,
122   PROP_MIN_FORCE_KEY_UNIT_INTERVAL,
123   PROP_LAST
124 };
125
126 struct _GstVideoEncoderPrivate
127 {
128   guint64 presentation_frame_number;
129   int distance_from_sync;
130
131   /* FIXME : (and introduce a context ?) */
132   gboolean drained;
133
134   gint64 min_latency;
135   gint64 max_latency;
136
137   /* FIXME 2.0: Use a GQueue or similar, see GstVideoCodecFrame::events */
138   GList *current_frame_events;
139
140   GList *headers;
141   gboolean new_headers;         /* Whether new headers were just set */
142
143   GQueue force_key_unit;        /* List of pending forced keyunits */
144   GstClockTime min_force_key_unit_interval;
145   GstClockTime last_force_key_unit_request;
146   GstClockTime last_key_unit;
147
148   guint32 system_frame_number;
149
150   GQueue frames;                /* Protected with OBJECT_LOCK */
151   GstVideoCodecState *input_state;
152   GstVideoCodecState *output_state;
153   gboolean output_state_changed;
154
155   gint64 bytes;
156   gint64 time;
157
158   GstAllocator *allocator;
159   GstAllocationParams params;
160
161   /* upstream stream tags (global tags are passed through as-is) */
162   GstTagList *upstream_tags;
163
164   /* subclass tags */
165   GstTagList *tags;
166   GstTagMergeMode tags_merge_mode;
167
168   gboolean tags_changed;
169
170   GstClockTime min_pts;
171   /* adjustment needed on pts, dts, segment start and stop to accommodate
172    * min_pts */
173   GstClockTime time_adjustment;
174
175   /* QoS properties */
176   gint qos_enabled;             /* ATOMIC */
177   gdouble proportion;           /* OBJECT_LOCK */
178   GstClockTime earliest_time;   /* OBJECT_LOCK */
179   GstClockTime qos_frame_duration;      /* OBJECT_LOCK */
180   /* qos messages: frames dropped/processed */
181   guint dropped;
182   guint processed;
183 };
184
185 typedef struct _ForcedKeyUnitEvent ForcedKeyUnitEvent;
186 struct _ForcedKeyUnitEvent
187 {
188   GstClockTime running_time;
189   gboolean pending;             /* TRUE if this was requested already */
190   gboolean all_headers;
191   guint count;
192   guint32 frame_id;
193 };
194
195 static void
196 forced_key_unit_event_free (ForcedKeyUnitEvent * evt)
197 {
198   g_slice_free (ForcedKeyUnitEvent, evt);
199 }
200
201 static ForcedKeyUnitEvent *
202 forced_key_unit_event_new (GstClockTime running_time, gboolean all_headers,
203     guint count)
204 {
205   ForcedKeyUnitEvent *evt = g_slice_new0 (ForcedKeyUnitEvent);
206
207   evt->running_time = running_time;
208   evt->all_headers = all_headers;
209   evt->count = count;
210
211   return evt;
212 }
213
214 static gint
215 forced_key_unit_event_compare (const ForcedKeyUnitEvent * a,
216     const ForcedKeyUnitEvent * b, gpointer user_data)
217 {
218   if (a->running_time == b->running_time) {
219     /* Sort pending ones before non-pending ones */
220     if (a->pending && !b->pending)
221       return -1;
222     if (!a->pending && b->pending)
223       return 1;
224     return 0;
225   }
226
227   if (a->running_time == GST_CLOCK_TIME_NONE)
228     return -1;
229   if (b->running_time == GST_CLOCK_TIME_NONE)
230     return 1;
231   if (a->running_time < b->running_time)
232     return -1;
233   return 1;
234 }
235
236 static GstElementClass *parent_class = NULL;
237 static gint private_offset = 0;
238
239 /* cached quark to avoid contention on the global quark table lock */
240 #define META_TAG_VIDEO meta_tag_video_quark
241 static GQuark meta_tag_video_quark;
242
243 static void gst_video_encoder_class_init (GstVideoEncoderClass * klass);
244 static void gst_video_encoder_init (GstVideoEncoder * enc,
245     GstVideoEncoderClass * klass);
246
247 static void gst_video_encoder_finalize (GObject * object);
248
249 static gboolean gst_video_encoder_setcaps (GstVideoEncoder * enc,
250     GstCaps * caps);
251 static GstCaps *gst_video_encoder_sink_getcaps (GstVideoEncoder * encoder,
252     GstCaps * filter);
253 static gboolean gst_video_encoder_src_event (GstPad * pad, GstObject * parent,
254     GstEvent * event);
255 static gboolean gst_video_encoder_sink_event (GstPad * pad, GstObject * parent,
256     GstEvent * event);
257 static GstFlowReturn gst_video_encoder_chain (GstPad * pad, GstObject * parent,
258     GstBuffer * buf);
259 static GstStateChangeReturn gst_video_encoder_change_state (GstElement *
260     element, GstStateChange transition);
261 static gboolean gst_video_encoder_sink_query (GstPad * pad, GstObject * parent,
262     GstQuery * query);
263 static gboolean gst_video_encoder_src_query (GstPad * pad, GstObject * parent,
264     GstQuery * query);
265 static GstVideoCodecFrame *gst_video_encoder_new_frame (GstVideoEncoder *
266     encoder, GstBuffer * buf, GstClockTime pts, GstClockTime dts,
267     GstClockTime duration);
268
269 static gboolean gst_video_encoder_sink_event_default (GstVideoEncoder * encoder,
270     GstEvent * event);
271 static gboolean gst_video_encoder_src_event_default (GstVideoEncoder * encoder,
272     GstEvent * event);
273 static gboolean gst_video_encoder_decide_allocation_default (GstVideoEncoder *
274     encoder, GstQuery * query);
275 static gboolean gst_video_encoder_propose_allocation_default (GstVideoEncoder *
276     encoder, GstQuery * query);
277 static gboolean gst_video_encoder_negotiate_default (GstVideoEncoder * encoder);
278 static gboolean gst_video_encoder_negotiate_unlocked (GstVideoEncoder *
279     encoder);
280
281 static gboolean gst_video_encoder_sink_query_default (GstVideoEncoder * encoder,
282     GstQuery * query);
283 static gboolean gst_video_encoder_src_query_default (GstVideoEncoder * encoder,
284     GstQuery * query);
285
286 static gboolean gst_video_encoder_transform_meta_default (GstVideoEncoder *
287     encoder, GstVideoCodecFrame * frame, GstMeta * meta);
288
289 /* we can't use G_DEFINE_ABSTRACT_TYPE because we need the klass in the _init
290  * method to get to the padtemplates */
291 GType
292 gst_video_encoder_get_type (void)
293 {
294   static gsize type = 0;
295
296   if (g_once_init_enter (&type)) {
297     GType _type;
298     static const GTypeInfo info = {
299       sizeof (GstVideoEncoderClass),
300       NULL,
301       NULL,
302       (GClassInitFunc) gst_video_encoder_class_init,
303       NULL,
304       NULL,
305       sizeof (GstVideoEncoder),
306       0,
307       (GInstanceInitFunc) gst_video_encoder_init,
308     };
309     const GInterfaceInfo preset_interface_info = {
310       NULL,                     /* interface_init */
311       NULL,                     /* interface_finalize */
312       NULL                      /* interface_data */
313     };
314
315     _type = g_type_register_static (GST_TYPE_ELEMENT,
316         "GstVideoEncoder", &info, G_TYPE_FLAG_ABSTRACT);
317     private_offset =
318         g_type_add_instance_private (_type, sizeof (GstVideoEncoderPrivate));
319     g_type_add_interface_static (_type, GST_TYPE_PRESET,
320         &preset_interface_info);
321     g_once_init_leave (&type, _type);
322   }
323   return type;
324 }
325
326 static inline GstVideoEncoderPrivate *
327 gst_video_encoder_get_instance_private (GstVideoEncoder * self)
328 {
329   return (G_STRUCT_MEMBER_P (self, private_offset));
330 }
331
332 static void
333 gst_video_encoder_set_property (GObject * object, guint prop_id,
334     const GValue * value, GParamSpec * pspec)
335 {
336   GstVideoEncoder *sink = GST_VIDEO_ENCODER (object);
337
338   switch (prop_id) {
339     case PROP_QOS:
340       gst_video_encoder_set_qos_enabled (sink, g_value_get_boolean (value));
341       break;
342     case PROP_MIN_FORCE_KEY_UNIT_INTERVAL:
343       gst_video_encoder_set_min_force_key_unit_interval (sink,
344           g_value_get_uint64 (value));
345       break;
346     default:
347       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
348       break;
349   }
350 }
351
352 static void
353 gst_video_encoder_get_property (GObject * object, guint prop_id, GValue * value,
354     GParamSpec * pspec)
355 {
356   GstVideoEncoder *sink = GST_VIDEO_ENCODER (object);
357
358   switch (prop_id) {
359     case PROP_QOS:
360       g_value_set_boolean (value, gst_video_encoder_is_qos_enabled (sink));
361       break;
362     case PROP_MIN_FORCE_KEY_UNIT_INTERVAL:
363       g_value_set_uint64 (value,
364           gst_video_encoder_get_min_force_key_unit_interval (sink));
365       break;
366     default:
367       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
368       break;
369   }
370 }
371
372 static void
373 gst_video_encoder_class_init (GstVideoEncoderClass * klass)
374 {
375   GObjectClass *gobject_class;
376   GstElementClass *gstelement_class;
377
378   gobject_class = G_OBJECT_CLASS (klass);
379   gstelement_class = GST_ELEMENT_CLASS (klass);
380
381   GST_DEBUG_CATEGORY_INIT (videoencoder_debug, "videoencoder", 0,
382       "Base Video Encoder");
383
384   parent_class = g_type_class_peek_parent (klass);
385
386   if (private_offset != 0)
387     g_type_class_adjust_private_offset (klass, &private_offset);
388
389   gobject_class->set_property = gst_video_encoder_set_property;
390   gobject_class->get_property = gst_video_encoder_get_property;
391   gobject_class->finalize = gst_video_encoder_finalize;
392
393   gstelement_class->change_state =
394       GST_DEBUG_FUNCPTR (gst_video_encoder_change_state);
395
396   klass->sink_event = gst_video_encoder_sink_event_default;
397   klass->src_event = gst_video_encoder_src_event_default;
398   klass->propose_allocation = gst_video_encoder_propose_allocation_default;
399   klass->decide_allocation = gst_video_encoder_decide_allocation_default;
400   klass->negotiate = gst_video_encoder_negotiate_default;
401   klass->sink_query = gst_video_encoder_sink_query_default;
402   klass->src_query = gst_video_encoder_src_query_default;
403   klass->transform_meta = gst_video_encoder_transform_meta_default;
404
405   g_object_class_install_property (gobject_class, PROP_QOS,
406       g_param_spec_boolean ("qos", "Qos",
407           "Handle Quality-of-Service events from downstream", DEFAULT_QOS,
408           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
409
410   /**
411    * GstVideoEncoder:min-force-key-unit-interval:
412    *
413    * Minimum interval between force-keyunit requests in nanoseconds. See
414    * gst_video_encoder_set_min_force_key_unit_interval() for more details.
415    *
416    * Since: 1.18
417    **/
418   g_object_class_install_property (gobject_class,
419       PROP_MIN_FORCE_KEY_UNIT_INTERVAL,
420       g_param_spec_uint64 ("min-force-key-unit-interval",
421           "Minimum Force Keyunit Interval",
422           "Minimum interval between force-keyunit requests in nanoseconds", 0,
423           G_MAXUINT64, DEFAULT_MIN_FORCE_KEY_UNIT_INTERVAL,
424           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
425
426   meta_tag_video_quark = g_quark_from_static_string (GST_META_TAG_VIDEO_STR);
427 }
428
429 static GList *
430 _flush_events (GstPad * pad, GList * events)
431 {
432   GList *tmp;
433
434   for (tmp = events; tmp; tmp = tmp->next) {
435     if (GST_EVENT_TYPE (tmp->data) != GST_EVENT_EOS &&
436         GST_EVENT_TYPE (tmp->data) != GST_EVENT_SEGMENT &&
437         GST_EVENT_IS_STICKY (tmp->data)) {
438       gst_pad_store_sticky_event (pad, GST_EVENT_CAST (tmp->data));
439     }
440     gst_event_unref (tmp->data);
441   }
442   g_list_free (events);
443
444   return NULL;
445 }
446
447 static gboolean
448 gst_video_encoder_reset (GstVideoEncoder * encoder, gboolean hard)
449 {
450   GstVideoEncoderPrivate *priv = encoder->priv;
451   gboolean ret = TRUE;
452
453   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
454
455   priv->presentation_frame_number = 0;
456   priv->distance_from_sync = 0;
457
458   g_queue_clear_full (&priv->force_key_unit,
459       (GDestroyNotify) forced_key_unit_event_free);
460   priv->last_force_key_unit_request = GST_CLOCK_TIME_NONE;
461   priv->last_key_unit = GST_CLOCK_TIME_NONE;
462
463   priv->drained = TRUE;
464
465   GST_OBJECT_LOCK (encoder);
466   priv->bytes = 0;
467   priv->time = 0;
468   GST_OBJECT_UNLOCK (encoder);
469
470   priv->time_adjustment = GST_CLOCK_TIME_NONE;
471
472   if (hard) {
473     gst_segment_init (&encoder->input_segment, GST_FORMAT_TIME);
474     gst_segment_init (&encoder->output_segment, GST_FORMAT_TIME);
475
476     if (priv->input_state)
477       gst_video_codec_state_unref (priv->input_state);
478     priv->input_state = NULL;
479     if (priv->output_state)
480       gst_video_codec_state_unref (priv->output_state);
481     priv->output_state = NULL;
482
483     if (priv->upstream_tags) {
484       gst_tag_list_unref (priv->upstream_tags);
485       priv->upstream_tags = NULL;
486     }
487     if (priv->tags)
488       gst_tag_list_unref (priv->tags);
489     priv->tags = NULL;
490     priv->tags_merge_mode = GST_TAG_MERGE_APPEND;
491     priv->tags_changed = FALSE;
492
493     g_list_foreach (priv->headers, (GFunc) gst_event_unref, NULL);
494     g_list_free (priv->headers);
495     priv->headers = NULL;
496     priv->new_headers = FALSE;
497
498     if (priv->allocator) {
499       gst_object_unref (priv->allocator);
500       priv->allocator = NULL;
501     }
502
503     g_list_foreach (priv->current_frame_events, (GFunc) gst_event_unref, NULL);
504     g_list_free (priv->current_frame_events);
505     priv->current_frame_events = NULL;
506
507     GST_OBJECT_LOCK (encoder);
508     priv->proportion = 0.5;
509     priv->earliest_time = GST_CLOCK_TIME_NONE;
510     priv->qos_frame_duration = 0;
511     GST_OBJECT_UNLOCK (encoder);
512
513     priv->dropped = 0;
514     priv->processed = 0;
515   } else {
516     GList *l;
517
518     for (l = priv->frames.head; l; l = l->next) {
519       GstVideoCodecFrame *frame = l->data;
520
521       frame->events = _flush_events (encoder->srcpad, frame->events);
522     }
523     priv->current_frame_events = _flush_events (encoder->srcpad,
524         encoder->priv->current_frame_events);
525   }
526
527   g_queue_clear_full (&priv->frames,
528       (GDestroyNotify) gst_video_codec_frame_unref);
529
530   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
531
532   return ret;
533 }
534
535 /* Always call reset() in one way or another after this */
536 static gboolean
537 gst_video_encoder_flush (GstVideoEncoder * encoder)
538 {
539   GstVideoEncoderClass *klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
540   gboolean ret = TRUE;
541
542   if (klass->flush)
543     ret = klass->flush (encoder);
544
545   return ret;
546 }
547
548 static void
549 gst_video_encoder_init (GstVideoEncoder * encoder, GstVideoEncoderClass * klass)
550 {
551   GstVideoEncoderPrivate *priv;
552   GstPadTemplate *pad_template;
553   GstPad *pad;
554
555   GST_DEBUG_OBJECT (encoder, "gst_video_encoder_init");
556
557   priv = encoder->priv = gst_video_encoder_get_instance_private (encoder);
558
559   pad_template =
560       gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink");
561   g_return_if_fail (pad_template != NULL);
562
563   encoder->sinkpad = pad = gst_pad_new_from_template (pad_template, "sink");
564
565   gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_video_encoder_chain));
566   gst_pad_set_event_function (pad,
567       GST_DEBUG_FUNCPTR (gst_video_encoder_sink_event));
568   gst_pad_set_query_function (pad,
569       GST_DEBUG_FUNCPTR (gst_video_encoder_sink_query));
570   gst_element_add_pad (GST_ELEMENT (encoder), encoder->sinkpad);
571
572   pad_template =
573       gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "src");
574   g_return_if_fail (pad_template != NULL);
575
576   encoder->srcpad = pad = gst_pad_new_from_template (pad_template, "src");
577
578   gst_pad_set_query_function (pad,
579       GST_DEBUG_FUNCPTR (gst_video_encoder_src_query));
580   gst_pad_set_event_function (pad,
581       GST_DEBUG_FUNCPTR (gst_video_encoder_src_event));
582   gst_element_add_pad (GST_ELEMENT (encoder), encoder->srcpad);
583
584   gst_segment_init (&encoder->input_segment, GST_FORMAT_TIME);
585   gst_segment_init (&encoder->output_segment, GST_FORMAT_TIME);
586
587   g_rec_mutex_init (&encoder->stream_lock);
588
589   priv->headers = NULL;
590   priv->new_headers = FALSE;
591
592   g_queue_init (&priv->frames);
593   g_queue_init (&priv->force_key_unit);
594
595   priv->min_latency = 0;
596   priv->max_latency = 0;
597   priv->min_pts = GST_CLOCK_TIME_NONE;
598   priv->time_adjustment = GST_CLOCK_TIME_NONE;
599
600   gst_video_encoder_reset (encoder, TRUE);
601 }
602
603 /**
604  * gst_video_encoder_set_headers:
605  * @encoder: a #GstVideoEncoder
606  * @headers: (transfer full) (element-type GstBuffer): a list of #GstBuffer containing the codec header
607  *
608  * Set the codec headers to be sent downstream whenever requested.
609  */
610 void
611 gst_video_encoder_set_headers (GstVideoEncoder * video_encoder, GList * headers)
612 {
613   GST_VIDEO_ENCODER_STREAM_LOCK (video_encoder);
614
615   GST_DEBUG_OBJECT (video_encoder, "new headers %p", headers);
616   if (video_encoder->priv->headers) {
617     g_list_foreach (video_encoder->priv->headers, (GFunc) gst_buffer_unref,
618         NULL);
619     g_list_free (video_encoder->priv->headers);
620   }
621   video_encoder->priv->headers = headers;
622   video_encoder->priv->new_headers = TRUE;
623
624   GST_VIDEO_ENCODER_STREAM_UNLOCK (video_encoder);
625 }
626
627 static GstVideoCodecState *
628 _new_output_state (GstCaps * caps, GstVideoCodecState * reference)
629 {
630   GstVideoCodecState *state;
631
632   state = g_slice_new0 (GstVideoCodecState);
633   state->ref_count = 1;
634   gst_video_info_init (&state->info);
635
636   if (!gst_video_info_set_format (&state->info, GST_VIDEO_FORMAT_ENCODED, 0, 0)) {
637     g_slice_free (GstVideoCodecState, state);
638     return NULL;
639   }
640
641   state->caps = caps;
642
643   if (reference) {
644     GstVideoInfo *tgt, *ref;
645
646     tgt = &state->info;
647     ref = &reference->info;
648
649     /* Copy over extra fields from reference state */
650     tgt->interlace_mode = ref->interlace_mode;
651     tgt->flags = ref->flags;
652     tgt->width = ref->width;
653     tgt->height = ref->height;
654     tgt->chroma_site = ref->chroma_site;
655     tgt->colorimetry = ref->colorimetry;
656     tgt->par_n = ref->par_n;
657     tgt->par_d = ref->par_d;
658     tgt->fps_n = ref->fps_n;
659     tgt->fps_d = ref->fps_d;
660
661     GST_VIDEO_INFO_FIELD_ORDER (tgt) = GST_VIDEO_INFO_FIELD_ORDER (ref);
662
663     GST_VIDEO_INFO_MULTIVIEW_MODE (tgt) = GST_VIDEO_INFO_MULTIVIEW_MODE (ref);
664     GST_VIDEO_INFO_MULTIVIEW_FLAGS (tgt) = GST_VIDEO_INFO_MULTIVIEW_FLAGS (ref);
665
666     if (reference->mastering_display_info) {
667       state->mastering_display_info = g_slice_dup (GstVideoMasteringDisplayInfo,
668           reference->mastering_display_info);
669     }
670     if (reference->content_light_level) {
671       state->content_light_level = g_slice_dup (GstVideoContentLightLevel,
672           reference->content_light_level);
673     }
674   }
675
676   return state;
677 }
678
679 static GstVideoCodecState *
680 _new_input_state (GstCaps * caps)
681 {
682   GstVideoCodecState *state;
683   GstStructure *c_struct;
684   const gchar *s;
685
686   state = g_slice_new0 (GstVideoCodecState);
687   state->ref_count = 1;
688   gst_video_info_init (&state->info);
689   if (G_UNLIKELY (!gst_video_info_from_caps (&state->info, caps)))
690     goto parse_fail;
691   state->caps = gst_caps_ref (caps);
692
693   c_struct = gst_caps_get_structure (caps, 0);
694
695   if ((s = gst_structure_get_string (c_struct, "mastering-display-info"))) {
696     state->mastering_display_info = g_slice_new (GstVideoMasteringDisplayInfo);
697     gst_video_mastering_display_info_from_string (state->mastering_display_info,
698         s);
699   }
700   if ((s = gst_structure_get_string (c_struct, "content-light-level"))) {
701     state->content_light_level = g_slice_new (GstVideoContentLightLevel);
702     gst_video_content_light_level_from_string (state->content_light_level, s);
703   }
704
705   return state;
706
707 parse_fail:
708   {
709     g_slice_free (GstVideoCodecState, state);
710     return NULL;
711   }
712 }
713
714 static gboolean
715 gst_video_encoder_setcaps (GstVideoEncoder * encoder, GstCaps * caps)
716 {
717   GstVideoEncoderClass *encoder_class;
718   GstVideoCodecState *state;
719   gboolean ret = TRUE;
720
721   encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);
722
723   GST_DEBUG_OBJECT (encoder, "setcaps %" GST_PTR_FORMAT, caps);
724
725   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
726
727   if (encoder->priv->input_state) {
728     GST_DEBUG_OBJECT (encoder,
729         "Checking if caps changed old %" GST_PTR_FORMAT " new %" GST_PTR_FORMAT,
730         encoder->priv->input_state->caps, caps);
731     if (gst_caps_is_equal (encoder->priv->input_state->caps, caps))
732       goto caps_not_changed;
733   }
734
735   state = _new_input_state (caps);
736   if (G_UNLIKELY (!state))
737     goto parse_fail;
738
739   if (encoder->priv->input_state
740       && gst_video_info_is_equal (&state->info,
741           &encoder->priv->input_state->info)) {
742     gst_video_codec_state_unref (state);
743     goto caps_not_changed;
744   }
745
746   if (encoder_class->reset) {
747     GST_FIXME_OBJECT (encoder, "GstVideoEncoder::reset() is deprecated");
748     encoder_class->reset (encoder, TRUE);
749   }
750
751   /* and subclass should be ready to configure format at any time around */
752   if (encoder_class->set_format != NULL)
753     ret = encoder_class->set_format (encoder, state);
754
755   if (ret) {
756     if (encoder->priv->input_state)
757       gst_video_codec_state_unref (encoder->priv->input_state);
758     encoder->priv->input_state = state;
759   } else {
760     gst_video_codec_state_unref (state);
761   }
762
763   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
764
765   if (!ret)
766     GST_WARNING_OBJECT (encoder, "rejected caps %" GST_PTR_FORMAT, caps);
767
768   return ret;
769
770 caps_not_changed:
771   {
772     GST_DEBUG_OBJECT (encoder, "Caps did not change - ignore");
773     GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
774     return TRUE;
775   }
776
777   /* ERRORS */
778 parse_fail:
779   {
780     GST_WARNING_OBJECT (encoder, "Failed to parse caps");
781     GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
782     return FALSE;
783   }
784 }
785
786 /**
787  * gst_video_encoder_proxy_getcaps:
788  * @enc: a #GstVideoEncoder
789  * @caps: (allow-none): initial caps
790  * @filter: (allow-none): filter caps
791  *
792  * Returns caps that express @caps (or sink template caps if @caps == NULL)
793  * restricted to resolution/format/... combinations supported by downstream
794  * elements (e.g. muxers).
795  *
796  * Returns: (transfer full): a #GstCaps owned by caller
797  */
798 GstCaps *
799 gst_video_encoder_proxy_getcaps (GstVideoEncoder * encoder, GstCaps * caps,
800     GstCaps * filter)
801 {
802   return __gst_video_element_proxy_getcaps (GST_ELEMENT_CAST (encoder),
803       GST_VIDEO_ENCODER_SINK_PAD (encoder),
804       GST_VIDEO_ENCODER_SRC_PAD (encoder), caps, filter);
805 }
806
807 static GstCaps *
808 gst_video_encoder_sink_getcaps (GstVideoEncoder * encoder, GstCaps * filter)
809 {
810   GstVideoEncoderClass *klass;
811   GstCaps *caps;
812
813   klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
814
815   if (klass->getcaps)
816     caps = klass->getcaps (encoder, filter);
817   else
818     caps = gst_video_encoder_proxy_getcaps (encoder, NULL, filter);
819
820   GST_LOG_OBJECT (encoder, "Returning caps %" GST_PTR_FORMAT, caps);
821
822   return caps;
823 }
824
825 static gboolean
826 gst_video_encoder_decide_allocation_default (GstVideoEncoder * encoder,
827     GstQuery * query)
828 {
829   GstAllocator *allocator = NULL;
830   GstAllocationParams params;
831   gboolean update_allocator;
832
833   /* we got configuration from our peer or the decide_allocation method,
834    * parse them */
835   if (gst_query_get_n_allocation_params (query) > 0) {
836     /* try the allocator */
837     gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
838     update_allocator = TRUE;
839   } else {
840     allocator = NULL;
841     gst_allocation_params_init (&params);
842     update_allocator = FALSE;
843   }
844
845   if (update_allocator)
846     gst_query_set_nth_allocation_param (query, 0, allocator, &params);
847   else
848     gst_query_add_allocation_param (query, allocator, &params);
849   if (allocator)
850     gst_object_unref (allocator);
851
852   return TRUE;
853 }
854
855 static gboolean
856 gst_video_encoder_propose_allocation_default (GstVideoEncoder * encoder,
857     GstQuery * query)
858 {
859   GstCaps *caps;
860   GstVideoInfo info;
861   GstBufferPool *pool;
862   guint size;
863
864   gst_query_parse_allocation (query, &caps, NULL);
865
866   if (caps == NULL)
867     return FALSE;
868
869   if (!gst_video_info_from_caps (&info, caps))
870     return FALSE;
871
872   size = GST_VIDEO_INFO_SIZE (&info);
873
874   if (gst_query_get_n_allocation_pools (query) == 0) {
875     GstStructure *structure;
876     GstAllocator *allocator = NULL;
877     GstAllocationParams params = { 0, 15, 0, 0 };
878
879     if (gst_query_get_n_allocation_params (query) > 0)
880       gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
881     else
882       gst_query_add_allocation_param (query, allocator, &params);
883
884     pool = gst_video_buffer_pool_new ();
885
886     structure = gst_buffer_pool_get_config (pool);
887     gst_buffer_pool_config_set_params (structure, caps, size, 0, 0);
888     gst_buffer_pool_config_set_allocator (structure, allocator, &params);
889
890     if (allocator)
891       gst_object_unref (allocator);
892
893     if (!gst_buffer_pool_set_config (pool, structure))
894       goto config_failed;
895
896     gst_query_add_allocation_pool (query, pool, size, 0, 0);
897     gst_object_unref (pool);
898     gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
899   }
900
901   return TRUE;
902
903   /* ERRORS */
904 config_failed:
905   {
906     GST_ERROR_OBJECT (encoder, "failed to set config");
907     gst_object_unref (pool);
908     return FALSE;
909   }
910 }
911
912 static gboolean
913 gst_video_encoder_sink_query_default (GstVideoEncoder * encoder,
914     GstQuery * query)
915 {
916   GstPad *pad = GST_VIDEO_ENCODER_SINK_PAD (encoder);
917   gboolean res = FALSE;
918
919   switch (GST_QUERY_TYPE (query)) {
920     case GST_QUERY_CAPS:
921     {
922       GstCaps *filter, *caps;
923
924       gst_query_parse_caps (query, &filter);
925       caps = gst_video_encoder_sink_getcaps (encoder, filter);
926       gst_query_set_caps_result (query, caps);
927       gst_caps_unref (caps);
928       res = TRUE;
929       break;
930     }
931     case GST_QUERY_CONVERT:
932     {
933       GstFormat src_fmt, dest_fmt;
934       gint64 src_val, dest_val;
935
936       GST_DEBUG_OBJECT (encoder, "convert query");
937
938       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
939       GST_OBJECT_LOCK (encoder);
940       if (encoder->priv->input_state != NULL)
941         res = __gst_video_rawvideo_convert (encoder->priv->input_state,
942             src_fmt, src_val, &dest_fmt, &dest_val);
943       else
944         res = FALSE;
945       GST_OBJECT_UNLOCK (encoder);
946       if (!res)
947         goto error;
948       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
949       break;
950     }
951     case GST_QUERY_ALLOCATION:
952     {
953       GstVideoEncoderClass *klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
954
955       if (klass->propose_allocation)
956         res = klass->propose_allocation (encoder, query);
957       break;
958     }
959     default:
960       res = gst_pad_query_default (pad, GST_OBJECT (encoder), query);
961       break;
962   }
963   return res;
964
965 error:
966   GST_DEBUG_OBJECT (encoder, "query failed");
967   return res;
968 }
969
970 static gboolean
971 gst_video_encoder_sink_query (GstPad * pad, GstObject * parent,
972     GstQuery * query)
973 {
974   GstVideoEncoder *encoder;
975   GstVideoEncoderClass *encoder_class;
976   gboolean ret = FALSE;
977
978   encoder = GST_VIDEO_ENCODER (parent);
979   encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);
980
981   GST_DEBUG_OBJECT (encoder, "received query %d, %s", GST_QUERY_TYPE (query),
982       GST_QUERY_TYPE_NAME (query));
983
984   if (encoder_class->sink_query)
985     ret = encoder_class->sink_query (encoder, query);
986
987   return ret;
988 }
989
990 static void
991 gst_video_encoder_finalize (GObject * object)
992 {
993   GstVideoEncoder *encoder;
994
995   GST_DEBUG_OBJECT (object, "finalize");
996
997   encoder = GST_VIDEO_ENCODER (object);
998   g_rec_mutex_clear (&encoder->stream_lock);
999
1000   if (encoder->priv->allocator) {
1001     gst_object_unref (encoder->priv->allocator);
1002     encoder->priv->allocator = NULL;
1003   }
1004
1005   G_OBJECT_CLASS (parent_class)->finalize (object);
1006 }
1007
1008 static gboolean
1009 gst_video_encoder_push_event (GstVideoEncoder * encoder, GstEvent * event)
1010 {
1011   switch (GST_EVENT_TYPE (event)) {
1012     case GST_EVENT_SEGMENT:
1013     {
1014       GstSegment segment;
1015
1016       GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1017
1018       gst_event_copy_segment (event, &segment);
1019
1020       GST_DEBUG_OBJECT (encoder, "segment %" GST_SEGMENT_FORMAT, &segment);
1021
1022       if (segment.format != GST_FORMAT_TIME) {
1023         GST_DEBUG_OBJECT (encoder, "received non TIME segment");
1024         GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1025         break;
1026       }
1027
1028       if (encoder->priv->time_adjustment != GST_CLOCK_TIME_NONE) {
1029         segment.start += encoder->priv->time_adjustment;
1030         if (GST_CLOCK_TIME_IS_VALID (segment.position)) {
1031           segment.position += encoder->priv->time_adjustment;
1032         }
1033         if (GST_CLOCK_TIME_IS_VALID (segment.stop)) {
1034           segment.stop += encoder->priv->time_adjustment;
1035         }
1036       }
1037
1038       encoder->output_segment = segment;
1039       GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1040
1041       gst_event_unref (event);
1042       event = gst_event_new_segment (&encoder->output_segment);
1043
1044       break;
1045     }
1046     default:
1047       break;
1048   }
1049
1050   return gst_pad_push_event (encoder->srcpad, event);
1051 }
1052
1053 static GstEvent *
1054 gst_video_encoder_create_merged_tags_event (GstVideoEncoder * enc)
1055 {
1056   GstTagList *merged_tags;
1057
1058   GST_LOG_OBJECT (enc, "upstream : %" GST_PTR_FORMAT, enc->priv->upstream_tags);
1059   GST_LOG_OBJECT (enc, "encoder  : %" GST_PTR_FORMAT, enc->priv->tags);
1060   GST_LOG_OBJECT (enc, "mode     : %d", enc->priv->tags_merge_mode);
1061
1062   merged_tags =
1063       gst_tag_list_merge (enc->priv->upstream_tags, enc->priv->tags,
1064       enc->priv->tags_merge_mode);
1065
1066   GST_DEBUG_OBJECT (enc, "merged   : %" GST_PTR_FORMAT, merged_tags);
1067
1068   if (merged_tags == NULL)
1069     return NULL;
1070
1071   if (gst_tag_list_is_empty (merged_tags)) {
1072     gst_tag_list_unref (merged_tags);
1073     return NULL;
1074   }
1075
1076   return gst_event_new_tag (merged_tags);
1077 }
1078
1079 static inline void
1080 gst_video_encoder_check_and_push_tags (GstVideoEncoder * encoder)
1081 {
1082   if (encoder->priv->tags_changed) {
1083     GstEvent *tags_event;
1084
1085     tags_event = gst_video_encoder_create_merged_tags_event (encoder);
1086
1087     if (tags_event != NULL)
1088       gst_video_encoder_push_event (encoder, tags_event);
1089
1090     encoder->priv->tags_changed = FALSE;
1091   }
1092 }
1093
1094 static gboolean
1095 gst_video_encoder_sink_event_default (GstVideoEncoder * encoder,
1096     GstEvent * event)
1097 {
1098   GstVideoEncoderClass *encoder_class;
1099   gboolean ret = FALSE;
1100
1101   encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);
1102
1103   switch (GST_EVENT_TYPE (event)) {
1104     case GST_EVENT_CAPS:
1105     {
1106       GstCaps *caps;
1107
1108       gst_event_parse_caps (event, &caps);
1109       ret = gst_video_encoder_setcaps (encoder, caps);
1110
1111       gst_event_unref (event);
1112       event = NULL;
1113       break;
1114     }
1115     case GST_EVENT_EOS:
1116     {
1117       GstFlowReturn flow_ret;
1118
1119       GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1120
1121       if (encoder_class->finish) {
1122         flow_ret = encoder_class->finish (encoder);
1123       } else {
1124         flow_ret = GST_FLOW_OK;
1125       }
1126
1127       if (encoder->priv->current_frame_events) {
1128         GList *l;
1129
1130         for (l = g_list_last (encoder->priv->current_frame_events); l;
1131             l = g_list_previous (l)) {
1132           GstEvent *event = GST_EVENT (l->data);
1133
1134           gst_video_encoder_push_event (encoder, event);
1135         }
1136       }
1137       g_list_free (encoder->priv->current_frame_events);
1138       encoder->priv->current_frame_events = NULL;
1139
1140       gst_video_encoder_check_and_push_tags (encoder);
1141
1142       ret = (flow_ret == GST_FLOW_OK);
1143       GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1144       break;
1145     }
1146     case GST_EVENT_SEGMENT:
1147     {
1148       GstSegment segment;
1149
1150       GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1151
1152       gst_event_copy_segment (event, &segment);
1153
1154       GST_DEBUG_OBJECT (encoder, "segment %" GST_SEGMENT_FORMAT, &segment);
1155
1156       if (segment.format != GST_FORMAT_TIME) {
1157         GST_DEBUG_OBJECT (encoder, "received non TIME newsegment");
1158         GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1159         break;
1160       }
1161
1162       encoder->input_segment = segment;
1163       ret = TRUE;
1164       GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1165       break;
1166     }
1167     case GST_EVENT_CUSTOM_DOWNSTREAM:
1168     {
1169       if (gst_video_event_is_force_key_unit (event)) {
1170         GstClockTime running_time;
1171         gboolean all_headers;
1172         guint count;
1173
1174         if (gst_video_event_parse_downstream_force_key_unit (event,
1175                 NULL, NULL, &running_time, &all_headers, &count)) {
1176           ForcedKeyUnitEvent *fevt;
1177
1178           GST_OBJECT_LOCK (encoder);
1179           fevt = forced_key_unit_event_new (running_time, all_headers, count);
1180           g_queue_insert_sorted (&encoder->priv->force_key_unit, fevt,
1181               (GCompareDataFunc) forced_key_unit_event_compare, NULL);
1182           GST_OBJECT_UNLOCK (encoder);
1183
1184           GST_DEBUG_OBJECT (encoder,
1185               "force-key-unit event: running-time %" GST_TIME_FORMAT
1186               ", all_headers %d, count %u",
1187               GST_TIME_ARGS (running_time), all_headers, count);
1188         }
1189         gst_event_unref (event);
1190         event = NULL;
1191         ret = TRUE;
1192       }
1193       break;
1194     }
1195     case GST_EVENT_STREAM_START:
1196     {
1197       GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1198       /* Flush upstream tags after a STREAM_START */
1199       GST_DEBUG_OBJECT (encoder, "STREAM_START, clearing upstream tags");
1200       if (encoder->priv->upstream_tags) {
1201         gst_tag_list_unref (encoder->priv->upstream_tags);
1202         encoder->priv->upstream_tags = NULL;
1203         encoder->priv->tags_changed = TRUE;
1204       }
1205       GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1206       break;
1207     }
1208     case GST_EVENT_TAG:
1209     {
1210       GstTagList *tags;
1211
1212       gst_event_parse_tag (event, &tags);
1213
1214       if (gst_tag_list_get_scope (tags) == GST_TAG_SCOPE_STREAM) {
1215         GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1216         if (encoder->priv->upstream_tags != tags) {
1217           tags = gst_tag_list_copy (tags);
1218
1219           /* FIXME: make generic based on GST_TAG_FLAG_ENCODED */
1220           gst_tag_list_remove_tag (tags, GST_TAG_CODEC);
1221           gst_tag_list_remove_tag (tags, GST_TAG_AUDIO_CODEC);
1222           gst_tag_list_remove_tag (tags, GST_TAG_VIDEO_CODEC);
1223           gst_tag_list_remove_tag (tags, GST_TAG_SUBTITLE_CODEC);
1224           gst_tag_list_remove_tag (tags, GST_TAG_CONTAINER_FORMAT);
1225           gst_tag_list_remove_tag (tags, GST_TAG_BITRATE);
1226           gst_tag_list_remove_tag (tags, GST_TAG_NOMINAL_BITRATE);
1227           gst_tag_list_remove_tag (tags, GST_TAG_MAXIMUM_BITRATE);
1228           gst_tag_list_remove_tag (tags, GST_TAG_MINIMUM_BITRATE);
1229           gst_tag_list_remove_tag (tags, GST_TAG_ENCODER);
1230           gst_tag_list_remove_tag (tags, GST_TAG_ENCODER_VERSION);
1231
1232           if (encoder->priv->upstream_tags)
1233             gst_tag_list_unref (encoder->priv->upstream_tags);
1234           encoder->priv->upstream_tags = tags;
1235           GST_INFO_OBJECT (encoder, "upstream tags: %" GST_PTR_FORMAT, tags);
1236         }
1237         gst_event_unref (event);
1238         event = gst_video_encoder_create_merged_tags_event (encoder);
1239         GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1240         if (!event)
1241           ret = TRUE;
1242       }
1243       break;
1244     }
1245     case GST_EVENT_FLUSH_STOP:{
1246       GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1247       gst_video_encoder_flush (encoder);
1248       gst_segment_init (&encoder->input_segment, GST_FORMAT_TIME);
1249       gst_segment_init (&encoder->output_segment, GST_FORMAT_TIME);
1250       gst_video_encoder_reset (encoder, FALSE);
1251       GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1252       break;
1253     }
1254     default:
1255       break;
1256   }
1257
1258   /* Forward non-serialized events and EOS/FLUSH_STOP immediately.
1259    * For EOS this is required because no buffer or serialized event
1260    * will come after EOS and nothing could trigger another
1261    * _finish_frame() call.   *
1262    * If the subclass handles sending of EOS manually it can simply
1263    * not chain up to the parent class' event handler
1264    *
1265    * For FLUSH_STOP this is required because it is expected
1266    * to be forwarded immediately and no buffers are queued anyway.
1267    */
1268   if (event) {
1269     if (!GST_EVENT_IS_SERIALIZED (event)
1270         || GST_EVENT_TYPE (event) == GST_EVENT_EOS
1271         || GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
1272       ret = gst_video_encoder_push_event (encoder, event);
1273     } else {
1274       GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1275       encoder->priv->current_frame_events =
1276           g_list_prepend (encoder->priv->current_frame_events, event);
1277       GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1278       ret = TRUE;
1279     }
1280   }
1281
1282   return ret;
1283 }
1284
1285 static gboolean
1286 gst_video_encoder_sink_event (GstPad * pad, GstObject * parent,
1287     GstEvent * event)
1288 {
1289   GstVideoEncoder *enc;
1290   GstVideoEncoderClass *klass;
1291   gboolean ret = TRUE;
1292
1293   enc = GST_VIDEO_ENCODER (parent);
1294   klass = GST_VIDEO_ENCODER_GET_CLASS (enc);
1295
1296   GST_DEBUG_OBJECT (enc, "received event %d, %s", GST_EVENT_TYPE (event),
1297       GST_EVENT_TYPE_NAME (event));
1298
1299   if (klass->sink_event)
1300     ret = klass->sink_event (enc, event);
1301
1302   return ret;
1303 }
1304
1305 static gboolean
1306 gst_video_encoder_src_event_default (GstVideoEncoder * encoder,
1307     GstEvent * event)
1308 {
1309   gboolean ret = FALSE;
1310   GstVideoEncoderPrivate *priv = encoder->priv;
1311
1312   switch (GST_EVENT_TYPE (event)) {
1313     case GST_EVENT_CUSTOM_UPSTREAM:
1314     {
1315       if (gst_video_event_is_force_key_unit (event)) {
1316         GstClockTime running_time;
1317         gboolean all_headers;
1318         guint count;
1319
1320         if (gst_video_event_parse_upstream_force_key_unit (event,
1321                 &running_time, &all_headers, &count)) {
1322           ForcedKeyUnitEvent *fevt;
1323
1324           GST_OBJECT_LOCK (encoder);
1325           fevt = forced_key_unit_event_new (running_time, all_headers, count);
1326           g_queue_insert_sorted (&encoder->priv->force_key_unit, fevt,
1327               (GCompareDataFunc) forced_key_unit_event_compare, NULL);
1328           GST_OBJECT_UNLOCK (encoder);
1329
1330           GST_DEBUG_OBJECT (encoder,
1331               "force-key-unit event: running-time %" GST_TIME_FORMAT
1332               ", all_headers %d, count %u",
1333               GST_TIME_ARGS (running_time), all_headers, count);
1334         }
1335         gst_event_unref (event);
1336         event = NULL;
1337         ret = TRUE;
1338       }
1339       break;
1340     }
1341     case GST_EVENT_QOS:
1342     {
1343       GstQOSType type;
1344       gdouble proportion;
1345       GstClockTimeDiff diff;
1346       GstClockTime timestamp;
1347
1348       if (!g_atomic_int_get (&priv->qos_enabled))
1349         break;
1350
1351       gst_event_parse_qos (event, &type, &proportion, &diff, &timestamp);
1352
1353       GST_OBJECT_LOCK (encoder);
1354       priv->proportion = proportion;
1355       if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (timestamp))) {
1356         if (G_UNLIKELY (diff > 0)) {
1357           priv->earliest_time = timestamp + 2 * diff + priv->qos_frame_duration;
1358         } else {
1359           priv->earliest_time = timestamp + diff;
1360         }
1361       } else {
1362         priv->earliest_time = GST_CLOCK_TIME_NONE;
1363       }
1364       GST_OBJECT_UNLOCK (encoder);
1365
1366       GST_DEBUG_OBJECT (encoder,
1367           "got QoS %" GST_TIME_FORMAT ", %" GST_STIME_FORMAT ", %g",
1368           GST_TIME_ARGS (timestamp), GST_STIME_ARGS (diff), proportion);
1369
1370       ret = gst_pad_push_event (encoder->sinkpad, event);
1371       event = NULL;
1372       break;
1373     }
1374     default:
1375       break;
1376   }
1377
1378   if (event)
1379     ret =
1380         gst_pad_event_default (encoder->srcpad, GST_OBJECT_CAST (encoder),
1381         event);
1382
1383   return ret;
1384 }
1385
1386 static gboolean
1387 gst_video_encoder_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
1388 {
1389   GstVideoEncoder *encoder;
1390   GstVideoEncoderClass *klass;
1391   gboolean ret = FALSE;
1392
1393   encoder = GST_VIDEO_ENCODER (parent);
1394   klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
1395
1396   GST_LOG_OBJECT (encoder, "handling event: %" GST_PTR_FORMAT, event);
1397
1398   if (klass->src_event)
1399     ret = klass->src_event (encoder, event);
1400
1401   return ret;
1402 }
1403
1404 static gboolean
1405 gst_video_encoder_src_query_default (GstVideoEncoder * enc, GstQuery * query)
1406 {
1407   GstPad *pad = GST_VIDEO_ENCODER_SRC_PAD (enc);
1408   GstVideoEncoderPrivate *priv;
1409   gboolean res;
1410
1411   priv = enc->priv;
1412
1413   GST_LOG_OBJECT (enc, "handling query: %" GST_PTR_FORMAT, query);
1414
1415   switch (GST_QUERY_TYPE (query)) {
1416     case GST_QUERY_CONVERT:
1417     {
1418       GstFormat src_fmt, dest_fmt;
1419       gint64 src_val, dest_val;
1420
1421       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
1422       GST_OBJECT_LOCK (enc);
1423       res =
1424           __gst_video_encoded_video_convert (priv->bytes, priv->time, src_fmt,
1425           src_val, &dest_fmt, &dest_val);
1426       GST_OBJECT_UNLOCK (enc);
1427       if (!res)
1428         goto error;
1429       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1430       break;
1431     }
1432     case GST_QUERY_LATENCY:
1433     {
1434       gboolean live;
1435       GstClockTime min_latency, max_latency;
1436
1437       res = gst_pad_peer_query (enc->sinkpad, query);
1438       if (res) {
1439         gst_query_parse_latency (query, &live, &min_latency, &max_latency);
1440         GST_DEBUG_OBJECT (enc, "Peer latency: live %d, min %"
1441             GST_TIME_FORMAT " max %" GST_TIME_FORMAT, live,
1442             GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
1443
1444         GST_OBJECT_LOCK (enc);
1445         min_latency += priv->min_latency;
1446         if (max_latency == GST_CLOCK_TIME_NONE
1447             || enc->priv->max_latency == GST_CLOCK_TIME_NONE)
1448           max_latency = GST_CLOCK_TIME_NONE;
1449         else
1450           max_latency += enc->priv->max_latency;
1451         GST_OBJECT_UNLOCK (enc);
1452
1453         gst_query_set_latency (query, live, min_latency, max_latency);
1454       }
1455     }
1456       break;
1457     default:
1458       res = gst_pad_query_default (pad, GST_OBJECT (enc), query);
1459   }
1460   return res;
1461
1462 error:
1463   GST_DEBUG_OBJECT (enc, "query failed");
1464   return res;
1465 }
1466
1467 static gboolean
1468 gst_video_encoder_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
1469 {
1470   GstVideoEncoder *encoder;
1471   GstVideoEncoderClass *encoder_class;
1472   gboolean ret = FALSE;
1473
1474   encoder = GST_VIDEO_ENCODER (parent);
1475   encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);
1476
1477   GST_DEBUG_OBJECT (encoder, "received query %d, %s", GST_QUERY_TYPE (query),
1478       GST_QUERY_TYPE_NAME (query));
1479
1480   if (encoder_class->src_query)
1481     ret = encoder_class->src_query (encoder, query);
1482
1483   return ret;
1484 }
1485
1486 static GstVideoCodecFrame *
1487 gst_video_encoder_new_frame (GstVideoEncoder * encoder, GstBuffer * buf,
1488     GstClockTime pts, GstClockTime dts, GstClockTime duration)
1489 {
1490   GstVideoEncoderPrivate *priv = encoder->priv;
1491   GstVideoCodecFrame *frame;
1492
1493   frame = g_slice_new0 (GstVideoCodecFrame);
1494
1495   frame->ref_count = 1;
1496
1497   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1498   frame->system_frame_number = priv->system_frame_number;
1499   priv->system_frame_number++;
1500
1501   frame->presentation_frame_number = priv->presentation_frame_number;
1502   priv->presentation_frame_number++;
1503   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1504
1505   frame->events = priv->current_frame_events;
1506   priv->current_frame_events = NULL;
1507   frame->input_buffer = buf;
1508   frame->pts = pts;
1509   frame->dts = dts;
1510   frame->duration = duration;
1511   frame->abidata.ABI.ts = pts;
1512
1513   return frame;
1514 }
1515
1516
1517 static GstFlowReturn
1518 gst_video_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
1519 {
1520   GstVideoEncoder *encoder;
1521   GstVideoEncoderPrivate *priv;
1522   GstVideoEncoderClass *klass;
1523   GstVideoCodecFrame *frame;
1524   GstClockTime pts, duration;
1525   GstFlowReturn ret = GST_FLOW_OK;
1526   guint64 start, stop, cstart, cstop;
1527
1528   encoder = GST_VIDEO_ENCODER (parent);
1529   priv = encoder->priv;
1530   klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
1531
1532   g_return_val_if_fail (klass->handle_frame != NULL, GST_FLOW_ERROR);
1533
1534   if (!encoder->priv->input_state)
1535     goto not_negotiated;
1536
1537   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1538
1539   pts = GST_BUFFER_PTS (buf);
1540   duration = GST_BUFFER_DURATION (buf);
1541
1542   GST_LOG_OBJECT (encoder,
1543       "received buffer of size %" G_GSIZE_FORMAT " with PTS %" GST_TIME_FORMAT
1544       ", DTS %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT,
1545       gst_buffer_get_size (buf), GST_TIME_ARGS (pts),
1546       GST_TIME_ARGS (GST_BUFFER_DTS (buf)), GST_TIME_ARGS (duration));
1547
1548   start = pts;
1549   if (GST_CLOCK_TIME_IS_VALID (duration))
1550     stop = start + duration;
1551   else
1552     stop = GST_CLOCK_TIME_NONE;
1553
1554   /* Drop buffers outside of segment */
1555   if (!gst_segment_clip (&encoder->input_segment,
1556           GST_FORMAT_TIME, start, stop, &cstart, &cstop)) {
1557     GST_DEBUG_OBJECT (encoder, "clipping to segment dropped frame");
1558     gst_buffer_unref (buf);
1559     goto done;
1560   }
1561
1562   if (GST_CLOCK_TIME_IS_VALID (cstop))
1563     duration = cstop - cstart;
1564   else
1565     duration = GST_CLOCK_TIME_NONE;
1566
1567   if (priv->min_pts != GST_CLOCK_TIME_NONE
1568       && priv->time_adjustment == GST_CLOCK_TIME_NONE) {
1569     if (cstart < priv->min_pts) {
1570       priv->time_adjustment = priv->min_pts - cstart;
1571     }
1572   }
1573
1574   if (priv->time_adjustment != GST_CLOCK_TIME_NONE) {
1575     cstart += priv->time_adjustment;
1576   }
1577
1578   /* incoming DTS is not really relevant and does not make sense anyway,
1579    * so pass along _NONE and maybe come up with something better later on */
1580   frame = gst_video_encoder_new_frame (encoder, buf, cstart,
1581       GST_CLOCK_TIME_NONE, duration);
1582
1583   GST_OBJECT_LOCK (encoder);
1584   if (priv->force_key_unit.head) {
1585     GList *l;
1586     GstClockTime running_time;
1587     gboolean throttled, have_fevt = FALSE, have_pending_none_fevt = FALSE;
1588     GQueue matching_fevt = G_QUEUE_INIT;
1589
1590     running_time =
1591         gst_segment_to_running_time (&encoder->output_segment, GST_FORMAT_TIME,
1592         cstart);
1593
1594     throttled = (priv->min_force_key_unit_interval != 0 &&
1595         priv->min_force_key_unit_interval != GST_CLOCK_TIME_NONE &&
1596         ((priv->last_force_key_unit_request != GST_CLOCK_TIME_NONE &&
1597                 priv->last_force_key_unit_request +
1598                 priv->min_force_key_unit_interval > running_time)
1599             || (priv->last_key_unit != GST_CLOCK_TIME_NONE
1600                 && priv->last_key_unit + priv->min_force_key_unit_interval >
1601                 running_time)));
1602
1603     for (l = priv->force_key_unit.head; l && (!throttled || !have_fevt);
1604         l = l->next) {
1605       ForcedKeyUnitEvent *fevt = l->data;
1606
1607       /* Skip pending keyunits */
1608       if (fevt->pending) {
1609         if (fevt->running_time == GST_CLOCK_TIME_NONE)
1610           have_pending_none_fevt = TRUE;
1611         continue;
1612       }
1613
1614       /* Simple case, keyunit ASAP */
1615       if (fevt->running_time == GST_CLOCK_TIME_NONE) {
1616         have_fevt = TRUE;
1617         if (!throttled)
1618           g_queue_push_tail (&matching_fevt, fevt);
1619         continue;
1620       }
1621
1622       /* Event for before this frame */
1623       if (fevt->running_time <= running_time) {
1624         have_fevt = TRUE;
1625         if (!throttled)
1626           g_queue_push_tail (&matching_fevt, fevt);
1627         continue;
1628       }
1629
1630       /* Otherwise all following events are in the future */
1631       break;
1632     }
1633
1634     if (throttled && have_fevt) {
1635       GstClockTime last_time;
1636
1637       if (priv->last_force_key_unit_request != GST_CLOCK_TIME_NONE &&
1638           priv->last_force_key_unit_request +
1639           priv->min_force_key_unit_interval > running_time) {
1640         last_time = priv->last_force_key_unit_request;
1641       } else {
1642         last_time = priv->last_key_unit;
1643       }
1644
1645       GST_DEBUG_OBJECT (encoder,
1646           "Not requesting a new key unit yet due to throttling (%"
1647           GST_TIME_FORMAT " + %" GST_TIME_FORMAT " > %" GST_TIME_FORMAT,
1648           GST_TIME_ARGS (last_time),
1649           GST_TIME_ARGS (priv->min_force_key_unit_interval),
1650           GST_TIME_ARGS (running_time));
1651       g_queue_clear (&matching_fevt);
1652     }
1653
1654     if (matching_fevt.length > 0) {
1655       ForcedKeyUnitEvent *fevt;
1656       gboolean all_headers = FALSE;
1657       gboolean force_keyunit = FALSE;
1658
1659       while ((fevt = g_queue_pop_head (&matching_fevt))) {
1660         fevt->pending = TRUE;
1661
1662         if ((fevt->running_time == GST_CLOCK_TIME_NONE
1663                 && have_pending_none_fevt)
1664             || (priv->last_force_key_unit_request != GST_CLOCK_TIME_NONE
1665                 && fevt->running_time != GST_CLOCK_TIME_NONE
1666                 && fevt->running_time <= priv->last_force_key_unit_request) ||
1667             (priv->last_key_unit != GST_CLOCK_TIME_NONE
1668                 && fevt->running_time != GST_CLOCK_TIME_NONE
1669                 && fevt->running_time <= priv->last_key_unit)) {
1670           GST_DEBUG_OBJECT (encoder,
1671               "Not requesting another key unit at running time %"
1672               GST_TIME_FORMAT, GST_TIME_ARGS (fevt->running_time));
1673         } else {
1674           force_keyunit = TRUE;
1675           fevt->frame_id = frame->system_frame_number;
1676           if (fevt->all_headers)
1677             all_headers = TRUE;
1678         }
1679       }
1680
1681       if (force_keyunit) {
1682         GST_DEBUG_OBJECT (encoder,
1683             "Forcing a key unit at running time %" GST_TIME_FORMAT,
1684             GST_TIME_ARGS (running_time));
1685
1686         GST_VIDEO_CODEC_FRAME_SET_FORCE_KEYFRAME (frame);
1687         if (all_headers)
1688           GST_VIDEO_CODEC_FRAME_SET_FORCE_KEYFRAME_HEADERS (frame);
1689         priv->last_force_key_unit_request = running_time;
1690       }
1691     }
1692   }
1693   GST_OBJECT_UNLOCK (encoder);
1694
1695   g_queue_push_tail (&priv->frames, gst_video_codec_frame_ref (frame));
1696
1697   /* new data, more finish needed */
1698   priv->drained = FALSE;
1699
1700   GST_LOG_OBJECT (encoder, "passing frame pfn %d to subclass",
1701       frame->presentation_frame_number);
1702
1703   frame->deadline =
1704       gst_segment_to_running_time (&encoder->input_segment, GST_FORMAT_TIME,
1705       frame->pts);
1706
1707   ret = klass->handle_frame (encoder, frame);
1708
1709 done:
1710   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1711
1712   return ret;
1713
1714   /* ERRORS */
1715 not_negotiated:
1716   {
1717     GST_ELEMENT_ERROR (encoder, CORE, NEGOTIATION, (NULL),
1718         ("encoder not initialized"));
1719     gst_buffer_unref (buf);
1720     return GST_FLOW_NOT_NEGOTIATED;
1721   }
1722 }
1723
1724 static GstStateChangeReturn
1725 gst_video_encoder_change_state (GstElement * element, GstStateChange transition)
1726 {
1727   GstVideoEncoder *encoder;
1728   GstVideoEncoderClass *encoder_class;
1729   GstStateChangeReturn ret;
1730
1731   encoder = GST_VIDEO_ENCODER (element);
1732   encoder_class = GST_VIDEO_ENCODER_GET_CLASS (element);
1733
1734   switch (transition) {
1735     case GST_STATE_CHANGE_NULL_TO_READY:
1736       /* open device/library if needed */
1737       if (encoder_class->open && !encoder_class->open (encoder))
1738         goto open_failed;
1739       break;
1740     case GST_STATE_CHANGE_READY_TO_PAUSED:
1741       GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1742       gst_video_encoder_reset (encoder, TRUE);
1743       GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1744
1745       /* Initialize device/library if needed */
1746       if (encoder_class->start && !encoder_class->start (encoder))
1747         goto start_failed;
1748       break;
1749     default:
1750       break;
1751   }
1752
1753   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1754
1755   switch (transition) {
1756     case GST_STATE_CHANGE_PAUSED_TO_READY:{
1757       gboolean stopped = TRUE;
1758
1759       if (encoder_class->stop)
1760         stopped = encoder_class->stop (encoder);
1761
1762       GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1763       gst_video_encoder_reset (encoder, TRUE);
1764       GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1765
1766       if (!stopped)
1767         goto stop_failed;
1768       break;
1769     }
1770     case GST_STATE_CHANGE_READY_TO_NULL:
1771       /* close device/library if needed */
1772       if (encoder_class->close && !encoder_class->close (encoder))
1773         goto close_failed;
1774       break;
1775     default:
1776       break;
1777   }
1778
1779   return ret;
1780
1781   /* Errors */
1782
1783 open_failed:
1784   {
1785     GST_ELEMENT_ERROR (encoder, LIBRARY, INIT, (NULL),
1786         ("Failed to open encoder"));
1787     return GST_STATE_CHANGE_FAILURE;
1788   }
1789
1790 start_failed:
1791   {
1792     GST_ELEMENT_ERROR (encoder, LIBRARY, INIT, (NULL),
1793         ("Failed to start encoder"));
1794     return GST_STATE_CHANGE_FAILURE;
1795   }
1796
1797 stop_failed:
1798   {
1799     GST_ELEMENT_ERROR (encoder, LIBRARY, INIT, (NULL),
1800         ("Failed to stop encoder"));
1801     return GST_STATE_CHANGE_FAILURE;
1802   }
1803
1804 close_failed:
1805   {
1806     GST_ELEMENT_ERROR (encoder, LIBRARY, INIT, (NULL),
1807         ("Failed to close encoder"));
1808     return GST_STATE_CHANGE_FAILURE;
1809   }
1810 }
1811
1812 static gboolean
1813 gst_video_encoder_negotiate_default (GstVideoEncoder * encoder)
1814 {
1815   GstVideoEncoderClass *klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
1816   GstAllocator *allocator;
1817   GstAllocationParams params;
1818   gboolean ret = TRUE;
1819   GstVideoCodecState *state = encoder->priv->output_state;
1820   GstVideoInfo *info = &state->info;
1821   GstQuery *query = NULL;
1822   GstVideoCodecFrame *frame;
1823   GstCaps *prevcaps;
1824   gchar *colorimetry;
1825
1826   g_return_val_if_fail (state->caps != NULL, FALSE);
1827
1828   if (encoder->priv->output_state_changed) {
1829     GstStructure *out_struct;
1830
1831     state->caps = gst_caps_make_writable (state->caps);
1832
1833     /* Fill caps */
1834     gst_caps_set_simple (state->caps, "width", G_TYPE_INT, info->width,
1835         "height", G_TYPE_INT, info->height,
1836         "pixel-aspect-ratio", GST_TYPE_FRACTION,
1837         info->par_n, info->par_d, NULL);
1838     if (info->flags & GST_VIDEO_FLAG_VARIABLE_FPS && info->fps_n != 0) {
1839       /* variable fps with a max-framerate */
1840       gst_caps_set_simple (state->caps, "framerate", GST_TYPE_FRACTION, 0, 1,
1841           "max-framerate", GST_TYPE_FRACTION, info->fps_n, info->fps_d, NULL);
1842     } else {
1843       /* no variable fps or no max-framerate */
1844       gst_caps_set_simple (state->caps, "framerate", GST_TYPE_FRACTION,
1845           info->fps_n, info->fps_d, NULL);
1846     }
1847     if (state->codec_data)
1848       gst_caps_set_simple (state->caps, "codec_data", GST_TYPE_BUFFER,
1849           state->codec_data, NULL);
1850
1851     gst_caps_set_simple (state->caps, "interlace-mode", G_TYPE_STRING,
1852         gst_video_interlace_mode_to_string (info->interlace_mode), NULL);
1853     if (info->interlace_mode == GST_VIDEO_INTERLACE_MODE_INTERLEAVED &&
1854         GST_VIDEO_INFO_FIELD_ORDER (info) != GST_VIDEO_FIELD_ORDER_UNKNOWN)
1855       gst_caps_set_simple (state->caps, "field-order", G_TYPE_STRING,
1856           gst_video_field_order_to_string (GST_VIDEO_INFO_FIELD_ORDER (info)),
1857           NULL);
1858
1859     colorimetry = gst_video_colorimetry_to_string (&info->colorimetry);
1860     if (colorimetry)
1861       gst_caps_set_simple (state->caps, "colorimetry", G_TYPE_STRING,
1862           colorimetry, NULL);
1863     g_free (colorimetry);
1864
1865     if (info->chroma_site != GST_VIDEO_CHROMA_SITE_UNKNOWN) {
1866       gchar *chroma_site = gst_video_chroma_site_to_string (info->chroma_site);
1867
1868       if (!chroma_site) {
1869         GST_WARNING ("Couldn't convert chroma-site 0x%x to string",
1870             info->chroma_site);
1871       } else {
1872         gst_caps_set_simple (state->caps,
1873             "chroma-site", G_TYPE_STRING, chroma_site, NULL);
1874         g_free (chroma_site);
1875       }
1876     }
1877
1878     if (GST_VIDEO_INFO_MULTIVIEW_MODE (info) != GST_VIDEO_MULTIVIEW_MODE_NONE) {
1879       const gchar *caps_mview_mode =
1880           gst_video_multiview_mode_to_caps_string (GST_VIDEO_INFO_MULTIVIEW_MODE
1881           (info));
1882
1883       gst_caps_set_simple (state->caps, "multiview-mode", G_TYPE_STRING,
1884           caps_mview_mode, "multiview-flags", GST_TYPE_VIDEO_MULTIVIEW_FLAGSET,
1885           GST_VIDEO_INFO_MULTIVIEW_FLAGS (info), GST_FLAG_SET_MASK_EXACT, NULL);
1886     }
1887
1888     out_struct = gst_caps_get_structure (state->caps, 0);
1889
1890     /* forward upstream mastering display info and content light level
1891      * if subclass didn't set */
1892     if (state->mastering_display_info &&
1893         !gst_structure_has_field (out_struct, "mastering-display-info")) {
1894       gst_video_mastering_display_info_add_to_caps
1895           (state->mastering_display_info, state->caps);
1896     }
1897
1898     if (state->content_light_level &&
1899         !gst_structure_has_field (out_struct, "content-light-level")) {
1900       gst_video_content_light_level_add_to_caps (state->content_light_level,
1901           state->caps);
1902     }
1903
1904     encoder->priv->output_state_changed = FALSE;
1905   }
1906
1907   if (state->allocation_caps == NULL)
1908     state->allocation_caps = gst_caps_ref (state->caps);
1909
1910   /* Push all pending pre-caps events of the oldest frame before
1911    * setting caps */
1912   frame = encoder->priv->frames.head ? encoder->priv->frames.head->data : NULL;
1913   if (frame || encoder->priv->current_frame_events) {
1914     GList **events, *l;
1915
1916     if (frame) {
1917       events = &frame->events;
1918     } else {
1919       events = &encoder->priv->current_frame_events;
1920     }
1921
1922     for (l = g_list_last (*events); l;) {
1923       GstEvent *event = GST_EVENT (l->data);
1924       GList *tmp;
1925
1926       if (GST_EVENT_TYPE (event) < GST_EVENT_CAPS) {
1927         gst_video_encoder_push_event (encoder, event);
1928         tmp = l;
1929         l = l->prev;
1930         *events = g_list_delete_link (*events, tmp);
1931       } else {
1932         l = l->prev;
1933       }
1934     }
1935   }
1936
1937   prevcaps = gst_pad_get_current_caps (encoder->srcpad);
1938   if (!prevcaps || !gst_caps_is_equal (prevcaps, state->caps))
1939     ret = gst_pad_set_caps (encoder->srcpad, state->caps);
1940   else
1941     ret = TRUE;
1942   if (prevcaps)
1943     gst_caps_unref (prevcaps);
1944
1945   if (!ret)
1946     goto done;
1947
1948   query = gst_query_new_allocation (state->allocation_caps, TRUE);
1949   if (!gst_pad_peer_query (encoder->srcpad, query)) {
1950     GST_DEBUG_OBJECT (encoder, "didn't get downstream ALLOCATION hints");
1951   }
1952
1953   g_assert (klass->decide_allocation != NULL);
1954   ret = klass->decide_allocation (encoder, query);
1955
1956   GST_DEBUG_OBJECT (encoder, "ALLOCATION (%d) params: %" GST_PTR_FORMAT, ret,
1957       query);
1958
1959   if (!ret)
1960     goto no_decide_allocation;
1961
1962   /* we got configuration from our peer or the decide_allocation method,
1963    * parse them */
1964   if (gst_query_get_n_allocation_params (query) > 0) {
1965     gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
1966   } else {
1967     allocator = NULL;
1968     gst_allocation_params_init (&params);
1969   }
1970
1971   if (encoder->priv->allocator)
1972     gst_object_unref (encoder->priv->allocator);
1973   encoder->priv->allocator = allocator;
1974   encoder->priv->params = params;
1975
1976 done:
1977   if (query)
1978     gst_query_unref (query);
1979
1980   return ret;
1981
1982   /* Errors */
1983 no_decide_allocation:
1984   {
1985     GST_WARNING_OBJECT (encoder, "Subclass failed to decide allocation");
1986     goto done;
1987   }
1988 }
1989
1990 static gboolean
1991 gst_video_encoder_negotiate_unlocked (GstVideoEncoder * encoder)
1992 {
1993   GstVideoEncoderClass *klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
1994   gboolean ret = TRUE;
1995
1996   if (G_LIKELY (klass->negotiate))
1997     ret = klass->negotiate (encoder);
1998
1999   return ret;
2000 }
2001
2002 /**
2003  * gst_video_encoder_negotiate:
2004  * @encoder: a #GstVideoEncoder
2005  *
2006  * Negotiate with downstream elements to currently configured #GstVideoCodecState.
2007  * Unmark GST_PAD_FLAG_NEED_RECONFIGURE in any case. But mark it again if
2008  * negotiate fails.
2009  *
2010  * Returns: %TRUE if the negotiation succeeded, else %FALSE.
2011  */
2012 gboolean
2013 gst_video_encoder_negotiate (GstVideoEncoder * encoder)
2014 {
2015   GstVideoEncoderClass *klass;
2016   gboolean ret = TRUE;
2017
2018   g_return_val_if_fail (GST_IS_VIDEO_ENCODER (encoder), FALSE);
2019   g_return_val_if_fail (encoder->priv->output_state, FALSE);
2020
2021   klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
2022
2023   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2024   gst_pad_check_reconfigure (encoder->srcpad);
2025   if (klass->negotiate) {
2026     ret = klass->negotiate (encoder);
2027     if (!ret)
2028       gst_pad_mark_reconfigure (encoder->srcpad);
2029   }
2030   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2031
2032   return ret;
2033 }
2034
2035 /**
2036  * gst_video_encoder_allocate_output_buffer:
2037  * @encoder: a #GstVideoEncoder
2038  * @size: size of the buffer
2039  *
2040  * Helper function that allocates a buffer to hold an encoded video frame
2041  * for @encoder's current #GstVideoCodecState.
2042  *
2043  * Returns: (transfer full): allocated buffer
2044  */
2045 GstBuffer *
2046 gst_video_encoder_allocate_output_buffer (GstVideoEncoder * encoder, gsize size)
2047 {
2048   GstBuffer *buffer;
2049   gboolean needs_reconfigure = FALSE;
2050
2051   g_return_val_if_fail (size > 0, NULL);
2052
2053   GST_DEBUG ("alloc src buffer");
2054
2055   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2056   needs_reconfigure = gst_pad_check_reconfigure (encoder->srcpad);
2057   if (G_UNLIKELY (encoder->priv->output_state_changed
2058           || (encoder->priv->output_state && needs_reconfigure))) {
2059     if (!gst_video_encoder_negotiate_unlocked (encoder)) {
2060       GST_DEBUG_OBJECT (encoder, "Failed to negotiate, fallback allocation");
2061       gst_pad_mark_reconfigure (encoder->srcpad);
2062       goto fallback;
2063     }
2064   }
2065
2066   buffer =
2067       gst_buffer_new_allocate (encoder->priv->allocator, size,
2068       &encoder->priv->params);
2069   if (!buffer) {
2070     GST_INFO_OBJECT (encoder, "couldn't allocate output buffer");
2071     goto fallback;
2072   }
2073
2074   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2075
2076   return buffer;
2077
2078 fallback:
2079   buffer = gst_buffer_new_allocate (NULL, size, NULL);
2080
2081   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2082
2083   return buffer;
2084 }
2085
2086 /**
2087  * gst_video_encoder_allocate_output_frame:
2088  * @encoder: a #GstVideoEncoder
2089  * @frame: a #GstVideoCodecFrame
2090  * @size: size of the buffer
2091  *
2092  * Helper function that allocates a buffer to hold an encoded video frame for @encoder's
2093  * current #GstVideoCodecState.  Subclass should already have configured video
2094  * state and set src pad caps.
2095  *
2096  * The buffer allocated here is owned by the frame and you should only
2097  * keep references to the frame, not the buffer.
2098  *
2099  * Returns: %GST_FLOW_OK if an output buffer could be allocated
2100  */
2101 GstFlowReturn
2102 gst_video_encoder_allocate_output_frame (GstVideoEncoder *
2103     encoder, GstVideoCodecFrame * frame, gsize size)
2104 {
2105   gboolean needs_reconfigure = FALSE;
2106
2107   g_return_val_if_fail (frame->output_buffer == NULL, GST_FLOW_ERROR);
2108
2109   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2110   needs_reconfigure = gst_pad_check_reconfigure (encoder->srcpad);
2111   if (G_UNLIKELY (encoder->priv->output_state_changed
2112           || (encoder->priv->output_state && needs_reconfigure))) {
2113     if (!gst_video_encoder_negotiate_unlocked (encoder)) {
2114       GST_DEBUG_OBJECT (encoder, "Failed to negotiate, fallback allocation");
2115       gst_pad_mark_reconfigure (encoder->srcpad);
2116     }
2117   }
2118
2119   GST_LOG_OBJECT (encoder, "alloc buffer size %" G_GSIZE_FORMAT, size);
2120
2121   frame->output_buffer =
2122       gst_buffer_new_allocate (encoder->priv->allocator, size,
2123       &encoder->priv->params);
2124
2125   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2126
2127   return frame->output_buffer ? GST_FLOW_OK : GST_FLOW_ERROR;
2128 }
2129
2130 static void
2131 gst_video_encoder_release_frame (GstVideoEncoder * enc,
2132     GstVideoCodecFrame * frame)
2133 {
2134   GList *link;
2135
2136   /* unref once from the list */
2137   link = g_queue_find (&enc->priv->frames, frame);
2138   if (link) {
2139     gst_video_codec_frame_unref (frame);
2140     g_queue_delete_link (&enc->priv->frames, link);
2141   }
2142   /* unref because this function takes ownership */
2143   gst_video_codec_frame_unref (frame);
2144 }
2145
2146 static gboolean
2147 gst_video_encoder_transform_meta_default (GstVideoEncoder *
2148     encoder, GstVideoCodecFrame * frame, GstMeta * meta)
2149 {
2150   const GstMetaInfo *info = meta->info;
2151   const gchar *const *tags;
2152   const gchar *const supported_tags[] = {
2153     GST_META_TAG_VIDEO_STR,
2154     GST_META_TAG_VIDEO_ORIENTATION_STR,
2155     GST_META_TAG_VIDEO_SIZE_STR,
2156     NULL,
2157   };
2158
2159   tags = gst_meta_api_type_get_tags (info->api);
2160
2161   if (!tags)
2162     return TRUE;
2163
2164   while (*tags) {
2165     if (!g_strv_contains (supported_tags, *tags))
2166       return FALSE;
2167     tags++;
2168   }
2169
2170   return TRUE;
2171 }
2172
2173 typedef struct
2174 {
2175   GstVideoEncoder *encoder;
2176   GstVideoCodecFrame *frame;
2177 } CopyMetaData;
2178
2179 static gboolean
2180 foreach_metadata (GstBuffer * inbuf, GstMeta ** meta, gpointer user_data)
2181 {
2182   CopyMetaData *data = user_data;
2183   GstVideoEncoder *encoder = data->encoder;
2184   GstVideoEncoderClass *klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
2185   GstVideoCodecFrame *frame = data->frame;
2186   const GstMetaInfo *info = (*meta)->info;
2187   gboolean do_copy = FALSE;
2188
2189   if (gst_meta_api_type_has_tag (info->api, _gst_meta_tag_memory)) {
2190     /* never call the transform_meta with memory specific metadata */
2191     GST_DEBUG_OBJECT (encoder, "not copying memory specific metadata %s",
2192         g_type_name (info->api));
2193     do_copy = FALSE;
2194   } else if (klass->transform_meta) {
2195     do_copy = klass->transform_meta (encoder, frame, *meta);
2196     GST_DEBUG_OBJECT (encoder, "transformed metadata %s: copy: %d",
2197         g_type_name (info->api), do_copy);
2198   }
2199
2200   /* we only copy metadata when the subclass implemented a transform_meta
2201    * function and when it returns %TRUE */
2202   if (do_copy && info->transform_func) {
2203     GstMetaTransformCopy copy_data = { FALSE, 0, -1 };
2204     GST_DEBUG_OBJECT (encoder, "copy metadata %s", g_type_name (info->api));
2205     /* simply copy then */
2206     info->transform_func (frame->output_buffer, *meta, inbuf,
2207         _gst_meta_transform_copy, &copy_data);
2208   }
2209   return TRUE;
2210 }
2211
2212 static void
2213 gst_video_encoder_drop_frame (GstVideoEncoder * enc, GstVideoCodecFrame * frame)
2214 {
2215   GstVideoEncoderPrivate *priv = enc->priv;
2216   GstClockTime stream_time, jitter, earliest_time, qostime, timestamp;
2217   GstSegment *segment;
2218   GstMessage *qos_msg;
2219   gdouble proportion;
2220
2221   GST_DEBUG_OBJECT (enc, "dropping frame %" GST_TIME_FORMAT,
2222       GST_TIME_ARGS (frame->pts));
2223
2224   priv->dropped++;
2225
2226   /* post QoS message */
2227   GST_OBJECT_LOCK (enc);
2228   proportion = priv->proportion;
2229   earliest_time = priv->earliest_time;
2230   GST_OBJECT_UNLOCK (enc);
2231
2232   timestamp = frame->pts;
2233   segment = &enc->output_segment;
2234   if (G_UNLIKELY (segment->format == GST_FORMAT_UNDEFINED))
2235     segment = &enc->input_segment;
2236   stream_time =
2237       gst_segment_to_stream_time (segment, GST_FORMAT_TIME, timestamp);
2238   qostime = gst_segment_to_running_time (segment, GST_FORMAT_TIME, timestamp);
2239   jitter = GST_CLOCK_DIFF (qostime, earliest_time);
2240   qos_msg =
2241       gst_message_new_qos (GST_OBJECT_CAST (enc), FALSE, qostime, stream_time,
2242       timestamp, GST_CLOCK_TIME_NONE);
2243   gst_message_set_qos_values (qos_msg, jitter, proportion, 1000000);
2244   gst_message_set_qos_stats (qos_msg, GST_FORMAT_BUFFERS,
2245       priv->processed, priv->dropped);
2246   gst_element_post_message (GST_ELEMENT_CAST (enc), qos_msg);
2247 }
2248
2249 static GstFlowReturn
2250 gst_video_encoder_can_push_unlocked (GstVideoEncoder * encoder)
2251 {
2252   GstVideoEncoderPrivate *priv = encoder->priv;
2253   gboolean needs_reconfigure;
2254
2255   needs_reconfigure = gst_pad_check_reconfigure (encoder->srcpad);
2256   if (G_UNLIKELY (priv->output_state_changed || (priv->output_state
2257               && needs_reconfigure))) {
2258     if (!gst_video_encoder_negotiate_unlocked (encoder)) {
2259       gst_pad_mark_reconfigure (encoder->srcpad);
2260       if (GST_PAD_IS_FLUSHING (encoder->srcpad))
2261         return GST_FLOW_FLUSHING;
2262       else
2263         return GST_FLOW_NOT_NEGOTIATED;
2264     }
2265   }
2266
2267   if (G_UNLIKELY (priv->output_state == NULL)) {
2268     GST_ERROR_OBJECT (encoder, "Output state was not configured");
2269     GST_ELEMENT_ERROR (encoder, LIBRARY, FAILED,
2270         ("Output state was not configured"), (NULL));
2271     return GST_FLOW_ERROR;
2272   }
2273
2274   return GST_FLOW_OK;
2275 }
2276
2277 static void
2278 gst_video_encoder_push_pending_unlocked (GstVideoEncoder * encoder,
2279     GstVideoCodecFrame * frame)
2280 {
2281   GstVideoEncoderPrivate *priv = encoder->priv;
2282   GList *l;
2283
2284   /* Push all pending events that arrived before this frame */
2285   for (l = priv->frames.head; l; l = l->next) {
2286     GstVideoCodecFrame *tmp = l->data;
2287
2288     if (tmp->events) {
2289       GList *k;
2290
2291       for (k = g_list_last (tmp->events); k; k = k->prev)
2292         gst_video_encoder_push_event (encoder, k->data);
2293       g_list_free (tmp->events);
2294       tmp->events = NULL;
2295     }
2296
2297     if (tmp == frame)
2298       break;
2299   }
2300
2301   gst_video_encoder_check_and_push_tags (encoder);
2302 }
2303
2304 static void
2305 gst_video_encoder_infer_dts_unlocked (GstVideoEncoder * encoder,
2306     GstVideoCodecFrame * frame)
2307 {
2308   /* DTS is expected to be monotonously increasing,
2309    * so a good guess is the lowest unsent PTS (all being OK) */
2310   GstVideoEncoderPrivate *priv = encoder->priv;
2311   GList *l;
2312   GstClockTime min_ts = GST_CLOCK_TIME_NONE;
2313   GstVideoCodecFrame *oframe = NULL;
2314   gboolean seen_none = FALSE;
2315
2316   /* some maintenance regardless */
2317   for (l = priv->frames.head; l; l = l->next) {
2318     GstVideoCodecFrame *tmp = l->data;
2319
2320     if (!GST_CLOCK_TIME_IS_VALID (tmp->abidata.ABI.ts)) {
2321       seen_none = TRUE;
2322       continue;
2323     }
2324
2325     if (!GST_CLOCK_TIME_IS_VALID (min_ts) || tmp->abidata.ABI.ts < min_ts) {
2326       min_ts = tmp->abidata.ABI.ts;
2327       oframe = tmp;
2328     }
2329   }
2330   /* save a ts if needed */
2331   if (oframe && oframe != frame) {
2332     oframe->abidata.ABI.ts = frame->abidata.ABI.ts;
2333   }
2334
2335   /* and set if needed */
2336   if (!GST_CLOCK_TIME_IS_VALID (frame->dts) && !seen_none) {
2337     frame->dts = min_ts;
2338     GST_DEBUG_OBJECT (encoder,
2339         "no valid DTS, using oldest PTS %" GST_TIME_FORMAT,
2340         GST_TIME_ARGS (frame->pts));
2341   }
2342 }
2343
2344 static void
2345 gst_video_encoder_send_header_unlocked (GstVideoEncoder * encoder,
2346     gboolean * discont, gboolean key_unit)
2347 {
2348   GstVideoEncoderPrivate *priv = encoder->priv;
2349
2350   if (G_UNLIKELY (priv->new_headers)) {
2351     GList *tmp;
2352
2353     GST_DEBUG_OBJECT (encoder, "Sending headers");
2354
2355     /* First make all buffers metadata-writable */
2356     for (tmp = priv->headers; tmp; tmp = tmp->next) {
2357       GstBuffer *tmpbuf = GST_BUFFER (tmp->data);
2358
2359       tmp->data = tmpbuf = gst_buffer_make_writable (tmpbuf);
2360
2361       GST_OBJECT_LOCK (encoder);
2362       priv->bytes += gst_buffer_get_size (tmpbuf);
2363       GST_OBJECT_UNLOCK (encoder);
2364
2365       if (G_UNLIKELY (key_unit)) {
2366         key_unit = FALSE;
2367         GST_BUFFER_FLAG_UNSET (tmpbuf, GST_BUFFER_FLAG_DELTA_UNIT);
2368       } else {
2369         GST_BUFFER_FLAG_SET (tmpbuf, GST_BUFFER_FLAG_DELTA_UNIT);
2370       }
2371
2372       if (G_UNLIKELY (*discont)) {
2373         GST_LOG_OBJECT (encoder, "marking discont");
2374         GST_BUFFER_FLAG_SET (tmpbuf, GST_BUFFER_FLAG_DISCONT);
2375         *discont = FALSE;
2376       } else {
2377         GST_BUFFER_FLAG_UNSET (tmpbuf, GST_BUFFER_FLAG_DISCONT);
2378       }
2379
2380       gst_pad_push (encoder->srcpad, gst_buffer_ref (tmpbuf));
2381     }
2382     priv->new_headers = FALSE;
2383   }
2384 }
2385
2386 static void
2387 gst_video_encoder_transform_meta_unlocked (GstVideoEncoder * encoder,
2388     GstVideoCodecFrame * frame)
2389 {
2390   GstVideoEncoderClass *encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);
2391
2392   if (encoder_class->transform_meta) {
2393     if (G_LIKELY (frame->input_buffer)) {
2394       CopyMetaData data;
2395
2396       data.encoder = encoder;
2397       data.frame = frame;
2398       gst_buffer_foreach_meta (frame->input_buffer, foreach_metadata, &data);
2399     } else {
2400       GST_FIXME_OBJECT (encoder,
2401           "Can't copy metadata because input frame disappeared");
2402     }
2403   }
2404 }
2405
2406 static void
2407 gst_video_encoder_send_key_unit_unlocked (GstVideoEncoder * encoder,
2408     GstVideoCodecFrame * frame, gboolean * send_headers)
2409 {
2410   GstVideoEncoderPrivate *priv = encoder->priv;
2411   GstClockTime stream_time, running_time;
2412   GstEvent *ev;
2413   GList *l;
2414   GQueue matching_fevt = G_QUEUE_INIT;
2415   ForcedKeyUnitEvent *fevt;
2416
2417   running_time =
2418       gst_segment_to_running_time (&encoder->output_segment, GST_FORMAT_TIME,
2419       frame->pts);
2420
2421   GST_OBJECT_LOCK (encoder);
2422   for (l = priv->force_key_unit.head; l;) {
2423     fevt = l->data;
2424
2425     /* Skip non-pending keyunits */
2426     if (!fevt->pending) {
2427       l = l->next;
2428       continue;
2429     }
2430
2431     /* Exact match using the frame id */
2432     if (frame->system_frame_number == fevt->frame_id) {
2433       GList *next = l->next;
2434       g_queue_push_tail (&matching_fevt, fevt);
2435       g_queue_delete_link (&priv->force_key_unit, l);
2436       l = next;
2437       continue;
2438     }
2439
2440     /* Simple case, keyunit ASAP */
2441     if (fevt->running_time == GST_CLOCK_TIME_NONE) {
2442       GList *next = l->next;
2443       g_queue_push_tail (&matching_fevt, fevt);
2444       g_queue_delete_link (&priv->force_key_unit, l);
2445       l = next;
2446       continue;
2447     }
2448
2449     /* Event for before this frame */
2450     if (fevt->running_time <= running_time) {
2451       GList *next = l->next;
2452       g_queue_push_tail (&matching_fevt, fevt);
2453       g_queue_delete_link (&priv->force_key_unit, l);
2454       l = next;
2455       continue;
2456     }
2457
2458     /* Otherwise all following events are in the future */
2459     break;
2460   }
2461
2462   GST_OBJECT_UNLOCK (encoder);
2463
2464   while ((fevt = g_queue_pop_head (&matching_fevt))) {
2465     stream_time =
2466         gst_segment_to_stream_time (&encoder->output_segment, GST_FORMAT_TIME,
2467         frame->pts);
2468
2469     ev = gst_video_event_new_downstream_force_key_unit
2470         (frame->pts, stream_time, running_time, fevt->all_headers, fevt->count);
2471
2472     gst_video_encoder_push_event (encoder, ev);
2473
2474     if (fevt->all_headers)
2475       *send_headers = TRUE;
2476
2477     GST_DEBUG_OBJECT (encoder,
2478         "Forced key unit: running-time %" GST_TIME_FORMAT
2479         ", all_headers %d, count %u",
2480         GST_TIME_ARGS (running_time), fevt->all_headers, fevt->count);
2481     forced_key_unit_event_free (fevt);
2482   }
2483 }
2484
2485 /**
2486  * gst_video_encoder_finish_frame:
2487  * @encoder: a #GstVideoEncoder
2488  * @frame: (transfer full): an encoded #GstVideoCodecFrame
2489  *
2490  * @frame must have a valid encoded data buffer, whose metadata fields
2491  * are then appropriately set according to frame data or no buffer at
2492  * all if the frame should be dropped.
2493  * It is subsequently pushed downstream or provided to @pre_push.
2494  * In any case, the frame is considered finished and released.
2495  *
2496  * After calling this function the output buffer of the frame is to be
2497  * considered read-only. This function will also change the metadata
2498  * of the buffer.
2499  *
2500  * Returns: a #GstFlowReturn resulting from sending data downstream
2501  */
2502 GstFlowReturn
2503 gst_video_encoder_finish_frame (GstVideoEncoder * encoder,
2504     GstVideoCodecFrame * frame)
2505 {
2506   GstVideoEncoderPrivate *priv = encoder->priv;
2507   GstFlowReturn ret = GST_FLOW_OK;
2508   GstVideoEncoderClass *encoder_class;
2509   gboolean send_headers = FALSE;
2510   gboolean key_unit = FALSE;
2511   gboolean discont = FALSE;
2512   GstBuffer *buffer;
2513
2514   g_return_val_if_fail (frame, GST_FLOW_ERROR);
2515
2516   discont = (frame->presentation_frame_number == 0
2517       && frame->abidata.ABI.num_subframes == 0);
2518
2519   encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);
2520
2521   GST_LOG_OBJECT (encoder,
2522       "finish frame fpn %d sync point: %d", frame->presentation_frame_number,
2523       GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame));
2524
2525   GST_LOG_OBJECT (encoder, "frame PTS %" GST_TIME_FORMAT
2526       ", DTS %" GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts),
2527       GST_TIME_ARGS (frame->dts));
2528
2529   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2530
2531   ret = gst_video_encoder_can_push_unlocked (encoder);
2532   if (ret != GST_FLOW_OK)
2533     goto done;
2534
2535   if (frame->abidata.ABI.num_subframes == 0)
2536     gst_video_encoder_push_pending_unlocked (encoder, frame);
2537
2538   /* no buffer data means this frame is skipped/dropped */
2539   if (!frame->output_buffer) {
2540     gst_video_encoder_drop_frame (encoder, frame);
2541     goto done;
2542   }
2543
2544   priv->processed++;
2545
2546   if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame) && priv->force_key_unit.head)
2547     gst_video_encoder_send_key_unit_unlocked (encoder, frame, &send_headers);
2548
2549   if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)
2550       && frame->abidata.ABI.num_subframes == 0) {
2551     priv->distance_from_sync = 0;
2552     key_unit = TRUE;
2553     /* For keyframes, DTS = PTS, if encoder doesn't decide otherwise */
2554     if (!GST_CLOCK_TIME_IS_VALID (frame->dts)) {
2555       frame->dts = frame->pts;
2556     }
2557     priv->last_key_unit =
2558         gst_segment_to_running_time (&encoder->output_segment, GST_FORMAT_TIME,
2559         frame->pts);
2560   }
2561
2562   gst_video_encoder_infer_dts_unlocked (encoder, frame);
2563
2564   frame->distance_from_sync = priv->distance_from_sync;
2565   priv->distance_from_sync++;
2566
2567   /* We need a writable buffer for the metadata changes below */
2568   frame->output_buffer = gst_buffer_make_writable (frame->output_buffer);
2569
2570   GST_BUFFER_PTS (frame->output_buffer) = frame->pts;
2571   GST_BUFFER_DTS (frame->output_buffer) = frame->dts;
2572   GST_BUFFER_DURATION (frame->output_buffer) = frame->duration;
2573
2574   /* At this stage we have a full frame in subframe use case ,
2575    * let's mark it to enabled some latency optimization
2576    *  in some uses cases like RTP. */
2577
2578   GST_BUFFER_FLAG_SET (frame->output_buffer, GST_VIDEO_BUFFER_FLAG_MARKER);
2579
2580   GST_OBJECT_LOCK (encoder);
2581   /* update rate estimate */
2582   priv->bytes += gst_buffer_get_size (frame->output_buffer);
2583   if (GST_CLOCK_TIME_IS_VALID (frame->duration)) {
2584     priv->time += frame->duration;
2585   } else {
2586     /* better none than nothing valid */
2587     priv->time = GST_CLOCK_TIME_NONE;
2588   }
2589   GST_OBJECT_UNLOCK (encoder);
2590
2591   if (G_UNLIKELY (send_headers))
2592     priv->new_headers = TRUE;
2593
2594   gst_video_encoder_send_header_unlocked (encoder, &discont, key_unit);
2595
2596   if (key_unit) {
2597     GST_BUFFER_FLAG_UNSET (frame->output_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2598   } else {
2599     GST_BUFFER_FLAG_SET (frame->output_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2600   }
2601
2602   if (G_UNLIKELY (discont)) {
2603     GST_LOG_OBJECT (encoder, "marking discont");
2604     GST_BUFFER_FLAG_SET (frame->output_buffer, GST_BUFFER_FLAG_DISCONT);
2605   }
2606
2607   if (encoder_class->pre_push)
2608     ret = encoder_class->pre_push (encoder, frame);
2609
2610   gst_video_encoder_transform_meta_unlocked (encoder, frame);
2611
2612   /* Get an additional ref to the buffer, which is going to be pushed
2613    * downstream, the original ref is owned by the frame */
2614   if (ret == GST_FLOW_OK)
2615     buffer = gst_buffer_ref (frame->output_buffer);
2616
2617   /* Release frame so the buffer is writable when we push it downstream
2618    * if possible, i.e. if the subclass does not hold additional references
2619    * to the frame
2620    */
2621   gst_video_encoder_release_frame (encoder, frame);
2622   frame = NULL;
2623
2624   if (ret == GST_FLOW_OK) {
2625     GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2626     ret = gst_pad_push (encoder->srcpad, buffer);
2627     GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2628   }
2629
2630 done:
2631   /* handed out */
2632   if (frame)
2633     gst_video_encoder_release_frame (encoder, frame);
2634
2635   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2636
2637   return ret;
2638 }
2639
2640 /**
2641  * gst_video_encoder_finish_subframe:
2642  * @encoder: a #GstVideoEncoder
2643  * @frame: (transfer none): a #GstVideoCodecFrame being encoded
2644  *
2645  * If multiple subframes are produced for one input frame then use this method
2646  * for each subframe, except for the last one. Before calling this function,
2647  * you need to fill frame->output_buffer with the encoded buffer to push.
2648
2649  * You must call #gst_video_encoder_finish_frame() for the last sub-frame
2650  * to tell the encoder that the frame has been fully encoded.
2651  *
2652  * This function will change the metadata of @frame and frame->output_buffer
2653  * will be pushed downstream.
2654  *
2655  * Returns: a #GstFlowReturn resulting from pushing the buffer downstream.
2656  *
2657  * Since: 1.18
2658  */
2659 GstFlowReturn
2660 gst_video_encoder_finish_subframe (GstVideoEncoder * encoder,
2661     GstVideoCodecFrame * frame)
2662 {
2663   GstVideoEncoderPrivate *priv = encoder->priv;
2664   GstVideoEncoderClass *encoder_class;
2665   GstFlowReturn ret = GST_FLOW_OK;
2666   GstBuffer *subframe_buffer = NULL;
2667   gboolean discont = FALSE;
2668   gboolean send_headers = FALSE;
2669   gboolean key_unit = FALSE;
2670
2671   g_return_val_if_fail (frame, GST_FLOW_ERROR);
2672   g_return_val_if_fail (frame->output_buffer, GST_FLOW_ERROR);
2673
2674   subframe_buffer = frame->output_buffer;
2675
2676   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2677   discont = (frame->presentation_frame_number == 0
2678       && frame->abidata.ABI.num_subframes == 0);
2679
2680   encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);
2681
2682   GST_LOG_OBJECT (encoder,
2683       "finish subframe %u of frame fpn %u PTS %" GST_TIME_FORMAT ", DTS %"
2684       GST_TIME_FORMAT " sync point: %d", frame->abidata.ABI.num_subframes,
2685       frame->presentation_frame_number, GST_TIME_ARGS (frame->pts),
2686       GST_TIME_ARGS (frame->dts), GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame));
2687
2688   ret = gst_video_encoder_can_push_unlocked (encoder);
2689   if (ret != GST_FLOW_OK)
2690     goto done;
2691
2692   if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame) && priv->force_key_unit.head)
2693     gst_video_encoder_send_key_unit_unlocked (encoder, frame, &send_headers);
2694
2695   /* Push pending events only for the first subframe ie segment event.
2696    * Push new incoming events on finish_frame otherwise.
2697    */
2698   if (frame->abidata.ABI.num_subframes == 0)
2699     gst_video_encoder_push_pending_unlocked (encoder, frame);
2700
2701   if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)
2702       && frame->abidata.ABI.num_subframes == 0) {
2703     priv->distance_from_sync = 0;
2704     key_unit = TRUE;
2705     /* For keyframes, DTS = PTS, if encoder doesn't decide otherwise */
2706     if (!GST_CLOCK_TIME_IS_VALID (frame->dts)) {
2707       frame->dts = frame->pts;
2708     }
2709     priv->last_key_unit =
2710         gst_segment_to_running_time (&encoder->output_segment, GST_FORMAT_TIME,
2711         frame->pts);
2712   }
2713
2714   gst_video_encoder_infer_dts_unlocked (encoder, frame);
2715
2716   /* We need a writable buffer for the metadata changes below */
2717   subframe_buffer = gst_buffer_make_writable (subframe_buffer);
2718
2719   GST_BUFFER_PTS (subframe_buffer) = frame->pts;
2720   GST_BUFFER_DTS (subframe_buffer) = frame->dts;
2721   GST_BUFFER_DURATION (subframe_buffer) = frame->duration;
2722
2723   GST_OBJECT_LOCK (encoder);
2724   /* update rate estimate */
2725   priv->bytes += gst_buffer_get_size (subframe_buffer);
2726   GST_OBJECT_UNLOCK (encoder);
2727
2728   if (G_UNLIKELY (send_headers))
2729     priv->new_headers = TRUE;
2730
2731   gst_video_encoder_send_header_unlocked (encoder, &discont, key_unit);
2732
2733   if (key_unit) {
2734     GST_BUFFER_FLAG_UNSET (subframe_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2735   } else {
2736     GST_BUFFER_FLAG_SET (subframe_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2737   }
2738
2739   if (G_UNLIKELY (discont)) {
2740     GST_LOG_OBJECT (encoder, "marking discont buffer: %" GST_PTR_FORMAT,
2741         subframe_buffer);
2742     GST_BUFFER_FLAG_SET (subframe_buffer, GST_BUFFER_FLAG_DISCONT);
2743   }
2744
2745   if (encoder_class->pre_push) {
2746     ret = encoder_class->pre_push (encoder, frame);
2747   }
2748
2749   gst_video_encoder_transform_meta_unlocked (encoder, frame);
2750
2751   if (ret == GST_FLOW_OK) {
2752     GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2753     ret = gst_pad_push (encoder->srcpad, subframe_buffer);
2754     subframe_buffer = NULL;
2755     GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2756   }
2757
2758 done:
2759   frame->abidata.ABI.num_subframes++;
2760   if (subframe_buffer)
2761     gst_buffer_unref (subframe_buffer);
2762   frame->output_buffer = NULL;
2763
2764   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2765
2766   return ret;
2767 }
2768
2769 /**
2770  * gst_video_encoder_get_output_state:
2771  * @encoder: a #GstVideoEncoder
2772  *
2773  * Get the current #GstVideoCodecState
2774  *
2775  * Returns: (transfer full): #GstVideoCodecState describing format of video data.
2776  */
2777 GstVideoCodecState *
2778 gst_video_encoder_get_output_state (GstVideoEncoder * encoder)
2779 {
2780   GstVideoCodecState *state;
2781
2782   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2783   state = gst_video_codec_state_ref (encoder->priv->output_state);
2784   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2785
2786   return state;
2787 }
2788
2789 /**
2790  * gst_video_encoder_set_output_state:
2791  * @encoder: a #GstVideoEncoder
2792  * @caps: (transfer full): the #GstCaps to use for the output
2793  * @reference: (allow-none) (transfer none): An optional reference @GstVideoCodecState
2794  *
2795  * Creates a new #GstVideoCodecState with the specified caps as the output state
2796  * for the encoder.
2797  * Any previously set output state on @encoder will be replaced by the newly
2798  * created one.
2799  *
2800  * The specified @caps should not contain any resolution, pixel-aspect-ratio,
2801  * framerate, codec-data, .... Those should be specified instead in the returned
2802  * #GstVideoCodecState.
2803  *
2804  * If the subclass wishes to copy over existing fields (like pixel aspect ratio,
2805  * or framerate) from an existing #GstVideoCodecState, it can be provided as a
2806  * @reference.
2807  *
2808  * If the subclass wishes to override some fields from the output state (like
2809  * pixel-aspect-ratio or framerate) it can do so on the returned #GstVideoCodecState.
2810  *
2811  * The new output state will only take effect (set on pads and buffers) starting
2812  * from the next call to #gst_video_encoder_finish_frame().
2813  *
2814  * Returns: (transfer full): the newly configured output state.
2815  */
2816 GstVideoCodecState *
2817 gst_video_encoder_set_output_state (GstVideoEncoder * encoder, GstCaps * caps,
2818     GstVideoCodecState * reference)
2819 {
2820   GstVideoEncoderPrivate *priv = encoder->priv;
2821   GstVideoCodecState *state;
2822
2823   g_return_val_if_fail (caps != NULL, NULL);
2824
2825   state = _new_output_state (caps, reference);
2826   if (!state)
2827     return NULL;
2828
2829   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2830   if (priv->output_state)
2831     gst_video_codec_state_unref (priv->output_state);
2832   priv->output_state = gst_video_codec_state_ref (state);
2833
2834   if (priv->output_state != NULL && priv->output_state->info.fps_n > 0) {
2835     priv->qos_frame_duration =
2836         gst_util_uint64_scale (GST_SECOND, priv->output_state->info.fps_d,
2837         priv->output_state->info.fps_n);
2838   } else {
2839     priv->qos_frame_duration = 0;
2840   }
2841
2842   priv->output_state_changed = TRUE;
2843   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2844
2845   return state;
2846 }
2847
2848 /**
2849  * gst_video_encoder_set_latency:
2850  * @encoder: a #GstVideoEncoder
2851  * @min_latency: minimum latency
2852  * @max_latency: maximum latency
2853  *
2854  * Informs baseclass of encoding latency.
2855  */
2856 void
2857 gst_video_encoder_set_latency (GstVideoEncoder * encoder,
2858     GstClockTime min_latency, GstClockTime max_latency)
2859 {
2860   g_return_if_fail (GST_CLOCK_TIME_IS_VALID (min_latency));
2861   g_return_if_fail (max_latency >= min_latency);
2862
2863   GST_OBJECT_LOCK (encoder);
2864   encoder->priv->min_latency = min_latency;
2865   encoder->priv->max_latency = max_latency;
2866   GST_OBJECT_UNLOCK (encoder);
2867
2868   gst_element_post_message (GST_ELEMENT_CAST (encoder),
2869       gst_message_new_latency (GST_OBJECT_CAST (encoder)));
2870 }
2871
2872 /**
2873  * gst_video_encoder_get_latency:
2874  * @encoder: a #GstVideoEncoder
2875  * @min_latency: (out) (allow-none): address of variable in which to store the
2876  *     configured minimum latency, or %NULL
2877  * @max_latency: (out) (allow-none): address of variable in which to store the
2878  *     configured maximum latency, or %NULL
2879  *
2880  * Query the configured encoding latency. Results will be returned via
2881  * @min_latency and @max_latency.
2882  */
2883 void
2884 gst_video_encoder_get_latency (GstVideoEncoder * encoder,
2885     GstClockTime * min_latency, GstClockTime * max_latency)
2886 {
2887   GST_OBJECT_LOCK (encoder);
2888   if (min_latency)
2889     *min_latency = encoder->priv->min_latency;
2890   if (max_latency)
2891     *max_latency = encoder->priv->max_latency;
2892   GST_OBJECT_UNLOCK (encoder);
2893 }
2894
2895 /**
2896  * gst_video_encoder_get_oldest_frame:
2897  * @encoder: a #GstVideoEncoder
2898  *
2899  * Get the oldest unfinished pending #GstVideoCodecFrame
2900  *
2901  * Returns: (transfer full): oldest unfinished pending #GstVideoCodecFrame
2902  */
2903 GstVideoCodecFrame *
2904 gst_video_encoder_get_oldest_frame (GstVideoEncoder * encoder)
2905 {
2906   GstVideoCodecFrame *frame = NULL;
2907
2908   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2909   if (encoder->priv->frames.head)
2910     frame = gst_video_codec_frame_ref (encoder->priv->frames.head->data);
2911   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2912
2913   return (GstVideoCodecFrame *) frame;
2914 }
2915
2916 /**
2917  * gst_video_encoder_get_frame:
2918  * @encoder: a #GstVideoEncoder
2919  * @frame_number: system_frame_number of a frame
2920  *
2921  * Get a pending unfinished #GstVideoCodecFrame
2922  *
2923  * Returns: (transfer full): pending unfinished #GstVideoCodecFrame identified by @frame_number.
2924  */
2925 GstVideoCodecFrame *
2926 gst_video_encoder_get_frame (GstVideoEncoder * encoder, int frame_number)
2927 {
2928   GList *g;
2929   GstVideoCodecFrame *frame = NULL;
2930
2931   GST_DEBUG_OBJECT (encoder, "frame_number : %d", frame_number);
2932
2933   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2934   for (g = encoder->priv->frames.head; g; g = g->next) {
2935     GstVideoCodecFrame *tmp = g->data;
2936
2937     if (tmp->system_frame_number == frame_number) {
2938       frame = gst_video_codec_frame_ref (tmp);
2939       break;
2940     }
2941   }
2942   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2943
2944   return frame;
2945 }
2946
2947 /**
2948  * gst_video_encoder_get_frames:
2949  * @encoder: a #GstVideoEncoder
2950  *
2951  * Get all pending unfinished #GstVideoCodecFrame
2952  *
2953  * Returns: (transfer full) (element-type GstVideoCodecFrame): pending unfinished #GstVideoCodecFrame.
2954  */
2955 GList *
2956 gst_video_encoder_get_frames (GstVideoEncoder * encoder)
2957 {
2958   GList *frames;
2959
2960   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2961   frames =
2962       g_list_copy_deep (encoder->priv->frames.head,
2963       (GCopyFunc) gst_video_codec_frame_ref, NULL);
2964   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2965
2966   return frames;
2967 }
2968
2969 /**
2970  * gst_video_encoder_merge_tags:
2971  * @encoder: a #GstVideoEncoder
2972  * @tags: (allow-none): a #GstTagList to merge, or NULL to unset
2973  *     previously-set tags
2974  * @mode: the #GstTagMergeMode to use, usually #GST_TAG_MERGE_REPLACE
2975  *
2976  * Sets the video encoder tags and how they should be merged with any
2977  * upstream stream tags. This will override any tags previously-set
2978  * with gst_video_encoder_merge_tags().
2979  *
2980  * Note that this is provided for convenience, and the subclass is
2981  * not required to use this and can still do tag handling on its own.
2982  *
2983  * MT safe.
2984  */
2985 void
2986 gst_video_encoder_merge_tags (GstVideoEncoder * encoder,
2987     const GstTagList * tags, GstTagMergeMode mode)
2988 {
2989   g_return_if_fail (GST_IS_VIDEO_ENCODER (encoder));
2990   g_return_if_fail (tags == NULL || GST_IS_TAG_LIST (tags));
2991   g_return_if_fail (tags == NULL || mode != GST_TAG_MERGE_UNDEFINED);
2992
2993   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2994   if (encoder->priv->tags != tags) {
2995     if (encoder->priv->tags) {
2996       gst_tag_list_unref (encoder->priv->tags);
2997       encoder->priv->tags = NULL;
2998       encoder->priv->tags_merge_mode = GST_TAG_MERGE_APPEND;
2999     }
3000     if (tags) {
3001       encoder->priv->tags = gst_tag_list_ref ((GstTagList *) tags);
3002       encoder->priv->tags_merge_mode = mode;
3003     }
3004
3005     GST_DEBUG_OBJECT (encoder, "setting encoder tags to %" GST_PTR_FORMAT,
3006         tags);
3007     encoder->priv->tags_changed = TRUE;
3008   }
3009   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
3010 }
3011
3012 /**
3013  * gst_video_encoder_get_allocator:
3014  * @encoder: a #GstVideoEncoder
3015  * @allocator: (out) (allow-none) (transfer full): the #GstAllocator
3016  * used
3017  * @params: (out) (allow-none) (transfer full): the
3018  * #GstAllocationParams of @allocator
3019  *
3020  * Lets #GstVideoEncoder sub-classes to know the memory @allocator
3021  * used by the base class and its @params.
3022  *
3023  * Unref the @allocator after use it.
3024  */
3025 void
3026 gst_video_encoder_get_allocator (GstVideoEncoder * encoder,
3027     GstAllocator ** allocator, GstAllocationParams * params)
3028 {
3029   g_return_if_fail (GST_IS_VIDEO_ENCODER (encoder));
3030
3031   if (allocator)
3032     *allocator = encoder->priv->allocator ?
3033         gst_object_ref (encoder->priv->allocator) : NULL;
3034
3035   if (params)
3036     *params = encoder->priv->params;
3037 }
3038
3039 /**
3040  * gst_video_encoder_set_min_pts:
3041  * @encoder: a #GstVideoEncoder
3042  * @min_pts: minimal PTS that will be passed to handle_frame
3043  *
3044  * Request minimal value for PTS passed to handle_frame.
3045  *
3046  * For streams with reordered frames this can be used to ensure that there
3047  * is enough time to accommodate first DTS, which may be less than first PTS
3048  *
3049  * Since: 1.6
3050  */
3051 void
3052 gst_video_encoder_set_min_pts (GstVideoEncoder * encoder, GstClockTime min_pts)
3053 {
3054   g_return_if_fail (GST_IS_VIDEO_ENCODER (encoder));
3055   encoder->priv->min_pts = min_pts;
3056   encoder->priv->time_adjustment = GST_CLOCK_TIME_NONE;
3057 }
3058
3059 /**
3060  * gst_video_encoder_get_max_encode_time:
3061  * @encoder: a #GstVideoEncoder
3062  * @frame: a #GstVideoCodecFrame
3063  *
3064  * Determines maximum possible encoding time for @frame that will
3065  * allow it to encode and arrive in time (as determined by QoS events).
3066  * In particular, a negative result means encoding in time is no longer possible
3067  * and should therefore occur as soon/skippy as possible.
3068  *
3069  * If no QoS events have been received from downstream, or if
3070  * #GstVideoEncoder:qos is disabled this function returns #G_MAXINT64.
3071  *
3072  * Returns: max decoding time.
3073  * Since: 1.14
3074  */
3075 GstClockTimeDiff
3076 gst_video_encoder_get_max_encode_time (GstVideoEncoder *
3077     encoder, GstVideoCodecFrame * frame)
3078 {
3079   GstClockTimeDiff deadline;
3080   GstClockTime earliest_time;
3081
3082   if (!g_atomic_int_get (&encoder->priv->qos_enabled))
3083     return G_MAXINT64;
3084
3085   GST_OBJECT_LOCK (encoder);
3086   earliest_time = encoder->priv->earliest_time;
3087   if (GST_CLOCK_TIME_IS_VALID (earliest_time)
3088       && GST_CLOCK_TIME_IS_VALID (frame->deadline))
3089     deadline = GST_CLOCK_DIFF (earliest_time, frame->deadline);
3090   else
3091     deadline = G_MAXINT64;
3092
3093   GST_LOG_OBJECT (encoder, "earliest %" GST_TIME_FORMAT
3094       ", frame deadline %" GST_TIME_FORMAT ", deadline %" GST_STIME_FORMAT,
3095       GST_TIME_ARGS (earliest_time), GST_TIME_ARGS (frame->deadline),
3096       GST_STIME_ARGS (deadline));
3097
3098   GST_OBJECT_UNLOCK (encoder);
3099
3100   return deadline;
3101 }
3102
3103 /**
3104  * gst_video_encoder_set_qos_enabled:
3105  * @encoder: the encoder
3106  * @enabled: the new qos value.
3107  *
3108  * Configures @encoder to handle Quality-of-Service events from downstream.
3109  * Since: 1.14
3110  */
3111 void
3112 gst_video_encoder_set_qos_enabled (GstVideoEncoder * encoder, gboolean enabled)
3113 {
3114   g_return_if_fail (GST_IS_VIDEO_ENCODER (encoder));
3115
3116   g_atomic_int_set (&encoder->priv->qos_enabled, enabled);
3117 }
3118
3119 /**
3120  * gst_video_encoder_is_qos_enabled:
3121  * @encoder: the encoder
3122  *
3123  * Checks if @encoder is currently configured to handle Quality-of-Service
3124  * events from downstream.
3125  *
3126  * Returns: %TRUE if the encoder is configured to perform Quality-of-Service.
3127  * Since: 1.14
3128  */
3129 gboolean
3130 gst_video_encoder_is_qos_enabled (GstVideoEncoder * encoder)
3131 {
3132   gboolean res;
3133
3134   g_return_val_if_fail (GST_IS_VIDEO_ENCODER (encoder), FALSE);
3135
3136   res = g_atomic_int_get (&encoder->priv->qos_enabled);
3137
3138   return res;
3139 }
3140
3141 /**
3142  * gst_video_encoder_set_min_force_key_unit_interval:
3143  * @encoder: the encoder
3144  * @interval: minimum interval
3145  *
3146  * Sets the minimum interval for requesting keyframes based on force-keyunit
3147  * events. Setting this to 0 will allow to handle every event, setting this to
3148  * %GST_CLOCK_TIME_NONE causes force-keyunit events to be ignored.
3149  *
3150  * Since: 1.18
3151  */
3152 void
3153 gst_video_encoder_set_min_force_key_unit_interval (GstVideoEncoder * encoder,
3154     GstClockTime interval)
3155 {
3156   g_return_if_fail (GST_IS_VIDEO_ENCODER (encoder));
3157
3158   GST_OBJECT_LOCK (encoder);
3159   encoder->priv->min_force_key_unit_interval = interval;
3160   GST_OBJECT_UNLOCK (encoder);
3161 }
3162
3163 /**
3164  * gst_video_encoder_get_min_force_key_unit_interval:
3165  * @encoder: the encoder
3166  *
3167  * Returns the minimum force-keyunit interval, see gst_video_encoder_set_min_force_key_unit_interval()
3168  * for more details.
3169  *
3170  * Returns: the minimum force-keyunit interval
3171  *
3172  * Since: 1.18
3173  */
3174 GstClockTime
3175 gst_video_encoder_get_min_force_key_unit_interval (GstVideoEncoder * encoder)
3176 {
3177   GstClockTime interval;
3178
3179   g_return_val_if_fail (GST_IS_VIDEO_ENCODER (encoder), GST_CLOCK_TIME_NONE);
3180
3181   GST_OBJECT_LOCK (encoder);
3182   interval = encoder->priv->min_force_key_unit_interval;
3183   GST_OBJECT_UNLOCK (encoder);
3184
3185   return interval;
3186 }