documentation: fixed a heap o' typos
[platform/upstream/gstreamer.git] / ext / x265 / gstx265enc.c
1 /* GStreamer H265 encoder plugin
2  * Copyright (C) 2005 Michal Benes <michal.benes@itonis.tv>
3  * Copyright (C) 2005 Josef Zlomek <josef.zlomek@itonis.tv>
4  * Copyright (C) 2008 Mark Nauwelaerts <mnauw@users.sf.net>
5  * Copyright (C) 2014 Thijs Vermeir <thijs.vermeir@barco.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 /**
24  * SECTION:element-x265enc
25  * @title: x265enc
26  *
27  * This element encodes raw video into H265 compressed data.
28  *
29  **/
30
31 #ifdef HAVE_CONFIG_H
32 #  include "config.h"
33 #endif
34
35 #include "gstx265enc.h"
36
37 #include <gst/pbutils/pbutils.h>
38 #include <gst/video/video.h>
39 #include <gst/video/gstvideometa.h>
40 #include <gst/video/gstvideopool.h>
41
42 #include <string.h>
43 #include <stdlib.h>
44
45 GST_DEBUG_CATEGORY_STATIC (x265_enc_debug);
46 #define GST_CAT_DEFAULT x265_enc_debug
47
48 static x265_api default_vtable;
49
50 static const x265_api *vtable_8bit = NULL;
51 static const x265_api *vtable_10bit = NULL;
52 static const x265_api *vtable_12bit = NULL;
53
54 enum
55 {
56   PROP_0,
57   PROP_BITRATE,
58   PROP_QP,
59   PROP_OPTION_STRING,
60   PROP_X265_LOG_LEVEL,
61   PROP_SPEED_PRESET,
62   PROP_TUNE,
63   PROP_KEY_INT_MAX
64 };
65
66 #define PROP_BITRATE_DEFAULT            (2 * 1024)
67 #define PROP_QP_DEFAULT                 -1
68 #define PROP_OPTION_STRING_DEFAULT      ""
69 #define PROP_LOG_LEVEL_DEFAULT           -1     /* None   */
70 #define PROP_SPEED_PRESET_DEFAULT        6      /* Medium */
71 #define PROP_TUNE_DEFAULT                2      /* SSIM   */
72 #define PROP_KEY_INT_MAX_DEFAULT         0      /* x265 lib default */
73
74 #define GST_X265_ENC_LOG_LEVEL_TYPE (gst_x265_enc_log_level_get_type())
75 static GType
76 gst_x265_enc_log_level_get_type (void)
77 {
78   static GType log_level = 0;
79
80   static const GEnumValue log_levels[] = {
81     {X265_LOG_NONE, "No logging", "none"},
82     {X265_LOG_ERROR, "Error", "error"},
83     {X265_LOG_WARNING, "Warning", "warning"},
84     {X265_LOG_INFO, "Info", "info"},
85     {X265_LOG_DEBUG, "Debug", "debug"},
86     {X265_LOG_FULL, "Full", "full"},
87     {0, NULL, NULL}
88   };
89
90   if (!log_level) {
91     log_level = g_enum_register_static ("GstX265LogLevel", log_levels);
92   }
93   return log_level;
94 }
95
96 #define GST_X265_ENC_SPEED_PRESET_TYPE (gst_x265_enc_speed_preset_get_type())
97 static GType
98 gst_x265_enc_speed_preset_get_type (void)
99 {
100   static GType speed_preset = 0;
101   static GEnumValue *speed_presets;
102   int n, i;
103
104   if (speed_preset != 0)
105     return speed_preset;
106
107   n = 0;
108   while (x265_preset_names[n] != NULL)
109     n++;
110
111   speed_presets = g_new0 (GEnumValue, n + 2);
112
113   speed_presets[0].value = 0;
114   speed_presets[0].value_name = "No preset";
115   speed_presets[0].value_nick = "No preset";
116
117   for (i = 0; i < n; i++) {
118     speed_presets[i + 1].value = i + 1;
119     speed_presets[i + 1].value_name = x265_preset_names[i];
120     speed_presets[i + 1].value_nick = x265_preset_names[i];
121   }
122
123   speed_preset = g_enum_register_static ("GstX265SpeedPreset", speed_presets);
124
125   return speed_preset;
126 }
127
128 #define GST_X265_ENC_TUNE_TYPE (gst_x265_enc_tune_get_type())
129 static GType
130 gst_x265_enc_tune_get_type (void)
131 {
132   static GType tune = 0;
133   static GEnumValue *tune_values;
134   int n, i;
135
136   if (tune != 0)
137     return tune;
138
139   n = 0;
140   while (x265_tune_names[n] != NULL)
141     n++;
142
143   tune_values = g_new0 (GEnumValue, n + 2);
144
145   tune_values[0].value = 0;
146   tune_values[0].value_name = "No tunning";
147   tune_values[0].value_nick = "No tunning";
148
149   for (i = 0; i < n; i++) {
150     tune_values[i + 1].value = i + 1;
151     tune_values[i + 1].value_name = x265_tune_names[i];
152     tune_values[i + 1].value_nick = x265_tune_names[i];
153   }
154
155   tune = g_enum_register_static ("GstX265Tune", tune_values);
156
157   return tune;
158 }
159
160 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
161     GST_PAD_SRC,
162     GST_PAD_ALWAYS,
163     GST_STATIC_CAPS ("video/x-h265, "
164         "framerate = (fraction) [0/1, MAX], "
165         "width = (int) [ 16, MAX ], " "height = (int) [ 16, MAX ], "
166         "stream-format = (string) byte-stream, "
167         "alignment = (string) au, "
168         "profile = (string) { main, main-still-picture, main-intra, main-444,"
169         " main-444-intra, main-444-still-picture,"
170         " main-10, main-10-intra, main-422-10, main-422-10-intra,"
171         " main-444-10, main-444-10-intra,"
172         " main-12, main-12-intra, main-422-12, main-422-12-intra,"
173         " main-444-12, main-444-12-intra }")
174     );
175
176 static void gst_x265_enc_finalize (GObject * object);
177 static gboolean gst_x265_enc_start (GstVideoEncoder * encoder);
178 static gboolean gst_x265_enc_stop (GstVideoEncoder * encoder);
179 static gboolean gst_x265_enc_flush (GstVideoEncoder * encoder);
180
181 static gboolean gst_x265_enc_init_encoder (GstX265Enc * encoder);
182 static void gst_x265_enc_close_encoder (GstX265Enc * encoder);
183
184 static GstFlowReturn gst_x265_enc_finish (GstVideoEncoder * encoder);
185 static GstFlowReturn gst_x265_enc_handle_frame (GstVideoEncoder * encoder,
186     GstVideoCodecFrame * frame);
187 static void gst_x265_enc_flush_frames (GstX265Enc * encoder, gboolean send);
188 static GstFlowReturn gst_x265_enc_encode_frame (GstX265Enc * encoder,
189     x265_picture * pic_in, GstVideoCodecFrame * input_frame, guint32 * i_nal,
190     gboolean send);
191 static gboolean gst_x265_enc_set_format (GstVideoEncoder * video_enc,
192     GstVideoCodecState * state);
193 static gboolean gst_x265_enc_propose_allocation (GstVideoEncoder * encoder,
194     GstQuery * query);
195
196 static void gst_x265_enc_set_property (GObject * object, guint prop_id,
197     const GValue * value, GParamSpec * pspec);
198 static void gst_x265_enc_get_property (GObject * object, guint prop_id,
199     GValue * value, GParamSpec * pspec);
200
201 #define gst_x265_enc_parent_class parent_class
202 G_DEFINE_TYPE_WITH_CODE (GstX265Enc, gst_x265_enc, GST_TYPE_VIDEO_ENCODER,
203     G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL));
204
205 static gboolean
206 gst_x265_enc_add_x265_chroma_format (GstStructure * s,
207     gboolean allow_420, gboolean allow_422, gboolean allow_444,
208     gboolean allow_8bit, gboolean allow_10bit, gboolean allow_12bit)
209 {
210   GValue fmts = G_VALUE_INIT;
211   GValue fmt = G_VALUE_INIT;
212   gboolean ret = FALSE;
213
214   g_value_init (&fmts, GST_TYPE_LIST);
215   g_value_init (&fmt, G_TYPE_STRING);
216
217   if (allow_8bit) {
218     if (allow_444) {
219       g_value_set_string (&fmt, "Y444");
220       gst_value_list_append_value (&fmts, &fmt);
221     }
222
223     if (allow_422) {
224       g_value_set_string (&fmt, "Y42B");
225       gst_value_list_append_value (&fmts, &fmt);
226     }
227
228     if (allow_420) {
229       g_value_set_string (&fmt, "I420");
230       gst_value_list_append_value (&fmts, &fmt);
231     }
232   }
233
234   if (allow_10bit) {
235     if (allow_444) {
236       if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
237         g_value_set_string (&fmt, "Y444_10LE");
238       else
239         g_value_set_string (&fmt, "Y444_10BE");
240
241       gst_value_list_append_value (&fmts, &fmt);
242     }
243
244     if (allow_422) {
245       if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
246         g_value_set_string (&fmt, "I422_10LE");
247       else
248         g_value_set_string (&fmt, "I422_10BE");
249
250       gst_value_list_append_value (&fmts, &fmt);
251     }
252
253     if (allow_420) {
254       if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
255         g_value_set_string (&fmt, "I420_10LE");
256       else
257         g_value_set_string (&fmt, "I420_10BE");
258
259       gst_value_list_append_value (&fmts, &fmt);
260     }
261   }
262
263   if (allow_12bit) {
264     if (allow_444) {
265       if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
266         g_value_set_string (&fmt, "Y444_12LE");
267       else
268         g_value_set_string (&fmt, "Y444_12BE");
269
270       gst_value_list_append_value (&fmts, &fmt);
271     }
272
273     if (allow_422) {
274       if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
275         g_value_set_string (&fmt, "I422_12LE");
276       else
277         g_value_set_string (&fmt, "I422_12BE");
278
279       gst_value_list_append_value (&fmts, &fmt);
280     }
281
282     if (allow_420) {
283       if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
284         g_value_set_string (&fmt, "I420_12LE");
285       else
286         g_value_set_string (&fmt, "I420_12BE");
287
288       gst_value_list_append_value (&fmts, &fmt);
289     }
290   }
291
292   if (gst_value_list_get_size (&fmts) != 0) {
293     gst_structure_take_value (s, "format", &fmts);
294     ret = TRUE;
295   } else {
296     g_value_unset (&fmts);
297   }
298
299   g_value_unset (&fmt);
300
301   return ret;
302 }
303
304 static gboolean
305 gst_x265_enc_sink_query (GstVideoEncoder * enc, GstQuery * query)
306 {
307   GstPad *pad = GST_VIDEO_ENCODER_SINK_PAD (enc);
308   gboolean res;
309
310   switch (GST_QUERY_TYPE (query)) {
311     case GST_QUERY_ACCEPT_CAPS:{
312       GstCaps *acceptable, *caps;
313
314       acceptable = gst_pad_get_pad_template_caps (pad);
315
316       gst_query_parse_accept_caps (query, &caps);
317
318       gst_query_set_accept_caps_result (query,
319           gst_caps_is_subset (caps, acceptable));
320       gst_caps_unref (acceptable);
321       res = TRUE;
322     }
323       break;
324     default:
325       res = GST_VIDEO_ENCODER_CLASS (parent_class)->sink_query (enc, query);
326       break;
327   }
328
329   return res;
330 }
331
332 static void
333 check_formats (const gchar * str, guint * max_chroma, guint * max_bit_minus_8)
334 {
335   if (!str)
336     return;
337
338   if (g_strrstr (str, "-444"))
339     *max_chroma = 2;
340   else if (g_strrstr (str, "-422") && *max_chroma < 1)
341     *max_chroma = 1;
342
343   if (g_strrstr (str, "-12"))
344     *max_bit_minus_8 = 4;
345   else if (g_strrstr (str, "-10") && *max_bit_minus_8 < 2)
346     *max_bit_minus_8 = 2;
347 }
348
349 static GstCaps *
350 gst_x265_enc_sink_getcaps (GstVideoEncoder * enc, GstCaps * filter)
351 {
352   GstCaps *templ_caps, *supported_incaps;
353   GstCaps *allowed;
354   GstCaps *fcaps;
355   gint i, j;
356   gboolean has_profile = FALSE;
357   guint max_chroma_index = 0;
358   guint max_bit_minus_8 = 0;
359
360   templ_caps = gst_pad_get_pad_template_caps (GST_VIDEO_ENCODER_SINK_PAD (enc));
361   allowed = gst_pad_get_allowed_caps (enc->srcpad);
362
363   GST_LOG_OBJECT (enc, "template caps %" GST_PTR_FORMAT, templ_caps);
364   GST_LOG_OBJECT (enc, "allowed caps %" GST_PTR_FORMAT, allowed);
365
366   if (!allowed) {
367     /* no peer */
368     supported_incaps = templ_caps;
369     goto done;
370   } else if (gst_caps_is_empty (allowed)) {
371     /* cannot negotiate, return empty caps */
372     gst_caps_unref (templ_caps);
373     return allowed;
374   }
375
376   /* fill format based on requested profile */
377   for (i = 0; i < gst_caps_get_size (allowed); i++) {
378     const GstStructure *allowed_s = gst_caps_get_structure (allowed, i);
379     const GValue *val;
380
381     if ((val = gst_structure_get_value (allowed_s, "profile"))) {
382       if (G_VALUE_HOLDS_STRING (val)) {
383         check_formats (g_value_get_string (val), &max_chroma_index,
384             &max_bit_minus_8);
385         has_profile = TRUE;
386       } else if (GST_VALUE_HOLDS_LIST (val)) {
387         for (j = 0; j < gst_value_list_get_size (val); j++) {
388           const GValue *vlist = gst_value_list_get_value (val, j);
389
390           if (G_VALUE_HOLDS_STRING (vlist)) {
391             check_formats (g_value_get_string (vlist), &max_chroma_index,
392                 &max_bit_minus_8);
393             has_profile = TRUE;
394           }
395         }
396       }
397     }
398   }
399
400   if (!has_profile) {
401     /* downstream did not request profile */
402     supported_incaps = templ_caps;
403   } else {
404     GstStructure *s;
405     gboolean has_12bit = FALSE;
406     gboolean has_10bit = FALSE;
407     gboolean has_8bit = TRUE;
408     gboolean has_444 = FALSE;
409     gboolean has_422 = FALSE;
410     gboolean has_420 = TRUE;
411
412     supported_incaps = gst_caps_new_simple ("video/x-raw",
413         "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1,
414         "width", GST_TYPE_INT_RANGE, 16, G_MAXINT,
415         "height", GST_TYPE_INT_RANGE, 16, G_MAXINT, NULL);
416
417     /* NOTE: 12bits profiles can accept 8bits and 10bits format */
418     if (max_bit_minus_8 >= 4)
419       has_12bit = TRUE;
420     if (max_bit_minus_8 >= 2)
421       has_10bit = TRUE;
422
423     has_8bit &= ! !vtable_8bit;
424     has_10bit &= ! !vtable_10bit;
425     has_12bit &= ! !vtable_12bit;
426
427     /* 4:4:4 profiles can handle 4:2:2 and 4:2:0 */
428     if (max_chroma_index >= 2)
429       has_444 = TRUE;
430     if (max_chroma_index >= 1)
431       has_422 = TRUE;
432
433     s = gst_caps_get_structure (supported_incaps, 0);
434     gst_x265_enc_add_x265_chroma_format (s, has_420, has_422, has_444,
435         has_8bit, has_10bit, has_12bit);
436
437     gst_caps_unref (templ_caps);
438   }
439
440 done:
441   GST_LOG_OBJECT (enc, "supported caps %" GST_PTR_FORMAT, supported_incaps);
442   fcaps = gst_video_encoder_proxy_getcaps (enc, supported_incaps, filter);
443   gst_clear_caps (&supported_incaps);
444   gst_clear_caps (&allowed);
445
446   GST_LOG_OBJECT (enc, "proxy caps %" GST_PTR_FORMAT, fcaps);
447
448   return fcaps;
449 }
450
451 static void
452 gst_x265_enc_class_init (GstX265EncClass * klass)
453 {
454   GObjectClass *gobject_class;
455   GstElementClass *element_class;
456   GstVideoEncoderClass *gstencoder_class;
457   GstPadTemplate *sink_templ;
458   GstCaps *supported_sinkcaps;
459
460   gobject_class = G_OBJECT_CLASS (klass);
461   element_class = GST_ELEMENT_CLASS (klass);
462   gstencoder_class = GST_VIDEO_ENCODER_CLASS (klass);
463
464   gobject_class->set_property = gst_x265_enc_set_property;
465   gobject_class->get_property = gst_x265_enc_get_property;
466   gobject_class->finalize = gst_x265_enc_finalize;
467
468   gstencoder_class->set_format = GST_DEBUG_FUNCPTR (gst_x265_enc_set_format);
469   gstencoder_class->handle_frame =
470       GST_DEBUG_FUNCPTR (gst_x265_enc_handle_frame);
471   gstencoder_class->start = GST_DEBUG_FUNCPTR (gst_x265_enc_start);
472   gstencoder_class->stop = GST_DEBUG_FUNCPTR (gst_x265_enc_stop);
473   gstencoder_class->flush = GST_DEBUG_FUNCPTR (gst_x265_enc_flush);
474   gstencoder_class->finish = GST_DEBUG_FUNCPTR (gst_x265_enc_finish);
475   gstencoder_class->getcaps = GST_DEBUG_FUNCPTR (gst_x265_enc_sink_getcaps);
476   gstencoder_class->sink_query = GST_DEBUG_FUNCPTR (gst_x265_enc_sink_query);
477   gstencoder_class->propose_allocation =
478       GST_DEBUG_FUNCPTR (gst_x265_enc_propose_allocation);
479
480   g_object_class_install_property (gobject_class, PROP_BITRATE,
481       g_param_spec_uint ("bitrate", "Bitrate", "Bitrate in kbit/sec", 1,
482           100 * 1024, PROP_BITRATE_DEFAULT,
483           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
484           GST_PARAM_MUTABLE_PLAYING));
485
486   g_object_class_install_property (gobject_class, PROP_QP,
487       g_param_spec_int ("qp", "Quantization parameter",
488           "QP for P slices in (implied) CQP mode (-1 = disabled)", -1,
489           51, PROP_QP_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
490
491   g_object_class_install_property (gobject_class, PROP_OPTION_STRING,
492       g_param_spec_string ("option-string", "Option string",
493           "String of x265 options (overridden by element properties)"
494           " in the format \"key1=value1:key2=value2\".",
495           PROP_OPTION_STRING_DEFAULT,
496           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
497
498   g_object_class_install_property (gobject_class, PROP_X265_LOG_LEVEL,
499       g_param_spec_enum ("log-level", "(internal) x265 log level",
500           "x265 log level", GST_X265_ENC_LOG_LEVEL_TYPE,
501           PROP_LOG_LEVEL_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
502
503   g_object_class_install_property (gobject_class, PROP_SPEED_PRESET,
504       g_param_spec_enum ("speed-preset", "Speed preset",
505           "Preset name for speed/quality tradeoff options",
506           GST_X265_ENC_SPEED_PRESET_TYPE, PROP_SPEED_PRESET_DEFAULT,
507           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
508
509   g_object_class_install_property (gobject_class, PROP_TUNE,
510       g_param_spec_enum ("tune", "Tune options",
511           "Preset name for tuning options", GST_X265_ENC_TUNE_TYPE,
512           PROP_TUNE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
513   /**
514    * GstX265Enc::key-int-max:
515    *
516    * Controls maximum number of frames since the last keyframe
517    *
518    * Since: 1.16
519    */
520   g_object_class_install_property (gobject_class, PROP_KEY_INT_MAX,
521       g_param_spec_int ("key-int-max", "Max key frame",
522           "Maximal distance between two key-frames (0 = x265 default / 250)",
523           0, G_MAXINT32, PROP_KEY_INT_MAX_DEFAULT, G_PARAM_READWRITE));
524
525   gst_element_class_set_static_metadata (element_class,
526       "x265enc", "Codec/Encoder/Video", "H265 Encoder",
527       "Thijs Vermeir <thijs.vermeir@barco.com>");
528
529   supported_sinkcaps = gst_caps_new_simple ("video/x-raw",
530       "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1,
531       "width", GST_TYPE_INT_RANGE, 16, G_MAXINT,
532       "height", GST_TYPE_INT_RANGE, 16, G_MAXINT, NULL);
533
534   gst_x265_enc_add_x265_chroma_format (gst_caps_get_structure
535       (supported_sinkcaps, 0), TRUE, TRUE, TRUE, ! !vtable_8bit,
536       ! !vtable_10bit, ! !vtable_12bit);
537
538   sink_templ = gst_pad_template_new ("sink",
539       GST_PAD_SINK, GST_PAD_ALWAYS, supported_sinkcaps);
540
541   gst_caps_unref (supported_sinkcaps);
542
543   gst_element_class_add_pad_template (element_class, sink_templ);
544   gst_element_class_add_static_pad_template (element_class, &src_factory);
545 }
546
547 /* initialize the new element
548  * instantiate pads and add them to element
549  * set functions
550  * initialize structure
551  */
552 static void
553 gst_x265_enc_init (GstX265Enc * encoder)
554 {
555   encoder->push_header = TRUE;
556
557   encoder->bitrate = PROP_BITRATE_DEFAULT;
558   encoder->qp = PROP_QP_DEFAULT;
559   encoder->option_string_prop = g_string_new (PROP_OPTION_STRING_DEFAULT);
560   encoder->log_level = PROP_LOG_LEVEL_DEFAULT;
561   encoder->speed_preset = PROP_SPEED_PRESET_DEFAULT;
562   encoder->tune = PROP_TUNE_DEFAULT;
563   encoder->keyintmax = PROP_KEY_INT_MAX_DEFAULT;
564   encoder->api = &default_vtable;
565
566   encoder->api->param_default (&encoder->x265param);
567
568   encoder->peer_profiles = g_ptr_array_new ();
569 }
570
571 typedef struct
572 {
573   GstVideoCodecFrame *frame;
574   GstVideoFrame vframe;
575 } FrameData;
576
577 static FrameData *
578 gst_x265_enc_queue_frame (GstX265Enc * enc, GstVideoCodecFrame * frame,
579     GstVideoInfo * info)
580 {
581   GstVideoFrame vframe;
582   FrameData *fdata;
583
584   if (!gst_video_frame_map (&vframe, info, frame->input_buffer, GST_MAP_READ))
585     return NULL;
586
587   fdata = g_slice_new (FrameData);
588   fdata->frame = gst_video_codec_frame_ref (frame);
589   fdata->vframe = vframe;
590
591   enc->pending_frames = g_list_prepend (enc->pending_frames, fdata);
592
593   return fdata;
594 }
595
596 static void
597 gst_x265_enc_dequeue_frame (GstX265Enc * enc, GstVideoCodecFrame * frame)
598 {
599   GList *l;
600
601   for (l = enc->pending_frames; l; l = l->next) {
602     FrameData *fdata = l->data;
603
604     if (fdata->frame != frame)
605       continue;
606
607     gst_video_frame_unmap (&fdata->vframe);
608     gst_video_codec_frame_unref (fdata->frame);
609     g_slice_free (FrameData, fdata);
610
611     enc->pending_frames = g_list_delete_link (enc->pending_frames, l);
612     return;
613   }
614 }
615
616 static void
617 gst_x265_enc_dequeue_all_frames (GstX265Enc * enc)
618 {
619   GList *l;
620
621   for (l = enc->pending_frames; l; l = l->next) {
622     FrameData *fdata = l->data;
623
624     gst_video_frame_unmap (&fdata->vframe);
625     gst_video_codec_frame_unref (fdata->frame);
626     g_slice_free (FrameData, fdata);
627   }
628   g_list_free (enc->pending_frames);
629   enc->pending_frames = NULL;
630 }
631
632 static gboolean
633 gst_x265_enc_start (GstVideoEncoder * encoder)
634 {
635   GstX265Enc *x265enc = GST_X265_ENC (encoder);
636
637   g_ptr_array_set_size (x265enc->peer_profiles, 0);
638
639   return TRUE;
640 }
641
642 static gboolean
643 gst_x265_enc_stop (GstVideoEncoder * encoder)
644 {
645   GstX265Enc *x265enc = GST_X265_ENC (encoder);
646
647   GST_DEBUG_OBJECT (encoder, "stop encoder");
648
649   gst_x265_enc_flush_frames (x265enc, FALSE);
650   gst_x265_enc_close_encoder (x265enc);
651   gst_x265_enc_dequeue_all_frames (x265enc);
652
653   if (x265enc->input_state)
654     gst_video_codec_state_unref (x265enc->input_state);
655   x265enc->input_state = NULL;
656
657   g_ptr_array_set_size (x265enc->peer_profiles, 0);
658
659   return TRUE;
660 }
661
662
663 static gboolean
664 gst_x265_enc_flush (GstVideoEncoder * encoder)
665 {
666   GstX265Enc *x265enc = GST_X265_ENC (encoder);
667
668   GST_DEBUG_OBJECT (encoder, "flushing encoder");
669
670   gst_x265_enc_flush_frames (x265enc, FALSE);
671   gst_x265_enc_close_encoder (x265enc);
672   gst_x265_enc_dequeue_all_frames (x265enc);
673
674   gst_x265_enc_init_encoder (x265enc);
675
676   return TRUE;
677 }
678
679 static void
680 gst_x265_enc_finalize (GObject * object)
681 {
682   GstX265Enc *encoder = GST_X265_ENC (object);
683
684   if (encoder->input_state)
685     gst_video_codec_state_unref (encoder->input_state);
686   encoder->input_state = NULL;
687
688   gst_x265_enc_close_encoder (encoder);
689
690   g_string_free (encoder->option_string_prop, TRUE);
691
692   if (encoder->peer_profiles)
693     g_ptr_array_free (encoder->peer_profiles, FALSE);
694
695   G_OBJECT_CLASS (parent_class)->finalize (object);
696 }
697
698 static gint
699 gst_x265_enc_gst_to_x265_video_format (GstVideoFormat format, gint * nplanes)
700 {
701   switch (format) {
702     case GST_VIDEO_FORMAT_I420:
703     case GST_VIDEO_FORMAT_YV12:
704     case GST_VIDEO_FORMAT_I420_10LE:
705     case GST_VIDEO_FORMAT_I420_10BE:
706     case GST_VIDEO_FORMAT_I420_12LE:
707     case GST_VIDEO_FORMAT_I420_12BE:
708       if (nplanes)
709         *nplanes = 3;
710       return X265_CSP_I420;
711     case GST_VIDEO_FORMAT_Y444:
712     case GST_VIDEO_FORMAT_Y444_10LE:
713     case GST_VIDEO_FORMAT_Y444_10BE:
714     case GST_VIDEO_FORMAT_Y444_12LE:
715     case GST_VIDEO_FORMAT_Y444_12BE:
716       if (nplanes)
717         *nplanes = 3;
718       return X265_CSP_I444;
719     case GST_VIDEO_FORMAT_Y42B:
720     case GST_VIDEO_FORMAT_I422_10LE:
721     case GST_VIDEO_FORMAT_I422_10BE:
722     case GST_VIDEO_FORMAT_I422_12LE:
723     case GST_VIDEO_FORMAT_I422_12BE:
724       if (nplanes)
725         *nplanes = 3;
726       return X265_CSP_I422;
727     default:
728       g_return_val_if_reached (GST_VIDEO_FORMAT_UNKNOWN);
729   }
730 }
731
732 /*
733  * gst_x265_enc_parse_options
734  * @encoder: Encoder to which options are assigned
735  * @str: Option string
736  *
737  * Parse option string and assign to x265 parameters
738  *
739  */
740 static gboolean
741 gst_x265_enc_parse_options (GstX265Enc * encoder, const gchar * str)
742 {
743   GStrv kvpairs;
744   guint npairs, i;
745   gint parse_result = 0, ret = 0;
746   gchar *options = (gchar *) str;
747   const x265_api *api = encoder->api;
748
749   g_assert (api != NULL);
750
751   while (*options == ':')
752     options++;
753
754   kvpairs = g_strsplit (options, ":", 0);
755   npairs = g_strv_length (kvpairs);
756
757   for (i = 0; i < npairs; i++) {
758     GStrv key_val = g_strsplit (kvpairs[i], "=", 2);
759
760     parse_result =
761         api->param_parse (&encoder->x265param, key_val[0], key_val[1]);
762
763     if (parse_result == X265_PARAM_BAD_NAME) {
764       GST_ERROR_OBJECT (encoder, "Bad name for option %s=%s",
765           key_val[0] ? key_val[0] : "", key_val[1] ? key_val[1] : "");
766     }
767     if (parse_result == X265_PARAM_BAD_VALUE) {
768       GST_ERROR_OBJECT (encoder,
769           "Bad value for option %s=%s (Note: a NULL value for a non-boolean triggers this)",
770           key_val[0] ? key_val[0] : "", key_val[1] ? key_val[1] : "");
771     }
772
773     g_strfreev (key_val);
774
775     if (parse_result)
776       ret++;
777   }
778
779   g_strfreev (kvpairs);
780   return !ret;
781 }
782
783 /*
784  * gst_x265_enc_init_encoder
785  * @encoder:  Encoder which should be initialized.
786  *
787  * Initialize x265 encoder.
788  *
789  */
790 static gboolean
791 gst_x265_enc_init_encoder (GstX265Enc * encoder)
792 {
793   GstVideoInfo *info;
794   guint bitdepth;
795   gboolean peer_intra = FALSE;
796
797   if (!encoder->input_state) {
798     GST_DEBUG_OBJECT (encoder, "Have no input state yet");
799     return FALSE;
800   }
801
802   info = &encoder->input_state->info;
803
804   /* make sure that the encoder is closed */
805   gst_x265_enc_close_encoder (encoder);
806
807   GST_OBJECT_LOCK (encoder);
808   bitdepth = GST_VIDEO_INFO_COMP_DEPTH (info, 0);
809   encoder->api = NULL;
810
811   switch (bitdepth) {
812     case 8:
813       if (vtable_8bit)
814         encoder->api = vtable_8bit;
815       else if (vtable_10bit)
816         encoder->api = vtable_10bit;
817       else
818         encoder->api = vtable_12bit;
819       break;
820     case 10:
821       if (vtable_10bit)
822         encoder->api = vtable_10bit;
823       else
824         encoder->api = vtable_12bit;
825       break;
826     case 12:
827       encoder->api = vtable_12bit;
828       break;
829     default:
830       break;
831   }
832
833   if (!encoder->api) {
834     GST_ERROR_OBJECT (encoder, "no %d bitdepth vtable available", bitdepth);
835     GST_OBJECT_UNLOCK (encoder);
836     return FALSE;
837   }
838
839   if (encoder->api->param_default_preset (&encoder->x265param,
840           x265_preset_names[encoder->speed_preset - 1],
841           x265_tune_names[encoder->tune - 1]) < 0) {
842     GST_DEBUG_OBJECT (encoder, "preset or tune unrecognized");
843     GST_OBJECT_UNLOCK (encoder);
844     return FALSE;
845   }
846
847   /* set up encoder parameters */
848   encoder->x265param.logLevel = encoder->log_level;
849   encoder->x265param.internalCsp =
850       gst_x265_enc_gst_to_x265_video_format (info->finfo->format, NULL);
851   if (info->fps_d == 0 || info->fps_n == 0) {
852   } else {
853     encoder->x265param.fpsNum = info->fps_n;
854     encoder->x265param.fpsDenom = info->fps_d;
855   }
856   encoder->x265param.sourceWidth = info->width;
857   encoder->x265param.sourceHeight = info->height;
858
859   /* x265 does not allow user to configure a picture size smaller than
860    * at least one CU size, and maxCUSize must be 16, 32, or 64.
861    * Therefore, we should be set the CU size according to the input resolution.
862    */
863   if (encoder->x265param.sourceWidth < 64
864       || encoder->x265param.sourceHeight < 64)
865     encoder->x265param.maxCUSize = 32;
866   if (encoder->x265param.sourceWidth < 32
867       || encoder->x265param.sourceHeight < 32)
868     encoder->x265param.maxCUSize = 16;
869
870   if (info->par_d > 0) {
871     encoder->x265param.vui.aspectRatioIdc = X265_EXTENDED_SAR;
872     encoder->x265param.vui.sarWidth = info->par_n;
873     encoder->x265param.vui.sarHeight = info->par_d;
874   }
875
876   encoder->x265param.vui.bEnableVideoSignalTypePresentFlag = 1;
877   /* Unspecified video format (5) */
878   encoder->x265param.vui.videoFormat = 5;
879   if (info->colorimetry.range == GST_VIDEO_COLOR_RANGE_0_255) {
880     encoder->x265param.vui.bEnableVideoFullRangeFlag = 1;
881   } else {
882     encoder->x265param.vui.bEnableVideoFullRangeFlag = 0;
883   }
884
885   encoder->x265param.vui.bEnableColorDescriptionPresentFlag = 1;
886   encoder->x265param.vui.matrixCoeffs =
887       gst_video_color_matrix_to_iso (info->colorimetry.matrix);
888   encoder->x265param.vui.colorPrimaries =
889       gst_video_color_primaries_to_iso (info->colorimetry.primaries);
890   encoder->x265param.vui.transferCharacteristics =
891       gst_video_color_transfer_to_iso (info->colorimetry.transfer);
892
893   if (encoder->qp != -1) {
894     /* CQP */
895     encoder->x265param.rc.qp = encoder->qp;
896     encoder->x265param.rc.rateControlMode = X265_RC_CQP;
897   } else {
898     /* ABR */
899     encoder->x265param.rc.bitrate = encoder->bitrate;
900     encoder->x265param.rc.rateControlMode = X265_RC_ABR;
901   }
902
903   if (encoder->peer_profiles->len > 0) {
904     gint i;
905
906     for (i = 0; i < encoder->peer_profiles->len; i++) {
907       const gchar *profile = g_ptr_array_index (encoder->peer_profiles, i);
908
909       GST_DEBUG_OBJECT (encoder, "Apply peer profile %s", profile);
910       if (encoder->api->param_apply_profile (&encoder->x265param, profile) < 0) {
911         GST_WARNING_OBJECT (encoder, "Failed to apply profile %s", profile);
912       } else {
913         /* libx265 chooses still-picture profile only if x265_param::totalFrames
914          * equals to one (otherwise, -intra profile will be chosen) */
915         if (g_strrstr (profile, "stillpicture"))
916           encoder->x265param.totalFrames = 1;
917
918         if (g_str_has_suffix (profile, "-intra"))
919           peer_intra = TRUE;
920
921         break;
922       }
923     }
924
925     if (i == encoder->peer_profiles->len) {
926       GST_ERROR_OBJECT (encoder, "Couldn't apply peer profile");
927       GST_OBJECT_UNLOCK (encoder);
928
929       return FALSE;
930     }
931   }
932
933   if (peer_intra) {
934     encoder->x265param.keyframeMax = 1;
935   } else if (encoder->keyintmax > 0) {
936     encoder->x265param.keyframeMax = encoder->keyintmax;
937   }
938 #if (X265_BUILD >= 79)
939   {
940     GstVideoMasteringDisplayInfo minfo;
941     GstVideoContentLightLevel cll;
942
943     if (gst_video_mastering_display_info_from_caps (&minfo,
944             encoder->input_state->caps)) {
945       guint16 displayPrimaryX[3];
946       guint16 displayPrimaryY[3];
947       guint16 whitePointX, whitePointY;
948       guint32 maxDisplayMasteringLuminance;
949       guint32 minDisplayMasteringLuminance;
950       const guint chroma_scale = 50000;
951       const guint luma_scale = 10000;
952
953       GST_DEBUG_OBJECT (encoder, "Apply mastering display info");
954
955       displayPrimaryX[0] =
956           (guint16) gst_util_uint64_scale_round (minfo.Gx_n, chroma_scale,
957           minfo.Gx_d);
958       displayPrimaryX[1] =
959           (guint16) gst_util_uint64_scale_round (minfo.Bx_n, chroma_scale,
960           minfo.Bx_d);
961       displayPrimaryX[2] =
962           (guint16) gst_util_uint64_scale_round (minfo.Rx_n, chroma_scale,
963           minfo.Rx_d);
964
965       displayPrimaryY[0] =
966           (guint16) gst_util_uint64_scale_round (minfo.Gy_n, chroma_scale,
967           minfo.Gy_d);
968       displayPrimaryY[1] =
969           (guint16) gst_util_uint64_scale_round (minfo.By_n, chroma_scale,
970           minfo.By_d);
971       displayPrimaryY[2] =
972           (guint16) gst_util_uint64_scale_round (minfo.Ry_n, chroma_scale,
973           minfo.Ry_d);
974
975       whitePointX =
976           (guint16) gst_util_uint64_scale_round (minfo.Wx_n, chroma_scale,
977           minfo.Wx_d);
978       whitePointY =
979           (guint16) gst_util_uint64_scale_round (minfo.Wy_n, chroma_scale,
980           minfo.Wy_d);
981
982       maxDisplayMasteringLuminance =
983           (guint32) gst_util_uint64_scale_round (minfo.max_luma_n, luma_scale,
984           minfo.max_luma_d);
985       minDisplayMasteringLuminance =
986           (guint32) gst_util_uint64_scale_round (minfo.min_luma_n, luma_scale,
987           minfo.min_luma_d);
988
989       encoder->x265param.masteringDisplayColorVolume =
990           g_strdup_printf ("G(%hu,%hu)B(%hu,%hu)R(%hu,%hu)WP(%hu,%hu)L(%u,%u)",
991           displayPrimaryX[0], displayPrimaryY[0],
992           displayPrimaryX[1], displayPrimaryY[1],
993           displayPrimaryX[2], displayPrimaryY[2],
994           whitePointX, whitePointY,
995           maxDisplayMasteringLuminance, minDisplayMasteringLuminance);
996     }
997
998     if (gst_video_content_light_level_from_caps (&cll,
999             encoder->input_state->caps)) {
1000       gdouble val;
1001
1002       GST_DEBUG_OBJECT (encoder, "Apply content light level");
1003
1004       gst_util_fraction_to_double (cll.maxCLL_n, cll.maxCLL_d, &val);
1005       encoder->x265param.maxCLL = (guint16) val;
1006
1007       gst_util_fraction_to_double (cll.maxFALL_n, cll.maxFALL_d, &val);
1008       encoder->x265param.maxFALL = (guint16) val;
1009     }
1010   }
1011 #endif
1012
1013   /* apply option-string property */
1014   if (encoder->option_string_prop && encoder->option_string_prop->len) {
1015     GST_DEBUG_OBJECT (encoder, "Applying option-string: %s",
1016         encoder->option_string_prop->str);
1017     if (gst_x265_enc_parse_options (encoder,
1018             encoder->option_string_prop->str) == FALSE) {
1019       GST_DEBUG_OBJECT (encoder, "Your option-string contains errors.");
1020       GST_OBJECT_UNLOCK (encoder);
1021       return FALSE;
1022     }
1023   }
1024
1025   encoder->reconfig = FALSE;
1026
1027   /* good start, will be corrected if needed */
1028   encoder->dts_offset = 0;
1029
1030   GST_OBJECT_UNLOCK (encoder);
1031
1032   encoder->x265enc = encoder->api->encoder_open (&encoder->x265param);
1033   if (!encoder->x265enc) {
1034     GST_ELEMENT_ERROR (encoder, STREAM, ENCODE,
1035         ("Can not initialize x265 encoder."), (NULL));
1036     return FALSE;
1037   }
1038
1039   encoder->push_header = TRUE;
1040
1041   return TRUE;
1042 }
1043
1044 /* gst_x265_enc_close_encoder
1045  * @encoder:  Encoder which should close.
1046  *
1047  * Close x265 encoder.
1048  */
1049 static void
1050 gst_x265_enc_close_encoder (GstX265Enc * encoder)
1051 {
1052   if (encoder->x265enc != NULL) {
1053     g_assert (encoder->api != NULL);
1054
1055     encoder->api->encoder_close (encoder->x265enc);
1056     encoder->x265enc = NULL;
1057   }
1058 }
1059
1060 static x265_nal *
1061 gst_x265_enc_bytestream_to_nal (x265_nal * input)
1062 {
1063   x265_nal *output;
1064   int i, j, zeros;
1065
1066   output = g_malloc (sizeof (x265_nal));
1067   output->payload = g_malloc (input->sizeBytes - 4);
1068   output->sizeBytes = input->sizeBytes - 4;
1069   output->type = input->type;
1070
1071   zeros = 0;
1072   for (i = 4, j = 0; i < input->sizeBytes; (i++, j++)) {
1073     if (input->payload[i] == 0x00) {
1074       zeros++;
1075     } else if (input->payload[i] == 0x03 && zeros == 2) {
1076       zeros = 0;
1077       j--;
1078       output->sizeBytes--;
1079       continue;
1080     } else {
1081       zeros = 0;
1082     }
1083     output->payload[j] = input->payload[i];
1084   }
1085
1086   return output;
1087 }
1088
1089 static void
1090 x265_nal_free (x265_nal * nal)
1091 {
1092   g_free (nal->payload);
1093   g_free (nal);
1094 }
1095
1096 static gboolean
1097 gst_x265_enc_set_level_tier_and_profile (GstX265Enc * encoder, GstCaps * caps)
1098 {
1099   x265_nal *nal, *vps_nal;
1100   guint32 i_nal;
1101   int header_return;
1102   const x265_api *api = encoder->api;
1103   GstStructure *s;
1104   const gchar *profile;
1105   GstCaps *allowed_caps;
1106   GstStructure *s2;
1107   const gchar *allowed_profile;
1108
1109   GST_DEBUG_OBJECT (encoder, "set profile, level and tier");
1110
1111   g_assert (api != NULL);
1112
1113   header_return = api->encoder_headers (encoder->x265enc, &nal, &i_nal);
1114   if (header_return < 0) {
1115     GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, ("Encode x265 header failed."),
1116         ("x265_encoder_headers return code=%d", header_return));
1117     return FALSE;
1118   }
1119
1120   GST_DEBUG_OBJECT (encoder, "%d nal units in header", i_nal);
1121
1122   g_assert (nal[0].type == NAL_UNIT_VPS);
1123   vps_nal = gst_x265_enc_bytestream_to_nal (&nal[0]);
1124
1125   GST_MEMDUMP ("VPS", vps_nal->payload, vps_nal->sizeBytes);
1126
1127   gst_codec_utils_h265_caps_set_level_tier_and_profile (caps,
1128       vps_nal->payload + 6, vps_nal->sizeBytes - 6);
1129   x265_nal_free (vps_nal);
1130
1131   /* relaxing the profile condition since libx265 can select lower profile than
1132    * requested one via param_apply_profile()
1133    */
1134   s = gst_caps_get_structure (caps, 0);
1135   profile = gst_structure_get_string (s, "profile");
1136
1137   allowed_caps = gst_pad_get_allowed_caps (GST_VIDEO_ENCODER_SRC_PAD (encoder));
1138
1139   if (allowed_caps == NULL)
1140     goto no_peer;
1141
1142   if (!gst_caps_can_intersect (allowed_caps, caps)) {
1143     guint peer_bitdepth = 0;
1144     guint peer_chroma_format = 0;
1145     guint bitdepth = 0;
1146     guint chroma_format = 0;
1147
1148     allowed_caps = gst_caps_make_writable (allowed_caps);
1149     allowed_caps = gst_caps_truncate (allowed_caps);
1150     s2 = gst_caps_get_structure (allowed_caps, 0);
1151     gst_structure_fixate_field_string (s2, "profile", profile);
1152     allowed_profile = gst_structure_get_string (s2, "profile");
1153
1154     check_formats (allowed_profile, &peer_chroma_format, &peer_bitdepth);
1155     check_formats (profile, &chroma_format, &bitdepth);
1156
1157     if (chroma_format <= peer_chroma_format && bitdepth <= peer_bitdepth) {
1158       GST_INFO_OBJECT (encoder, "downstream requested %s profile, but "
1159           "encoder will now output %s profile (which is a subset), due "
1160           "to how it's been configured", allowed_profile, profile);
1161       gst_structure_set (s, "profile", G_TYPE_STRING, allowed_profile, NULL);
1162     }
1163   }
1164   gst_caps_unref (allowed_caps);
1165
1166 no_peer:
1167
1168   return TRUE;
1169 }
1170
1171 static GstBuffer *
1172 gst_x265_enc_get_header_buffer (GstX265Enc * encoder)
1173 {
1174   x265_nal *nal;
1175   guint32 i_nal, i, offset;
1176   gint32 vps_idx, sps_idx, pps_idx;
1177   int header_return;
1178   GstBuffer *buf;
1179   gsize header_size = 0;
1180   const x265_api *api = encoder->api;
1181
1182   g_assert (api != NULL);
1183
1184   header_return = api->encoder_headers (encoder->x265enc, &nal, &i_nal);
1185   if (header_return < 0) {
1186     GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, ("Encode x265 header failed."),
1187         ("x265_encoder_headers return code=%d", header_return));
1188     return FALSE;
1189   }
1190
1191   GST_DEBUG_OBJECT (encoder, "%d nal units in header", i_nal);
1192
1193   /* x265 returns also non header nal units with the call x265_encoder_headers.
1194    * The useful headers are sequential (VPS, SPS and PPS), so we look for this
1195    * nal units and only copy these tree nal units as the header */
1196
1197   vps_idx = sps_idx = pps_idx = -1;
1198   for (i = 0; i < i_nal; i++) {
1199     if (nal[i].type == NAL_UNIT_VPS) {
1200       vps_idx = i;
1201       header_size += nal[i].sizeBytes;
1202     } else if (nal[i].type == NAL_UNIT_SPS) {
1203       sps_idx = i;
1204       header_size += nal[i].sizeBytes;
1205     } else if (nal[i].type == NAL_UNIT_PPS) {
1206       pps_idx = i;
1207       header_size += nal[i].sizeBytes;
1208     } else if (nal[i].type == NAL_UNIT_PREFIX_SEI) {
1209       header_size += nal[i].sizeBytes;
1210     }
1211   }
1212
1213   if (vps_idx == -1 || sps_idx == -1 || pps_idx == -1) {
1214     GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, ("Encode x265 header failed."),
1215         ("x265_encoder_headers did not return VPS, SPS and PPS"));
1216     return FALSE;
1217   }
1218
1219   offset = 0;
1220   buf = gst_buffer_new_allocate (NULL, header_size, NULL);
1221   gst_buffer_fill (buf, offset, nal[vps_idx].payload, nal[vps_idx].sizeBytes);
1222   offset += nal[vps_idx].sizeBytes;
1223   gst_buffer_fill (buf, offset, nal[sps_idx].payload, nal[sps_idx].sizeBytes);
1224   offset += nal[sps_idx].sizeBytes;
1225   gst_buffer_fill (buf, offset, nal[pps_idx].payload, nal[pps_idx].sizeBytes);
1226   offset += nal[pps_idx].sizeBytes;
1227
1228   for (i = 0; i < i_nal; i++) {
1229     if (nal[i].type == NAL_UNIT_PREFIX_SEI) {
1230       gst_buffer_fill (buf, offset, nal[i].payload, nal[i].sizeBytes);
1231       offset += nal[i].sizeBytes;
1232     }
1233   }
1234
1235   return buf;
1236 }
1237
1238 /* gst_x265_enc_set_src_caps
1239  * Returns: TRUE on success.
1240  */
1241 static gboolean
1242 gst_x265_enc_set_src_caps (GstX265Enc * encoder, GstCaps * caps)
1243 {
1244   GstCaps *outcaps;
1245   GstStructure *structure;
1246   GstVideoCodecState *state;
1247   GstTagList *tags;
1248
1249   outcaps = gst_caps_new_empty_simple ("video/x-h265");
1250   structure = gst_caps_get_structure (outcaps, 0);
1251
1252   gst_structure_set (structure, "stream-format", G_TYPE_STRING, "byte-stream",
1253       NULL);
1254   gst_structure_set (structure, "alignment", G_TYPE_STRING, "au", NULL);
1255
1256   if (!gst_x265_enc_set_level_tier_and_profile (encoder, outcaps)) {
1257     gst_caps_unref (outcaps);
1258     return FALSE;
1259   }
1260
1261   state = gst_video_encoder_set_output_state (GST_VIDEO_ENCODER (encoder),
1262       outcaps, encoder->input_state);
1263   GST_DEBUG_OBJECT (encoder, "output caps: %" GST_PTR_FORMAT, state->caps);
1264   gst_video_codec_state_unref (state);
1265
1266   tags = gst_tag_list_new_empty ();
1267   gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_ENCODER, "x265",
1268       GST_TAG_ENCODER_VERSION, x265_version_str, NULL);
1269   gst_video_encoder_merge_tags (GST_VIDEO_ENCODER (encoder), tags,
1270       GST_TAG_MERGE_REPLACE);
1271   gst_tag_list_unref (tags);
1272
1273   return TRUE;
1274 }
1275
1276 static void
1277 gst_x265_enc_set_latency (GstX265Enc * encoder)
1278 {
1279   GstVideoInfo *info = &encoder->input_state->info;
1280   gint max_delayed_frames;
1281   GstClockTime latency;
1282
1283   /* FIXME get a real value from the encoder, this is currently not exposed */
1284   if (encoder->tune > 0 && encoder->tune <= G_N_ELEMENTS (x265_tune_names) &&
1285       strcmp (x265_tune_names[encoder->tune - 1], "zerolatency") == 0)
1286     max_delayed_frames = 0;
1287   else
1288     max_delayed_frames = 5;
1289
1290   if (info->fps_n) {
1291     latency = gst_util_uint64_scale_ceil (GST_SECOND * info->fps_d,
1292         max_delayed_frames, info->fps_n);
1293   } else {
1294     /* FIXME: Assume 25fps. This is better than reporting no latency at
1295      * all and then later failing in live pipelines
1296      */
1297     latency = gst_util_uint64_scale_ceil (GST_SECOND * 1,
1298         max_delayed_frames, 25);
1299   }
1300
1301   GST_INFO_OBJECT (encoder,
1302       "Updating latency to %" GST_TIME_FORMAT " (%d frames)",
1303       GST_TIME_ARGS (latency), max_delayed_frames);
1304
1305   gst_video_encoder_set_latency (GST_VIDEO_ENCODER (encoder), latency, latency);
1306 }
1307
1308 typedef struct
1309 {
1310   const gchar *gst_profile;
1311   const gchar *x265_profile;
1312 } GstX265EncProfileTable;
1313
1314 static const gchar *
1315 gst_x265_enc_profile_from_gst (const gchar * profile)
1316 {
1317   gint i;
1318   static const GstX265EncProfileTable profile_table[] = {
1319     /* 8 bits */
1320     {"main", "main"},
1321     {"main-still-picture", "mainstillpicture"},
1322     {"main-intra", "main-intra"},
1323     {"main-444", "main444-8"},
1324     {"main-444-intra", "main444-intra"},
1325     {"main-444-still-picture", "main444-stillpicture"},
1326     /* 10 bits */
1327     {"main-10", "main10"},
1328     {"main-10-intra", "main10-intra"},
1329     {"main-422-10", "main422-10"},
1330     {"main-422-10-intra", "main422-10-intra"},
1331     {"main-444-10", "main444-10"},
1332     {"main-444-10-intra", "main444-10-intra"},
1333     /* 12 bits */
1334     {"main-12", "main12"},
1335     {"main-12-intra", "main12-intra"},
1336     {"main-422-12", "main422-12"},
1337     {"main-422-12-intra", "main422-12-intra"},
1338     {"main-444-12", "main444-12"},
1339     {"main-444-12-intra", "main444-12-intra"},
1340   };
1341
1342   if (!profile)
1343     return NULL;
1344
1345   for (i = 0; i < G_N_ELEMENTS (profile_table); i++) {
1346     if (!strcmp (profile, profile_table[i].gst_profile))
1347       return profile_table[i].x265_profile;
1348   }
1349
1350   return NULL;
1351 }
1352
1353 static gboolean
1354 gst_x265_enc_set_format (GstVideoEncoder * video_enc,
1355     GstVideoCodecState * state)
1356 {
1357   GstX265Enc *encoder = GST_X265_ENC (video_enc);
1358   GstVideoInfo *info = &state->info;
1359   GstCaps *template_caps;
1360   GstCaps *allowed_caps = NULL;
1361
1362   /* If the encoder is initialized, do not reinitialize it again if not
1363    * necessary */
1364   if (encoder->x265enc) {
1365     GstVideoInfo *old = &encoder->input_state->info;
1366
1367     if (info->finfo->format == old->finfo->format
1368         && info->width == old->width && info->height == old->height
1369         && info->fps_n == old->fps_n && info->fps_d == old->fps_d
1370         && info->par_n == old->par_n && info->par_d == old->par_d) {
1371       gst_video_codec_state_unref (encoder->input_state);
1372       encoder->input_state = gst_video_codec_state_ref (state);
1373       return TRUE;
1374     }
1375
1376     /* clear out pending frames */
1377     gst_x265_enc_flush_frames (encoder, TRUE);
1378   }
1379
1380   if (encoder->input_state)
1381     gst_video_codec_state_unref (encoder->input_state);
1382   encoder->input_state = gst_video_codec_state_ref (state);
1383
1384   g_ptr_array_set_size (encoder->peer_profiles, 0);
1385
1386   template_caps = gst_static_pad_template_get_caps (&src_factory);
1387   allowed_caps = gst_pad_get_allowed_caps (GST_VIDEO_ENCODER_SRC_PAD (encoder));
1388
1389   GST_DEBUG_OBJECT (encoder, "allowed caps %" GST_PTR_FORMAT, allowed_caps);
1390
1391   /* allowed != template is meaning that downstream has some restriction
1392    * so we need check whether there is requested profile or not */
1393   if (allowed_caps && !gst_caps_is_equal (allowed_caps, template_caps)) {
1394     gint i, j;
1395
1396     if (gst_caps_is_empty (allowed_caps)) {
1397       gst_caps_unref (allowed_caps);
1398       gst_caps_unref (template_caps);
1399       return FALSE;
1400     }
1401
1402     for (i = 0; i < gst_caps_get_size (allowed_caps); i++) {
1403       GstStructure *s;
1404       const GValue *val;
1405       const gchar *profile;
1406       const gchar *x265_profile;
1407
1408       s = gst_caps_get_structure (allowed_caps, i);
1409
1410       if ((val = gst_structure_get_value (s, "profile"))) {
1411         if (G_VALUE_HOLDS_STRING (val)) {
1412           profile = g_value_get_string (val);
1413           x265_profile = gst_x265_enc_profile_from_gst (profile);
1414
1415           if (x265_profile) {
1416             GST_DEBUG_OBJECT (encoder,
1417                 "Add profile %s to peer profile list", x265_profile);
1418
1419             g_ptr_array_add (encoder->peer_profiles, (gpointer) x265_profile);
1420           }
1421         } else if (GST_VALUE_HOLDS_LIST (val)) {
1422           for (j = 0; j < gst_value_list_get_size (val); j++) {
1423             const GValue *vlist = gst_value_list_get_value (val, j);
1424             profile = g_value_get_string (vlist);
1425             x265_profile = gst_x265_enc_profile_from_gst (profile);
1426
1427             if (x265_profile) {
1428               GST_DEBUG_OBJECT (encoder,
1429                   "Add profile %s to peer profile list", x265_profile);
1430
1431               g_ptr_array_add (encoder->peer_profiles, (gpointer) x265_profile);
1432             }
1433           }
1434         }
1435       }
1436     }
1437   }
1438
1439   gst_clear_caps (&allowed_caps);
1440   gst_caps_unref (template_caps);
1441
1442
1443   if (!gst_x265_enc_init_encoder (encoder))
1444     return FALSE;
1445
1446   if (!gst_x265_enc_set_src_caps (encoder, state->caps)) {
1447     gst_x265_enc_close_encoder (encoder);
1448     return FALSE;
1449   }
1450
1451   gst_x265_enc_set_latency (encoder);
1452
1453   return TRUE;
1454 }
1455
1456 static GstFlowReturn
1457 gst_x265_enc_finish (GstVideoEncoder * encoder)
1458 {
1459   GST_DEBUG_OBJECT (encoder, "finish encoder");
1460
1461   gst_x265_enc_flush_frames (GST_X265_ENC (encoder), TRUE);
1462   gst_x265_enc_flush_frames (GST_X265_ENC (encoder), TRUE);
1463   return GST_FLOW_OK;
1464 }
1465
1466 static gboolean
1467 gst_x265_enc_propose_allocation (GstVideoEncoder * encoder, GstQuery * query)
1468 {
1469   gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
1470
1471   return GST_VIDEO_ENCODER_CLASS (parent_class)->propose_allocation (encoder,
1472       query);
1473 }
1474
1475 /* chain function
1476  * this function does the actual processing
1477  */
1478 static GstFlowReturn
1479 gst_x265_enc_handle_frame (GstVideoEncoder * video_enc,
1480     GstVideoCodecFrame * frame)
1481 {
1482   GstX265Enc *encoder = GST_X265_ENC (video_enc);
1483   GstVideoInfo *info = &encoder->input_state->info;
1484   GstFlowReturn ret;
1485   x265_picture pic_in;
1486   guint32 i_nal, i;
1487   FrameData *fdata;
1488   gint nplanes = 0;
1489   const x265_api *api = encoder->api;
1490
1491   g_assert (api != NULL);
1492
1493   if (G_UNLIKELY (encoder->x265enc == NULL))
1494     goto not_inited;
1495
1496   /* set up input picture */
1497   api->picture_init (&encoder->x265param, &pic_in);
1498
1499   fdata = gst_x265_enc_queue_frame (encoder, frame, info);
1500   if (!fdata)
1501     goto invalid_frame;
1502
1503   pic_in.colorSpace =
1504       gst_x265_enc_gst_to_x265_video_format (info->finfo->format, &nplanes);
1505   for (i = 0; i < nplanes; i++) {
1506     pic_in.planes[i] = GST_VIDEO_FRAME_PLANE_DATA (&fdata->vframe, i);
1507     pic_in.stride[i] = GST_VIDEO_FRAME_COMP_STRIDE (&fdata->vframe, i);
1508   }
1509
1510   pic_in.sliceType = X265_TYPE_AUTO;
1511   pic_in.pts = frame->pts;
1512   pic_in.dts = frame->dts;
1513   pic_in.bitDepth = info->finfo->depth[0];
1514   pic_in.userData = GINT_TO_POINTER (frame->system_frame_number);
1515
1516   ret = gst_x265_enc_encode_frame (encoder, &pic_in, frame, &i_nal, TRUE);
1517
1518   /* input buffer is released later on */
1519   return ret;
1520
1521 /* ERRORS */
1522 not_inited:
1523   {
1524     GST_WARNING_OBJECT (encoder, "Got buffer before set_caps was called");
1525     return GST_FLOW_NOT_NEGOTIATED;
1526   }
1527 invalid_frame:
1528   {
1529     GST_ERROR_OBJECT (encoder, "Failed to map frame");
1530     return GST_FLOW_ERROR;
1531   }
1532 }
1533
1534 static GstFlowReturn
1535 gst_x265_enc_encode_frame (GstX265Enc * encoder, x265_picture * pic_in,
1536     GstVideoCodecFrame * input_frame, guint32 * i_nal, gboolean send)
1537 {
1538   GstVideoCodecFrame *frame = NULL;
1539   GstBuffer *out_buf = NULL;
1540   x265_picture pic_out;
1541   x265_nal *nal;
1542   int i_size, i, offset;
1543   int encoder_return;
1544   GstFlowReturn ret = GST_FLOW_OK;
1545   gboolean update_latency = FALSE;
1546   const x265_api *api;
1547
1548   if (G_UNLIKELY (encoder->x265enc == NULL)) {
1549     if (input_frame)
1550       gst_video_codec_frame_unref (input_frame);
1551     return GST_FLOW_NOT_NEGOTIATED;
1552   }
1553
1554   api = encoder->api;
1555   g_assert (api != NULL);
1556
1557   GST_OBJECT_LOCK (encoder);
1558   if (encoder->reconfig) {
1559     /* x265_encoder_reconfig is not yet implemented thus we shut down and re-create encoder */
1560     gst_x265_enc_init_encoder (encoder);
1561     update_latency = TRUE;
1562   }
1563
1564   if (pic_in && input_frame) {
1565     if (GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (input_frame)) {
1566       GST_INFO_OBJECT (encoder, "Forcing key frame");
1567       pic_in->sliceType = X265_TYPE_IDR;
1568     }
1569   }
1570   GST_OBJECT_UNLOCK (encoder);
1571
1572   if (G_UNLIKELY (update_latency))
1573     gst_x265_enc_set_latency (encoder);
1574
1575   encoder_return = api->encoder_encode (encoder->x265enc,
1576       &nal, i_nal, pic_in, &pic_out);
1577
1578   GST_DEBUG_OBJECT (encoder, "encoder result (%d) with %u nal units",
1579       encoder_return, *i_nal);
1580
1581   if (encoder_return < 0) {
1582     GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, ("Encode x265 frame failed."),
1583         ("x265_encoder_encode return code=%d", encoder_return));
1584     ret = GST_FLOW_ERROR;
1585     /* Make sure we finish this frame */
1586     frame = input_frame;
1587     goto out;
1588   }
1589
1590   /* Input frame is now queued */
1591   if (input_frame)
1592     gst_video_codec_frame_unref (input_frame);
1593
1594   if (!*i_nal) {
1595     ret = GST_FLOW_OK;
1596     GST_LOG_OBJECT (encoder, "no output yet");
1597     goto out;
1598   }
1599
1600   frame = gst_video_encoder_get_frame (GST_VIDEO_ENCODER (encoder),
1601       GPOINTER_TO_INT (pic_out.userData));
1602   g_assert (frame || !send);
1603
1604   GST_DEBUG_OBJECT (encoder,
1605       "output picture ready POC=%d system=%d frame found %d", pic_out.poc,
1606       GPOINTER_TO_INT (pic_out.userData), frame != NULL);
1607
1608   if (!send || !frame) {
1609     GST_LOG_OBJECT (encoder, "not sending (%d) or frame not found (%d)", send,
1610         frame != NULL);
1611     ret = GST_FLOW_OK;
1612     goto out;
1613   }
1614
1615   i_size = 0;
1616   offset = 0;
1617   for (i = 0; i < *i_nal; i++)
1618     i_size += nal[i].sizeBytes;
1619   out_buf = gst_buffer_new_allocate (NULL, i_size, NULL);
1620   for (i = 0; i < *i_nal; i++) {
1621     gst_buffer_fill (out_buf, offset, nal[i].payload, nal[i].sizeBytes);
1622     offset += nal[i].sizeBytes;
1623   }
1624
1625   if (pic_out.sliceType == X265_TYPE_IDR || pic_out.sliceType == X265_TYPE_I) {
1626     GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
1627   }
1628
1629   frame->output_buffer = out_buf;
1630
1631   if (encoder->push_header) {
1632     GstBuffer *header;
1633
1634     header = gst_x265_enc_get_header_buffer (encoder);
1635     frame->output_buffer = gst_buffer_append (header, frame->output_buffer);
1636     encoder->push_header = FALSE;
1637   }
1638
1639   GST_LOG_OBJECT (encoder,
1640       "output: dts %" G_GINT64_FORMAT " pts %" G_GINT64_FORMAT,
1641       (gint64) pic_out.dts, (gint64) pic_out.pts);
1642
1643   frame->dts = pic_out.dts + encoder->dts_offset;
1644
1645 out:
1646   if (frame) {
1647     gst_x265_enc_dequeue_frame (encoder, frame);
1648     ret = gst_video_encoder_finish_frame (GST_VIDEO_ENCODER (encoder), frame);
1649   }
1650
1651   return ret;
1652 }
1653
1654 static void
1655 gst_x265_enc_flush_frames (GstX265Enc * encoder, gboolean send)
1656 {
1657   GstFlowReturn flow_ret;
1658   guint32 i_nal;
1659
1660   /* first send the remaining frames */
1661   if (encoder->x265enc)
1662     do {
1663       flow_ret = gst_x265_enc_encode_frame (encoder, NULL, NULL, &i_nal, send);
1664     } while (flow_ret == GST_FLOW_OK && i_nal > 0);
1665 }
1666
1667 static void
1668 gst_x265_enc_reconfig (GstX265Enc * encoder)
1669 {
1670   encoder->x265param.rc.bitrate = encoder->bitrate;
1671   encoder->reconfig = TRUE;
1672 }
1673
1674 static void
1675 gst_x265_enc_set_property (GObject * object, guint prop_id,
1676     const GValue * value, GParamSpec * pspec)
1677 {
1678   GstX265Enc *encoder;
1679   GstState state;
1680
1681   encoder = GST_X265_ENC (object);
1682
1683   GST_OBJECT_LOCK (encoder);
1684
1685   state = GST_STATE (encoder);
1686   if ((state != GST_STATE_READY && state != GST_STATE_NULL) &&
1687       !(pspec->flags & GST_PARAM_MUTABLE_PLAYING))
1688     goto wrong_state;
1689
1690   switch (prop_id) {
1691     case PROP_BITRATE:
1692       encoder->bitrate = g_value_get_uint (value);
1693       break;
1694     case PROP_QP:
1695       encoder->qp = g_value_get_int (value);
1696       break;
1697     case PROP_OPTION_STRING:
1698       g_string_assign (encoder->option_string_prop, g_value_get_string (value));
1699       break;
1700     case PROP_X265_LOG_LEVEL:
1701       encoder->log_level = g_value_get_enum (value);
1702       break;
1703     case PROP_SPEED_PRESET:
1704       encoder->speed_preset = g_value_get_enum (value);
1705       break;
1706     case PROP_TUNE:
1707       encoder->tune = g_value_get_enum (value);
1708       break;
1709     case PROP_KEY_INT_MAX:
1710       encoder->keyintmax = g_value_get_int (value);
1711       break;
1712     default:
1713       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1714       break;
1715   }
1716
1717   gst_x265_enc_reconfig (encoder);
1718   GST_OBJECT_UNLOCK (encoder);
1719   return;
1720
1721 wrong_state:
1722   {
1723     GST_WARNING_OBJECT (encoder, "setting property in wrong state");
1724     GST_OBJECT_UNLOCK (encoder);
1725   }
1726 }
1727
1728 static void
1729 gst_x265_enc_get_property (GObject * object, guint prop_id,
1730     GValue * value, GParamSpec * pspec)
1731 {
1732   GstX265Enc *encoder;
1733
1734   encoder = GST_X265_ENC (object);
1735
1736   GST_OBJECT_LOCK (encoder);
1737   switch (prop_id) {
1738     case PROP_BITRATE:
1739       g_value_set_uint (value, encoder->bitrate);
1740       break;
1741     case PROP_QP:
1742       g_value_set_int (value, encoder->qp);
1743       break;
1744     case PROP_OPTION_STRING:
1745       g_value_set_string (value, encoder->option_string_prop->str);
1746       break;
1747     case PROP_X265_LOG_LEVEL:
1748       g_value_set_enum (value, encoder->log_level);
1749       break;
1750     case PROP_SPEED_PRESET:
1751       g_value_set_enum (value, encoder->speed_preset);
1752       break;
1753     case PROP_TUNE:
1754       g_value_set_enum (value, encoder->tune);
1755       break;
1756     case PROP_KEY_INT_MAX:
1757       g_value_set_int (value, encoder->keyintmax);
1758       break;
1759     default:
1760       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1761       break;
1762   }
1763   GST_OBJECT_UNLOCK (encoder);
1764 }
1765
1766 static gboolean
1767 plugin_init (GstPlugin * plugin)
1768 {
1769   GST_DEBUG_CATEGORY_INIT (x265_enc_debug, "x265enc", 0,
1770       "h265 encoding element");
1771
1772   GST_INFO ("x265 build: %u", X265_BUILD);
1773
1774   default_vtable = *x265_api_get (0);
1775
1776   GST_INFO ("x265 default bitdepth: %u", default_vtable.bit_depth);
1777
1778   switch (default_vtable.bit_depth) {
1779     case 8:
1780       vtable_8bit = &default_vtable;
1781       break;
1782     case 10:
1783       vtable_10bit = &default_vtable;
1784       break;
1785     case 12:
1786       vtable_12bit = &default_vtable;
1787       break;
1788     default:
1789       GST_WARNING ("Unknown default bitdepth %d", default_vtable.bit_depth);
1790       break;
1791   }
1792
1793   if (!vtable_8bit && (vtable_8bit = x265_api_get (8)))
1794     GST_INFO ("x265 8bit api available");
1795
1796   if (!vtable_10bit && (vtable_10bit = x265_api_get (10)))
1797     GST_INFO ("x265 10bit api available");
1798
1799 #if (X265_BUILD >= 68)
1800   if (!vtable_12bit && (vtable_12bit = x265_api_get (12)))
1801     GST_INFO ("x265 12bit api available");
1802 #endif
1803
1804   return gst_element_register (plugin, "x265enc",
1805       GST_RANK_PRIMARY, GST_TYPE_X265_ENC);
1806 }
1807
1808 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
1809     GST_VERSION_MINOR,
1810     x265,
1811     "x265-based H265 plugins",
1812     plugin_init, VERSION, "GPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)