2 * Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
3 * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation
8 * version 2.1 of the License.
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 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 #include "gstomxmpeg4videoenc.h"
29 GST_DEBUG_CATEGORY_STATIC (gst_omx_mpeg4_video_enc_debug_category);
30 #define GST_CAT_DEFAULT gst_omx_mpeg4_video_enc_debug_category
33 static gboolean gst_omx_mpeg4_video_enc_set_format (GstOMXVideoEnc * enc,
34 GstOMXPort * port, GstVideoCodecState * state);
35 static GstCaps *gst_omx_mpeg4_video_enc_get_caps (GstOMXVideoEnc * enc,
36 GstOMXPort * port, GstVideoCodecState * state);
43 /* class initialization */
46 GST_DEBUG_CATEGORY_INIT (gst_omx_mpeg4_video_enc_debug_category, "omxmpeg4videoenc", 0, \
47 "debug category for gst-omx video encoder base class");
49 G_DEFINE_TYPE_WITH_CODE (GstOMXMPEG4VideoEnc, gst_omx_mpeg4_video_enc,
50 GST_TYPE_OMX_VIDEO_ENC, DEBUG_INIT);
53 gst_omx_mpeg4_video_enc_class_init (GstOMXMPEG4VideoEncClass * klass)
55 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
56 GstOMXVideoEncClass *videoenc_class = GST_OMX_VIDEO_ENC_CLASS (klass);
58 videoenc_class->set_format =
59 GST_DEBUG_FUNCPTR (gst_omx_mpeg4_video_enc_set_format);
60 videoenc_class->get_caps =
61 GST_DEBUG_FUNCPTR (gst_omx_mpeg4_video_enc_get_caps);
63 videoenc_class->cdata.default_src_template_caps = "video/mpeg, "
64 "mpegversion=(int) 4, "
65 "systemstream=(boolean) false, "
66 "width=(int) [ 16, 4096 ], " "height=(int) [ 16, 4096 ]";
68 gst_element_class_set_static_metadata (element_class,
69 "OpenMAX MPEG4 Video Encoder",
70 "Codec/Encoder/Video/Hardware",
71 "Encode MPEG4 video streams",
72 "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
74 gst_omx_set_default_role (&videoenc_class->cdata, "video_encoder.mpeg4");
78 gst_omx_mpeg4_video_enc_init (GstOMXMPEG4VideoEnc * self)
83 gst_omx_mpeg4_video_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port,
84 GstVideoCodecState * state)
86 GstOMXMPEG4VideoEnc *self = GST_OMX_MPEG4_VIDEO_ENC (enc);
87 GstCaps *peercaps, *intersection;
88 OMX_PARAM_PORTDEFINITIONTYPE port_def;
89 OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
91 const gchar *profile_string, *level_string;
93 gst_omx_port_get_port_definition (GST_OMX_VIDEO_ENC (self)->enc_out_port,
95 port_def.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
97 gst_omx_port_update_port_definition (GST_OMX_VIDEO_ENC
98 (self)->enc_out_port, &port_def);
99 if (err != OMX_ErrorNone)
102 GST_OMX_INIT_STRUCT (¶m);
103 param.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
106 gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
107 OMX_IndexParamVideoProfileLevelCurrent, ¶m);
108 if (err != OMX_ErrorNone) {
109 GST_WARNING_OBJECT (self,
110 "Getting profile/level not supported by component");
114 peercaps = gst_pad_peer_query_caps (GST_VIDEO_ENCODER_SRC_PAD (enc), NULL);
119 gst_caps_intersect (peercaps,
120 gst_pad_get_pad_template_caps (GST_VIDEO_ENCODER_SRC_PAD (enc)));
122 gst_caps_unref (peercaps);
123 if (gst_caps_is_empty (intersection)) {
124 gst_caps_unref (intersection);
125 GST_ERROR_OBJECT (self, "Empty caps");
129 s = gst_caps_get_structure (intersection, 0);
130 profile_string = gst_structure_get_string (s, "profile");
131 if (profile_string) {
132 if (g_str_equal (profile_string, "simple")) {
133 param.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
134 } else if (g_str_equal (profile_string, "simple-scalable")) {
135 param.eProfile = OMX_VIDEO_MPEG4ProfileSimpleScalable;
136 } else if (g_str_equal (profile_string, "core")) {
137 param.eProfile = OMX_VIDEO_MPEG4ProfileCore;
138 } else if (g_str_equal (profile_string, "main")) {
139 param.eProfile = OMX_VIDEO_MPEG4ProfileMain;
140 } else if (g_str_equal (profile_string, "n-bit")) {
141 param.eProfile = OMX_VIDEO_MPEG4ProfileNbit;
142 } else if (g_str_equal (profile_string, "scalable")) {
143 param.eProfile = OMX_VIDEO_MPEG4ProfileScalableTexture;
144 } else if (g_str_equal (profile_string, "simple-face")) {
145 param.eProfile = OMX_VIDEO_MPEG4ProfileSimpleFace;
146 } else if (g_str_equal (profile_string, "simple-fba")) {
147 param.eProfile = OMX_VIDEO_MPEG4ProfileSimpleFBA;
148 } else if (g_str_equal (profile_string, "basic-animated-texture")) {
149 param.eProfile = OMX_VIDEO_MPEG4ProfileBasicAnimated;
150 } else if (g_str_equal (profile_string, "hybrid")) {
151 param.eProfile = OMX_VIDEO_MPEG4ProfileHybrid;
152 } else if (g_str_equal (profile_string, "advanced-real-time-simple")) {
153 param.eProfile = OMX_VIDEO_MPEG4ProfileAdvancedRealTime;
154 } else if (g_str_equal (profile_string, "core-scalable")) {
155 param.eProfile = OMX_VIDEO_MPEG4ProfileCoreScalable;
156 } else if (g_str_equal (profile_string, "advanced-coding-efficiency")) {
157 param.eProfile = OMX_VIDEO_MPEG4ProfileAdvancedCoding;
158 } else if (g_str_equal (profile_string, "advanced-core")) {
159 param.eProfile = OMX_VIDEO_MPEG4ProfileAdvancedCore;
160 } else if (g_str_equal (profile_string, "advanced-scalable-texture")) {
161 param.eProfile = OMX_VIDEO_MPEG4ProfileAdvancedScalable;
162 } else if (g_str_equal (profile_string, "advanced-simple")) {
163 param.eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
165 goto unsupported_profile;
168 level_string = gst_structure_get_string (s, "level");
170 if (g_str_equal (level_string, "0")) {
171 param.eLevel = OMX_VIDEO_MPEG4Level0;
172 } else if (g_str_equal (level_string, "0b")) {
173 param.eLevel = OMX_VIDEO_MPEG4Level0b;
174 } else if (g_str_equal (level_string, "1")) {
175 param.eLevel = OMX_VIDEO_MPEG4Level1;
176 } else if (g_str_equal (level_string, "2")) {
177 param.eLevel = OMX_VIDEO_MPEG4Level2;
178 } else if (g_str_equal (level_string, "3")) {
179 param.eLevel = OMX_VIDEO_MPEG4Level3;
180 } else if (g_str_equal (level_string, "4")) {
181 param.eLevel = OMX_VIDEO_MPEG4Level4;
182 } else if (g_str_equal (level_string, "4a")) {
183 param.eLevel = OMX_VIDEO_MPEG4Level4a;
184 } else if (g_str_equal (level_string, "5")) {
185 param.eLevel = OMX_VIDEO_MPEG4Level5;
187 goto unsupported_level;
191 gst_caps_unref (intersection);
195 gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc,
196 OMX_IndexParamVideoProfileLevelCurrent, ¶m);
197 if (err == OMX_ErrorUnsupportedIndex) {
198 GST_WARNING_OBJECT (self,
199 "Setting profile/level not supported by component");
200 } else if (err != OMX_ErrorNone) {
201 GST_ERROR_OBJECT (self,
202 "Error setting profile %u and level %u: %s (0x%08x)",
203 (guint) param.eProfile, (guint) param.eLevel,
204 gst_omx_error_to_string (err), err);
211 GST_ERROR_OBJECT (self, "Unsupported profile %s", profile_string);
212 gst_caps_unref (intersection);
216 GST_ERROR_OBJECT (self, "Unsupported level %s", level_string);
217 gst_caps_unref (intersection);
222 gst_omx_mpeg4_video_enc_get_caps (GstOMXVideoEnc * enc, GstOMXPort * port,
223 GstVideoCodecState * state)
225 GstOMXMPEG4VideoEnc *self = GST_OMX_MPEG4_VIDEO_ENC (enc);
228 OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
229 const gchar *profile, *level;
232 gst_caps_new_simple ("video/mpeg", "mpegversion", G_TYPE_INT, 4,
233 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
235 GST_OMX_INIT_STRUCT (¶m);
236 param.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
239 gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
240 OMX_IndexParamVideoProfileLevelCurrent, ¶m);
241 if (err != OMX_ErrorNone && err != OMX_ErrorUnsupportedIndex) {
242 gst_caps_unref (caps);
246 if (err == OMX_ErrorNone) {
247 switch (param.eProfile) {
248 case OMX_VIDEO_MPEG4ProfileSimple:
251 case OMX_VIDEO_MPEG4ProfileSimpleScalable:
252 profile = "simple-scalable";
254 case OMX_VIDEO_MPEG4ProfileCore:
257 case OMX_VIDEO_MPEG4ProfileMain:
260 case OMX_VIDEO_MPEG4ProfileNbit:
263 case OMX_VIDEO_MPEG4ProfileScalableTexture:
264 profile = "scalable";
266 case OMX_VIDEO_MPEG4ProfileSimpleFace:
267 profile = "simple-face";
269 case OMX_VIDEO_MPEG4ProfileSimpleFBA:
270 profile = "simple-fba";
272 case OMX_VIDEO_MPEG4ProfileBasicAnimated:
273 profile = "basic-animated-texture";
275 case OMX_VIDEO_MPEG4ProfileHybrid:
278 case OMX_VIDEO_MPEG4ProfileAdvancedRealTime:
279 profile = "advanced-real-time-simple";
281 case OMX_VIDEO_MPEG4ProfileCoreScalable:
282 profile = "core-scalable";
284 case OMX_VIDEO_MPEG4ProfileAdvancedCoding:
285 profile = "advanced-coding-efficiency";
287 case OMX_VIDEO_MPEG4ProfileAdvancedCore:
288 profile = "advanced-core";
290 case OMX_VIDEO_MPEG4ProfileAdvancedScalable:
291 profile = "advanced-scalable-texture";
293 case OMX_VIDEO_MPEG4ProfileAdvancedSimple:
294 profile = "advanced-simple";
297 g_assert_not_reached ();
301 switch (param.eLevel) {
302 case OMX_VIDEO_MPEG4Level0:
305 case OMX_VIDEO_MPEG4Level0b:
308 case OMX_VIDEO_MPEG4Level1:
311 case OMX_VIDEO_MPEG4Level2:
314 case OMX_VIDEO_MPEG4Level3:
317 case OMX_VIDEO_MPEG4Level4:
320 case OMX_VIDEO_MPEG4Level4a:
323 case OMX_VIDEO_MPEG4Level5:
327 g_assert_not_reached ();
331 gst_caps_set_simple (caps,
332 "profile", G_TYPE_STRING, profile, "level", G_TYPE_STRING, level, NULL);