Tizen 2.0 Release
[framework/multimedia/gst-plugins-bad0.10.git] / sys / applemedia / vth264encbin.c
1 /*
2  * Copyright (C) 2010 Ole André Vadla Ravnås <oravnas@cisco.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23
24 #include "vth264encbin.h"
25
26 #include <string.h>
27 #include <gst/video/video.h>
28
29 #define VT_H264_ENC_BIN_DEFAULT_BITRATE 768
30
31 GST_DEBUG_CATEGORY_STATIC (gst_vt_h264_enc_bin_debug);
32 #define GST_CAT_DEFAULT gst_vt_h264_enc_bin_debug
33
34 enum
35 {
36   PROP_0,
37   PROP_BITRATE
38 };
39
40 enum
41 {
42   H264PARSE_OUTPUT_FORMAT_AVC_SAMPLE = 0,
43   H264PARSE_OUTPUT_FORMAT_BYTE_STREAM = 1,
44   H264PARSE_OUTPUT_FORMAT_INPUT = 2
45 };
46
47 static GstStaticPadTemplate vth264encbin_sink_template =
48 GST_STATIC_PAD_TEMPLATE ("sink",
49     GST_PAD_SINK,
50     GST_PAD_ALWAYS,
51     GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("NV12"))
52     );
53
54 static GstStaticPadTemplate vth264encbin_src_template =
55 GST_STATIC_PAD_TEMPLATE ("src",
56     GST_PAD_SRC,
57     GST_PAD_ALWAYS,
58     GST_STATIC_CAPS ("video/x-h264, stream-format = (string) byte-stream"));
59
60 #define TAA_VT_H264_ENC_BIN_GET_PRIVATE(obj)  \
61    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_VT_H264_ENC_BIN, \
62                                  GstVTH264EncBinPrivate))
63
64 struct _GstVTH264EncBinPrivate
65 {
66   GstElement *encoder;
67   GstElement *parser;
68 };
69
70 GST_BOILERPLATE (GstVTH264EncBin, gst_vt_h264_enc_bin, GstBin, GST_TYPE_BIN);
71
72 static void
73 gst_vt_h264_enc_bin_base_init (gpointer gclass)
74 {
75   GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
76
77   gst_element_class_set_details_simple (element_class,
78       "VTH264EncBin",
79       "Encoder/Video",
80       "VideoToolbox H.264 encoder bin",
81       "Ole André Vadla Ravnås <oravnas@cisco.com>");
82
83   gst_element_class_add_static_pad_template (element_class,
84       &vth264encbin_sink_template);
85   gst_element_class_add_static_pad_template (element_class,
86       &vth264encbin_src_template);
87 }
88
89 static void
90 gst_vt_h264_enc_bin_init (GstVTH264EncBin * self, GstVTH264EncBinClass * gclass)
91 {
92   GstVTH264EncBinPrivate *priv;
93   GstPad *encoder_sinkpad, *parser_srcpad, *ghost_pad;
94
95   self->priv = priv = TAA_VT_H264_ENC_BIN_GET_PRIVATE (self);
96
97   priv->encoder = gst_element_factory_make ("vtenc_h264", "encoder");
98   priv->parser = gst_element_factory_make ("h264parse", "parser");
99   gst_bin_add_many (GST_BIN_CAST (self), priv->encoder, priv->parser, NULL);
100   gst_element_link (priv->encoder, priv->parser);
101
102   encoder_sinkpad = gst_element_get_static_pad (priv->encoder, "sink");
103   ghost_pad = gst_ghost_pad_new_from_template ("sink", encoder_sinkpad,
104       gst_static_pad_template_get (&vth264encbin_sink_template));
105   gst_object_unref (encoder_sinkpad);
106   gst_element_add_pad (GST_ELEMENT_CAST (self), ghost_pad);
107
108   parser_srcpad = gst_element_get_static_pad (priv->parser, "src");
109   ghost_pad = gst_ghost_pad_new_from_template ("src", parser_srcpad,
110       gst_static_pad_template_get (&vth264encbin_src_template));
111   gst_object_unref (parser_srcpad);
112   gst_element_add_pad (GST_ELEMENT_CAST (self), ghost_pad);
113
114   g_object_set (priv->encoder, "usage", 6, NULL);
115
116   g_object_set (priv->parser,
117       "output-format", H264PARSE_OUTPUT_FORMAT_BYTE_STREAM,
118       "split-packetized", TRUE, NULL);
119 }
120
121 static void
122 gst_vt_h264_enc_bin_get_property (GObject * obj, guint prop_id,
123     GValue * value, GParamSpec * pspec)
124 {
125   GstVTH264EncBin *self = GST_VT_H264_ENC_BIN_CAST (obj);
126
127   switch (prop_id) {
128     case PROP_BITRATE:
129       g_object_get_property (G_OBJECT (self->priv->encoder),
130           g_param_spec_get_name (pspec), value);
131       break;
132     default:
133       G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
134       break;
135   }
136 }
137
138 static void
139 gst_vt_h264_enc_bin_set_property (GObject * obj, guint prop_id,
140     const GValue * value, GParamSpec * pspec)
141 {
142   GstVTH264EncBin *self = GST_VT_H264_ENC_BIN_CAST (obj);
143
144   switch (prop_id) {
145     case PROP_BITRATE:
146       g_object_set_property (G_OBJECT (self->priv->encoder),
147           g_param_spec_get_name (pspec), value);
148       break;
149     default:
150       G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
151       break;
152   }
153 }
154
155 static void
156 gst_vt_h264_enc_bin_class_init (GstVTH264EncBinClass * klass)
157 {
158   GObjectClass *gobject_class = (GObjectClass *) klass;
159
160   gobject_class->get_property = gst_vt_h264_enc_bin_get_property;
161   gobject_class->set_property = gst_vt_h264_enc_bin_set_property;
162
163   g_type_class_add_private (klass, sizeof (GstVTH264EncBinPrivate));
164
165   g_object_class_install_property (gobject_class, PROP_BITRATE,
166       g_param_spec_uint ("bitrate", "Bitrate",
167           "Target video bitrate in kbps",
168           1, G_MAXUINT, VT_H264_ENC_BIN_DEFAULT_BITRATE,
169           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
170
171   GST_DEBUG_CATEGORY_INIT (gst_vt_h264_enc_bin_debug,
172       "vth264encbin", 0, "VideoToolbox H.264 encoder bin");
173 }