h264 encode: add h264 encode plugin and property settings
[vaapi:windyuan-gstreamer-vaapi.git] / gst / vaapi / gstvaapiencode_h264.c
1 /*
2  *  gstvaapiencode_h264.c - VA-API H.264 encoder
3  *
4  *  Copyright (C) 2012-2013 Intel Corporation
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Lesser General Public License
8  *  as published by the Free Software Foundation; either version 2.1
9  *  of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public
17  *  License along with this library; if not, write to the Free
18  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  *  Boston, MA 02110-1301 USA
20  */
21
22 #include "gst/vaapi/sysdeps.h"
23 #include "gst/vaapi/gstvaapicompat.h"
24
25 #include "gstvaapiencode_h264.h"
26 #include "gst/vaapi/gstvaapiencoder_h264.h"
27 #include "gst/vaapi/gstvaapiencoder_h264_priv.h"
28 #include "gst/vaapi/gstvaapidisplay.h"
29 #include "gst/vaapi/gstvaapivalue.h"
30 #include "gst/vaapi/gstvaapisurface.h"
31
32 #include <string.h>
33
34 GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug);
35 #define GST_CAT_DEFAULT gst_vaapi_h264_encode_debug
36
37 #define GST_CAPS_CODEC(CODEC) CODEC "; "
38
39 static const char gst_vaapiencode_h264_sink_caps_str[] =
40     GST_VAAPI_SURFACE_CAPS;
41
42 static const char gst_vaapiencode_h264_src_caps_str[] =
43     GST_CAPS_CODEC("video/x-h264");
44
45 static GstStaticPadTemplate gst_vaapiencode_h264_sink_factory =
46     GST_STATIC_PAD_TEMPLATE(
47         "sink",
48         GST_PAD_SINK,
49         GST_PAD_ALWAYS,
50         GST_STATIC_CAPS(gst_vaapiencode_h264_sink_caps_str));
51
52 static GstStaticPadTemplate gst_vaapiencode_h264_src_factory =
53     GST_STATIC_PAD_TEMPLATE(
54         "src",
55         GST_PAD_SRC,
56         GST_PAD_ALWAYS,
57         GST_STATIC_CAPS(gst_vaapiencode_h264_src_caps_str));
58
59 /* h264 encode */
60 G_DEFINE_TYPE(
61     GstVaapiEncodeH264,
62     gst_vaapiencode_h264,
63     GST_TYPE_VAAPIENCODE)
64
65 enum {
66     H264_PROP_0,
67     H264_PROP_PROFILE,
68     H264_PROP_LEVEL,
69     H264_PROP_RATE_CONTROL,
70     H264_PROP_BITRATE,
71     H264_PROP_INTRA_PERIOD,
72     H264_PROP_INIT_QP,
73     H264_PROP_MIN_QP,
74     H264_PROP_SLICE_NUM,
75     H264_PROP_B_FRAME_NUM,
76 };
77
78 static void
79 gst_vaapiencode_h264_init(
80     GstVaapiEncodeH264 *h264_encode
81 )
82 {
83     GstVaapiEncode *encode = GST_VAAPIENCODE(h264_encode);
84     encode->encoder = gst_vaapi_encoder_h264_new(NULL);
85     g_assert(encode->encoder);
86 }
87
88 static void
89 gst_vaapiencode_h264_finalize(GObject *object)
90 {
91     //GstVaapiEncodeH264 * const h264_encode = GST_VAAPIENCODE_H264(object);
92     G_OBJECT_CLASS(gst_vaapiencode_h264_parent_class)->finalize(object);
93 }
94
95 static void
96 gst_vaapiencode_h264_set_property(
97     GObject *object,
98     guint prop_id,
99     const GValue *value,
100     GParamSpec *pspec
101 )
102 {
103     GstVaapiEncode *encode = GST_VAAPIENCODE(object);
104     GstVaapiEncoderH264 *h264encoder = GST_VAAPI_ENCODER_H264(encode->encoder);
105
106     g_assert(h264encoder);
107
108     switch (prop_id) {
109     case H264_PROP_PROFILE: {
110         guint profile = g_value_get_uint(value);
111         h264encoder->profile = profile;
112         break;
113     }
114
115     case H264_PROP_LEVEL: {
116         guint level = g_value_get_uint(value);
117         h264encoder->level = level;
118         break;
119     }
120
121     case H264_PROP_RATE_CONTROL: {
122       GST_VAAPI_ENCODER_RATE_CONTROL(h264encoder) = g_value_get_enum(value);
123       break;
124     }
125
126     case H264_PROP_BITRATE: {
127         h264encoder->bitrate = g_value_get_uint(value);
128         break;
129     }
130
131     case H264_PROP_INTRA_PERIOD:
132         h264encoder->intra_period = g_value_get_uint(value);
133         break;
134
135     case H264_PROP_INIT_QP:
136         h264encoder->init_qp = g_value_get_uint(value);
137         break;
138
139     case H264_PROP_MIN_QP:
140         h264encoder->min_qp = g_value_get_uint(value);
141         break;
142
143     case H264_PROP_SLICE_NUM:
144         h264encoder->slice_num= g_value_get_uint(value);
145         break;
146
147     case H264_PROP_B_FRAME_NUM:
148         h264encoder->b_frame_num= g_value_get_uint(value);
149         break;
150
151     default:
152         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
153         break;
154     }
155 }
156
157 static void
158 gst_vaapiencode_h264_get_property (
159     GObject * object,
160     guint prop_id,
161     GValue * value,
162     GParamSpec * pspec
163 )
164 {
165     GstVaapiEncode *encode = GST_VAAPIENCODE(object);
166     GstVaapiEncoderH264 *h264encoder = GST_VAAPI_ENCODER_H264(encode->encoder);
167     g_assert(h264encoder);
168
169     switch (prop_id) {
170     case H264_PROP_PROFILE:
171         g_value_set_uint (value, h264encoder->profile);
172         break;
173     case H264_PROP_LEVEL:
174         g_value_set_uint (value, h264encoder->level);
175         break;
176     case H264_PROP_RATE_CONTROL:
177         g_value_set_enum(value, GST_VAAPI_ENCODER_RATE_CONTROL(h264encoder));
178         break;
179     case H264_PROP_BITRATE:
180         g_value_set_uint (value, h264encoder->bitrate);
181         break;
182     case H264_PROP_INTRA_PERIOD:
183         g_value_set_uint (value, h264encoder->intra_period);
184         break;
185     case H264_PROP_INIT_QP:
186         g_value_set_uint (value, h264encoder->init_qp);
187         break;
188     case H264_PROP_MIN_QP:
189         g_value_set_uint (value, h264encoder->min_qp);
190         break;
191     case H264_PROP_SLICE_NUM:
192         g_value_set_uint (value, h264encoder->slice_num);
193         break;
194     case H264_PROP_B_FRAME_NUM:
195         g_value_set_uint (value, h264encoder->b_frame_num);
196         break;
197     default:
198         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
199         break;
200     }
201 }
202
203 static GstVaapiEncoder *
204 gst_vaapiencode_h264_create_encoder(GstVaapiDisplay *display)
205 {
206     return gst_vaapi_encoder_h264_new(display);
207 }
208
209 static void
210 gst_vaapiencode_h264_class_init(GstVaapiEncodeH264Class *klass)
211 {
212     GObjectClass * const object_class = G_OBJECT_CLASS(klass);
213     GstElementClass *const element_class = GST_ELEMENT_CLASS(klass);
214     GstVaapiEncodeClass *const encode_class = GST_VAAPIENCODE_CLASS(klass);
215     GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_encode_debug,
216                            "vaapih264encode",
217                            0,
218                            "vaapih264encode element");
219
220     object_class->finalize      = gst_vaapiencode_h264_finalize;
221     object_class->set_property  = gst_vaapiencode_h264_set_property;
222     object_class->get_property  = gst_vaapiencode_h264_get_property;
223
224     encode_class->create_encoder = gst_vaapiencode_h264_create_encoder;
225
226     gst_element_class_set_static_metadata(element_class,
227         "VA-API h264 encoder",
228         "Codec/Encoder/Video",
229         "A VA-API based video encoder",
230         "Wind Yuan <feng.yuan@intel.com>");
231
232     /* sink pad */
233     gst_element_class_add_pad_template(
234         element_class,
235         gst_static_pad_template_get(&gst_vaapiencode_h264_sink_factory)
236     );
237
238     /* src pad */
239     gst_element_class_add_pad_template(
240         element_class,
241         gst_static_pad_template_get(&gst_vaapiencode_h264_src_factory)
242     );
243
244     g_object_class_install_property (
245         object_class,
246         H264_PROP_PROFILE,
247         g_param_spec_uint (
248             "profile",
249             "H264 Profile",
250             "Profile supports: Baseline, Main, High",
251             GST_VAAPI_PROFILE_H264_BASELINE,
252             GST_VAAPI_PROFILE_H264_HIGH,
253             GST_VAAPI_ENCODER_H264_DEFAULT_PROFILE,
254             G_PARAM_READWRITE));
255
256     g_object_class_install_property (
257       object_class,
258       H264_PROP_LEVEL,
259       g_param_spec_uint (
260           "level",
261           "H264 level idc",
262           "Level idc supports: 10, 11, 12, 13, 20, 21, 22, 30, 31, 32, 40, 41",
263           GST_VAAPI_ENCODER_H264_LEVEL_10,
264           GST_VAAPI_ENCODER_H264_LEVEL_51,
265           GST_VAAPI_ENCODER_H264_DEFAULT_LEVEL,
266           G_PARAM_READWRITE));
267
268     g_object_class_install_property (
269       object_class,
270       H264_PROP_RATE_CONTROL,
271       g_param_spec_enum ("rate-control",
272           "rate-control",
273           "Rate control mode",
274           GST_VAAPI_TYPE_RATE_CONTROL,
275           GST_VAAPI_RATECONTROL_NONE,
276           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
277
278     g_object_class_install_property (
279       object_class,
280       H264_PROP_BITRATE,
281       g_param_spec_uint (
282           "bitrate",
283           "H264 encoding bitrate(kbps)",
284           "H264 encoding bitrate(kbps), (0, auto-calculate)",
285           0,
286           100*1024,
287           0,
288           G_PARAM_READWRITE));
289
290     g_object_class_install_property (
291       object_class,
292       H264_PROP_INTRA_PERIOD,
293       g_param_spec_uint (
294           "intra-period",
295           "H264 encoding intra-period",
296           "H264 encoding intra-period",
297           1,
298           300,
299           GST_VAAPI_ENCODER_H264_DEFAULT_INTRA_PERIOD,
300           G_PARAM_READWRITE));
301
302     g_object_class_install_property (
303       object_class,
304       H264_PROP_INIT_QP,
305       g_param_spec_uint (
306           "init-qp",
307           "H264 init-qp",
308           "H264 init-qp",
309           1,
310           51,
311           GST_VAAPI_ENCODER_H264_DEFAULT_INIT_QP,
312           G_PARAM_READWRITE));
313
314     g_object_class_install_property (
315       object_class,
316       H264_PROP_MIN_QP,
317       g_param_spec_uint (
318           "min-qp",
319           "H264 min-qp",
320           "H264 min-qp",
321           1,
322           51,
323           GST_VAAPI_ENCODER_H264_DEFAULT_MIN_QP,
324           G_PARAM_READWRITE));
325
326     g_object_class_install_property (
327       object_class,
328       H264_PROP_SLICE_NUM,
329       g_param_spec_uint (
330           "slice-num",
331           "H264 slice num",
332           "H264 slice num",
333           1,
334           200,
335           1,
336           G_PARAM_READWRITE));
337
338     g_object_class_install_property (
339       object_class,
340       H264_PROP_B_FRAME_NUM,
341       g_param_spec_uint (
342           "b-frame-num",
343           "B frams num",
344           "B frams num",
345           0,
346           10,
347           0,
348           G_PARAM_READWRITE));
349 }