videoencoder: plug some leaks
[platform/upstream/gstreamer.git] / 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., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  */
24
25 /**
26  * SECTION:gstvideoencoder
27  * @short_description: Base class for video encoders
28  * @see_also:
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  * <orderedlist>
35  * <listitem>
36  *   <itemizedlist><title>Configuration</title>
37  *   <listitem><para>
38  *     Initially, GstVideoEncoder calls @start when the encoder element
39  *     is activated, which allows subclass to perform any global setup.
40  *   </para></listitem>
41  *   <listitem><para>
42  *     GstVideoEncoder calls @set_format to inform subclass of the format
43  *     of input video data that it is about to receive.  Subclass should
44  *     setup for encoding and configure base class as appropriate
45  *     (e.g. latency). While unlikely, it might be called more than once,
46  *     if changing input parameters require reconfiguration.  Baseclass
47  *     will ensure that processing of current configuration is finished.
48  *   </para></listitem>
49  *   <listitem><para>
50  *     GstVideoEncoder calls @stop at end of all processing.
51  *   </para></listitem>
52  *   </itemizedlist>
53  * </listitem>
54  * <listitem>
55  *   <itemizedlist>
56  *   <title>Data processing</title>
57  *     <listitem><para>
58  *       Base class collects input data and metadata into a frame and hands
59  *       this to subclass' @handle_frame.
60  *     </para></listitem>
61  *     <listitem><para>
62  *       If codec processing results in encoded data, subclass should call
63  *       @gst_video_encoder_finish_frame to have encoded data pushed
64  *       downstream.
65  *     </para></listitem>
66  *     <listitem><para>
67  *       If implemented, baseclass calls subclass @pre_push just prior to
68  *       pushing to allow subclasses to modify some metadata on the buffer.
69  *       If it returns GST_FLOW_OK, the buffer is pushed downstream.
70  *     </para></listitem>
71  *     <listitem><para>
72  *       GstVideoEncoderClass will handle both srcpad and sinkpad events.
73  *       Sink events will be passed to subclass if @event callback has been
74  *       provided.
75  *     </para></listitem>
76  *   </itemizedlist>
77  * </listitem>
78  * <listitem>
79  *   <itemizedlist><title>Shutdown phase</title>
80  *   <listitem><para>
81  *     GstVideoEncoder class calls @stop to inform the subclass that data
82  *     parsing will be stopped.
83  *   </para></listitem>
84  *   </itemizedlist>
85  * </listitem>
86  * </orderedlist>
87  *
88  * Subclass is responsible for providing pad template caps for
89  * source and sink pads. The pads need to be named "sink" and "src". It should
90  * also be able to provide fixed src pad caps in @getcaps by the time it calls
91  * @gst_video_encoder_finish_frame.
92  *
93  * Things that subclass need to take care of:
94  * <itemizedlist>
95  *   <listitem><para>Provide pad templates</para></listitem>
96  *   <listitem><para>
97  *      Provide source pad caps before pushing the first buffer
98  *   </para></listitem>
99  *   <listitem><para>
100  *      Accept data in @handle_frame and provide encoded results to
101  *      @gst_video_encoder_finish_frame.
102  *   </para></listitem>
103  * </itemizedlist>
104  *
105  */
106
107 #ifdef HAVE_CONFIG_H
108 #include "config.h"
109 #endif
110
111 /* TODO
112  *
113  * * Change _set_output_format() to steal the reference of the provided caps
114  * * Calculate actual latency based on input/output timestamp/frame_number
115  *   and if it exceeds the recorded one, save it and emit a GST_MESSAGE_LATENCY
116  */
117
118 /* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex
119  * with newer GLib versions (>= 2.31.0) */
120 #define GLIB_DISABLE_DEPRECATION_WARNINGS
121
122 #include "gstvideoencoder.h"
123 #include "gstvideoutils.h"
124
125 #include <gst/video/gstvideometa.h>
126 #include <gst/video/gstvideopool.h>
127
128 #include <string.h>
129
130 GST_DEBUG_CATEGORY (videoencoder_debug);
131 #define GST_CAT_DEFAULT videoencoder_debug
132
133 #define GST_VIDEO_ENCODER_GET_PRIVATE(obj)  \
134     (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_VIDEO_ENCODER, \
135         GstVideoEncoderPrivate))
136
137 struct _GstVideoEncoderPrivate
138 {
139   guint64 presentation_frame_number;
140   int distance_from_sync;
141
142   /* FIXME : (and introduce a context ?) */
143   gboolean drained;
144   gboolean at_eos;
145   gboolean do_caps;
146
147   gint64 min_latency;
148   gint64 max_latency;
149
150   GList *current_frame_events;
151
152   GList *headers;
153   gboolean new_headers;         /* Whether new headers were just set */
154
155   GList *force_key_unit;        /* List of pending forced keyunits */
156
157   guint32 system_frame_number;
158
159   GList *frames;                /* Protected with OBJECT_LOCK */
160   GstVideoCodecState *input_state;
161   GstVideoCodecState *output_state;
162   gboolean output_state_changed;
163
164   gint64 bytes;
165   gint64 time;
166
167   GstAllocator *allocator;
168   GstAllocationParams params;
169
170   GstTagList *tags;
171   gboolean tags_changed;
172 };
173
174 typedef struct _ForcedKeyUnitEvent ForcedKeyUnitEvent;
175 struct _ForcedKeyUnitEvent
176 {
177   GstClockTime running_time;
178   gboolean pending;             /* TRUE if this was requested already */
179   gboolean all_headers;
180   guint count;
181 };
182
183 static void
184 forced_key_unit_event_free (ForcedKeyUnitEvent * evt)
185 {
186   g_slice_free (ForcedKeyUnitEvent, evt);
187 }
188
189 static ForcedKeyUnitEvent *
190 forced_key_unit_event_new (GstClockTime running_time, gboolean all_headers,
191     guint count)
192 {
193   ForcedKeyUnitEvent *evt = g_slice_new0 (ForcedKeyUnitEvent);
194
195   evt->running_time = running_time;
196   evt->all_headers = all_headers;
197   evt->count = count;
198
199   return evt;
200 }
201
202 static GstElementClass *parent_class = NULL;
203 static void gst_video_encoder_class_init (GstVideoEncoderClass * klass);
204 static void gst_video_encoder_init (GstVideoEncoder * enc,
205     GstVideoEncoderClass * klass);
206
207 static void gst_video_encoder_finalize (GObject * object);
208
209 static gboolean gst_video_encoder_setcaps (GstVideoEncoder * enc,
210     GstCaps * caps);
211 static GstCaps *gst_video_encoder_sink_getcaps (GstVideoEncoder * encoder,
212     GstCaps * filter);
213 static gboolean gst_video_encoder_src_event (GstPad * pad, GstObject * parent,
214     GstEvent * event);
215 static gboolean gst_video_encoder_sink_event (GstPad * pad, GstObject * parent,
216     GstEvent * event);
217 static GstFlowReturn gst_video_encoder_chain (GstPad * pad, GstObject * parent,
218     GstBuffer * buf);
219 static GstStateChangeReturn gst_video_encoder_change_state (GstElement *
220     element, GstStateChange transition);
221 static gboolean gst_video_encoder_sink_query (GstPad * pad, GstObject * parent,
222     GstQuery * query);
223 static gboolean gst_video_encoder_src_query (GstPad * pad, GstObject * parent,
224     GstQuery * query);
225 static GstVideoCodecFrame *gst_video_encoder_new_frame (GstVideoEncoder *
226     encoder, GstBuffer * buf, GstClockTime pts, GstClockTime dts,
227     GstClockTime duration);
228
229 static gboolean gst_video_encoder_sink_event_default (GstVideoEncoder * encoder,
230     GstEvent * event);
231 static gboolean gst_video_encoder_src_event_default (GstVideoEncoder * encoder,
232     GstEvent * event);
233 static gboolean gst_video_encoder_decide_allocation_default (GstVideoEncoder *
234     encoder, GstQuery * query);
235 static gboolean gst_video_encoder_propose_allocation_default (GstVideoEncoder *
236     encoder, GstQuery * query);
237 static gboolean gst_video_encoder_negotiate_default (GstVideoEncoder * encoder);
238
239 /* we can't use G_DEFINE_ABSTRACT_TYPE because we need the klass in the _init
240  * method to get to the padtemplates */
241 GType
242 gst_video_encoder_get_type (void)
243 {
244   static volatile gsize type = 0;
245
246   if (g_once_init_enter (&type)) {
247     GType _type;
248     static const GTypeInfo info = {
249       sizeof (GstVideoEncoderClass),
250       NULL,
251       NULL,
252       (GClassInitFunc) gst_video_encoder_class_init,
253       NULL,
254       NULL,
255       sizeof (GstVideoEncoder),
256       0,
257       (GInstanceInitFunc) gst_video_encoder_init,
258     };
259     const GInterfaceInfo preset_interface_info = {
260       NULL,                     /* interface_init */
261       NULL,                     /* interface_finalize */
262       NULL                      /* interface_data */
263     };
264
265     _type = g_type_register_static (GST_TYPE_ELEMENT,
266         "GstVideoEncoder", &info, G_TYPE_FLAG_ABSTRACT);
267     g_type_add_interface_static (_type, GST_TYPE_PRESET,
268         &preset_interface_info);
269     g_once_init_leave (&type, _type);
270   }
271   return type;
272 }
273
274 static void
275 gst_video_encoder_class_init (GstVideoEncoderClass * klass)
276 {
277   GObjectClass *gobject_class;
278   GstElementClass *gstelement_class;
279
280   gobject_class = G_OBJECT_CLASS (klass);
281   gstelement_class = GST_ELEMENT_CLASS (klass);
282
283   GST_DEBUG_CATEGORY_INIT (videoencoder_debug, "videoencoder", 0,
284       "Base Video Encoder");
285
286   parent_class = g_type_class_peek_parent (klass);
287
288   g_type_class_add_private (klass, sizeof (GstVideoEncoderPrivate));
289
290   gobject_class->finalize = gst_video_encoder_finalize;
291
292   gstelement_class->change_state =
293       GST_DEBUG_FUNCPTR (gst_video_encoder_change_state);
294
295   klass->sink_event = gst_video_encoder_sink_event_default;
296   klass->src_event = gst_video_encoder_src_event_default;
297   klass->propose_allocation = gst_video_encoder_propose_allocation_default;
298   klass->decide_allocation = gst_video_encoder_decide_allocation_default;
299   klass->negotiate = gst_video_encoder_negotiate_default;
300 }
301
302 static void
303 gst_video_encoder_reset (GstVideoEncoder * encoder)
304 {
305   GstVideoEncoderPrivate *priv = encoder->priv;
306   GList *g;
307
308   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
309
310   priv->presentation_frame_number = 0;
311   priv->distance_from_sync = 0;
312
313   g_list_foreach (priv->force_key_unit, (GFunc) forced_key_unit_event_free,
314       NULL);
315   g_list_free (priv->force_key_unit);
316   priv->force_key_unit = NULL;
317
318   priv->drained = TRUE;
319   priv->min_latency = 0;
320   priv->max_latency = 0;
321
322   g_list_foreach (priv->headers, (GFunc) gst_event_unref, NULL);
323   g_list_free (priv->headers);
324   priv->headers = NULL;
325   priv->new_headers = FALSE;
326
327   g_list_foreach (priv->current_frame_events, (GFunc) gst_event_unref, NULL);
328   g_list_free (priv->current_frame_events);
329   priv->current_frame_events = NULL;
330
331   for (g = priv->frames; g; g = g->next) {
332     gst_video_codec_frame_unref ((GstVideoCodecFrame *) g->data);
333   }
334   g_list_free (priv->frames);
335   priv->frames = NULL;
336
337   priv->bytes = 0;
338   priv->time = 0;
339
340   if (priv->input_state)
341     gst_video_codec_state_unref (priv->input_state);
342   priv->input_state = NULL;
343   if (priv->output_state)
344     gst_video_codec_state_unref (priv->output_state);
345   priv->output_state = NULL;
346
347   if (priv->tags)
348     gst_tag_list_unref (priv->tags);
349   priv->tags = NULL;
350   priv->tags_changed = FALSE;
351
352   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
353 }
354
355 static void
356 gst_video_encoder_init (GstVideoEncoder * encoder, GstVideoEncoderClass * klass)
357 {
358   GstVideoEncoderPrivate *priv;
359   GstPadTemplate *pad_template;
360   GstPad *pad;
361
362   GST_DEBUG_OBJECT (encoder, "gst_video_encoder_init");
363
364   priv = encoder->priv = GST_VIDEO_ENCODER_GET_PRIVATE (encoder);
365
366   pad_template =
367       gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink");
368   g_return_if_fail (pad_template != NULL);
369
370   encoder->sinkpad = pad = gst_pad_new_from_template (pad_template, "sink");
371
372   gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_video_encoder_chain));
373   gst_pad_set_event_function (pad,
374       GST_DEBUG_FUNCPTR (gst_video_encoder_sink_event));
375   gst_pad_set_query_function (pad,
376       GST_DEBUG_FUNCPTR (gst_video_encoder_sink_query));
377   gst_element_add_pad (GST_ELEMENT (encoder), encoder->sinkpad);
378
379   pad_template =
380       gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "src");
381   g_return_if_fail (pad_template != NULL);
382
383   encoder->srcpad = pad = gst_pad_new_from_template (pad_template, "src");
384
385   gst_pad_set_query_function (pad,
386       GST_DEBUG_FUNCPTR (gst_video_encoder_src_query));
387   gst_pad_set_event_function (pad,
388       GST_DEBUG_FUNCPTR (gst_video_encoder_src_event));
389   gst_element_add_pad (GST_ELEMENT (encoder), encoder->srcpad);
390
391   gst_segment_init (&encoder->input_segment, GST_FORMAT_TIME);
392   gst_segment_init (&encoder->output_segment, GST_FORMAT_TIME);
393
394   g_rec_mutex_init (&encoder->stream_lock);
395
396   priv->at_eos = FALSE;
397   priv->headers = NULL;
398   priv->new_headers = FALSE;
399
400   gst_video_encoder_reset (encoder);
401 }
402
403 static gboolean
404 gst_video_encoded_video_convert (gint64 bytes, gint64 time,
405     GstFormat src_format, gint64 src_value, GstFormat * dest_format,
406     gint64 * dest_value)
407 {
408   gboolean res = FALSE;
409
410   g_return_val_if_fail (dest_format != NULL, FALSE);
411   g_return_val_if_fail (dest_value != NULL, FALSE);
412
413   if (G_UNLIKELY (src_format == *dest_format || src_value == 0 ||
414           src_value == -1)) {
415     if (dest_value)
416       *dest_value = src_value;
417     return TRUE;
418   }
419
420   if (bytes <= 0 || time <= 0) {
421     GST_DEBUG ("not enough metadata yet to convert");
422     goto exit;
423   }
424
425   switch (src_format) {
426     case GST_FORMAT_BYTES:
427       switch (*dest_format) {
428         case GST_FORMAT_TIME:
429           *dest_value = gst_util_uint64_scale (src_value, time, bytes);
430           res = TRUE;
431           break;
432         default:
433           res = FALSE;
434       }
435       break;
436     case GST_FORMAT_TIME:
437       switch (*dest_format) {
438         case GST_FORMAT_BYTES:
439           *dest_value = gst_util_uint64_scale (src_value, bytes, time);
440           res = TRUE;
441           break;
442         default:
443           res = FALSE;
444       }
445       break;
446     default:
447       GST_DEBUG ("unhandled conversion from %d to %d", src_format,
448           *dest_format);
449       res = FALSE;
450   }
451
452 exit:
453   return res;
454 }
455
456 /**
457  * gst_video_encoder_set_headers:
458  * @encoder: a #GstVideoEncoder
459  * @headers: (transfer full) (element-type GstBuffer): a list of #GstBuffer containing the codec header
460  *
461  * Set the codec headers to be sent downstream whenever requested.
462  */
463 void
464 gst_video_encoder_set_headers (GstVideoEncoder * video_encoder, GList * headers)
465 {
466   GST_VIDEO_ENCODER_STREAM_LOCK (video_encoder);
467
468   GST_DEBUG_OBJECT (video_encoder, "new headers %p", headers);
469   if (video_encoder->priv->headers) {
470     g_list_foreach (video_encoder->priv->headers, (GFunc) gst_buffer_unref,
471         NULL);
472     g_list_free (video_encoder->priv->headers);
473   }
474   video_encoder->priv->headers = headers;
475   video_encoder->priv->new_headers = TRUE;
476
477   GST_VIDEO_ENCODER_STREAM_UNLOCK (video_encoder);
478 }
479
480 static gboolean
481 gst_video_encoder_drain (GstVideoEncoder * enc)
482 {
483   GstVideoEncoderPrivate *priv;
484   GstVideoEncoderClass *enc_class;
485   gboolean ret = TRUE;
486
487   enc_class = GST_VIDEO_ENCODER_GET_CLASS (enc);
488   priv = enc->priv;
489
490   GST_DEBUG_OBJECT (enc, "draining");
491
492   if (priv->drained) {
493     GST_DEBUG_OBJECT (enc, "already drained");
494     return TRUE;
495   }
496
497   if (enc_class->reset) {
498     GST_DEBUG_OBJECT (enc, "requesting subclass to finish");
499     ret = enc_class->reset (enc, TRUE);
500   }
501   /* everything should be away now */
502   if (priv->frames) {
503     /* not fatal/impossible though if subclass/enc eats stuff */
504     g_list_foreach (priv->frames, (GFunc) gst_video_codec_frame_unref, NULL);
505     g_list_free (priv->frames);
506     priv->frames = NULL;
507   }
508
509   return ret;
510 }
511
512 static GstVideoCodecState *
513 _new_output_state (GstCaps * caps, GstVideoCodecState * reference)
514 {
515   GstVideoCodecState *state;
516
517   state = g_slice_new0 (GstVideoCodecState);
518   state->ref_count = 1;
519   gst_video_info_init (&state->info);
520   gst_video_info_set_format (&state->info, GST_VIDEO_FORMAT_ENCODED, 0, 0);
521
522   state->caps = caps;
523
524   if (reference) {
525     GstVideoInfo *tgt, *ref;
526
527     tgt = &state->info;
528     ref = &reference->info;
529
530     /* Copy over extra fields from reference state */
531     tgt->interlace_mode = ref->interlace_mode;
532     tgt->flags = ref->flags;
533     tgt->width = ref->width;
534     tgt->height = ref->height;
535     tgt->chroma_site = ref->chroma_site;
536     tgt->colorimetry = ref->colorimetry;
537     tgt->par_n = ref->par_n;
538     tgt->par_d = ref->par_d;
539     tgt->fps_n = ref->fps_n;
540     tgt->fps_d = ref->fps_d;
541   }
542
543   return state;
544 }
545
546 static GstVideoCodecState *
547 _new_input_state (GstCaps * caps)
548 {
549   GstVideoCodecState *state;
550
551   state = g_slice_new0 (GstVideoCodecState);
552   state->ref_count = 1;
553   gst_video_info_init (&state->info);
554   if (G_UNLIKELY (!gst_video_info_from_caps (&state->info, caps)))
555     goto parse_fail;
556   state->caps = gst_caps_ref (caps);
557
558   return state;
559
560 parse_fail:
561   {
562     g_slice_free (GstVideoCodecState, state);
563     return NULL;
564   }
565 }
566
567 static gboolean
568 gst_video_encoder_setcaps (GstVideoEncoder * encoder, GstCaps * caps)
569 {
570   GstVideoEncoderClass *encoder_class;
571   GstVideoCodecState *state;
572   gboolean ret;
573   gboolean samecaps = FALSE;
574
575   encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);
576
577   /* subclass should do something here ... */
578   g_return_val_if_fail (encoder_class->set_format != NULL, FALSE);
579
580   GST_DEBUG_OBJECT (encoder, "setcaps %" GST_PTR_FORMAT, caps);
581
582   state = _new_input_state (caps);
583   if (G_UNLIKELY (!state))
584     goto parse_fail;
585
586   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
587
588   if (encoder->priv->input_state)
589     samecaps =
590         gst_video_info_is_equal (&state->info,
591         &encoder->priv->input_state->info);
592
593   if (!samecaps) {
594     /* arrange draining pending frames */
595     gst_video_encoder_drain (encoder);
596
597     /* and subclass should be ready to configure format at any time around */
598     ret = encoder_class->set_format (encoder, state);
599     if (ret) {
600       if (encoder->priv->input_state)
601         gst_video_codec_state_unref (encoder->priv->input_state);
602       encoder->priv->input_state = state;
603     } else
604       gst_video_codec_state_unref (state);
605   } else {
606     /* no need to stir things up */
607     GST_DEBUG_OBJECT (encoder,
608         "new video format identical to configured format");
609     gst_video_codec_state_unref (state);
610     ret = TRUE;
611   }
612
613   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
614
615   if (!ret)
616     GST_WARNING_OBJECT (encoder, "rejected caps %" GST_PTR_FORMAT, caps);
617
618   return ret;
619
620 parse_fail:
621   {
622     GST_WARNING_OBJECT (encoder, "Failed to parse caps");
623     return FALSE;
624   }
625 }
626
627 /**
628  * gst_video_encoder_proxy_getcaps:
629  * @enc: a #GstVideoEncoder
630  * @caps: initial caps
631  * @filter: filter caps
632  *
633  * Returns caps that express @caps (or sink template caps if @caps == NULL)
634  * restricted to resolution/format/... combinations supported by downstream
635  * elements (e.g. muxers).
636  *
637  * Returns: a #GstCaps owned by caller
638  */
639 GstCaps *
640 gst_video_encoder_proxy_getcaps (GstVideoEncoder * encoder, GstCaps * caps,
641     GstCaps * filter)
642 {
643   GstCaps *templ_caps;
644   GstCaps *allowed;
645   GstCaps *fcaps, *filter_caps;
646   gint i, j;
647
648   /* Allow downstream to specify width/height/framerate/PAR constraints
649    * and forward them upstream for video converters to handle
650    */
651   templ_caps =
652       caps ? gst_caps_ref (caps) :
653       gst_pad_get_pad_template_caps (encoder->sinkpad);
654   allowed = gst_pad_get_allowed_caps (encoder->srcpad);
655
656   if (!allowed || gst_caps_is_empty (allowed) || gst_caps_is_any (allowed)) {
657     fcaps = templ_caps;
658     goto done;
659   }
660
661   GST_LOG_OBJECT (encoder, "template caps %" GST_PTR_FORMAT, templ_caps);
662   GST_LOG_OBJECT (encoder, "allowed caps %" GST_PTR_FORMAT, allowed);
663
664   filter_caps = gst_caps_new_empty ();
665
666   for (i = 0; i < gst_caps_get_size (templ_caps); i++) {
667     GQuark q_name =
668         gst_structure_get_name_id (gst_caps_get_structure (templ_caps, i));
669
670     for (j = 0; j < gst_caps_get_size (allowed); j++) {
671       const GstStructure *allowed_s = gst_caps_get_structure (allowed, j);
672       const GValue *val;
673       GstStructure *s;
674
675       s = gst_structure_new_id_empty (q_name);
676       if ((val = gst_structure_get_value (allowed_s, "width")))
677         gst_structure_set_value (s, "width", val);
678       if ((val = gst_structure_get_value (allowed_s, "height")))
679         gst_structure_set_value (s, "height", val);
680       if ((val = gst_structure_get_value (allowed_s, "framerate")))
681         gst_structure_set_value (s, "framerate", val);
682       if ((val = gst_structure_get_value (allowed_s, "pixel-aspect-ratio")))
683         gst_structure_set_value (s, "pixel-aspect-ratio", val);
684
685       filter_caps = gst_caps_merge_structure (filter_caps, s);
686     }
687   }
688
689   fcaps = gst_caps_intersect (filter_caps, templ_caps);
690   gst_caps_unref (filter_caps);
691   gst_caps_unref (templ_caps);
692
693   if (filter) {
694     GST_LOG_OBJECT (encoder, "intersecting with %" GST_PTR_FORMAT, filter);
695     filter_caps = gst_caps_intersect (fcaps, filter);
696     gst_caps_unref (fcaps);
697     fcaps = filter_caps;
698   }
699
700 done:
701   gst_caps_replace (&allowed, NULL);
702
703   GST_LOG_OBJECT (encoder, "proxy caps %" GST_PTR_FORMAT, fcaps);
704
705   return fcaps;
706 }
707
708 static GstCaps *
709 gst_video_encoder_sink_getcaps (GstVideoEncoder * encoder, GstCaps * filter)
710 {
711   GstVideoEncoderClass *klass;
712   GstCaps *caps;
713
714   klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
715
716   if (klass->getcaps)
717     caps = klass->getcaps (encoder, filter);
718   else
719     caps = gst_video_encoder_proxy_getcaps (encoder, NULL, filter);
720
721   GST_LOG_OBJECT (encoder, "Returning caps %" GST_PTR_FORMAT, caps);
722
723   return caps;
724 }
725
726 static gboolean
727 gst_video_encoder_decide_allocation_default (GstVideoEncoder * encoder,
728     GstQuery * query)
729 {
730   GstAllocator *allocator = NULL;
731   GstAllocationParams params;
732   gboolean update_allocator;
733
734   /* we got configuration from our peer or the decide_allocation method,
735    * parse them */
736   if (gst_query_get_n_allocation_params (query) > 0) {
737     /* try the allocator */
738     gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
739     update_allocator = TRUE;
740   } else {
741     allocator = NULL;
742     gst_allocation_params_init (&params);
743     update_allocator = FALSE;
744   }
745
746   if (update_allocator)
747     gst_query_set_nth_allocation_param (query, 0, allocator, &params);
748   else
749     gst_query_add_allocation_param (query, allocator, &params);
750   if (allocator)
751     gst_object_unref (allocator);
752
753   return TRUE;
754 }
755
756 static gboolean
757 gst_video_encoder_propose_allocation_default (GstVideoEncoder * encoder,
758     GstQuery * query)
759 {
760   GstCaps *caps;
761   GstVideoInfo info;
762   GstBufferPool *pool;
763   guint size;
764
765   gst_query_parse_allocation (query, &caps, NULL);
766
767   if (caps == NULL)
768     return FALSE;
769
770   if (!gst_video_info_from_caps (&info, caps))
771     return FALSE;
772
773   size = GST_VIDEO_INFO_SIZE (&info);
774
775   if (gst_query_get_n_allocation_pools (query) == 0) {
776     GstStructure *structure;
777     GstAllocator *allocator = NULL;
778     GstAllocationParams params = { 0, 15, 0, 0 };
779
780     if (gst_query_get_n_allocation_params (query) > 0)
781       gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
782     else
783       gst_query_add_allocation_param (query, allocator, &params);
784
785     pool = gst_video_buffer_pool_new ();
786
787     structure = gst_buffer_pool_get_config (pool);
788     gst_buffer_pool_config_set_params (structure, caps, size, 0, 0);
789     gst_buffer_pool_config_set_allocator (structure, allocator, &params);
790
791     if (allocator)
792       gst_object_unref (allocator);
793
794     if (!gst_buffer_pool_set_config (pool, structure))
795       goto config_failed;
796
797     gst_query_add_allocation_pool (query, pool, size, 0, 0);
798     gst_object_unref (pool);
799     gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
800   }
801
802   return TRUE;
803
804   /* ERRORS */
805 config_failed:
806   {
807     GST_ERROR_OBJECT (encoder, "failed to set config");
808     gst_object_unref (pool);
809     return FALSE;
810   }
811 }
812
813 static gboolean
814 gst_video_encoder_sink_query (GstPad * pad, GstObject * parent,
815     GstQuery * query)
816 {
817   GstVideoEncoder *encoder;
818   gboolean res = FALSE;
819
820   encoder = GST_VIDEO_ENCODER (parent);
821
822   switch (GST_QUERY_TYPE (query)) {
823     case GST_QUERY_CAPS:
824     {
825       GstCaps *filter, *caps;
826
827       gst_query_parse_caps (query, &filter);
828       caps = gst_video_encoder_sink_getcaps (encoder, filter);
829       gst_query_set_caps_result (query, caps);
830       gst_caps_unref (caps);
831       res = TRUE;
832       break;
833     }
834     case GST_QUERY_ALLOCATION:
835     {
836       GstVideoEncoderClass *klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
837
838       if (klass->propose_allocation)
839         res = klass->propose_allocation (encoder, query);
840       break;
841     }
842     default:
843       res = gst_pad_query_default (pad, parent, query);
844       break;
845   }
846   return res;
847 }
848
849 static void
850 gst_video_encoder_finalize (GObject * object)
851 {
852   GstVideoEncoder *encoder;
853
854   GST_DEBUG_OBJECT (object, "finalize");
855
856   encoder = GST_VIDEO_ENCODER (object);
857   if (encoder->priv->headers) {
858     g_list_foreach (encoder->priv->headers, (GFunc) gst_buffer_unref, NULL);
859     g_list_free (encoder->priv->headers);
860   }
861   g_rec_mutex_clear (&encoder->stream_lock);
862
863   if (encoder->priv->allocator) {
864     gst_object_unref (encoder->priv->allocator);
865     encoder->priv->allocator = NULL;
866   }
867
868   G_OBJECT_CLASS (parent_class)->finalize (object);
869 }
870
871 static gboolean
872 gst_video_encoder_push_event (GstVideoEncoder * encoder, GstEvent * event)
873 {
874   switch (GST_EVENT_TYPE (event)) {
875     case GST_EVENT_SEGMENT:
876     {
877       GstSegment segment;
878
879       GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
880
881       gst_event_copy_segment (event, &segment);
882
883       GST_DEBUG_OBJECT (encoder, "segment %" GST_SEGMENT_FORMAT, &segment);
884
885       if (segment.format != GST_FORMAT_TIME) {
886         GST_DEBUG_OBJECT (encoder, "received non TIME segment");
887         GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
888         break;
889       }
890
891       encoder->output_segment = segment;
892       GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
893       break;
894     }
895     default:
896       break;
897   }
898
899   return gst_pad_push_event (encoder->srcpad, event);
900 }
901
902 static gboolean
903 gst_video_encoder_sink_event_default (GstVideoEncoder * encoder,
904     GstEvent * event)
905 {
906   GstVideoEncoderClass *encoder_class;
907   gboolean ret = FALSE;
908
909   encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);
910
911   switch (GST_EVENT_TYPE (event)) {
912     case GST_EVENT_CAPS:
913     {
914       GstCaps *caps;
915
916       gst_event_parse_caps (event, &caps);
917       ret = TRUE;
918       encoder->priv->do_caps = TRUE;
919       gst_event_unref (event);
920       event = NULL;
921       break;
922     }
923     case GST_EVENT_EOS:
924     {
925       GstFlowReturn flow_ret;
926
927       GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
928       encoder->priv->at_eos = TRUE;
929
930       if (encoder_class->finish) {
931         flow_ret = encoder_class->finish (encoder);
932       } else {
933         flow_ret = GST_FLOW_OK;
934       }
935
936       ret = (flow_ret == GST_FLOW_OK);
937       GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
938       break;
939     }
940     case GST_EVENT_SEGMENT:
941     {
942       GstSegment segment;
943
944       GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
945
946       gst_event_copy_segment (event, &segment);
947
948       GST_DEBUG_OBJECT (encoder, "segment %" GST_SEGMENT_FORMAT, &segment);
949
950       if (segment.format != GST_FORMAT_TIME) {
951         GST_DEBUG_OBJECT (encoder, "received non TIME newsegment");
952         GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
953         break;
954       }
955
956       encoder->priv->at_eos = FALSE;
957
958       encoder->input_segment = segment;
959       ret = TRUE;
960       GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
961       break;
962     }
963     case GST_EVENT_CUSTOM_DOWNSTREAM:
964     {
965       if (gst_video_event_is_force_key_unit (event)) {
966         GstClockTime running_time;
967         gboolean all_headers;
968         guint count;
969
970         if (gst_video_event_parse_downstream_force_key_unit (event,
971                 NULL, NULL, &running_time, &all_headers, &count)) {
972           ForcedKeyUnitEvent *fevt;
973
974           GST_OBJECT_LOCK (encoder);
975           fevt = forced_key_unit_event_new (running_time, all_headers, count);
976           encoder->priv->force_key_unit =
977               g_list_append (encoder->priv->force_key_unit, fevt);
978           GST_OBJECT_UNLOCK (encoder);
979
980           GST_DEBUG_OBJECT (encoder,
981               "force-key-unit event: running-time %" GST_TIME_FORMAT
982               ", all_headers %d, count %u",
983               GST_TIME_ARGS (running_time), all_headers, count);
984         }
985         gst_event_unref (event);
986         event = NULL;
987         ret = TRUE;
988       }
989       break;
990     }
991     case GST_EVENT_TAG:
992     {
993       GstTagList *tags;
994
995       gst_event_parse_tag (event, &tags);
996
997       if (gst_tag_list_get_scope (tags) == GST_TAG_SCOPE_STREAM) {
998         tags = gst_tag_list_copy (tags);
999
1000         /* FIXME: make generic based on GST_TAG_FLAG_ENCODED */
1001         gst_tag_list_remove_tag (tags, GST_TAG_CODEC);
1002         gst_tag_list_remove_tag (tags, GST_TAG_AUDIO_CODEC);
1003         gst_tag_list_remove_tag (tags, GST_TAG_VIDEO_CODEC);
1004         gst_tag_list_remove_tag (tags, GST_TAG_SUBTITLE_CODEC);
1005         gst_tag_list_remove_tag (tags, GST_TAG_CONTAINER_FORMAT);
1006         gst_tag_list_remove_tag (tags, GST_TAG_BITRATE);
1007         gst_tag_list_remove_tag (tags, GST_TAG_NOMINAL_BITRATE);
1008         gst_tag_list_remove_tag (tags, GST_TAG_MAXIMUM_BITRATE);
1009         gst_tag_list_remove_tag (tags, GST_TAG_MINIMUM_BITRATE);
1010         gst_tag_list_remove_tag (tags, GST_TAG_ENCODER);
1011         gst_tag_list_remove_tag (tags, GST_TAG_ENCODER_VERSION);
1012
1013         gst_video_encoder_merge_tags (encoder, tags, GST_TAG_MERGE_REPLACE);
1014         gst_tag_list_unref (tags);
1015         gst_event_unref (event);
1016         event = NULL;
1017         ret = TRUE;
1018       }
1019       break;
1020     }
1021     default:
1022       break;
1023   }
1024
1025   /* Forward non-serialized events and EOS/FLUSH_STOP immediately.
1026    * For EOS this is required because no buffer or serialized event
1027    * will come after EOS and nothing could trigger another
1028    * _finish_frame() call.   *
1029    * If the subclass handles sending of EOS manually it can simply
1030    * not chain up to the parent class' event handler
1031    *
1032    * For FLUSH_STOP this is required because it is expected
1033    * to be forwarded immediately and no buffers are queued anyway.
1034    */
1035   if (event) {
1036     if (!GST_EVENT_IS_SERIALIZED (event)
1037         || GST_EVENT_TYPE (event) == GST_EVENT_EOS
1038         || GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
1039       ret = gst_video_encoder_push_event (encoder, event);
1040     } else {
1041       GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1042       encoder->priv->current_frame_events =
1043           g_list_prepend (encoder->priv->current_frame_events, event);
1044       GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1045       ret = TRUE;
1046     }
1047   }
1048
1049   return ret;
1050 }
1051
1052 static gboolean
1053 gst_video_encoder_sink_event (GstPad * pad, GstObject * parent,
1054     GstEvent * event)
1055 {
1056   GstVideoEncoder *enc;
1057   GstVideoEncoderClass *klass;
1058   gboolean ret = TRUE;
1059
1060   enc = GST_VIDEO_ENCODER (parent);
1061   klass = GST_VIDEO_ENCODER_GET_CLASS (enc);
1062
1063   GST_DEBUG_OBJECT (enc, "received event %d, %s", GST_EVENT_TYPE (event),
1064       GST_EVENT_TYPE_NAME (event));
1065
1066   if (klass->sink_event)
1067     ret = klass->sink_event (enc, event);
1068
1069   return ret;
1070 }
1071
1072 static gboolean
1073 gst_video_encoder_src_event_default (GstVideoEncoder * encoder,
1074     GstEvent * event)
1075 {
1076   gboolean ret = FALSE;
1077
1078   switch (GST_EVENT_TYPE (event)) {
1079     case GST_EVENT_CUSTOM_UPSTREAM:
1080     {
1081       if (gst_video_event_is_force_key_unit (event)) {
1082         GstClockTime running_time;
1083         gboolean all_headers;
1084         guint count;
1085
1086         if (gst_video_event_parse_upstream_force_key_unit (event,
1087                 &running_time, &all_headers, &count)) {
1088           ForcedKeyUnitEvent *fevt;
1089
1090           GST_OBJECT_LOCK (encoder);
1091           fevt = forced_key_unit_event_new (running_time, all_headers, count);
1092           encoder->priv->force_key_unit =
1093               g_list_append (encoder->priv->force_key_unit, fevt);
1094           GST_OBJECT_UNLOCK (encoder);
1095
1096           GST_DEBUG_OBJECT (encoder,
1097               "force-key-unit event: running-time %" GST_TIME_FORMAT
1098               ", all_headers %d, count %u",
1099               GST_TIME_ARGS (running_time), all_headers, count);
1100         }
1101         gst_event_unref (event);
1102         event = NULL;
1103         ret = TRUE;
1104       }
1105       break;
1106     }
1107     default:
1108       break;
1109   }
1110
1111   if (event)
1112     ret =
1113         gst_pad_event_default (encoder->srcpad, GST_OBJECT_CAST (encoder),
1114         event);
1115
1116   return ret;
1117 }
1118
1119 static gboolean
1120 gst_video_encoder_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
1121 {
1122   GstVideoEncoder *encoder;
1123   GstVideoEncoderClass *klass;
1124   gboolean ret = FALSE;
1125
1126   encoder = GST_VIDEO_ENCODER (parent);
1127   klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
1128
1129   GST_LOG_OBJECT (encoder, "handling event: %" GST_PTR_FORMAT, event);
1130
1131   if (klass->src_event)
1132     ret = klass->src_event (encoder, event);
1133
1134   return ret;
1135 }
1136
1137 static gboolean
1138 gst_video_encoder_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
1139 {
1140   GstVideoEncoderPrivate *priv;
1141   GstVideoEncoder *enc;
1142   gboolean res;
1143
1144   enc = GST_VIDEO_ENCODER (parent);
1145   priv = enc->priv;
1146
1147   GST_LOG_OBJECT (enc, "handling query: %" GST_PTR_FORMAT, query);
1148
1149   switch (GST_QUERY_TYPE (query)) {
1150     case GST_QUERY_CONVERT:
1151     {
1152       GstFormat src_fmt, dest_fmt;
1153       gint64 src_val, dest_val;
1154
1155       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
1156       res =
1157           gst_video_encoded_video_convert (priv->bytes, priv->time, src_fmt,
1158           src_val, &dest_fmt, &dest_val);
1159       if (!res)
1160         goto error;
1161       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1162       break;
1163     }
1164     case GST_QUERY_LATENCY:
1165     {
1166       gboolean live;
1167       GstClockTime min_latency, max_latency;
1168
1169       res = gst_pad_peer_query (enc->sinkpad, query);
1170       if (res) {
1171         gst_query_parse_latency (query, &live, &min_latency, &max_latency);
1172         GST_DEBUG_OBJECT (enc, "Peer latency: live %d, min %"
1173             GST_TIME_FORMAT " max %" GST_TIME_FORMAT, live,
1174             GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
1175
1176         GST_OBJECT_LOCK (enc);
1177         min_latency += priv->min_latency;
1178         if (enc->priv->max_latency == GST_CLOCK_TIME_NONE) {
1179           max_latency = GST_CLOCK_TIME_NONE;
1180         } else if (max_latency != GST_CLOCK_TIME_NONE) {
1181           max_latency += enc->priv->max_latency;
1182         }
1183         GST_OBJECT_UNLOCK (enc);
1184
1185         gst_query_set_latency (query, live, min_latency, max_latency);
1186       }
1187     }
1188       break;
1189     default:
1190       res = gst_pad_query_default (pad, parent, query);
1191   }
1192   return res;
1193
1194 error:
1195   GST_DEBUG_OBJECT (enc, "query failed");
1196   return res;
1197 }
1198
1199 static GstVideoCodecFrame *
1200 gst_video_encoder_new_frame (GstVideoEncoder * encoder, GstBuffer * buf,
1201     GstClockTime pts, GstClockTime dts, GstClockTime duration)
1202 {
1203   GstVideoEncoderPrivate *priv = encoder->priv;
1204   GstVideoCodecFrame *frame;
1205
1206   frame = g_slice_new0 (GstVideoCodecFrame);
1207
1208   frame->ref_count = 1;
1209
1210   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1211   frame->system_frame_number = priv->system_frame_number;
1212   priv->system_frame_number++;
1213
1214   frame->presentation_frame_number = priv->presentation_frame_number;
1215   priv->presentation_frame_number++;
1216   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1217
1218   frame->events = priv->current_frame_events;
1219   priv->current_frame_events = NULL;
1220   frame->input_buffer = buf;
1221   frame->pts = pts;
1222   frame->dts = dts;
1223   frame->duration = duration;
1224
1225   return frame;
1226 }
1227
1228
1229 static GstFlowReturn
1230 gst_video_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
1231 {
1232   GstVideoEncoder *encoder;
1233   GstVideoEncoderPrivate *priv;
1234   GstVideoEncoderClass *klass;
1235   GstVideoCodecFrame *frame;
1236   GstClockTime pts, dts, duration;
1237   GstFlowReturn ret = GST_FLOW_OK;
1238   guint64 start, stop, cstart, cstop;
1239
1240   encoder = GST_VIDEO_ENCODER (parent);
1241   priv = encoder->priv;
1242   klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
1243
1244   g_return_val_if_fail (klass->handle_frame != NULL, GST_FLOW_ERROR);
1245
1246   if (G_UNLIKELY (encoder->priv->do_caps)) {
1247     GstCaps *caps = gst_pad_get_current_caps (encoder->sinkpad);
1248     if (!caps)
1249       goto not_negotiated;
1250     if (!gst_video_encoder_setcaps (encoder, caps)) {
1251       gst_caps_unref (caps);
1252       goto not_negotiated;
1253     }
1254     gst_caps_unref (caps);
1255     encoder->priv->do_caps = FALSE;
1256   }
1257
1258   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1259
1260   pts = GST_BUFFER_PTS (buf);
1261   dts = GST_BUFFER_DTS (buf);
1262   duration = GST_BUFFER_DURATION (buf);
1263
1264   GST_LOG_OBJECT (encoder,
1265       "received buffer of size %" G_GSIZE_FORMAT " with PTS %" GST_TIME_FORMAT
1266       ", PTS %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT,
1267       gst_buffer_get_size (buf), GST_TIME_ARGS (pts), GST_TIME_ARGS (dts),
1268       GST_TIME_ARGS (duration));
1269
1270   if (priv->at_eos) {
1271     ret = GST_FLOW_EOS;
1272     goto done;
1273   }
1274
1275   start = pts;
1276   if (GST_CLOCK_TIME_IS_VALID (duration))
1277     stop = start + duration;
1278   else
1279     stop = GST_CLOCK_TIME_NONE;
1280
1281   /* Drop buffers outside of segment */
1282   if (!gst_segment_clip (&encoder->output_segment,
1283           GST_FORMAT_TIME, start, stop, &cstart, &cstop)) {
1284     GST_DEBUG_OBJECT (encoder, "clipping to segment dropped frame");
1285     gst_buffer_unref (buf);
1286     goto done;
1287   }
1288
1289   frame =
1290       gst_video_encoder_new_frame (encoder, buf, cstart, dts, cstop - cstart);
1291
1292   GST_OBJECT_LOCK (encoder);
1293   if (priv->force_key_unit) {
1294     ForcedKeyUnitEvent *fevt = NULL;
1295     GstClockTime running_time;
1296     GList *l;
1297
1298     running_time =
1299         gst_segment_to_running_time (&encoder->output_segment, GST_FORMAT_TIME,
1300         cstart);
1301
1302     for (l = priv->force_key_unit; l; l = l->next) {
1303       ForcedKeyUnitEvent *tmp = l->data;
1304
1305       /* Skip pending keyunits */
1306       if (tmp->pending)
1307         continue;
1308
1309       /* Simple case, keyunit ASAP */
1310       if (tmp->running_time == GST_CLOCK_TIME_NONE) {
1311         fevt = tmp;
1312         break;
1313       }
1314
1315       /* Event for before this frame */
1316       if (tmp->running_time <= running_time) {
1317         fevt = tmp;
1318         break;
1319       }
1320     }
1321
1322     if (fevt) {
1323       GST_DEBUG_OBJECT (encoder,
1324           "Forcing a key unit at running time %" GST_TIME_FORMAT,
1325           GST_TIME_ARGS (running_time));
1326       GST_VIDEO_CODEC_FRAME_SET_FORCE_KEYFRAME (frame);
1327       if (fevt->all_headers)
1328         GST_VIDEO_CODEC_FRAME_SET_FORCE_KEYFRAME_HEADERS (frame);
1329       fevt->pending = TRUE;
1330     }
1331   }
1332   GST_OBJECT_UNLOCK (encoder);
1333
1334   gst_video_codec_frame_ref (frame);
1335   priv->frames = g_list_append (priv->frames, frame);
1336
1337   /* new data, more finish needed */
1338   priv->drained = FALSE;
1339
1340   GST_LOG_OBJECT (encoder, "passing frame pfn %d to subclass",
1341       frame->presentation_frame_number);
1342
1343   ret = klass->handle_frame (encoder, frame);
1344
1345 done:
1346   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1347
1348   return ret;
1349
1350   /* ERRORS */
1351 not_negotiated:
1352   {
1353     GST_ELEMENT_ERROR (encoder, CORE, NEGOTIATION, (NULL),
1354         ("encoder not initialized"));
1355     gst_buffer_unref (buf);
1356     return GST_FLOW_NOT_NEGOTIATED;
1357   }
1358 }
1359
1360 static GstStateChangeReturn
1361 gst_video_encoder_change_state (GstElement * element, GstStateChange transition)
1362 {
1363   GstVideoEncoder *encoder;
1364   GstVideoEncoderClass *encoder_class;
1365   GstStateChangeReturn ret;
1366
1367   encoder = GST_VIDEO_ENCODER (element);
1368   encoder_class = GST_VIDEO_ENCODER_GET_CLASS (element);
1369
1370   switch (transition) {
1371     case GST_STATE_CHANGE_NULL_TO_READY:
1372       /* open device/library if needed */
1373       if (encoder_class->open && !encoder_class->open (encoder))
1374         goto open_failed;
1375       break;
1376     case GST_STATE_CHANGE_READY_TO_PAUSED:
1377       /* Initialize device/library if needed */
1378       if (encoder_class->start && !encoder_class->start (encoder))
1379         goto start_failed;
1380       break;
1381     default:
1382       break;
1383   }
1384
1385   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1386
1387   switch (transition) {
1388     case GST_STATE_CHANGE_PAUSED_TO_READY:
1389       gst_video_encoder_reset (encoder);
1390       if (encoder_class->stop && !encoder_class->stop (encoder))
1391         goto stop_failed;
1392       break;
1393     case GST_STATE_CHANGE_READY_TO_NULL:
1394       /* close device/library if needed */
1395       if (encoder_class->close && !encoder_class->close (encoder))
1396         goto close_failed;
1397       break;
1398     default:
1399       break;
1400   }
1401
1402   return ret;
1403
1404   /* Errors */
1405
1406 open_failed:
1407   {
1408     GST_ELEMENT_ERROR (encoder, LIBRARY, INIT, (NULL),
1409         ("Failed to open encoder"));
1410     return GST_STATE_CHANGE_FAILURE;
1411   }
1412
1413 start_failed:
1414   {
1415     GST_ELEMENT_ERROR (encoder, LIBRARY, INIT, (NULL),
1416         ("Failed to start encoder"));
1417     return GST_STATE_CHANGE_FAILURE;
1418   }
1419
1420 stop_failed:
1421   {
1422     GST_ELEMENT_ERROR (encoder, LIBRARY, INIT, (NULL),
1423         ("Failed to stop encoder"));
1424     return GST_STATE_CHANGE_FAILURE;
1425   }
1426
1427 close_failed:
1428   {
1429     GST_ELEMENT_ERROR (encoder, LIBRARY, INIT, (NULL),
1430         ("Failed to close encoder"));
1431     return GST_STATE_CHANGE_FAILURE;
1432   }
1433 }
1434
1435 static gboolean
1436 gst_video_encoder_negotiate_default (GstVideoEncoder * encoder)
1437 {
1438   GstVideoEncoderClass *klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
1439   GstAllocator *allocator;
1440   GstAllocationParams params;
1441   gboolean ret;
1442   GstVideoCodecState *state = encoder->priv->output_state;
1443   GstVideoInfo *info = &state->info;
1444   GstQuery *query = NULL;
1445
1446   g_return_val_if_fail (state->caps != NULL, FALSE);
1447
1448   if (encoder->priv->output_state_changed) {
1449     state->caps = gst_caps_make_writable (state->caps);
1450
1451     /* Fill caps */
1452     gst_caps_set_simple (state->caps, "width", G_TYPE_INT, info->width,
1453         "height", G_TYPE_INT, info->height,
1454         "pixel-aspect-ratio", GST_TYPE_FRACTION,
1455         info->par_n, info->par_d, NULL);
1456     if (info->flags & GST_VIDEO_FLAG_VARIABLE_FPS && info->fps_n != 0) {
1457       /* variable fps with a max-framerate */
1458       gst_caps_set_simple (state->caps, "framerate", GST_TYPE_FRACTION, 0, 1,
1459           "max-framerate", GST_TYPE_FRACTION, info->fps_n, info->fps_d, NULL);
1460     } else {
1461       /* no variable fps or no max-framerate */
1462       gst_caps_set_simple (state->caps, "framerate", GST_TYPE_FRACTION,
1463           info->fps_n, info->fps_d, NULL);
1464     }
1465     if (state->codec_data)
1466       gst_caps_set_simple (state->caps, "codec_data", GST_TYPE_BUFFER,
1467           state->codec_data, NULL);
1468     encoder->priv->output_state_changed = FALSE;
1469   }
1470
1471   ret = gst_pad_set_caps (encoder->srcpad, state->caps);
1472   if (!ret)
1473     goto done;
1474
1475   query = gst_query_new_allocation (state->caps, TRUE);
1476   if (!gst_pad_peer_query (encoder->srcpad, query)) {
1477     GST_DEBUG_OBJECT (encoder, "didn't get downstream ALLOCATION hints");
1478   }
1479
1480   g_assert (klass->decide_allocation != NULL);
1481   ret = klass->decide_allocation (encoder, query);
1482
1483   GST_DEBUG_OBJECT (encoder, "ALLOCATION (%d) params: %" GST_PTR_FORMAT, ret,
1484       query);
1485
1486   if (!ret)
1487     goto no_decide_allocation;
1488
1489   /* we got configuration from our peer or the decide_allocation method,
1490    * parse them */
1491   if (gst_query_get_n_allocation_params (query) > 0) {
1492     gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
1493   } else {
1494     allocator = NULL;
1495     gst_allocation_params_init (&params);
1496   }
1497
1498   if (encoder->priv->allocator)
1499     gst_object_unref (encoder->priv->allocator);
1500   encoder->priv->allocator = allocator;
1501   encoder->priv->params = params;
1502
1503 done:
1504   if (query)
1505     gst_query_unref (query);
1506
1507   return ret;
1508
1509   /* Errors */
1510 no_decide_allocation:
1511   {
1512     GST_WARNING_OBJECT (encoder, "Subclass failed to decide allocation");
1513     goto done;
1514   }
1515 }
1516
1517 /**
1518  * gst_video_encoder_negotiate:
1519  * @encoder: a #GstVideoEncoder
1520  *
1521  * Negotiate with downstream elements to currently configured #GstVideoCodecState.
1522  *
1523  * Returns: #TRUE if the negotiation succeeded, else #FALSE.
1524  */
1525 gboolean
1526 gst_video_encoder_negotiate (GstVideoEncoder * encoder)
1527 {
1528   GstVideoEncoderClass *klass;
1529   gboolean ret = TRUE;
1530
1531   g_return_val_if_fail (GST_IS_VIDEO_ENCODER (encoder), FALSE);
1532
1533   klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
1534
1535   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1536   if (klass->negotiate)
1537     ret = klass->negotiate (encoder);
1538   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1539
1540   return ret;
1541 }
1542
1543 /**
1544  * gst_video_encoder_allocate_output_buffer:
1545  * @encoder: a #GstVideoEncoder
1546  * @size: size of the buffer
1547  *
1548  * Helper function that allocates a buffer to hold an encoded video frame
1549  * for @encoder's current #GstVideoCodecState.
1550  *
1551  * Returns: (transfer full): allocated buffer
1552  */
1553 GstBuffer *
1554 gst_video_encoder_allocate_output_buffer (GstVideoEncoder * encoder, gsize size)
1555 {
1556   GstBuffer *buffer;
1557
1558   g_return_val_if_fail (size > 0, NULL);
1559
1560   GST_DEBUG ("alloc src buffer");
1561
1562   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1563   if (G_UNLIKELY (encoder->priv->output_state_changed
1564           || (encoder->priv->output_state
1565               && gst_pad_check_reconfigure (encoder->srcpad))))
1566     gst_video_encoder_negotiate (encoder);
1567
1568   buffer =
1569       gst_buffer_new_allocate (encoder->priv->allocator, size,
1570       &encoder->priv->params);
1571
1572   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1573
1574   return buffer;
1575 }
1576
1577 /**
1578  * gst_video_encoder_allocate_output_frame:
1579  * @encoder: a #GstVideoEncoder
1580  * @frame: a #GstVideoCodecFrame
1581  * @size: size of the buffer
1582  *
1583  * Helper function that allocates a buffer to hold an encoded video frame for @encoder's
1584  * current #GstVideoCodecState.  Subclass should already have configured video
1585  * state and set src pad caps.
1586  *
1587  * The buffer allocated here is owned by the frame and you should only
1588  * keep references to the frame, not the buffer.
1589  *
1590  * Returns: %GST_FLOW_OK if an output buffer could be allocated
1591  */
1592 GstFlowReturn
1593 gst_video_encoder_allocate_output_frame (GstVideoEncoder *
1594     encoder, GstVideoCodecFrame * frame, gsize size)
1595 {
1596   g_return_val_if_fail (frame->output_buffer == NULL, GST_FLOW_ERROR);
1597
1598   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1599   if (G_UNLIKELY (encoder->priv->output_state_changed
1600           || (encoder->priv->output_state
1601               && gst_pad_check_reconfigure (encoder->srcpad))))
1602     gst_video_encoder_negotiate (encoder);
1603
1604   GST_LOG_OBJECT (encoder, "alloc buffer size %" G_GSIZE_FORMAT, size);
1605
1606   frame->output_buffer =
1607       gst_buffer_new_allocate (encoder->priv->allocator, size,
1608       &encoder->priv->params);
1609
1610   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1611
1612   return frame->output_buffer ? GST_FLOW_OK : GST_FLOW_ERROR;
1613 }
1614
1615 /**
1616  * gst_video_encoder_finish_frame:
1617  * @encoder: a #GstVideoEncoder
1618  * @frame: (transfer full): an encoded #GstVideoCodecFrame 
1619  *
1620  * @frame must have a valid encoded data buffer, whose metadata fields
1621  * are then appropriately set according to frame data or no buffer at
1622  * all if the frame should be dropped.
1623  * It is subsequently pushed downstream or provided to @pre_push.
1624  * In any case, the frame is considered finished and released.
1625  *
1626  * After calling this function the output buffer of the frame is to be
1627  * considered read-only. This function will also change the metadata
1628  * of the buffer.
1629  *
1630  * Returns: a #GstFlowReturn resulting from sending data downstream
1631  */
1632 GstFlowReturn
1633 gst_video_encoder_finish_frame (GstVideoEncoder * encoder,
1634     GstVideoCodecFrame * frame)
1635 {
1636   GstVideoEncoderPrivate *priv = encoder->priv;
1637   GstFlowReturn ret = GST_FLOW_OK;
1638   GstVideoEncoderClass *encoder_class;
1639   GList *l;
1640   gboolean send_headers = FALSE;
1641   gboolean discont = (frame->presentation_frame_number == 0);
1642
1643   encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);
1644
1645   GST_LOG_OBJECT (encoder,
1646       "finish frame fpn %d", frame->presentation_frame_number);
1647
1648   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1649
1650   if (G_UNLIKELY (priv->output_state_changed || (priv->output_state
1651               && gst_pad_check_reconfigure (encoder->srcpad))))
1652     gst_video_encoder_negotiate (encoder);
1653
1654
1655   if (G_UNLIKELY (priv->output_state == NULL))
1656     goto no_output_state;
1657
1658   /* Push all pending events that arrived before this frame */
1659   for (l = priv->frames; l; l = l->next) {
1660     GstVideoCodecFrame *tmp = l->data;
1661
1662     if (tmp->events) {
1663       GList *k;
1664
1665       for (k = g_list_last (tmp->events); k; k = k->prev)
1666         gst_video_encoder_push_event (encoder, k->data);
1667       g_list_free (tmp->events);
1668       tmp->events = NULL;
1669     }
1670
1671     if (tmp == frame)
1672       break;
1673   }
1674
1675   if (priv->tags && priv->tags_changed) {
1676     gst_video_encoder_push_event (encoder,
1677         gst_event_new_tag (gst_tag_list_ref (priv->tags)));
1678     priv->tags_changed = FALSE;
1679   }
1680
1681   /* no buffer data means this frame is skipped/dropped */
1682   if (!frame->output_buffer) {
1683     GST_DEBUG_OBJECT (encoder, "skipping frame %" GST_TIME_FORMAT,
1684         GST_TIME_ARGS (frame->pts));
1685     goto done;
1686   }
1687
1688   if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame) && priv->force_key_unit) {
1689     GstClockTime stream_time, running_time;
1690     GstEvent *ev;
1691     ForcedKeyUnitEvent *fevt = NULL;
1692     GList *l;
1693
1694     running_time =
1695         gst_segment_to_running_time (&encoder->output_segment, GST_FORMAT_TIME,
1696         frame->pts);
1697
1698     GST_OBJECT_LOCK (encoder);
1699     for (l = priv->force_key_unit; l; l = l->next) {
1700       ForcedKeyUnitEvent *tmp = l->data;
1701
1702       /* Skip non-pending keyunits */
1703       if (!tmp->pending)
1704         continue;
1705
1706       /* Simple case, keyunit ASAP */
1707       if (tmp->running_time == GST_CLOCK_TIME_NONE) {
1708         fevt = tmp;
1709         break;
1710       }
1711
1712       /* Event for before this frame */
1713       if (tmp->running_time <= running_time) {
1714         fevt = tmp;
1715         break;
1716       }
1717     }
1718
1719     if (fevt) {
1720       priv->force_key_unit = g_list_remove (priv->force_key_unit, fevt);
1721     }
1722     GST_OBJECT_UNLOCK (encoder);
1723
1724     if (fevt) {
1725       stream_time =
1726           gst_segment_to_stream_time (&encoder->output_segment, GST_FORMAT_TIME,
1727           frame->pts);
1728
1729       ev = gst_video_event_new_downstream_force_key_unit
1730           (frame->pts, stream_time, running_time,
1731           fevt->all_headers, fevt->count);
1732
1733       gst_video_encoder_push_event (encoder, ev);
1734
1735       if (fevt->all_headers)
1736         send_headers = TRUE;
1737
1738       GST_DEBUG_OBJECT (encoder,
1739           "Forced key unit: running-time %" GST_TIME_FORMAT
1740           ", all_headers %d, count %u",
1741           GST_TIME_ARGS (running_time), fevt->all_headers, fevt->count);
1742       forced_key_unit_event_free (fevt);
1743     }
1744   }
1745
1746   if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)) {
1747     priv->distance_from_sync = 0;
1748     GST_BUFFER_FLAG_UNSET (frame->output_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
1749     /* For keyframes, DTS = PTS */
1750     frame->dts = frame->pts;
1751   } else {
1752     GST_BUFFER_FLAG_SET (frame->output_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
1753   }
1754
1755   frame->distance_from_sync = priv->distance_from_sync;
1756   priv->distance_from_sync++;
1757
1758   GST_BUFFER_PTS (frame->output_buffer) = frame->pts;
1759   GST_BUFFER_DTS (frame->output_buffer) = frame->dts;
1760   GST_BUFFER_DURATION (frame->output_buffer) = frame->duration;
1761
1762   /* update rate estimate */
1763   priv->bytes += gst_buffer_get_size (frame->output_buffer);
1764   if (GST_CLOCK_TIME_IS_VALID (frame->duration)) {
1765     priv->time += frame->duration;
1766   } else {
1767     /* better none than nothing valid */
1768     priv->time = GST_CLOCK_TIME_NONE;
1769   }
1770
1771   if (G_UNLIKELY (send_headers || priv->new_headers)) {
1772     GList *tmp, *copy = NULL;
1773
1774     GST_DEBUG_OBJECT (encoder, "Sending headers");
1775
1776     /* First make all buffers metadata-writable */
1777     for (tmp = priv->headers; tmp; tmp = tmp->next) {
1778       GstBuffer *tmpbuf = GST_BUFFER (tmp->data);
1779
1780       copy = g_list_append (copy, gst_buffer_make_writable (tmpbuf));
1781     }
1782     g_list_free (priv->headers);
1783     priv->headers = copy;
1784
1785     for (tmp = priv->headers; tmp; tmp = tmp->next) {
1786       GstBuffer *tmpbuf = GST_BUFFER (tmp->data);
1787
1788       gst_buffer_ref (tmpbuf);
1789       priv->bytes += gst_buffer_get_size (tmpbuf);
1790       if (G_UNLIKELY (discont)) {
1791         GST_LOG_OBJECT (encoder, "marking discont");
1792         GST_BUFFER_FLAG_SET (tmpbuf, GST_BUFFER_FLAG_DISCONT);
1793         discont = FALSE;
1794       }
1795
1796       gst_pad_push (encoder->srcpad, tmpbuf);
1797     }
1798     priv->new_headers = FALSE;
1799   }
1800
1801   if (G_UNLIKELY (discont)) {
1802     GST_LOG_OBJECT (encoder, "marking discont");
1803     GST_BUFFER_FLAG_SET (frame->output_buffer, GST_BUFFER_FLAG_DISCONT);
1804   }
1805
1806   if (encoder_class->pre_push)
1807     ret = encoder_class->pre_push (encoder, frame);
1808
1809   /* A reference always needs to be owned by the frame on the buffer.
1810    * For that reason, we use a complete sub-buffer (zero-cost) to push
1811    * downstream.
1812    * The original buffer will be free-ed only when downstream AND the
1813    * current implementation are done with the frame. */
1814   if (ret == GST_FLOW_OK)
1815     ret = gst_pad_push (encoder->srcpad, gst_buffer_ref (frame->output_buffer));
1816
1817 done:
1818   /* handed out */
1819
1820   /* unref once from the list */
1821   l = g_list_find (priv->frames, frame);
1822   if (l) {
1823     gst_video_codec_frame_unref (frame);
1824     priv->frames = g_list_delete_link (priv->frames, l);
1825   }
1826   /* unref because this function takes ownership */
1827   gst_video_codec_frame_unref (frame);
1828
1829   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1830
1831   return ret;
1832
1833   /* ERRORS */
1834 no_output_state:
1835   {
1836     GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1837     GST_ERROR_OBJECT (encoder, "Output state was not configured");
1838     return GST_FLOW_ERROR;
1839   }
1840 }
1841
1842 /**
1843  * gst_video_encoder_get_output_state:
1844  * @encoder: a #GstVideoEncoder
1845  *
1846  * Get the current #GstVideoCodecState
1847  *
1848  * Returns: (transfer full): #GstVideoCodecState describing format of video data.
1849  */
1850 GstVideoCodecState *
1851 gst_video_encoder_get_output_state (GstVideoEncoder * encoder)
1852 {
1853   GstVideoCodecState *state;
1854
1855   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1856   state = gst_video_codec_state_ref (encoder->priv->output_state);
1857   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1858
1859   return state;
1860 }
1861
1862 /**
1863  * gst_video_encoder_set_output_state:
1864  * @encoder: a #GstVideoEncoder
1865  * @caps: (transfer full): the #GstCaps to use for the output
1866  * @reference: (allow-none) (transfer none): An optional reference @GstVideoCodecState
1867  *
1868  * Creates a new #GstVideoCodecState with the specified caps as the output state
1869  * for the encoder.
1870  * Any previously set output state on @decoder will be replaced by the newly
1871  * created one.
1872  *
1873  * The specified @caps should not contain any resolution, pixel-aspect-ratio,
1874  * framerate, codec-data, .... Those should be specified instead in the returned
1875  * #GstVideoCodecState.
1876  *
1877  * If the subclass wishes to copy over existing fields (like pixel aspect ratio,
1878  * or framerate) from an existing #GstVideoCodecState, it can be provided as a
1879  * @reference.
1880  *
1881  * If the subclass wishes to override some fields from the output state (like
1882  * pixel-aspect-ratio or framerate) it can do so on the returned #GstVideoCodecState.
1883  *
1884  * The new output state will only take effect (set on pads and buffers) starting
1885  * from the next call to #gst_video_encoder_finish_frame().
1886  *
1887  * Returns: (transfer full): the newly configured output state.
1888  */
1889 GstVideoCodecState *
1890 gst_video_encoder_set_output_state (GstVideoEncoder * encoder, GstCaps * caps,
1891     GstVideoCodecState * reference)
1892 {
1893   GstVideoEncoderPrivate *priv = encoder->priv;
1894   GstVideoCodecState *state;
1895
1896   g_return_val_if_fail (caps != NULL, NULL);
1897
1898   state = _new_output_state (caps, reference);
1899
1900   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1901   if (priv->output_state)
1902     gst_video_codec_state_unref (priv->output_state);
1903   priv->output_state = gst_video_codec_state_ref (state);
1904
1905   priv->output_state_changed = TRUE;
1906   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1907
1908   return state;
1909 }
1910
1911 /**
1912  * gst_video_encoder_set_latency:
1913  * @encoder: a #GstVideoEncoder
1914  * @min_latency: minimum latency
1915  * @max_latency: maximum latency
1916  *
1917  * Informs baseclass of encoding latency.
1918  */
1919 void
1920 gst_video_encoder_set_latency (GstVideoEncoder * encoder,
1921     GstClockTime min_latency, GstClockTime max_latency)
1922 {
1923   g_return_if_fail (GST_CLOCK_TIME_IS_VALID (min_latency));
1924   g_return_if_fail (max_latency >= min_latency);
1925
1926   GST_OBJECT_LOCK (encoder);
1927   encoder->priv->min_latency = min_latency;
1928   encoder->priv->max_latency = max_latency;
1929   GST_OBJECT_UNLOCK (encoder);
1930
1931   gst_element_post_message (GST_ELEMENT_CAST (encoder),
1932       gst_message_new_latency (GST_OBJECT_CAST (encoder)));
1933 }
1934
1935 /**
1936  * gst_video_encoder_get_latency:
1937  * @encoder: a #GstVideoEncoder
1938  * @min_latency: (out) (allow-none): address of variable in which to store the
1939  *     configured minimum latency, or %NULL
1940  * @max_latency: (out) (allow-none): address of variable in which to store the
1941  *     configured maximum latency, or %NULL
1942  *
1943  * Query the configured encoding latency. Results will be returned via
1944  * @min_latency and @max_latency.
1945  */
1946 void
1947 gst_video_encoder_get_latency (GstVideoEncoder * encoder,
1948     GstClockTime * min_latency, GstClockTime * max_latency)
1949 {
1950   GST_OBJECT_LOCK (encoder);
1951   if (min_latency)
1952     *min_latency = encoder->priv->min_latency;
1953   if (max_latency)
1954     *max_latency = encoder->priv->max_latency;
1955   GST_OBJECT_UNLOCK (encoder);
1956 }
1957
1958 /**
1959  * gst_video_encoder_get_oldest_frame:
1960  * @encoder: a #GstVideoEncoder
1961  *
1962  * Get the oldest unfinished pending #GstVideoCodecFrame
1963  *
1964  * Returns: (transfer full): oldest unfinished pending #GstVideoCodecFrame
1965  */
1966 GstVideoCodecFrame *
1967 gst_video_encoder_get_oldest_frame (GstVideoEncoder * encoder)
1968 {
1969   GstVideoCodecFrame *frame = NULL;
1970
1971   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1972   if (encoder->priv->frames)
1973     frame = gst_video_codec_frame_ref (encoder->priv->frames->data);
1974   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
1975
1976   return (GstVideoCodecFrame *) frame;
1977 }
1978
1979 /**
1980  * gst_video_encoder_get_frame:
1981  * @encoder: a #GstVideoEnccoder
1982  * @frame_number: system_frame_number of a frame
1983  *
1984  * Get a pending unfinished #GstVideoCodecFrame
1985  * 
1986  * Returns: (transfer full): pending unfinished #GstVideoCodecFrame identified by @frame_number.
1987  */
1988 GstVideoCodecFrame *
1989 gst_video_encoder_get_frame (GstVideoEncoder * encoder, int frame_number)
1990 {
1991   GList *g;
1992   GstVideoCodecFrame *frame = NULL;
1993
1994   GST_DEBUG_OBJECT (encoder, "frame_number : %d", frame_number);
1995
1996   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
1997   for (g = encoder->priv->frames; g; g = g->next) {
1998     GstVideoCodecFrame *tmp = g->data;
1999
2000     if (tmp->system_frame_number == frame_number) {
2001       frame = gst_video_codec_frame_ref (tmp);
2002       break;
2003     }
2004   }
2005   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2006
2007   return frame;
2008 }
2009
2010 /**
2011  * gst_video_encoder_get_frames:
2012  * @encoder: a #GstVideoEncoder
2013  *
2014  * Get all pending unfinished #GstVideoCodecFrame
2015  * 
2016  * Returns: (transfer full) (element-type GstVideoCodecFrame): pending unfinished #GstVideoCodecFrame.
2017  */
2018 GList *
2019 gst_video_encoder_get_frames (GstVideoEncoder * encoder)
2020 {
2021   GList *frames;
2022
2023   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2024   frames = g_list_copy (encoder->priv->frames);
2025   g_list_foreach (frames, (GFunc) gst_video_codec_frame_ref, NULL);
2026   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2027
2028   return frames;
2029 }
2030
2031 /**
2032  * gst_video_encoder_merge_tags:
2033  * @encoder: a #GstVideoEncoder
2034  * @tags: a #GstTagList to merge
2035  * @mode: the #GstTagMergeMode to use
2036  *
2037  * Adds tags to so-called pending tags, which will be processed
2038  * before pushing out data downstream.
2039  *
2040  * Note that this is provided for convenience, and the subclass is
2041  * not required to use this and can still do tag handling on its own.
2042  *
2043  * MT safe.
2044  */
2045 void
2046 gst_video_encoder_merge_tags (GstVideoEncoder * encoder,
2047     const GstTagList * tags, GstTagMergeMode mode)
2048 {
2049   GstTagList *otags;
2050
2051   g_return_if_fail (GST_IS_VIDEO_ENCODER (encoder));
2052   g_return_if_fail (tags == NULL || GST_IS_TAG_LIST (tags));
2053
2054   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
2055   if (tags)
2056     GST_DEBUG_OBJECT (encoder, "merging tags %" GST_PTR_FORMAT, tags);
2057   otags = encoder->priv->tags;
2058   encoder->priv->tags = gst_tag_list_merge (encoder->priv->tags, tags, mode);
2059   if (otags)
2060     gst_tag_list_unref (otags);
2061   encoder->priv->tags_changed = TRUE;
2062   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
2063 }
2064
2065 /**
2066  * gst_video_encoder_get_allocator:
2067  * @encoder: a #GstVideoEncoder
2068  * @allocator: (out) (allow-none) (transfer full): the #GstAllocator
2069  * used
2070  * @params: (out) (allow-none) (transfer full): the
2071  * #GstAllocatorParams of @allocator
2072  *
2073  * Lets #GstVideoEncoder sub-classes to know the memory @allocator
2074  * used by the base class and its @params.
2075  *
2076  * Unref the @allocator after use it.
2077  */
2078 void
2079 gst_video_encoder_get_allocator (GstVideoEncoder * encoder,
2080     GstAllocator ** allocator, GstAllocationParams * params)
2081 {
2082   g_return_if_fail (GST_IS_VIDEO_ENCODER (encoder));
2083
2084   if (allocator)
2085     *allocator = encoder->priv->allocator ?
2086         gst_object_ref (encoder->priv->allocator) : NULL;
2087
2088   if (params)
2089     *params = encoder->priv->params;
2090 }