2 * gstvaapiencode_h264.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 "gstvaapiencode_h264.h"
23 #include "gst/vaapi/gstvaapiencoder_h264.h"
24 #include "gst/vaapi/gstvaapivalue.h"
28 GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug);
29 #define GST_CAT_DEFAULT gst_vaapi_h264_encode_debug
31 static const char gst_vaapi_encode_h264_sink_caps_str[] =
32 GST_VAAPI_SURFACE_CAPS "; "
33 GST_VAAPI_BUFFER_SHARING_CAPS;
35 static const GstElementDetails gst_vaapi_encode_h264_details =
37 "VA-API h264 encoder",
38 "Codec/Encoder/Video",
39 "A VA-API based h264 encoder",
40 "Feng Yuan<feng.yuan@intel.com>");
43 static const char gst_vaapi_encode_h264_src_caps_str[] =
44 GST_CAPS_CODEC("video/x-h264");
46 static GstStaticPadTemplate gst_vaapi_encode_h264_sink_factory =
47 GST_STATIC_PAD_TEMPLATE(
51 GST_STATIC_CAPS(gst_vaapi_encode_h264_sink_caps_str));
53 static GstStaticPadTemplate gst_vaapi_encode_h264_src_factory =
54 GST_STATIC_PAD_TEMPLATE(
58 GST_STATIC_CAPS(gst_vaapi_encode_h264_src_caps_str));
63 gst_vaapi_encode_h264,
65 GST_TYPE_VAAPI_ENCODE)
71 H264_PROP_RATE_CONTROL,
73 H264_PROP_INTRA_PERIOD,
77 H264_PROP_B_FRAME_NUM,
81 gst_vaapi_encode_h264_init(
82 GstVaapiEncodeH264 *h264_encode,
83 GstVaapiEncodeH264Class *klass
86 GstVaapiEncode *encode = GST_VAAPI_ENCODE(h264_encode);
87 encode->encoder = GST_VAAPI_ENCODER(gst_vaapi_encoder_h264_new());
88 ENCODER_ASSERT(encode->encoder);
92 gst_vaapi_encode_h264_finalize(GObject *object)
94 //GstVaapiEncodeH264 * const h264_encode = GST_VAAPI_ENCODE_H264(object);
95 G_OBJECT_CLASS(parent_class)->finalize(object);
99 static inline gboolean
100 h264_check_valid_profile(guint profile)
102 static const guint limit_profiles[] = {
103 H264_PROFILE_BASELINE,
107 guint n_profiles = sizeof(limit_profiles)/sizeof(limit_profiles[0]);
109 for (i = 0; i < n_profiles; ++i) {
110 if (limit_profiles[i] == profile)
116 static inline gboolean
117 h264_check_valid_level(guint level)
119 static const guint limit_levels[] = {
136 guint n_levels = sizeof(limit_levels)/sizeof(limit_levels[0]);
138 for (i = 0; i < n_levels; ++i) {
139 if (limit_levels[i] == level)
148 gst_vaapi_encode_h264_set_property(
155 GstVaapiEncode *encode = GST_VAAPI_ENCODE(object);
156 GstVaapiEncoderH264 *h264encoder = GST_VAAPI_ENCODER_H264(encode->encoder);
158 ENCODER_ASSERT(h264encoder);
161 case H264_PROP_PROFILE: {
162 guint profile = g_value_get_uint(value);
163 if (h264_check_valid_profile(profile)) {
164 h264encoder->profile = profile;
166 ENCODER_LOG_ERROR("h264encode set property <profile> failed.");
171 case H264_PROP_LEVEL: {
172 guint level = g_value_get_uint(value);
173 if (h264_check_valid_level(level)) {
174 h264encoder->level= level;
176 ENCODER_LOG_ERROR("h264encode set property <level> failed.");
181 case H264_PROP_RATE_CONTROL: {
182 ENCODER_RATE_CONTROL(h264encoder) = g_value_get_enum(value);
186 case H264_PROP_BITRATE: {
187 h264encoder->bitrate = g_value_get_uint(value);
191 case H264_PROP_INTRA_PERIOD: {
192 h264encoder->intra_period = g_value_get_uint(value);
196 case H264_PROP_INIT_QP: {
197 h264encoder->init_qp = g_value_get_uint(value);
201 case H264_PROP_MIN_QP: {
202 h264encoder->min_qp = g_value_get_uint(value);
206 case H264_PROP_SLICE_NUM: {
207 h264encoder->slice_num= g_value_get_uint(value);
211 case H264_PROP_B_FRAME_NUM: {
212 h264encoder->b_frame_num= g_value_get_uint(value);
217 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
223 gst_vaapi_encode_h264_get_property (
230 GstVaapiEncode *encode = GST_VAAPI_ENCODE(object);
231 GstVaapiEncoderH264 *h264encoder = GST_VAAPI_ENCODER_H264(encode->encoder);
232 ENCODER_ASSERT(h264encoder);
235 case H264_PROP_PROFILE:
236 g_value_set_uint (value, h264encoder->profile);
239 case H264_PROP_LEVEL:
240 g_value_set_uint (value, h264encoder->level);
243 case H264_PROP_RATE_CONTROL:
244 g_value_set_enum(value, ENCODER_RATE_CONTROL(h264encoder));
247 case H264_PROP_BITRATE:
248 g_value_set_uint (value, h264encoder->bitrate);
251 case H264_PROP_INTRA_PERIOD:
252 g_value_set_uint (value, h264encoder->intra_period);
255 case H264_PROP_INIT_QP:
256 g_value_set_uint (value, h264encoder->init_qp);
259 case H264_PROP_MIN_QP:
260 g_value_set_uint (value, h264encoder->min_qp);
263 case H264_PROP_SLICE_NUM:
264 g_value_set_uint (value, h264encoder->slice_num);
267 case H264_PROP_B_FRAME_NUM:
268 g_value_set_uint (value, h264encoder->b_frame_num);
272 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
278 gst_vaapi_encode_h264_set_src_caps(
279 GstVaapiEncode* encode,
283 GstVaapiEncoderH264 *h264encoder = GST_VAAPI_ENCODER_H264(encode->encoder);
284 GstCaps *peer_caps, *allowed_caps;
286 const gchar *stream_format;
288 g_return_val_if_fail(caps,FALSE);
289 peer_caps = gst_pad_peer_get_caps_reffed(encode->srcpad);
291 allowed_caps = gst_caps_intersect(peer_caps, caps);
293 allowed_caps = gst_caps_make_writable(allowed_caps);
294 gst_pad_fixate_caps(encode->srcpad, caps);
295 s = gst_caps_get_structure (allowed_caps, 0);
296 stream_format = gst_structure_get_string (s, "stream-format");
298 if (!strcmp (stream_format, "avc")) {
299 gst_vaapi_encoder_h264_set_avc_flag(h264encoder, TRUE);
300 } else if (!strcmp (stream_format, "byte-stream")) {
301 gst_vaapi_encoder_h264_set_avc_flag(h264encoder, FALSE);
304 gst_caps_unref(allowed_caps);
306 gst_caps_unref(peer_caps);
308 gst_caps_set_simple(caps, "stream-format",
310 (gst_vaapi_encoder_h264_get_avc_flag(h264encoder) ? "avc" : "byte-stream"),
311 "alignment", G_TYPE_STRING, "au",
317 gst_vaapi_encode_h264_base_init(gpointer klass)
319 GstElementClass * const element_class = GST_ELEMENT_CLASS(klass);
321 gst_element_class_set_details(element_class, &gst_vaapi_encode_h264_details);
324 gst_element_class_add_pad_template(
326 gst_static_pad_template_get(&gst_vaapi_encode_h264_sink_factory)
330 gst_element_class_add_pad_template(
332 gst_static_pad_template_get(&gst_vaapi_encode_h264_src_factory)
337 gst_vaapi_encode_h264_class_init(GstVaapiEncodeH264Class *klass)
339 GObjectClass * const object_class = G_OBJECT_CLASS(klass);
340 GstVaapiEncodeClass *const encode_class = GST_VAAPI_ENCODE_CLASS(klass);
341 GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_encode_debug,
344 "vaapih264encode element");
346 object_class->finalize = gst_vaapi_encode_h264_finalize;
347 object_class->set_property = gst_vaapi_encode_h264_set_property;
348 object_class->get_property = gst_vaapi_encode_h264_get_property;
350 encode_class->set_encoder_src_caps = gst_vaapi_encode_h264_set_src_caps;
352 g_object_class_install_property (
358 "Profile supports: 66(Baseline), 77(Main), 100(High)",
359 H264_PROFILE_BASELINE,
361 H264_DEFAULT_PROFILE,
364 g_object_class_install_property (
370 "Level idc supports: 10, 11, 12, 13, 20, 21, 22, 30, 31, 32, 40, 41",
376 g_object_class_install_property (
378 H264_PROP_RATE_CONTROL,
379 g_param_spec_enum ("rate-control",
382 GST_VAAPI_TYPE_RATE_CONTROL,
383 GST_VAAPI_RATECONTROL_NONE,
384 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
386 g_object_class_install_property (
391 "H264 encoding bitrate(kbps)",
392 "H264 encoding bitrate(kbps), (0, auto-calculate)",
398 g_object_class_install_property (
400 H264_PROP_INTRA_PERIOD,
403 "H264 encoding intra-period",
404 "H264 encoding intra-period",
407 H264_DEFAULT_INTRA_PERIOD,
410 g_object_class_install_property (
419 H264_DEFAULT_INIT_QP,
422 g_object_class_install_property (
434 g_object_class_install_property (
446 g_object_class_install_property (
448 H264_PROP_B_FRAME_NUM,