change encoder log output format, support GST log
[vaapi:gstreamer-vaapi.git] / gst / vaapiencode / gstvaapih264encode.c
1 #include "gstvaapih264encode.h"
2 #include "gstvaapih264encoder.h"
3
4 GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug);
5 #define GST_CAT_DEFAULT gst_vaapi_h264_encode_debug
6
7 static const char gst_h264encode_sink_caps_str[] =
8     GST_CAPS_CODEC("video/x-raw-yuv, " "format = (fourcc) { I420 } ")
9     GST_CAPS_CODEC("video/x-raw-yuv, " "format = (fourcc) { NV12 } ")
10     GST_CAPS_CODEC("video/x-vaapi-surface ")
11     ;
12     
13 static const GstElementDetails gst_h264encode_details =
14     GST_ELEMENT_DETAILS(
15         "VA-API h264 encoder",
16         "Codec/Encoder/Video",
17         "A VA-API based h264 encoder",
18         "Feng Yuan<feng.yuan@intel.com>");
19
20
21 static const char gst_h264encode_src_caps_str[] =
22     GST_CAPS_CODEC("video/x-h264");
23
24 static GstStaticPadTemplate gst_h264encode_sink_factory =
25     GST_STATIC_PAD_TEMPLATE(
26         "sink",
27         GST_PAD_SINK,
28         GST_PAD_ALWAYS,
29         GST_STATIC_CAPS(gst_h264encode_sink_caps_str));
30
31 static GstStaticPadTemplate gst_h264encode_src_factory =
32     GST_STATIC_PAD_TEMPLATE(
33         "src",
34         GST_PAD_SRC,
35         GST_PAD_ALWAYS,
36         GST_STATIC_CAPS(gst_h264encode_src_caps_str));
37
38 static void gst_h264encode_finalize(GObject *object);
39 static void gst_h264encode_set_property(GObject *object, guint prop_id,
40     const GValue *value, GParamSpec *pspec);
41 static void gst_h264encode_get_property (GObject * object, guint prop_id,
42     GValue * value, GParamSpec * pspec);
43 static gboolean _h264_check_valid_profile(guint profile);
44 static gboolean _h264_check_valid_level(guint level);
45 static gboolean  gst_h264encode_set_src_caps(GstVaapiEncode* encode, GstCaps *caps);
46
47
48 /* h264 encode */
49 GST_BOILERPLATE(
50     GstH264Encode,
51     gst_h264encode,
52     GstVaapiEncode,
53     GST_TYPE_VAAPI_ENCODE);
54
55 enum {
56     H264_PROP_0,
57     H264_PROP_PROFILE,
58     H264_PROP_LEVEL,
59     H264_PROP_BITRATE,
60     H264_PROP_INTRA_PERIOD,
61     H264_PROP_INIT_QP,
62     H264_PROP_MIN_QP,
63     H264_PROP_SLICE_NUM,
64     H264_PROP_B_FRAME_NUM,
65 };
66
67
68 static void
69 gst_h264encode_base_init(gpointer klass)
70 {
71   GstElementClass * const element_class = GST_ELEMENT_CLASS(klass);
72
73   gst_element_class_set_details(element_class, &gst_h264encode_details);
74
75   /* sink pad */
76   gst_element_class_add_pad_template(
77       element_class,
78       gst_static_pad_template_get(&gst_h264encode_sink_factory)
79   );
80
81   /* src pad */
82   gst_element_class_add_pad_template(
83       element_class,
84       gst_static_pad_template_get(&gst_h264encode_src_factory)
85   );
86 }
87
88 static void
89 gst_h264encode_class_init(GstH264EncodeClass *klass)
90 {
91   GObjectClass * const object_class = G_OBJECT_CLASS(klass);
92   GstVaapiEncodeClass *const encode_class = GST_VAAPI_ENCODE_CLASS(klass);
93   GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_encode_debug, "vaapih264encode", 0,
94       "vaapih264encode element");
95
96   object_class->finalize      = gst_h264encode_finalize;
97   object_class->set_property  = gst_h264encode_set_property;
98   object_class->get_property  = gst_h264encode_get_property;
99
100   encode_class->set_encoder_src_caps = gst_h264encode_set_src_caps;
101   
102   g_object_class_install_property (object_class, H264_PROP_PROFILE,
103           g_param_spec_uint ("profile",
104               "H264 Profile",
105               "Profile supports: 66(Baseline), 77(Main), 100(High)",
106               H264_PROFILE_BASELINE,
107               H264_PROFILE_HIGH10,
108               H264_DEFAULT_PROFILE,
109               G_PARAM_READWRITE));
110     g_object_class_install_property (object_class, H264_PROP_LEVEL,
111           g_param_spec_uint ("level",
112               "H264 level idc",
113               "Level idc supports: 10, 11, 12, 13, 20, 21, 22, 30, 31, 32, 40, 41",
114               H264_LEVEL_10,
115               H264_LEVEL_41,
116               H264_DEFAULT_LEVEL,
117               G_PARAM_READWRITE));
118     g_object_class_install_property (object_class, H264_PROP_BITRATE,
119           g_param_spec_uint ("bitrate",
120               "H264 encoding bitrate",
121               "H264 encoding bitrate, 10k~100M, (0, auto-calculate)",
122               0,
123               100*1000*1000,
124               0,
125               G_PARAM_READWRITE));
126     g_object_class_install_property (object_class, H264_PROP_INTRA_PERIOD,
127           g_param_spec_uint ("intra-period",
128               "H264 encoding intra-period",
129               "H264 encoding intra-period",
130               1,
131               300,
132               H264_DEFAULT_INTRA_PERIOD,
133               G_PARAM_READWRITE));
134     g_object_class_install_property (object_class, H264_PROP_INIT_QP,
135           g_param_spec_uint ("init-qp",
136               "H264 init-qp",
137               "H264 init-qp",
138               1,
139               51,
140               H264_DEFAULT_INIT_QP,
141               G_PARAM_READWRITE));
142     g_object_class_install_property (object_class, H264_PROP_MIN_QP,
143           g_param_spec_uint ("min-qp",
144               "H264 min-qp",
145               "H264 min-qp",
146               1,
147               51,
148               H264_DEFAULT_MIN_QP,
149               G_PARAM_READWRITE));
150     g_object_class_install_property (object_class, H264_PROP_SLICE_NUM,
151           g_param_spec_uint ("slice-num",
152               "H264 slice num",
153               "H264 slice num",
154               1,
155               200,
156               1,
157               G_PARAM_READWRITE));
158     g_object_class_install_property (object_class, H264_PROP_B_FRAME_NUM,
159           g_param_spec_uint ("b-frame-num",
160               "B frams num",
161               "B frams num",
162               0,
163               10,
164               0,
165               G_PARAM_READWRITE));
166               
167 }
168
169 static void
170 gst_h264encode_init(GstH264Encode *h264_encode, GstH264EncodeClass *klass)
171 {
172   GstVaapiEncode *encode = GST_VAAPI_ENCODE(h264_encode);
173   encode->encoder = GST_VAAPI_ENCODER(gst_h264_encoder_new());
174   ENCODER_ASSERT(encode->encoder);
175 }
176
177 static void
178 gst_h264encode_finalize(GObject *object)
179 {
180   //GstH264Encode * const h264_encode = GST_H264ENCODE(object);
181   G_OBJECT_CLASS(parent_class)->finalize(object);
182 }
183
184 static void 
185 gst_h264encode_set_property(GObject *object, guint prop_id,
186     const GValue *value, GParamSpec *pspec)
187 {
188   GstVaapiEncode *encode = GST_VAAPI_ENCODE(object);
189   GstH264Encoder *h264encoder = GST_H264_ENCODER(encode->encoder);
190   
191   ENCODER_ASSERT(h264encoder);
192   
193   switch (prop_id) {
194     case H264_PROP_PROFILE: {
195       guint profile = g_value_get_uint(value);
196       if (_h264_check_valid_profile(profile)) {
197         h264encoder->profile = profile;
198       } else {
199         ENCODER_LOG_ERROR("h264encode set property <profile> failed.");
200       }
201     }
202       break;
203       
204     case H264_PROP_LEVEL: {
205       guint level = g_value_get_uint(value);
206       if (_h264_check_valid_level(level)) {
207         h264encoder->level= level;
208       } else {
209         ENCODER_LOG_ERROR("h264encode set property <level> failed.");
210       }
211     }
212       break;
213     
214     case H264_PROP_BITRATE: {
215       h264encoder->bitrate = g_value_get_uint(value);
216     }
217       break;
218     
219     case H264_PROP_INTRA_PERIOD: {
220       h264encoder->intra_period = g_value_get_uint(value);
221     }
222       break;
223     
224     case H264_PROP_INIT_QP: {
225       h264encoder->init_qp = g_value_get_uint(value);
226     }
227       break;
228
229     case H264_PROP_MIN_QP: {
230       h264encoder->min_qp = g_value_get_uint(value);
231     }
232       break;
233       
234     case H264_PROP_SLICE_NUM: {
235       h264encoder->slice_num= g_value_get_uint(value);
236     }
237       break;
238
239     case H264_PROP_B_FRAME_NUM: {
240       h264encoder->b_frame_num= g_value_get_uint(value);
241     }
242       break;
243       
244     default:
245       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
246       break;
247   }
248 }
249
250 static void 
251 gst_h264encode_get_property (GObject * object, guint prop_id,
252     GValue * value, GParamSpec * pspec)
253 {
254   GstVaapiEncode *encode = GST_VAAPI_ENCODE(object);
255   GstH264Encoder *h264encoder = GST_H264_ENCODER(encode->encoder);
256   ENCODER_ASSERT(h264encoder);
257
258   switch (prop_id) {
259     case H264_PROP_PROFILE: 
260       g_value_set_uint (value, h264encoder->profile);
261       break;
262       
263     case H264_PROP_LEVEL: 
264       g_value_set_uint (value, h264encoder->level);
265       break;
266     
267     case H264_PROP_BITRATE: 
268       g_value_set_uint (value, h264encoder->bitrate);
269       break;
270     
271     case H264_PROP_INTRA_PERIOD: 
272       g_value_set_uint (value, h264encoder->intra_period);
273       break;
274     
275     case H264_PROP_INIT_QP: 
276       g_value_set_uint (value, h264encoder->init_qp);
277       break;
278
279     case H264_PROP_MIN_QP: 
280       g_value_set_uint (value, h264encoder->min_qp);
281       break;
282       
283     case H264_PROP_SLICE_NUM:
284       g_value_set_uint (value, h264encoder->slice_num);
285       break;
286
287     case H264_PROP_B_FRAME_NUM:
288       g_value_set_uint (value, h264encoder->b_frame_num);
289       break;
290       
291     default:
292       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
293       break;
294   }
295 }
296
297
298 static gboolean 
299 _h264_check_valid_profile(guint profile)
300 {
301    static const guint limit_profiles[] = { 
302          H264_PROFILE_BASELINE, 
303          H264_PROFILE_MAIN,
304          H264_PROFILE_HIGH
305         };
306    guint n_profiles = sizeof(limit_profiles)/sizeof(limit_profiles[0]);
307    guint i;
308    for (i = 0; i < n_profiles; ++i) {
309      if (limit_profiles[i] == profile)
310        return TRUE;
311    }
312    return FALSE;
313 }
314
315 static gboolean 
316 _h264_check_valid_level(guint level)
317 {
318   static const guint limit_levels[] = { 
319         H264_LEVEL_10, 
320         H264_LEVEL_11,
321         H264_LEVEL_12,
322         H264_LEVEL_13,
323         H264_LEVEL_20,
324         H264_LEVEL_21,
325         H264_LEVEL_22,
326         H264_LEVEL_30,
327         H264_LEVEL_31,
328         H264_LEVEL_32,
329         H264_LEVEL_40,
330         H264_LEVEL_41,
331         H264_LEVEL_42,
332         H264_LEVEL_50,
333         H264_LEVEL_51
334        };
335   guint n_levels = sizeof(limit_levels)/sizeof(limit_levels[0]);
336   guint i;
337   for (i = 0; i < n_levels; ++i) {
338     if (limit_levels[i] == level)
339       return TRUE;
340   }
341   return FALSE;
342
343 }
344
345
346 static gboolean  
347 gst_h264encode_set_src_caps(GstVaapiEncode* encode, GstCaps *caps)
348 {
349   g_return_val_if_fail(caps,FALSE);
350   gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, "avc",
351                             "alignment", G_TYPE_STRING, "au",
352                             NULL);
353   return TRUE;
354 }
355
356