From b085e11c3716a3f58fcddaf8b553b57959dff139 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 29 Jul 2011 12:06:21 +0200 Subject: [PATCH] omxh263enc: Add H.263 encoder element --- omx/Makefile.am | 2 + omx/gstomx.c | 4 +- omx/gstomxh263enc.c | 302 ++++++++++++++++++++++++++++++++++++++++++++++++++++ omx/gstomxh263enc.h | 60 +++++++++++ 4 files changed, 367 insertions(+), 1 deletion(-) create mode 100644 omx/gstomxh263enc.c create mode 100644 omx/gstomxh263enc.h diff --git a/omx/Makefile.am b/omx/Makefile.am index ede5277..b2677e2 100644 --- a/omx/Makefile.am +++ b/omx/Makefile.am @@ -10,6 +10,7 @@ libgstopenmax_la_SOURCES = \ gstomxwmvdec.c \ gstomxmpeg4videoenc.c \ gstomxh264enc.c \ + gstomxh263enc.c \ gstbasevideocodec.c \ gstbasevideodecoder.c \ gstbasevideoencoder.c \ @@ -25,6 +26,7 @@ noinst_HEADERS = \ gstomxwmvdec.h \ gstomxmpeg4videoenc.h \ gstomxh264enc.h \ + gstomxh263enc.h \ gstbasevideocodec.h \ gstbasevideodecoder.h \ gstbasevideoencoder.h \ diff --git a/omx/gstomx.c b/omx/gstomx.c index f286a88..33bf7e3 100644 --- a/omx/gstomx.c +++ b/omx/gstomx.c @@ -32,6 +32,7 @@ #include "gstomxwmvdec.h" #include "gstomxmpeg4videoenc.h" #include "gstomxh264enc.h" +#include "gstomxh263enc.h" GST_DEBUG_CATEGORY (gstomx_debug); #define GST_CAT_DEFAULT gstomx_debug @@ -1701,7 +1702,8 @@ GQuark gst_omx_element_name_quark = 0; static GType (*types[]) (void) = { gst_omx_mpeg4_video_dec_get_type, gst_omx_h264_dec_get_type, gst_omx_h263_dec_get_type, gst_omx_wmv_dec_get_type, - gst_omx_mpeg4_video_enc_get_type, gst_omx_h264_enc_get_type}; + gst_omx_mpeg4_video_enc_get_type, gst_omx_h264_enc_get_type, + gst_omx_h263_enc_get_type}; static GKeyFile *config = NULL; GKeyFile * diff --git a/omx/gstomxh263enc.c b/omx/gstomxh263enc.c new file mode 100644 index 0000000..4e6911b --- /dev/null +++ b/omx/gstomxh263enc.c @@ -0,0 +1,302 @@ +/* + * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. + * Author: Sebastian Dröge , Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "gstomxh263enc.h" + +GST_DEBUG_CATEGORY_STATIC (gst_omx_h263_enc_debug_category); +#define GST_CAT_DEFAULT gst_omx_h263_enc_debug_category + +/* prototypes */ +static void gst_omx_h263_enc_finalize (GObject * object); +static gboolean gst_omx_h263_enc_set_format (GstOMXVideoEnc * enc, + GstOMXPort * port, GstVideoState * state); +static GstCaps *gst_omx_h263_enc_get_caps (GstOMXVideoEnc * enc, + GstOMXPort * port, GstVideoState * state); + +enum +{ + PROP_0 +}; + +/* class initialization */ + +#define DEBUG_INIT(bla) \ + GST_DEBUG_CATEGORY_INIT (gst_omx_h263_enc_debug_category, "omxh263enc", 0, \ + "debug category for gst-omx video encoder base class"); + +GST_BOILERPLATE_FULL (GstOMXH263Enc, gst_omx_h263_enc, + GstOMXVideoEnc, GST_TYPE_OMX_VIDEO_ENC, DEBUG_INIT); + +static void +gst_omx_h263_enc_base_init (gpointer g_class) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + GstOMXVideoEncClass *videoenc_class = GST_OMX_VIDEO_ENC_CLASS (g_class); + + gst_element_class_set_details_simple (element_class, + "OpenMAX H.263 Video Encoder", + "Codec/Encoder/Video", + "Encode H.263 video streams", + "Sebastian Dröge "); + + /* If no role was set from the config file we set the + * default H263 video encoder role */ + if (!videoenc_class->component_role) + videoenc_class->component_role = "video_encoder.h263"; +} + +static void +gst_omx_h263_enc_class_init (GstOMXH263EncClass * klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstOMXVideoEncClass *videoenc_class = GST_OMX_VIDEO_ENC_CLASS (klass); + + gobject_class->finalize = gst_omx_h263_enc_finalize; + + videoenc_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_h263_enc_set_format); + videoenc_class->get_caps = GST_DEBUG_FUNCPTR (gst_omx_h263_enc_get_caps); + + videoenc_class->default_src_template_caps = "video/x-h263, " + "width=(int) [ 16, 4096 ], " "height=(int) [ 16, 4096 ]"; + videoenc_class->default_sink_template_caps = GST_VIDEO_CAPS_YUV ("I420"); +} + +static void +gst_omx_h263_enc_init (GstOMXH263Enc * self, GstOMXH263EncClass * klass) +{ +} + +static void +gst_omx_h263_enc_finalize (GObject * object) +{ + /* GstOMXH263Enc *self = GST_OMX_H263_VIDEO_ENC (object); */ + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static gboolean +gst_omx_h263_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port, + GstVideoState * state) +{ + GstOMXH263Enc *self = GST_OMX_H263_ENC (enc); + GstCaps *peercaps; + OMX_VIDEO_H263PROFILETYPE profile = OMX_VIDEO_H263ProfileBaseline; + OMX_VIDEO_H263LEVELTYPE level = OMX_VIDEO_H263Level10; + + peercaps = gst_pad_peer_get_caps (GST_BASE_VIDEO_CODEC_SRC_PAD (enc)); + if (peercaps) { + GstStructure *s; + GstCaps *intersection; + guint profile_id, level_id; + OMX_VIDEO_PARAM_PROFILELEVELTYPE param; + OMX_ERRORTYPE err; + + intersection = + gst_caps_intersect (peercaps, + gst_pad_get_pad_template_caps (GST_BASE_VIDEO_CODEC_SRC_PAD (enc))); + gst_caps_unref (peercaps); + if (gst_caps_is_empty (intersection)) { + gst_caps_unref (intersection); + GST_ERROR_OBJECT (self, "Empty caps"); + return FALSE; + } + + s = gst_caps_get_structure (intersection, 0); + if (gst_structure_get_uint (s, "profile", &profile_id)) { + switch (profile_id) { + case 0: + profile = OMX_VIDEO_H263ProfileBaseline; + break; + case 1: + profile = OMX_VIDEO_H263ProfileH320Coding; + break; + case 2: + profile = OMX_VIDEO_H263ProfileBackwardCompatible; + break; + case 3: + profile = OMX_VIDEO_H263ProfileISWV2; + break; + case 4: + profile = OMX_VIDEO_H263ProfileISWV3; + break; + case 5: + profile = OMX_VIDEO_H263ProfileHighCompression; + break; + case 6: + profile = OMX_VIDEO_H263ProfileInternet; + break; + case 7: + profile = OMX_VIDEO_H263ProfileInterlace; + break; + case 8: + profile = OMX_VIDEO_H263ProfileHighLatency; + break; + default: + GST_ERROR_OBJECT (self, "Invalid profile %u", profile_id); + return FALSE; + } + } + if (gst_structure_get_uint (s, "level", &level_id)) { + switch (level_id) { + case 10: + level = OMX_VIDEO_H263Level10; + break; + case 20: + level = OMX_VIDEO_H263Level20; + break; + case 30: + level = OMX_VIDEO_H263Level30; + break; + case 40: + level = OMX_VIDEO_H263Level40; + break; + case 50: + level = OMX_VIDEO_H263Level50; + break; + case 60: + level = OMX_VIDEO_H263Level60; + break; + case 70: + level = OMX_VIDEO_H263Level70; + break; + default: + GST_ERROR_OBJECT (self, "Unsupported level %u", level_id); + return FALSE; + } + } + + GST_OMX_INIT_STRUCT (¶m); + param.nPortIndex = GST_OMX_VIDEO_ENC (self)->out_port->index; + param.eProfile = profile; + param.eLevel = level; + + err = + gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->component, + OMX_IndexParamVideoProfileLevelCurrent, ¶m); + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, + "Error setting profile %d and level %d: %s (0x%08x)", profile, level, + gst_omx_error_to_string (err), err); + return FALSE; + } + } + + return TRUE; +} + +static GstCaps * +gst_omx_h263_enc_get_caps (GstOMXVideoEnc * enc, GstOMXPort * port, + GstVideoState * state) +{ + GstOMXH263Enc *self = GST_OMX_H263_ENC (enc); + GstCaps *caps; + OMX_ERRORTYPE err; + OMX_VIDEO_PARAM_PROFILELEVELTYPE param; + guint profile, level; + + GST_OMX_INIT_STRUCT (¶m); + param.nPortIndex = GST_OMX_VIDEO_ENC (self)->out_port->index; + + err = + gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->component, + OMX_IndexParamVideoProfileLevelCurrent, ¶m); + if (err != OMX_ErrorNone) + return NULL; + + switch (param.eProfile) { + case OMX_VIDEO_H263ProfileBaseline: + profile = 0; + break; + case OMX_VIDEO_H263ProfileH320Coding: + profile = 1; + break; + case OMX_VIDEO_H263ProfileBackwardCompatible: + profile = 2; + break; + case OMX_VIDEO_H263ProfileISWV2: + profile = 3; + break; + case OMX_VIDEO_H263ProfileISWV3: + profile = 4; + break; + case OMX_VIDEO_H263ProfileHighCompression: + profile = 5; + break; + case OMX_VIDEO_H263ProfileInternet: + profile = 6; + break; + case OMX_VIDEO_H263ProfileInterlace: + profile = 7; + break; + case OMX_VIDEO_H263ProfileHighLatency: + profile = 8; + break; + default: + g_assert_not_reached (); + break; + } + + switch (param.eLevel) { + case OMX_VIDEO_H263Level10: + level = 10; + break; + case OMX_VIDEO_H263Level20: + level = 20; + break; + case OMX_VIDEO_H263Level30: + level = 30; + break; + case OMX_VIDEO_H263Level40: + level = 40; + break; + case OMX_VIDEO_H263Level50: + level = 50; + break; + case OMX_VIDEO_H263Level60: + level = 60; + break; + case OMX_VIDEO_H263Level70: + level = 70; + break; + default: + g_assert_not_reached (); + break; + } + + caps = + gst_caps_new_simple ("video/x-h263", "width", G_TYPE_INT, state->width, + "height", G_TYPE_INT, state->height, + "profile", G_TYPE_UINT, profile, "level", G_TYPE_UINT, level, NULL); + + if (state->fps_n != 0) + gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION, state->fps_n, + state->fps_d, NULL); + if (state->par_n != 1 || state->par_d != 1) + gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION, + state->par_n, state->par_d, NULL); + + return caps; +} diff --git a/omx/gstomxh263enc.h b/omx/gstomxh263enc.h new file mode 100644 index 0000000..0dbd0de --- /dev/null +++ b/omx/gstomxh263enc.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. + * Author: Sebastian Dröge , Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __GST_OMX_H263_ENC_H__ +#define __GST_OMX_H263_ENC_H__ + +#include +#include "gstomxvideoenc.h" + +G_BEGIN_DECLS + +#define GST_TYPE_OMX_H263_ENC \ + (gst_omx_h263_enc_get_type()) +#define GST_OMX_H263_ENC(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_H263_ENC,GstOMXH263Enc)) +#define GST_OMX_H263_ENC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_H263_ENC,GstOMXH263EncClass)) +#define GST_OMX_H263_ENC_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_H263_ENC,GstOMXH263EncClass)) +#define GST_IS_OMX_H263_ENC(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_H263_ENC)) +#define GST_IS_OMX_H263_ENC_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_H263_ENC)) + +typedef struct _GstOMXH263Enc GstOMXH263Enc; +typedef struct _GstOMXH263EncClass GstOMXH263EncClass; + +struct _GstOMXH263Enc +{ + GstOMXVideoEnc parent; +}; + +struct _GstOMXH263EncClass +{ + GstOMXVideoEncClass parent_class; +}; + +GType gst_omx_h263_enc_get_type (void); + +G_END_DECLS + +#endif /* __GST_OMX_H263_ENC_H__ */ + -- 2.7.4