2 * gstvaapih264encode.c - VA-API H.264 encoder
4 * Copyright (C) 2011 Intel Corporation
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.
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.
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
22 #include "gstvaapih264encode.h"
23 #include "gstvaapih264encoder.h"
25 GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug);
26 #define GST_CAT_DEFAULT gst_vaapi_h264_encode_debug
28 static const char gst_h264encode_sink_caps_str[] =
29 GST_CAPS_CODEC("video/x-raw-yuv, " "format = (fourcc) { I420 } ")
30 GST_CAPS_CODEC("video/x-raw-yuv, " "format = (fourcc) { NV12 } ")
31 GST_VAAPI_SURFACE_CAPS;
33 static const GstElementDetails gst_h264encode_details =
35 "VA-API h264 encoder",
36 "Codec/Encoder/Video",
37 "A VA-API based h264 encoder",
38 "Feng Yuan<feng.yuan@intel.com>");
41 static const char gst_h264encode_src_caps_str[] =
42 GST_CAPS_CODEC("video/x-h264");
44 static GstStaticPadTemplate gst_h264encode_sink_factory =
45 GST_STATIC_PAD_TEMPLATE(
49 GST_STATIC_CAPS(gst_h264encode_sink_caps_str));
51 static GstStaticPadTemplate gst_h264encode_src_factory =
52 GST_STATIC_PAD_TEMPLATE(
56 GST_STATIC_CAPS(gst_h264encode_src_caps_str));
58 static void gst_h264encode_finalize(GObject *object);
59 static void gst_h264encode_set_property(GObject *object, guint prop_id,
60 const GValue *value, GParamSpec *pspec);
61 static void gst_h264encode_get_property (GObject * object, guint prop_id,
62 GValue * value, GParamSpec * pspec);
63 static gboolean _h264_check_valid_profile(guint profile);
64 static gboolean _h264_check_valid_level(guint level);
65 static gboolean gst_h264encode_set_src_caps(GstVaapiEncode* encode, GstCaps *caps);
73 GST_TYPE_VAAPI_ENCODE);
80 H264_PROP_INTRA_PERIOD,
84 H264_PROP_B_FRAME_NUM,
89 gst_h264encode_base_init(gpointer klass)
91 GstElementClass * const element_class = GST_ELEMENT_CLASS(klass);
93 gst_element_class_set_details(element_class, &gst_h264encode_details);
96 gst_element_class_add_pad_template(
98 gst_static_pad_template_get(&gst_h264encode_sink_factory)
102 gst_element_class_add_pad_template(
104 gst_static_pad_template_get(&gst_h264encode_src_factory)
109 gst_h264encode_class_init(GstH264EncodeClass *klass)
111 GObjectClass * const object_class = G_OBJECT_CLASS(klass);
112 GstVaapiEncodeClass *const encode_class = GST_VAAPI_ENCODE_CLASS(klass);
113 GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_encode_debug, "vaapih264encode", 0,
114 "vaapih264encode element");
116 object_class->finalize = gst_h264encode_finalize;
117 object_class->set_property = gst_h264encode_set_property;
118 object_class->get_property = gst_h264encode_get_property;
120 encode_class->set_encoder_src_caps = gst_h264encode_set_src_caps;
122 g_object_class_install_property (object_class, H264_PROP_PROFILE,
123 g_param_spec_uint ("profile",
125 "Profile supports: 66(Baseline), 77(Main), 100(High)",
126 H264_PROFILE_BASELINE,
128 H264_DEFAULT_PROFILE,
130 g_object_class_install_property (object_class, H264_PROP_LEVEL,
131 g_param_spec_uint ("level",
133 "Level idc supports: 10, 11, 12, 13, 20, 21, 22, 30, 31, 32, 40, 41",
138 g_object_class_install_property (object_class, H264_PROP_BITRATE,
139 g_param_spec_uint ("bitrate",
140 "H264 encoding bitrate",
141 "H264 encoding bitrate, 10k~100M, (0, auto-calculate)",
146 g_object_class_install_property (object_class, H264_PROP_INTRA_PERIOD,
147 g_param_spec_uint ("intra-period",
148 "H264 encoding intra-period",
149 "H264 encoding intra-period",
152 H264_DEFAULT_INTRA_PERIOD,
154 g_object_class_install_property (object_class, H264_PROP_INIT_QP,
155 g_param_spec_uint ("init-qp",
160 H264_DEFAULT_INIT_QP,
162 g_object_class_install_property (object_class, H264_PROP_MIN_QP,
163 g_param_spec_uint ("min-qp",
170 g_object_class_install_property (object_class, H264_PROP_SLICE_NUM,
171 g_param_spec_uint ("slice-num",
178 g_object_class_install_property (object_class, H264_PROP_B_FRAME_NUM,
179 g_param_spec_uint ("b-frame-num",
190 gst_h264encode_init(GstH264Encode *h264_encode, GstH264EncodeClass *klass)
192 GstVaapiEncode *encode = GST_VAAPI_ENCODE(h264_encode);
193 encode->encoder = GST_VAAPI_ENCODER(gst_h264_encoder_new());
194 ENCODER_ASSERT(encode->encoder);
198 gst_h264encode_finalize(GObject *object)
200 //GstH264Encode * const h264_encode = GST_H264ENCODE(object);
201 G_OBJECT_CLASS(parent_class)->finalize(object);
205 gst_h264encode_set_property(GObject *object, guint prop_id,
206 const GValue *value, GParamSpec *pspec)
208 GstVaapiEncode *encode = GST_VAAPI_ENCODE(object);
209 GstH264Encoder *h264encoder = GST_H264_ENCODER(encode->encoder);
211 ENCODER_ASSERT(h264encoder);
214 case H264_PROP_PROFILE: {
215 guint profile = g_value_get_uint(value);
216 if (_h264_check_valid_profile(profile)) {
217 h264encoder->profile = profile;
219 ENCODER_LOG_ERROR("h264encode set property <profile> failed.");
224 case H264_PROP_LEVEL: {
225 guint level = g_value_get_uint(value);
226 if (_h264_check_valid_level(level)) {
227 h264encoder->level= level;
229 ENCODER_LOG_ERROR("h264encode set property <level> failed.");
234 case H264_PROP_BITRATE: {
235 h264encoder->bitrate = g_value_get_uint(value);
239 case H264_PROP_INTRA_PERIOD: {
240 h264encoder->intra_period = g_value_get_uint(value);
244 case H264_PROP_INIT_QP: {
245 h264encoder->init_qp = g_value_get_uint(value);
249 case H264_PROP_MIN_QP: {
250 h264encoder->min_qp = g_value_get_uint(value);
254 case H264_PROP_SLICE_NUM: {
255 h264encoder->slice_num= g_value_get_uint(value);
259 case H264_PROP_B_FRAME_NUM: {
260 h264encoder->b_frame_num= g_value_get_uint(value);
265 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
271 gst_h264encode_get_property (GObject * object, guint prop_id,
272 GValue * value, GParamSpec * pspec)
274 GstVaapiEncode *encode = GST_VAAPI_ENCODE(object);
275 GstH264Encoder *h264encoder = GST_H264_ENCODER(encode->encoder);
276 ENCODER_ASSERT(h264encoder);
279 case H264_PROP_PROFILE:
280 g_value_set_uint (value, h264encoder->profile);
283 case H264_PROP_LEVEL:
284 g_value_set_uint (value, h264encoder->level);
287 case H264_PROP_BITRATE:
288 g_value_set_uint (value, h264encoder->bitrate);
291 case H264_PROP_INTRA_PERIOD:
292 g_value_set_uint (value, h264encoder->intra_period);
295 case H264_PROP_INIT_QP:
296 g_value_set_uint (value, h264encoder->init_qp);
299 case H264_PROP_MIN_QP:
300 g_value_set_uint (value, h264encoder->min_qp);
303 case H264_PROP_SLICE_NUM:
304 g_value_set_uint (value, h264encoder->slice_num);
307 case H264_PROP_B_FRAME_NUM:
308 g_value_set_uint (value, h264encoder->b_frame_num);
312 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
319 _h264_check_valid_profile(guint profile)
321 static const guint limit_profiles[] = {
322 H264_PROFILE_BASELINE,
326 guint n_profiles = sizeof(limit_profiles)/sizeof(limit_profiles[0]);
328 for (i = 0; i < n_profiles; ++i) {
329 if (limit_profiles[i] == profile)
336 _h264_check_valid_level(guint level)
338 static const guint limit_levels[] = {
355 guint n_levels = sizeof(limit_levels)/sizeof(limit_levels[0]);
357 for (i = 0; i < n_levels; ++i) {
358 if (limit_levels[i] == level)
367 gst_h264encode_set_src_caps(GstVaapiEncode* encode, GstCaps *caps)
369 g_return_val_if_fail(caps,FALSE);
370 gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, "avc",
371 "alignment", G_TYPE_STRING, "au",