1 /* GStreamer
2 * Copyright (c) 2011, Texas Instruments Incorporated
3 * Copyright (c) 2011, Collabora Ltd.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 *
20 * Author: Alessandro Decina <alessandro.decina@collabora.com>
21 */
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
27 #include "gstducati.h"
28 #include "gstducatimpeg4enc.h"
30 #include <string.h>
32 #include <math.h>
34 #define GST_CAT_DEFAULT gst_ducati_debug
36 #define DEFAULT_PROFILE MPEG4_SIMPLE_PROFILE_IDC
37 #define DEFAULT_LEVEL IMPEG4ENC_SP_LEVEL_5
39 #define GST_TYPE_DUCATI_MPEG4ENC_PROFILE (gst_ducati_mpeg4enc_profile_get_type ())
40 #define GST_TYPE_DUCATI_MPEG4ENC_LEVEL (gst_ducati_mpeg4enc_level_get_type ())
43 enum
44 {
45 LAST_SIGNAL
46 };
48 enum
49 {
50 PROP_0,
51 PROP_PROFILE,
52 PROP_LEVEL,
53 };
55 static void gst_ducati_mpeg4enc_set_property (GObject * object, guint prop_id,
56 const GValue * value, GParamSpec * pspec);
57 static void gst_ducati_mpeg4enc_get_property (GObject * object, guint prop_id,
58 GValue * value, GParamSpec * pspec);
60 static gboolean gst_ducati_mpeg4enc_allocate_params (GstDucatiVidEnc *
61 self, gint params_sz, gint dynparams_sz, gint status_sz, gint inargs_sz,
62 gint outargs_sz);
63 static gboolean gst_ducati_mpeg4enc_configure (GstDucatiVidEnc * self);
66 static GstStaticPadTemplate gst_ducati_mpeg4enc_sink_template =
67 GST_STATIC_PAD_TEMPLATE ("sink",
68 GST_PAD_SINK,
69 GST_PAD_ALWAYS,
70 GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("NV12"))
71 );
73 static GstStaticPadTemplate gst_ducati_mpeg4enc_src_template =
74 GST_STATIC_PAD_TEMPLATE ("src",
75 GST_PAD_SRC,
76 GST_PAD_ALWAYS,
77 GST_STATIC_CAPS ("video/mpeg, mpegversion=4, systemstream=false")
78 );
80 #define parent_class gst_ducati_mpeg4enc_parent_class
81 G_DEFINE_TYPE (GstDucatiMPEG4Enc, gst_ducati_mpeg4enc, GST_TYPE_DUCATIVIDENC);
84 static GType
85 gst_ducati_mpeg4enc_profile_get_type (void)
86 {
87 static GType type = 0;
89 if (!type) {
90 static const GEnumValue vals[] = {
91 {IMPEG4ENC_SP_LEVEL_3, "Simple", "simple"},
92 {0, NULL, NULL},
93 };
95 type = g_enum_register_static ("GstDucatiMPEG4EncProfile", vals);
96 }
98 return type;
99 }
101 static GType
102 gst_ducati_mpeg4enc_level_get_type (void)
103 {
104 static GType type = 0;
106 if (!type) {
107 static const GEnumValue vals[] = {
108 {IMPEG4ENC_SP_LEVEL_0, "Level 0", "level-0"},
109 {IMPEG4ENC_SP_LEVEL_0B, "Level 0B", "level-0b"},
110 {IMPEG4ENC_SP_LEVEL_1, "Level 1", "level-1"},
111 {IMPEG4ENC_SP_LEVEL_2, "Level 2", "level-2"},
112 {IMPEG4ENC_SP_LEVEL_3, "Level 3", "level-3"},
113 {IMPEG4ENC_SP_LEVEL_4A, "Level 4", "level-4"},
114 {IMPEG4ENC_SP_LEVEL_5, "Level 5", "level-5"},
115 {IMPEG4ENC_SP_LEVEL_6, "Level 6", "level-6"},
116 {0, NULL, NULL},
117 };
119 type = g_enum_register_static ("GstDucatiMPEG4EncLevel", vals);
120 }
122 return type;
123 }
126 static void
127 gst_ducati_mpeg4enc_class_init (GstDucatiMPEG4EncClass * klass)
128 {
129 GObjectClass *gobject_class;
130 GstDucatiVidEncClass *videnc_class;
131 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
133 gobject_class = G_OBJECT_CLASS (klass);
134 videnc_class = GST_DUCATIVIDENC_CLASS (klass);
136 gst_element_class_add_pad_template (element_class,
137 gst_static_pad_template_get (&gst_ducati_mpeg4enc_src_template));
138 gst_element_class_add_pad_template (element_class,
139 gst_static_pad_template_get (&gst_ducati_mpeg4enc_sink_template));
141 gst_element_class_set_metadata (element_class, "MPEG4 Encoder",
142 "Codec/Encoder/Video",
143 "Encode raw video into MPEG4 stream",
144 "Alessandro Decina <alessandro.decina@collabora.com>");
146 GST_DUCATIVIDENC_CLASS (element_class)->codec_name = "ivahd_mpeg4enc";
148 gobject_class->set_property = gst_ducati_mpeg4enc_set_property;
149 gobject_class->get_property = gst_ducati_mpeg4enc_get_property;
151 videnc_class->allocate_params = gst_ducati_mpeg4enc_allocate_params;
152 videnc_class->configure = gst_ducati_mpeg4enc_configure;
154 g_object_class_install_property (gobject_class, PROP_PROFILE,
155 g_param_spec_enum ("profile", "MPEG4 Profile", "MPEG4 Profile",
156 GST_TYPE_DUCATI_MPEG4ENC_PROFILE, DEFAULT_PROFILE,
157 G_PARAM_READWRITE));
159 g_object_class_install_property (gobject_class, PROP_LEVEL,
160 g_param_spec_enum ("level", "MPEG4 Level", "MPEG4 Level",
161 GST_TYPE_DUCATI_MPEG4ENC_LEVEL, DEFAULT_LEVEL, G_PARAM_READWRITE));
162 }
164 static void
165 gst_ducati_mpeg4enc_init (GstDucatiMPEG4Enc * self)
166 {
167 GST_DEBUG ("gst_ducati_mpeg4enc_init");
169 self->profile = DEFAULT_PROFILE;
170 self->level = DEFAULT_LEVEL;
171 }
173 static void
174 gst_ducati_mpeg4enc_set_property (GObject * object, guint prop_id,
175 const GValue * value, GParamSpec * pspec)
176 {
177 GstDucatiMPEG4Enc *self;
179 g_return_if_fail (GST_IS_DUCATIMPEG4ENC (object));
180 self = GST_DUCATIMPEG4ENC (object);
182 switch (prop_id) {
183 case PROP_PROFILE:
184 self->profile = g_value_get_enum (value);
185 break;
186 case PROP_LEVEL:
187 self->level = g_value_get_enum (value);
188 break;
189 default:
190 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
191 }
192 }
194 static void
195 gst_ducati_mpeg4enc_get_property (GObject * object, guint prop_id,
196 GValue * value, GParamSpec * pspec)
197 {
198 GstDucatiMPEG4Enc *self;
200 g_return_if_fail (GST_IS_DUCATIMPEG4ENC (object));
201 self = GST_DUCATIMPEG4ENC (object);
203 switch (prop_id) {
204 case PROP_PROFILE:
205 g_value_set_enum (value, self->profile);
206 break;
207 case PROP_LEVEL:
208 g_value_set_enum (value, self->level);
209 break;
210 default:
211 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
212 }
213 }
215 static const char *
216 get_profile_name (guint profile)
217 {
218 switch (profile) {
219 case IMPEG4ENC_SP_LEVEL_3:
220 return "simple";
221 default:
222 return NULL;
223 }
224 }
226 static gboolean
227 gst_ducati_mpeg4enc_configure (GstDucatiVidEnc * videnc)
228 {
229 GstDucatiMPEG4Enc *self = GST_DUCATIMPEG4ENC (videnc);
230 const GstVideoCodecState *state;
231 GstCaps *caps;
232 const char *s;
233 gboolean ret = TRUE;
235 if (!GST_DUCATIVIDENC_CLASS (parent_class)->configure (videnc))
236 return FALSE;
238 videnc->params->profile = self->profile;
239 videnc->params->level = self->level;
240 videnc->params->maxInterFrameInterval = 0;
241 videnc->dynParams->mvAccuracy = IVIDENC2_MOTIONVECTOR_HALFPEL;
242 videnc->dynParams->interFrameInterval = 0;
244 state = videnc->input_state;
245 caps = gst_caps_new_simple ("video/mpeg",
246 "mpegversion", G_TYPE_INT, 4,
247 "systemstream", G_TYPE_BOOLEAN, FALSE,
248 "width", G_TYPE_INT, videnc->rect.w,
249 "height", G_TYPE_INT, videnc->rect.h,
250 "framerate", GST_TYPE_FRACTION, GST_VIDEO_INFO_FPS_N (&state->info), GST_VIDEO_INFO_FPS_D (&state->info),
251 "pixel-aspect-ratio", GST_TYPE_FRACTION, GST_VIDEO_INFO_PAR_N (&state->info), GST_VIDEO_INFO_PAR_D (&state->info),
252 NULL);
253 s = get_profile_name (self->profile);
254 if (s)
255 gst_caps_set_simple (caps, "profile", G_TYPE_STRING, s, NULL);
256 ret = gst_pad_set_caps (GST_VIDEO_ENCODER_SRC_PAD (self), caps);
258 return ret;
259 }
261 static gboolean
262 gst_ducati_mpeg4enc_allocate_params (GstDucatiVidEnc *
263 videnc, gint params_sz, gint dynparams_sz, gint status_sz, gint inargs_sz,
264 gint outargs_sz)
265 {
266 return GST_DUCATIVIDENC_CLASS (parent_class)->allocate_params (videnc,
267 sizeof (IVIDENC2_Params), sizeof (IVIDENC2_DynamicParams),
268 sizeof (IVIDENC2_Status), sizeof (IVIDENC2_InArgs),
269 sizeof (IVIDENC2_OutArgs));
270 }