mpeg2dec: Fix negotiation issue with playbin
[glsdk/gst-plugin-ducati.git] / src / gstducatimpeg4enc.c
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)
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;
126 static void
127 gst_ducati_mpeg4enc_class_init (GstDucatiMPEG4EncClass * klass)
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));
164 static void
165 gst_ducati_mpeg4enc_init (GstDucatiMPEG4Enc * self)
167   GST_DEBUG ("gst_ducati_mpeg4enc_init");
169   self->profile = DEFAULT_PROFILE;
170   self->level = DEFAULT_LEVEL;
173 static void
174 gst_ducati_mpeg4enc_set_property (GObject * object, guint prop_id,
175     const GValue * value, GParamSpec * pspec)
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   }
194 static void
195 gst_ducati_mpeg4enc_get_property (GObject * object, guint prop_id,
196     GValue * value, GParamSpec * pspec)
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   }
215 static const char *
216 get_profile_name (guint profile)
218   switch (profile) {
219     case IMPEG4ENC_SP_LEVEL_3:
220       return "simple";
221     default:
222       return NULL;
223   }
226 static gboolean
227 gst_ducati_mpeg4enc_configure (GstDucatiVidEnc * videnc)
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;
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)
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));