1 /*
2  *  gstvaapiencoder_priv.h - VA encoder abstraction (private definitions)
3  *
4  *  Copyright (C) 2013-2014 Intel Corporation
5  *    Author: Wind Yuan <feng.yuan@intel.com>
6  *    Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Lesser General Public License
10  *  as published by the Free Software Foundation; either version 2.1
11  *  of the License, or (at your option) any later version.
12  *
13  *  This library is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  Lesser General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Lesser General Public
19  *  License along with this library; if not, write to the Free
20  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  *  Boston, MA 02110-1301 USA
22  */
23 
24 #ifndef GST_VAAPI_ENCODER_PRIV_H
25 #define GST_VAAPI_ENCODER_PRIV_H
26 
27 #include <gst/vaapi/gstvaapiencoder.h>
28 #include <gst/vaapi/gstvaapiencoder_objects.h>
29 #include <gst/vaapi/gstvaapicontext.h>
30 #include <gst/vaapi/gstvaapivideopool.h>
31 #include <gst/video/gstvideoutils.h>
32 #include <gst/vaapi/gstvaapivalue.h>
33 
34 G_BEGIN_DECLS
35 
36 #define GST_VAAPI_ENCODER_CAST(encoder) \
37     ((GstVaapiEncoder *)(encoder))
38 
39 #define GST_VAAPI_ENCODER_CLASS(klass) \
40     ((GstVaapiEncoderClass *)(klass))
41 
42 #define GST_VAAPI_ENCODER_GET_CLASS(obj) \
43     GST_VAAPI_ENCODER_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj))
44 
45 /**
46  * GST_VAAPI_ENCODER_PACKED_HEADERS:
47  * @encoder: a #GstVaapiEncoder
48  *
49  * Macro that evaluates to the required set of VA packed headers that
50  * need to be submitted along with the corresponding param buffers.
51  * This is an internal macro that does not do any run-time type check.
52  */
53 #undef  GST_VAAPI_ENCODER_PACKED_HEADERS
54 #define GST_VAAPI_ENCODER_PACKED_HEADERS(encoder) \
55     GST_VAAPI_ENCODER_CAST(encoder)->packed_headers
56 
57 /**
58  * GST_VAAPI_ENCODER_DISPLAY:
59  * @encoder: a #GstVaapiEncoder
60  *
61  * Macro that evaluates to the #GstVaapiDisplay of @encoder.
62  * This is an internal macro that does not do any run-time type check.
63  */
64 #undef  GST_VAAPI_ENCODER_DISPLAY
65 #define GST_VAAPI_ENCODER_DISPLAY(encoder) \
66     GST_VAAPI_ENCODER_CAST(encoder)->display
67 
68 /**
69  * GST_VAAPI_ENCODER_CONTEXT:
70  * @encoder: a #GstVaapiEncoder
71  *
72  * Macro that evaluates to the #GstVaapiContext of @encoder.
73  * This is an internal macro that does not do any run-time type check.
74  */
75 #undef  GST_VAAPI_ENCODER_CONTEXT
76 #define GST_VAAPI_ENCODER_CONTEXT(encoder) \
77     GST_VAAPI_ENCODER_CAST(encoder)->context
78 
79 /**
80  * GST_VAAPI_ENCODER_VIDEO_INFO:
81  * @encoder: a #GstVaapiEncoder
82  *
83  * Macro that evaluates to the #GstVideoInfo of @encoder.
84  * This is an internal macro that does not do any run-time type check.
85  */
86 #undef  GST_VAAPI_ENCODER_VIDEO_INFO
87 #define GST_VAAPI_ENCODER_VIDEO_INFO(encoder) \
88   (&GST_VAAPI_ENCODER_CAST (encoder)->video_info)
89 
90 /**
91  * GST_VAAPI_ENCODER_WIDTH:
92  * @encoder: a #GstVaapiEncoder
93  *
94  * Macro that evaluates to the coded width of the picture.
95  * This is an internal macro that does not do any run-time type check.
96  */
97 #undef  GST_VAAPI_ENCODER_WIDTH
98 #define GST_VAAPI_ENCODER_WIDTH(encoder) \
99   (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)->width)
100 
101 /**
102  * GST_VAAPI_ENCODER_HEIGHT:
103  * @encoder: a #GstVaapiEncoder
104  *
105  * Macro that evaluates to the coded height of the picture.
106  * This is an internal macro that does not do any run-time type check.
107  */
108 #undef  GST_VAAPI_ENCODER_HEIGHT
109 #define GST_VAAPI_ENCODER_HEIGHT(encoder) \
110   (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)->height)
111 
112 /**
113  * GST_VAAPI_ENCODER_FPS_N:
114  * @encoder: a #GstVaapiEncoder
115  *
116  * Macro that evaluates to the coded framerate numerator.
117  * This is an internal macro that does not do any run-time type check.
118  */
119 #undef  GST_VAAPI_ENCODER_FPS_N
120 #define GST_VAAPI_ENCODER_FPS_N(encoder) \
121   (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)->fps_n)
122 
123 /**
124  * GST_VAAPI_ENCODER_FPS_D:
125  * @encoder: a #GstVaapiEncoder
126  *
127  * Macro that evaluates to the coded framerate denominator.
128  * This is an internal macro that does not do any run-time type check.
129  */
130 #undef  GST_VAAPI_ENCODER_FPS_D
131 #define GST_VAAPI_ENCODER_FPS_D(encoder) \
132   (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)->fps_d)
133 
134 /**
135  * GST_VAAPI_ENCODER_RATE_CONTROL:
136  * @encoder: a #GstVaapiEncoder
137  *
138  * Macro that evaluates to the rate control.
139  * This is an internal macro that does not do any run-time type check.
140  */
141 #undef  GST_VAAPI_ENCODER_RATE_CONTROL
142 #define GST_VAAPI_ENCODER_RATE_CONTROL(encoder) \
143   (GST_VAAPI_ENCODER_CAST (encoder)->rate_control)
144 
145 /**
146  * GST_VAAPI_ENCODER_KEYFRAME_PERIOD:
147  * @encoder: a #GstVaapiEncoder
148  *
149  * Macro that evaluates to the keyframe period.
150  * This is an internal macro that does not do any run-time type check.
151  */
152 #undef  GST_VAAPI_ENCODER_KEYFRAME_PERIOD
153 #define GST_VAAPI_ENCODER_KEYFRAME_PERIOD(encoder) \
154   (GST_VAAPI_ENCODER_CAST (encoder)->keyframe_period)
155 
156 /**
157  * GST_VAAPI_ENCODER_TUNE:
158  * @encoder: a #GstVaapiEncoder
159  *
160  * Macro that evaluates to the tuning option.
161  * This is an internal macro that does not do any run-time type check.
162  */
163 #undef  GST_VAAPI_ENCODER_TUNE
164 #define GST_VAAPI_ENCODER_TUNE(encoder) \
165   (GST_VAAPI_ENCODER_CAST (encoder)->tune)
166 
167 /**
168  * GST_VAAPI_ENCODER_QUALITY_LEVEL:
169  * @encoder: a #GstVaapiEncoder
170  *
171  * Macro that evaluates to the quality level
172  * This is an internal macro that does not do any run-time type check.
173  */
174 #undef  GST_VAAPI_ENCODER_QUALITY_LEVEL
175 #define GST_VAAPI_ENCODER_QUALITY_LEVEL(encoder) \
176   (GST_VAAPI_ENCODER_CAST (encoder)->va_quality_level.quality_level)
177 
178 /**
179  * GST_VAAPI_ENCODER_VA_RATE_CONTROL:
180  * @encoder: a #GstVaapiEncoder
181  *
182  * Macro that evaluates to #VAEncMiscParameterRateControl
183  * This is an internal macro that does not do any run-time type check.
184  */
185 #undef  GST_VAAPI_ENCODER_VA_RATE_CONTROL
186 #define GST_VAAPI_ENCODER_VA_RATE_CONTROL(encoder) \
187   (GST_VAAPI_ENCODER_CAST (encoder)->va_ratecontrol)
188 
189 /**
190  * GST_VAAPI_ENCODER_VA_FRAME_RATE:
191  * @encoder: a #GstVaapiEncoder
192  *
193  * Macro that evaluates to #VAEncMiscParameterFrameRate
194  * This is an internal macro that does not do any run-time type check.
195  */
196 #undef  GST_VAAPI_ENCODER_VA_FRAME_RATE
197 #define GST_VAAPI_ENCODER_VA_FRAME_RATE(encoder) \
198   (GST_VAAPI_ENCODER_CAST (encoder)->va_framerate)
199 
200 /**
201  * GST_VAAPI_ENCODER_VA_HRD:
202  * @encoder: a #GstVaapiEncoder
203  *
204  * Macro that evaluates to #VAEncMiscParameterHRD
205  * This is an internal macro that does not do any run-time type check.
206  */
207 #undef  GST_VAAPI_ENCODER_VA_HRD
208 #define GST_VAAPI_ENCODER_VA_HRD(encoder) \
209   (GST_VAAPI_ENCODER_CAST (encoder)->va_hrd)
210 
211 /* Generate a mask for the supplied tuning option (internal) */
212 #define GST_VAAPI_ENCODER_TUNE_MASK(TUNE) \
213   (1U << G_PASTE (GST_VAAPI_ENCODER_TUNE_, TUNE))
214 
215 #define GST_VAAPI_TYPE_ENCODER_TUNE \
216   (gst_vaapi_encoder_tune_get_type ())
217 
218 #define GST_VAAPI_TYPE_ENCODER_MBBRC \
219   (gst_vaapi_encoder_mbbrc_get_type ())
220 
221 typedef struct _GstVaapiEncoderClass GstVaapiEncoderClass;
222 typedef struct _GstVaapiEncoderClassData GstVaapiEncoderClassData;
223 
224 /* Private GstVaapiEncoderPropInfo definition */
225 typedef struct {
226   gint prop;
227   GParamSpec *pspec;
228 } GstVaapiEncoderPropData;
229 
230 #define GST_VAAPI_ENCODER_PROPERTIES_APPEND(props, id, pspec) do {      \
231     props = gst_vaapi_encoder_properties_append (props, id, pspec);     \
232     if (!props)                                                         \
233       return NULL;                                                      \
234   } while (0)
235 
236 G_GNUC_INTERNAL
237 GPtrArray *
238 gst_vaapi_encoder_properties_append (GPtrArray * props, gint prop_id,
239     GParamSpec *pspec);
240 
241 G_GNUC_INTERNAL
242 GPtrArray *
243 gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass);
244 
245 struct _GstVaapiEncoder
246 {
247   /*< private >*/
248   GstVaapiMiniObject parent_instance;
249 
250   GPtrArray *properties;
251   GstVaapiDisplay *display;
252   GstVaapiContext *context;
253   GstVaapiContextInfo context_info;
254   GstVaapiEncoderTune tune;
255   guint packed_headers;
256 
257   VADisplay va_display;
258   VAContextID va_context;
259   GstVideoInfo video_info;
260   GstVaapiProfile profile;
261   guint num_ref_frames;
262   GstVaapiRateControl rate_control;
263   guint32 rate_control_mask;
264   guint bitrate; /* kbps */
265   guint keyframe_period;
266 
267   /* Maximum number of reference frames supported
268    * for the reference picture list 0 and list 2 */
269   guint max_num_ref_frames_0;
270   guint max_num_ref_frames_1;
271 
272   /* parameters */
273   VAEncMiscParameterBufferQualityLevel va_quality_level;
274 
275   GMutex mutex;
276   GCond surface_free;
277   GCond codedbuf_free;
278   guint codedbuf_size;
279   GstVaapiVideoPool *codedbuf_pool;
280   GAsyncQueue *codedbuf_queue;
281   guint32 num_codedbuf_queued;
282 
283   guint got_packed_headers:1;
284   guint got_rate_control_mask:1;
285 
286   /* miscellaneous buffer parameters */
287   VAEncMiscParameterRateControl va_ratecontrol;
288   VAEncMiscParameterFrameRate va_framerate;
289   VAEncMiscParameterHRD va_hrd;
290 
291   gint8 default_roi_value;
292 };
293 
294 struct _GstVaapiEncoderClassData
295 {
296   /*< private >*/
297   GstVaapiCodec codec;
298   guint32 packed_headers;
299 
300   GType (*rate_control_get_type)(void);
301   GstVaapiRateControl default_rate_control;
302   guint32 rate_control_mask;
303 
304   GType (*encoder_tune_get_type)(void);
305   GstVaapiEncoderTune default_encoder_tune;
306   guint32 encoder_tune_mask;
307 };
308 
309 #define GST_VAAPI_ENCODER_DEFINE_CLASS_DATA(CODEC)                      \
310   GST_VAAPI_TYPE_DEFINE_ENUM_SUBSET_FROM_MASK(                          \
311       G_PASTE (GstVaapiRateControl, CODEC),                             \
312       G_PASTE (gst_vaapi_rate_control_, CODEC),                         \
313       GST_VAAPI_TYPE_RATE_CONTROL, SUPPORTED_RATECONTROLS);             \
314                                                                         \
315   GST_VAAPI_TYPE_DEFINE_ENUM_SUBSET_FROM_MASK(                          \
316       G_PASTE (GstVaapiEncoderTune, CODEC),                             \
317       G_PASTE (gst_vaapi_encoder_tune_, CODEC),                         \
318       GST_VAAPI_TYPE_ENCODER_TUNE, SUPPORTED_TUNE_OPTIONS);             \
319                                                                         \
320   static const GstVaapiEncoderClassData g_class_data = {                \
321     .codec = G_PASTE (GST_VAAPI_CODEC_, CODEC),                         \
322     .packed_headers = SUPPORTED_PACKED_HEADERS,                         \
323     .rate_control_get_type =                                            \
324         G_PASTE (G_PASTE (gst_vaapi_rate_control_, CODEC), _get_type),  \
325     .default_rate_control = DEFAULT_RATECONTROL,                        \
326     .rate_control_mask = SUPPORTED_RATECONTROLS,                        \
327     .encoder_tune_get_type =                                            \
328         G_PASTE (G_PASTE (gst_vaapi_encoder_tune_, CODEC), _get_type),  \
329     .default_encoder_tune = GST_VAAPI_ENCODER_TUNE_NONE,                \
330     .encoder_tune_mask = SUPPORTED_TUNE_OPTIONS,                        \
331   }
332 
333 struct _GstVaapiEncoderClass
334 {
335   /*< private >*/
336   GstVaapiMiniObjectClass parent_class;
337 
338   const GstVaapiEncoderClassData *class_data;
339 
340   gboolean              (*init)         (GstVaapiEncoder * encoder);
341   void                  (*finalize)     (GstVaapiEncoder * encoder);
342 
343   GstVaapiEncoderStatus (*reconfigure)  (GstVaapiEncoder * encoder);
344 
345   GPtrArray *           (*get_default_properties) (void);
346   GstVaapiEncoderStatus (*set_property) (GstVaapiEncoder * encoder,
347                                          gint prop_id,
348                                          const GValue * value);
349 
350   GstVaapiEncoderStatus (*reordering)   (GstVaapiEncoder * encoder,
351                                          GstVideoCodecFrame * in,
352                                          GstVaapiEncPicture ** out);
353   GstVaapiEncoderStatus (*encode)       (GstVaapiEncoder * encoder,
354                                          GstVaapiEncPicture * picture,
355                                          GstVaapiCodedBufferProxy * codedbuf);
356 
357   GstVaapiEncoderStatus (*flush)        (GstVaapiEncoder * encoder);
358 
359   /* get_codec_data can be NULL */
360   GstVaapiEncoderStatus (*get_codec_data) (GstVaapiEncoder * encoder,
361                                            GstBuffer ** codec_data);
362 
363   /* To create a secondary context for a single base encoder */
364   gboolean              (*ensure_secondary_context) (GstVaapiEncoder * encoder);
365 
366   /* Iterator that retrieves the pending pictures in the reordered
367    * list */
368   gboolean              (*get_pending_reordered) (GstVaapiEncoder * encoder,
369                                                   GstVaapiEncPicture ** picture,
370                                                   gpointer * state);
371 };
372 
373 #define GST_VAAPI_ENCODER_CLASS_HOOK(codec, func) \
374   .func = G_PASTE (G_PASTE (G_PASTE (gst_vaapi_encoder_,codec),_), func)
375 
376 #define GST_VAAPI_ENCODER_CLASS_INIT_BASE(CODEC)                \
377   .parent_class = {                                             \
378     .size = sizeof (G_PASTE (GstVaapiEncoder, CODEC)),          \
379     .finalize = (GDestroyNotify) gst_vaapi_encoder_finalize     \
380   }
381 
382 #define GST_VAAPI_ENCODER_CLASS_INIT(CODEC, codec)              \
383   GST_VAAPI_ENCODER_CLASS_INIT_BASE (CODEC),                    \
384     .class_data = &g_class_data,                                \
385     GST_VAAPI_ENCODER_CLASS_HOOK (codec, init),                 \
386     GST_VAAPI_ENCODER_CLASS_HOOK (codec, finalize),             \
387     GST_VAAPI_ENCODER_CLASS_HOOK (codec, reconfigure),          \
388     GST_VAAPI_ENCODER_CLASS_HOOK (codec, get_default_properties), \
389     GST_VAAPI_ENCODER_CLASS_HOOK (codec, reordering),           \
390     GST_VAAPI_ENCODER_CLASS_HOOK (codec, encode),               \
391     GST_VAAPI_ENCODER_CLASS_HOOK (codec, flush)
392 
393 G_GNUC_INTERNAL
394 GstVaapiEncoder *
395 gst_vaapi_encoder_new (const GstVaapiEncoderClass * klass,
396     GstVaapiDisplay * display);
397 
398 G_GNUC_INTERNAL
399 void
400 gst_vaapi_encoder_finalize (GstVaapiEncoder * encoder);
401 
402 G_GNUC_INTERNAL
403 GstVaapiSurfaceProxy *
404 gst_vaapi_encoder_create_surface (GstVaapiEncoder *
405     encoder);
406 
407 static inline void
gst_vaapi_encoder_release_surface(GstVaapiEncoder * encoder,GstVaapiSurfaceProxy * proxy)408 gst_vaapi_encoder_release_surface (GstVaapiEncoder * encoder,
409     GstVaapiSurfaceProxy * proxy)
410 {
411   gst_vaapi_surface_proxy_unref (proxy);
412 }
413 
414 G_GNUC_INTERNAL
415 gboolean
416 gst_vaapi_encoder_ensure_param_quality_level (GstVaapiEncoder * encoder,
417     GstVaapiEncPicture * picture);
418 
419 G_GNUC_INTERNAL
420 gboolean
421 gst_vaapi_encoder_ensure_param_control_rate (GstVaapiEncoder * encoder,
422     GstVaapiEncPicture * picture);
423 
424 G_GNUC_INTERNAL
425 gboolean
426 gst_vaapi_encoder_ensure_param_roi_regions (GstVaapiEncoder * encoder,
427     GstVaapiEncPicture * picture);
428 
429 G_GNUC_INTERNAL
430 gboolean
431 gst_vaapi_encoder_ensure_num_slices (GstVaapiEncoder * encoder,
432     GstVaapiProfile profile, GstVaapiEntrypoint entrypoint,
433     guint media_max_slices, guint * num_slices);
434 
435 G_GNUC_INTERNAL
436 gboolean
437 gst_vaapi_encoder_ensure_max_num_ref_frames (GstVaapiEncoder * encoder,
438     GstVaapiProfile profile, GstVaapiEntrypoint entrypoint);
439 
440 G_END_DECLS
441 
442 #endif /* GST_VAAPI_ENCODER_PRIV_H */
443