diff options
author | nvidia <nvidia@nvidia.com> | 2015-11-04 15:57:23 +0000 |
---|---|---|
committer | Javier Jardón <jjardon@gnome.org> | 2015-11-04 16:07:49 +0000 |
commit | 72cd0878cf111dd1ec4081ece6d188122a293d64 (patch) | |
tree | 41c772015ff05a956e794fb3f419e00348e339bf /omx | |
parent | f3f9330332050f6e18b8fbeabf3791604b862ab0 (diff) | |
download | gst-omx-72cd0878cf111dd1ec4081ece6d188122a293d64.tar.gz |
Add NVIDIA omx implementationbaserock/1.0.0.1/tegra
Diffstat (limited to 'omx')
61 files changed, 11024 insertions, 518 deletions
diff --git a/omx/Makefile.am b/omx/Makefile.am index dbe2f54..ed48e55 100644 --- a/omx/Makefile.am +++ b/omx/Makefile.am @@ -11,6 +11,7 @@ THEORA_H_FILES=gstomxtheoradec.h endif libgstomx_la_SOURCES = \ + $(top_builddir)/gstomx_config.c \ gstomx.c \ gstomxvideodec.c \ gstomxvideoenc.c \ @@ -28,6 +29,19 @@ libgstomx_la_SOURCES = \ gstomxh263enc.c \ gstomxaacenc.c +if USE_OMX_TARGET_TEGRA +libgstomx_la_SOURCES += \ + gstomxvideosink.c \ + gstnvhdmioverlaysink.c \ + gstnvoverlaysink.c \ + gstomxaudiodec.c \ + gstomxaacdec.c \ + gstomxamrnbdec.c \ + gstomxamrwbdec.c \ + gstomxmpegaudiodec.c \ + gstomxvp8enc.c +endif + noinst_HEADERS = \ gstomx.h \ gstomxvideodec.h \ @@ -46,6 +60,19 @@ noinst_HEADERS = \ gstomxh263enc.h \ gstomxaacenc.h +if USE_OMX_TARGET_TEGRA +noinst_HEADERS += \ + gstomxvideosink.h \ + gstnvhdmioverlaysink.h \ + gstnvoverlaysink.h \ + gstomxaudiodec.h \ + gstomxaacdec.h \ + gstomxamrnbdec.h \ + gstomxamrwbdec.h \ + gstomxmpegaudiodec.h \ + gstomxvp8enc.h +endif + if !HAVE_EXTERNAL_OMX OMX_INCLUDEPATH = -I$(abs_srcdir)/openmax endif diff --git a/omx/gstnvhdmioverlaysink.c b/omx/gstnvhdmioverlaysink.c new file mode 100644 index 0000000..8b41a84 --- /dev/null +++ b/omx/gstnvhdmioverlaysink.c @@ -0,0 +1,102 @@ +/* GStreamer + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Suite 500, + * Boston, MA 02110-1335, USA. + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gst/gst.h> +#include <gst/video/gstvideosink.h> +#include "gstnvhdmioverlaysink.h" + +GST_DEBUG_CATEGORY_STATIC (gst_nv_hdmi_overlay_sink_debug_category); +#define GST_CAT_DEFAULT gst_nv_hdmi_overlay_sink_debug_category + +/* prototypes */ + +static void gst_nv_hdmi_overlay_sink_set_property (GObject * object, + guint property_id, const GValue * value, GParamSpec * pspec); +static void gst_nv_hdmi_overlay_sink_get_property (GObject * object, + guint property_id, GValue * value, GParamSpec * pspec); + +enum +{ + PROP_0 +}; + +/* class initialization */ + +G_DEFINE_TYPE_WITH_CODE (GstNvHDMIOverlaySink, gst_nv_hdmi_overlay_sink, + GST_TYPE_OMX_VIDEO_SINK, + GST_DEBUG_CATEGORY_INIT (gst_nv_hdmi_overlay_sink_debug_category, + "nvhdmioverlaysink", 0, + "debug category for nvhdmioverlaysink element")); + +static void +gst_nv_hdmi_overlay_sink_class_init (GstNvHDMIOverlaySinkClass * klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstOmxVideoSinkClass *videosink_class = GST_OMX_VIDEO_SINK_CLASS (klass); + + videosink_class->cdata.default_sink_template_caps = "video/x-raw(memory:NVMM), " + "width = (int) [ 1, max ] , " + "height = (int) [ 1, max ] , " "framerate = (fraction) [ 0, max ];" + "video/x-raw, " + "width = (int) [ 1, max ] , " + "height = (int) [ 1, max ] , " "framerate = (fraction) [ 0, max ]"; + + gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass), + "OpenMax HDMI Video Sink", "Sink/Video", "Renders Video to HDMI", + "Jitendra Kumar <jitendrak@nvidia.com>"); + + gobject_class->set_property = gst_nv_hdmi_overlay_sink_set_property; + gobject_class->get_property = gst_nv_hdmi_overlay_sink_get_property; +} + +static void +gst_nv_hdmi_overlay_sink_init (GstNvHDMIOverlaySink * nvhdmioverlaysink) +{ +} + +void +gst_nv_hdmi_overlay_sink_set_property (GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec) +{ + /* GstNvHDMIOverlaySink *nvhdmioverlaysink = GST_NV_HDMI_OVERLAY_SINK (object); */ + + switch (property_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +void +gst_nv_hdmi_overlay_sink_get_property (GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) +{ + /* GstNvHDMIOverlaySink *nvhdmioverlaysink = GST_NV_HDMI_OVERLAY_SINK (object); */ + + switch (property_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} diff --git a/omx/gstnvhdmioverlaysink.h b/omx/gstnvhdmioverlaysink.h new file mode 100644 index 0000000..9921768 --- /dev/null +++ b/omx/gstnvhdmioverlaysink.h @@ -0,0 +1,49 @@ +/* GStreamer + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GST_NV_HDMI_OVERLAY_SINK_H_ +#define _GST_NV_HDMI_OVERLAY_SINK_H_ + +#include "gstomxvideosink.h" + +G_BEGIN_DECLS +#define GST_TYPE_NV_HDMI_OVERLAY_SINK (gst_nv_hdmi_overlay_sink_get_type()) +#define GST_NV_HDMI_OVERLAY_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_NV_HDMI_OVERLAY_SINK,GstNvHDMIOverlaySink)) +#define GST_NV_HDMI_OVERLAY_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_NV_HDMI_OVERLAY_SINK,GstNvHDMIOverlaySinkClass)) +#define GST_NV_HDMI_OVERLAY_SINK_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_NV_HDMI_OVERLAY_SINK,GstNvHDMIOverlaySinkClass)) +#define GST_IS_NV_HDMI_OVERLAY_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_NV_HDMI_OVERLAY_SINK)) +#define GST_IS_NV_HDMI_OVERLAY_SINK_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_NV_HDMI_OVERLAY_SINK)) +typedef struct _GstNvHDMIOverlaySink GstNvHDMIOverlaySink; +typedef struct _GstNvHDMIOverlaySinkClass GstNvHDMIOverlaySinkClass; + +struct _GstNvHDMIOverlaySink +{ + GstOmxVideoSink parent; +}; + +struct _GstNvHDMIOverlaySinkClass +{ + GstOmxVideoSinkClass parent_class; +}; + +GType gst_nv_hdmi_overlay_sink_get_type (void); + +G_END_DECLS +#endif diff --git a/omx/gstnvoverlaysink.c b/omx/gstnvoverlaysink.c new file mode 100644 index 0000000..d0979fc --- /dev/null +++ b/omx/gstnvoverlaysink.c @@ -0,0 +1,102 @@ +/* GStreamer + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Suite 500, + * Boston, MA 02110-1335, USA. + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gst/gst.h> +#include <gst/video/gstvideosink.h> +#include "gstnvoverlaysink.h" + +GST_DEBUG_CATEGORY_STATIC (gst_nv_overlay_sink_debug_category); +#define GST_CAT_DEFAULT gst_nv_overlay_sink_debug_category + +/* prototypes */ + +static void gst_nv_overlay_sink_set_property (GObject * object, + guint property_id, const GValue * value, GParamSpec * pspec); +static void gst_nv_overlay_sink_get_property (GObject * object, + guint property_id, GValue * value, GParamSpec * pspec); + +enum +{ + PROP_0 +}; + +/* class initialization */ + +G_DEFINE_TYPE_WITH_CODE (GstNvOverlaySink, gst_nv_overlay_sink, + GST_TYPE_OMX_VIDEO_SINK, + GST_DEBUG_CATEGORY_INIT (gst_nv_overlay_sink_debug_category, + "nvoverlaysink", 0, "debug category for nvoverlaysink element")); + +static void +gst_nv_overlay_sink_class_init (GstNvOverlaySinkClass * klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstOmxVideoSinkClass *videosink_class = GST_OMX_VIDEO_SINK_CLASS (klass); + + videosink_class->cdata.default_sink_template_caps = "video/x-raw(memory:NVMM), " + "width = (int) [ 1, max ] , " + "height = (int) [ 1, max ] , " "framerate = (fraction) [ 0, max ];" + "video/x-raw, " + "width = (int) [ 1, max ] , " + "height = (int) [ 1, max ] , " "framerate = (fraction) [ 0, max ] "; + + + gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass), + "OpenMax Video Sink", "Sink/Video", "Renders Video", + "Jitendra Kumar <jitendrak@nvidia.com>"); + + gobject_class->set_property = gst_nv_overlay_sink_set_property; + gobject_class->get_property = gst_nv_overlay_sink_get_property; +} + +static void +gst_nv_overlay_sink_init (GstNvOverlaySink * nvoverlaysink) +{ +} + +void +gst_nv_overlay_sink_set_property (GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec) +{ + /* GstNvOverlaySink *nvoverlaysink = GST_NV_OVERLAY_SINK (object); */ + + switch (property_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +void +gst_nv_overlay_sink_get_property (GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) +{ + /* GstNvOverlaySink *nvoverlaysink = GST_NV_OVERLAY_SINK (object); */ + + switch (property_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} diff --git a/omx/gstnvoverlaysink.h b/omx/gstnvoverlaysink.h new file mode 100644 index 0000000..373498f --- /dev/null +++ b/omx/gstnvoverlaysink.h @@ -0,0 +1,49 @@ +/* GStreamer + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GST_NV_OVERLAY_SINK_H_ +#define _GST_NV_OVERLAY_SINK_H_ + +#include "gstomxvideosink.h" + +G_BEGIN_DECLS +#define GST_TYPE_NV_OVERLAY_SINK (gst_nv_overlay_sink_get_type()) +#define GST_NV_OVERLAY_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_NV_OVERLAY_SINK,GstNvOverlaySink)) +#define GST_NV_OVERLAY_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_NV_OVERLAY_SINK,GstNvOverlaySinkClass)) +#define GST_NV_OVERLAY_SINK_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_NV_OVERLAY_SINK,GstNvOverlaySinkClass)) +#define GST_IS_NV_OVERLAY_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_NV_OVERLAY_SINK)) +#define GST_IS_NV_OVERLAY_SINK_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_NV_OVERLAY_SINK)) +typedef struct _GstNvOverlaySink GstNvOverlaySink; +typedef struct _GstNvOverlaySinkClass GstNvOverlaySinkClass; + +struct _GstNvOverlaySink +{ + GstOmxVideoSink parent; +}; + +struct _GstNvOverlaySinkClass +{ + GstOmxVideoSinkClass parent_class; +}; + +GType gst_nv_overlay_sink_get_type (void); + +G_END_DECLS +#endif diff --git a/omx/gstomx.c b/omx/gstomx.c index 4a81de9..fc3379c 100644 --- a/omx/gstomx.c +++ b/omx/gstomx.c @@ -3,6 +3,7 @@ * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. * Copyright (C) 2013, Collabora Ltd. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> + * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -33,13 +34,23 @@ #include "gstomxmpeg4videodec.h" #include "gstomxh264dec.h" #include "gstomxh263dec.h" -#include "gstomxvp8dec.h" #include "gstomxtheoradec.h" #include "gstomxwmvdec.h" #include "gstomxmpeg4videoenc.h" #include "gstomxh264enc.h" #include "gstomxh263enc.h" #include "gstomxaacenc.h" +#include "gstnvoverlaysink.h" +#include "gstnvhdmioverlaysink.h" +#include "gstomxaacdec.h" +#include "gstomxmpegaudiodec.h" +#include "gstomxamrnbdec.h" +#include "gstomxamrwbdec.h" + +#ifdef HAVE_VP8 +#include "gstomxvp8dec.h" +#include "gstomxvp8enc.h" +#endif GST_DEBUG_CATEGORY (gstomx_debug); #define GST_CAT_DEFAULT gstomx_debug @@ -47,6 +58,8 @@ GST_DEBUG_CATEGORY (gstomx_debug); G_LOCK_DEFINE_STATIC (core_handles); static GHashTable *core_handles; +extern const char *default_config; + GstOMXCore * gst_omx_core_acquire (const gchar * filename) { @@ -359,6 +372,10 @@ gst_omx_component_handle_messages (GstOMXComponent * comp) buf->omx_buf->nOffset = 0; buf->omx_buf->nFilledLen = 0; + /*Unref buffer, so it can be used again */ + if (buf->gst_buf) + gst_buffer_unref (buf->gst_buf); + /* Reset all flags, some implementations don't * reset them themselves and the flags are not * valid anymore after the buffer was consumed @@ -396,6 +413,13 @@ gst_omx_component_handle_messages (GstOMXComponent * comp) g_mutex_unlock (&comp->messages_lock); } + +void +gst_omx_handle_messages (GstOMXComponent * comp) +{ + gst_omx_component_handle_messages (comp); +} + /* NOTE: comp->messages_lock will be used */ static void gst_omx_component_send_message (GstOMXComponent * comp, GstOMXMessage * msg) @@ -508,7 +532,10 @@ EventHandler (OMX_HANDLETYPE hComponent, OMX_PTR pAppData, OMX_EVENTTYPE eEvent, GST_DEBUG_OBJECT (comp->parent, "%s settings changed (port index: %u)", comp->name, (guint) msg->content.port_settings_changed.port); - gst_omx_component_send_message (comp, msg); + /* ignore crop and scale events */ + if (nData2 != OMX_IndexConfigCommonOutputCrop + && nData2 != OMX_IndexConfigCommonScale) + gst_omx_component_send_message (comp, msg); break; } case OMX_EventBufferFlag:{ @@ -930,6 +957,7 @@ gst_omx_component_add_port (GstOMXComponent * comp, guint32 index) port->enabled_pending = FALSE; port->disabled_pending = FALSE; port->eos = FALSE; + port->reconfigure = FALSE; if (port->port_def.eDir == OMX_DirInput) comp->n_in_ports++; @@ -1060,6 +1088,23 @@ gst_omx_component_set_config (GstOMXComponent * comp, OMX_INDEXTYPE index, } OMX_ERRORTYPE +gst_omx_component_get_index (GstOMXComponent * comp, gpointer str, + OMX_INDEXTYPE * index) +{ + OMX_ERRORTYPE err; + g_return_val_if_fail (comp != NULL, OMX_ErrorUndefined); + g_return_val_if_fail (index != NULL, OMX_ErrorUndefined); + + GST_DEBUG_OBJECT (comp->parent, "Getting %s Extension index for %s", + comp->name, (char *) str); + err = OMX_GetExtensionIndex (comp->handle, str, index); + GST_DEBUG_OBJECT (comp->parent, "Got %s Extension index for %s: %s " + "(0x%08x)", comp->name, (char *) str, gst_omx_error_to_string (err), err); + + return err; +} + +OMX_ERRORTYPE gst_omx_component_setup_tunnel (GstOMXComponent * comp1, GstOMXPort * port1, GstOMXComponent * comp2, GstOMXPort * port2) { @@ -2317,9 +2362,12 @@ static const GGetTypeFunction types[] = { 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_h263_enc_get_type, - gst_omx_aac_enc_get_type, gst_omx_mjpeg_dec_get_type + gst_omx_aac_enc_get_type, gst_omx_mjpeg_dec_get_type, + gst_nv_overlay_sink_get_type, gst_nv_hdmi_overlay_sink_get_type, + gst_omx_aac_dec_get_type, gst_omx_mpegaudio_dec_get_type, + gst_omx_amrnb_dec_get_type, gst_omx_amrwb_dec_get_type #ifdef HAVE_VP8 - , gst_omx_vp8_dec_get_type + , gst_omx_vp8_dec_get_type, gst_omx_vp8_enc_get_type #endif #ifdef HAVE_THEORA , gst_omx_theora_dec_get_type @@ -2336,6 +2384,8 @@ static const struct TypeOffest base_types[] = { {gst_omx_video_dec_get_type, G_STRUCT_OFFSET (GstOMXVideoDecClass, cdata)}, {gst_omx_video_enc_get_type, G_STRUCT_OFFSET (GstOMXVideoEncClass, cdata)}, {gst_omx_audio_enc_get_type, G_STRUCT_OFFSET (GstOMXAudioEncClass, cdata)}, + {gst_omx_video_sink_get_type, G_STRUCT_OFFSET (GstOmxVideoSinkClass, cdata)}, + {gst_omx_audio_dec_get_type, G_STRUCT_OFFSET (GstOMXAudioDecClass, cdata)}, }; static GKeyFile *config = NULL; @@ -2728,13 +2778,25 @@ plugin_init (GstPlugin * plugin) gchar *paths; paths = g_strjoinv (":", config_dirs); - GST_ERROR ("Failed to load configuration file: %s (searched in: %s as per " + GST_WARNING + ("Failed to load configuration file: %s (searched in: %s as per " "GST_OMX_CONFIG_DIR environment variable, the xdg user config " "directory (or XDG_CONFIG_HOME) and the system config directory " "(or XDG_CONFIG_DIRS)", err->message, paths); + g_free (paths); g_error_free (err); - goto done; + err = NULL; + GST_INFO ("Using default configuration"); + if (default_config == NULL || !g_key_file_load_from_data (config, + default_config, strlen (default_config), G_KEY_FILE_NONE, &err)) { + if (err) { + GST_ERROR ("Failed to use default configuration: %s", err->message); + g_error_free (err); + } else + GST_ERROR ("Failed to use default configuration: no config string"); + goto done; + } } /* Initialize all types */ diff --git a/omx/gstomx.h b/omx/gstomx.h index 8af81b8..76f6622 100644 --- a/omx/gstomx.h +++ b/omx/gstomx.h @@ -3,6 +3,7 @@ * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. * Copyright (C) 2013, Collabora Ltd. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> + * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -48,6 +49,10 @@ #include <OMX_Core.h> #include <OMX_Component.h> +#ifdef USE_OMX_TARGET_TEGRA +#include "NVOMX_IndexExtensions.h" +#endif + #ifdef USE_OMX_TARGET_RPI #include <OMX_Broadcom.h> #endif @@ -57,7 +62,6 @@ #endif G_BEGIN_DECLS - #define GST_OMX_INIT_STRUCT(st) G_STMT_START { \ memset ((st), 0, sizeof (*(st))); \ (st)->nSize = sizeof (*(st)); \ @@ -66,7 +70,6 @@ G_BEGIN_DECLS (st)->nVersion.s.nRevision = OMX_VERSION_REVISION; \ (st)->nVersion.s.nStep = OMX_VERSION_STEP; \ } G_STMT_END - /* Different hacks that are required to work around * bugs in different OpenMAX implementations */ @@ -91,22 +94,18 @@ G_BEGIN_DECLS * Happens with Qualcomm's OpenMAX implementation. */ #define GST_OMX_HACK_NO_COMPONENT_RECONFIGURE G_GUINT64_CONSTANT (0x0000000000000010) - /* If the component does not accept empty EOS buffers. * Happens with Qualcomm's OpenMAX implementation. */ #define GST_OMX_HACK_NO_EMPTY_EOS_BUFFER G_GUINT64_CONSTANT (0x0000000000000020) - /* If the component might not acknowledge a drain. * Happens with TI's Ducati OpenMAX implementation. */ #define GST_OMX_HACK_DRAIN_MAY_NOT_RETURN G_GUINT64_CONSTANT (0x0000000000000040) - /* If the component doesn't allow any component role to be set. * Happens with Broadcom's OpenMAX implementation. */ #define GST_OMX_HACK_NO_COMPONENT_ROLE G_GUINT64_CONSTANT (0x0000000000000080) - typedef struct _GstOMXCore GstOMXCore; typedef struct _GstOMXPort GstOMXPort; typedef enum _GstOMXPortDirection GstOMXPortDirection; @@ -115,7 +114,8 @@ typedef struct _GstOMXBuffer GstOMXBuffer; typedef struct _GstOMXClassData GstOMXClassData; typedef struct _GstOMXMessage GstOMXMessage; -typedef enum { +typedef enum +{ /* Everything good and the buffer is valid */ GST_OMX_ACQUIRE_BUFFER_OK = 0, /* The port is flushing, exit ASAP */ @@ -128,25 +128,28 @@ typedef enum { GST_OMX_ACQUIRE_BUFFER_ERROR } GstOMXAcquireBufferReturn; -struct _GstOMXCore { +struct _GstOMXCore +{ /* Handle to the OpenMAX IL core shared library */ GModule *module; /* Current number of users, transitions from/to 0 * call init/deinit */ GMutex lock; - gint user_count; /* LOCK */ + gint user_count; /* LOCK */ /* OpenMAX core library functions, protected with LOCK */ - OMX_ERRORTYPE (*init) (void); - OMX_ERRORTYPE (*deinit) (void); - OMX_ERRORTYPE (*get_handle) (OMX_HANDLETYPE * handle, + OMX_ERRORTYPE (*init) (void); + OMX_ERRORTYPE (*deinit) (void); + OMX_ERRORTYPE (*get_handle) (OMX_HANDLETYPE * handle, OMX_STRING name, OMX_PTR data, OMX_CALLBACKTYPE * callbacks); - OMX_ERRORTYPE (*free_handle) (OMX_HANDLETYPE handle); - OMX_ERRORTYPE (*setup_tunnel) (OMX_HANDLETYPE output, OMX_U32 outport, OMX_HANDLETYPE input, OMX_U32 inport); + OMX_ERRORTYPE (*free_handle) (OMX_HANDLETYPE handle); + OMX_ERRORTYPE (*setup_tunnel) (OMX_HANDLETYPE output, OMX_U32 outport, + OMX_HANDLETYPE input, OMX_U32 inport); }; -typedef enum { +typedef enum +{ GST_OMX_MESSAGE_STATE_SET, GST_OMX_MESSAGE_FLUSH, GST_OMX_MESSAGE_ERROR, @@ -156,37 +159,47 @@ typedef enum { GST_OMX_MESSAGE_BUFFER_DONE, } GstOMXMessageType; -typedef enum { +typedef enum +{ GST_OMX_COMPONENT_TYPE_SINK, GST_OMX_COMPONENT_TYPE_SOURCE, GST_OMX_COMPONENT_TYPE_FILTER } GstOmxComponentType; -struct _GstOMXMessage { +struct _GstOMXMessage +{ GstOMXMessageType type; - union { - struct { + union + { + struct + { OMX_STATETYPE state; } state_set; - struct { + struct + { OMX_U32 port; } flush; - struct { + struct + { OMX_ERRORTYPE error; } error; - struct { + struct + { OMX_U32 port; OMX_BOOL enable; } port_enable; - struct { + struct + { OMX_U32 port; } port_settings_changed; - struct { + struct + { OMX_U32 port; OMX_U32 flags; } buffer_flag; - struct { + struct + { OMX_HANDLETYPE component; OMX_PTR app_data; OMX_BUFFERHEADERTYPE *buffer; @@ -195,20 +208,22 @@ struct _GstOMXMessage { } content; }; -struct _GstOMXPort { +struct _GstOMXPort +{ GstOMXComponent *comp; guint32 index; gboolean tunneled; OMX_PARAM_PORTDEFINITIONTYPE port_def; - GPtrArray *buffers; /* Contains GstOMXBuffer* */ - GQueue pending_buffers; /* Contains GstOMXBuffer* */ + GPtrArray *buffers; /* Contains GstOMXBuffer* */ + GQueue pending_buffers; /* Contains GstOMXBuffer* */ gboolean flushing; - gboolean flushed; /* TRUE after OMX_CommandFlush was done */ - gboolean enabled_pending; /* TRUE after OMX_Command{En,Dis}able */ - gboolean disabled_pending; /* was done until it took effect */ - gboolean eos; /* TRUE after a buffer with EOS flag was received */ + gboolean flushed; /* TRUE after OMX_CommandFlush was done */ + gboolean enabled_pending; /* TRUE after OMX_Command{En,Dis}able */ + gboolean disabled_pending; /* was done until it took effect */ + gboolean eos; /* TRUE after a buffer with EOS flag was received */ + gboolean reconfigure; /* TRUE incase port needs to be reconfigured */ /* Increased whenever the settings of these port change. * If settings_cookie != configured_settings_cookie @@ -218,18 +233,19 @@ struct _GstOMXPort { gint configured_settings_cookie; }; -struct _GstOMXComponent { +struct _GstOMXComponent +{ GstObject *parent; - gchar *name; /* for debugging mostly */ + gchar *name; /* for debugging mostly */ OMX_HANDLETYPE handle; GstOMXCore *core; - guint64 hacks; /* Flags, GST_OMX_HACK_* */ + guint64 hacks; /* Flags, GST_OMX_HACK_* */ /* Added once, never changed. No locks necessary */ - GPtrArray *ports; /* Contains GstOMXPort* */ + GPtrArray *ports; /* Contains GstOMXPort* */ gint n_in_ports, n_out_ports; /* Locking order: lock -> messages_lock @@ -238,7 +254,7 @@ struct _GstOMXComponent { * Always check that messages is empty before waiting */ GMutex lock; - GQueue messages; /* Queue of GstOMXMessages */ + GQueue messages; /* Queue of GstOMXMessages */ GMutex messages_lock; GCond messages_cond; @@ -251,9 +267,11 @@ struct _GstOMXComponent { GList *pending_reconfigure_outports; }; -struct _GstOMXBuffer { +struct _GstOMXBuffer +{ GstOMXPort *port; OMX_BUFFERHEADERTYPE *omx_buf; + GstBuffer *gst_buf; /* TRUE if the buffer is used by the port, i.e. * between {Empty,Fill}ThisBuffer and the callback @@ -267,7 +285,8 @@ struct _GstOMXBuffer { gboolean eglimage; }; -struct _GstOMXClassData { +struct _GstOMXClassData +{ const gchar *core_name; const gchar *component_name; const gchar *component_role; @@ -282,65 +301,88 @@ struct _GstOMXClassData { GstOmxComponentType type; }; -GKeyFile * gst_omx_get_configuration (void); +GKeyFile *gst_omx_get_configuration (void); -const gchar * gst_omx_error_to_string (OMX_ERRORTYPE err); -const gchar * gst_omx_state_to_string (OMX_STATETYPE state); -const gchar * gst_omx_command_to_string (OMX_COMMANDTYPE cmd); +const gchar *gst_omx_error_to_string (OMX_ERRORTYPE err); +const gchar *gst_omx_state_to_string (OMX_STATETYPE state); +const gchar *gst_omx_command_to_string (OMX_COMMANDTYPE cmd); -guint64 gst_omx_parse_hacks (gchar ** hacks); +guint64 gst_omx_parse_hacks (gchar ** hacks); -GstOMXCore * gst_omx_core_acquire (const gchar * filename); -void gst_omx_core_release (GstOMXCore * core); +GstOMXCore *gst_omx_core_acquire (const gchar * filename); +void gst_omx_core_release (GstOMXCore * core); -GstOMXComponent * gst_omx_component_new (GstObject * parent, const gchar *core_name, const gchar *component_name, const gchar * component_role, guint64 hacks); -void gst_omx_component_free (GstOMXComponent * comp); +GstOMXComponent *gst_omx_component_new (GstObject * parent, + const gchar * core_name, const gchar * component_name, + const gchar * component_role, guint64 hacks); +void gst_omx_component_free (GstOMXComponent * comp); -OMX_ERRORTYPE gst_omx_component_set_state (GstOMXComponent * comp, OMX_STATETYPE state); -OMX_STATETYPE gst_omx_component_get_state (GstOMXComponent * comp, GstClockTime timeout); +OMX_ERRORTYPE gst_omx_component_set_state (GstOMXComponent * comp, + OMX_STATETYPE state); +OMX_STATETYPE gst_omx_component_get_state (GstOMXComponent * comp, + GstClockTime timeout); -OMX_ERRORTYPE gst_omx_component_get_last_error (GstOMXComponent * comp); -const gchar * gst_omx_component_get_last_error_string (GstOMXComponent * comp); +OMX_ERRORTYPE gst_omx_component_get_last_error (GstOMXComponent * comp); +const gchar *gst_omx_component_get_last_error_string (GstOMXComponent * comp); -GstOMXPort * gst_omx_component_add_port (GstOMXComponent * comp, guint32 index); -GstOMXPort * gst_omx_component_get_port (GstOMXComponent * comp, guint32 index); +GstOMXPort *gst_omx_component_add_port (GstOMXComponent * comp, guint32 index); +GstOMXPort *gst_omx_component_get_port (GstOMXComponent * comp, guint32 index); -OMX_ERRORTYPE gst_omx_component_get_parameter (GstOMXComponent * comp, OMX_INDEXTYPE index, gpointer param); -OMX_ERRORTYPE gst_omx_component_set_parameter (GstOMXComponent * comp, OMX_INDEXTYPE index, gpointer param); +OMX_ERRORTYPE gst_omx_component_get_parameter (GstOMXComponent * comp, + OMX_INDEXTYPE index, gpointer param); +OMX_ERRORTYPE gst_omx_component_set_parameter (GstOMXComponent * comp, + OMX_INDEXTYPE index, gpointer param); -OMX_ERRORTYPE gst_omx_component_get_config (GstOMXComponent * comp, OMX_INDEXTYPE index, gpointer config); -OMX_ERRORTYPE gst_omx_component_set_config (GstOMXComponent * comp, OMX_INDEXTYPE index, gpointer config); -OMX_ERRORTYPE gst_omx_component_setup_tunnel (GstOMXComponent * comp1, GstOMXPort * port1, GstOMXComponent * comp2, GstOMXPort * port2); -OMX_ERRORTYPE gst_omx_component_close_tunnel (GstOMXComponent * comp1, GstOMXPort * port1, GstOMXComponent * comp2, GstOMXPort * port2); +OMX_ERRORTYPE gst_omx_component_get_config (GstOMXComponent * comp, + OMX_INDEXTYPE index, gpointer config); +OMX_ERRORTYPE gst_omx_component_set_config (GstOMXComponent * comp, + OMX_INDEXTYPE index, gpointer config); +OMX_ERRORTYPE gst_omx_component_setup_tunnel (GstOMXComponent * comp1, + GstOMXPort * port1, GstOMXComponent * comp2, GstOMXPort * port2); +OMX_ERRORTYPE gst_omx_component_close_tunnel (GstOMXComponent * comp1, + GstOMXPort * port1, GstOMXComponent * comp2, GstOMXPort * port2); -OMX_ERRORTYPE gst_omx_port_get_port_definition (GstOMXPort * port, OMX_PARAM_PORTDEFINITIONTYPE * port_def); -OMX_ERRORTYPE gst_omx_port_update_port_definition (GstOMXPort *port, OMX_PARAM_PORTDEFINITIONTYPE *port_definition); +OMX_ERRORTYPE gst_omx_port_get_port_definition (GstOMXPort * port, + OMX_PARAM_PORTDEFINITIONTYPE * port_def); +OMX_ERRORTYPE gst_omx_port_update_port_definition (GstOMXPort * port, + OMX_PARAM_PORTDEFINITIONTYPE * port_definition); -GstOMXAcquireBufferReturn gst_omx_port_acquire_buffer (GstOMXPort *port, GstOMXBuffer **buf); -OMX_ERRORTYPE gst_omx_port_release_buffer (GstOMXPort *port, GstOMXBuffer *buf); +GstOMXAcquireBufferReturn gst_omx_port_acquire_buffer (GstOMXPort * port, + GstOMXBuffer ** buf); +OMX_ERRORTYPE gst_omx_port_release_buffer (GstOMXPort * port, + GstOMXBuffer * buf); -OMX_ERRORTYPE gst_omx_port_set_flushing (GstOMXPort *port, GstClockTime timeout, gboolean flush); -gboolean gst_omx_port_is_flushing (GstOMXPort *port); +OMX_ERRORTYPE gst_omx_port_set_flushing (GstOMXPort * port, + GstClockTime timeout, gboolean flush); +gboolean gst_omx_port_is_flushing (GstOMXPort * port); -OMX_ERRORTYPE gst_omx_port_allocate_buffers (GstOMXPort *port); -OMX_ERRORTYPE gst_omx_port_use_buffers (GstOMXPort *port, const GList *buffers); -OMX_ERRORTYPE gst_omx_port_use_eglimages (GstOMXPort *port, const GList *images); -OMX_ERRORTYPE gst_omx_port_deallocate_buffers (GstOMXPort *port); -OMX_ERRORTYPE gst_omx_port_populate (GstOMXPort *port); -OMX_ERRORTYPE gst_omx_port_wait_buffers_released (GstOMXPort * port, GstClockTime timeout); +OMX_ERRORTYPE gst_omx_port_allocate_buffers (GstOMXPort * port); +OMX_ERRORTYPE gst_omx_port_use_buffers (GstOMXPort * port, + const GList * buffers); +OMX_ERRORTYPE gst_omx_port_use_eglimages (GstOMXPort * port, + const GList * images); +OMX_ERRORTYPE gst_omx_port_deallocate_buffers (GstOMXPort * port); +OMX_ERRORTYPE gst_omx_port_populate (GstOMXPort * port); +OMX_ERRORTYPE gst_omx_port_wait_buffers_released (GstOMXPort * port, + GstClockTime timeout); -OMX_ERRORTYPE gst_omx_port_mark_reconfigured (GstOMXPort * port); +OMX_ERRORTYPE gst_omx_port_mark_reconfigured (GstOMXPort * port); -OMX_ERRORTYPE gst_omx_port_set_enabled (GstOMXPort * port, gboolean enabled); -OMX_ERRORTYPE gst_omx_port_wait_enabled (GstOMXPort * port, GstClockTime timeout); -gboolean gst_omx_port_is_enabled (GstOMXPort * port); +OMX_ERRORTYPE gst_omx_port_set_enabled (GstOMXPort * port, gboolean enabled); +OMX_ERRORTYPE gst_omx_port_wait_enabled (GstOMXPort * port, + GstClockTime timeout); +gboolean gst_omx_port_is_enabled (GstOMXPort * port); -void gst_omx_set_default_role (GstOMXClassData *class_data, const gchar *default_role); +void gst_omx_set_default_role (GstOMXClassData * class_data, + const gchar * default_role); +OMX_ERRORTYPE gst_omx_component_get_index (GstOMXComponent * comp, gpointer str, + OMX_INDEXTYPE * index); -G_END_DECLS +void gst_omx_handle_messages (GstOMXComponent * comp); +G_END_DECLS #endif /* __GST_OMX_H__ */ diff --git a/omx/gstomxaacdec.c b/omx/gstomxaacdec.c new file mode 100644 index 0000000..2bbde71 --- /dev/null +++ b/omx/gstomxaacdec.c @@ -0,0 +1,164 @@ +/* GStreamer + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Suite 500, + * Boston, MA 02110-1335, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gst/gst.h> +#include <gst/audio/gstaudiodecoder.h> +#include "gstomxaacdec.h" + +GST_DEBUG_CATEGORY_STATIC (gst_omx_aac_dec_debug_category); +#define GST_CAT_DEFAULT gst_omx_aac_dec_debug_category + +/* prototypes */ + +static gboolean gst_omx_aac_dec_set_format (GstOMXAudioDec * decoder, + GstOMXPort * port, GstCaps * caps); + +/* class initialization */ + +G_DEFINE_TYPE_WITH_CODE (GstOMXAACDec, gst_omx_aac_dec, GST_TYPE_OMX_AUDIO_DEC, + GST_DEBUG_CATEGORY_INIT (gst_omx_aac_dec_debug_category, "omxaacdec", 0, + "debug category for omxaacdec element")); + +static void +gst_omx_aac_dec_class_init (GstOMXAACDecClass * klass) +{ + GstOMXAudioDecClass *omxdec_class = GST_OMX_AUDIO_DEC_CLASS (klass); + + omxdec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_aac_dec_set_format); + + omxdec_class->cdata.default_sink_template_caps = "audio/mpeg, " + "mpegversion = (int) {2,4}, " + "stream-format = (string) {raw, adts, adif}"; + + gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass), + "OpenMax AAC decoder", "Codec/Decoder/Audio", "Decodes AAC audio streams", + "Jitendra Kumar <jitendrak@nvidia.com>"); + + gst_omx_set_default_role (&omxdec_class->cdata, "audio_decoder.eaacplus"); +} + +static void +gst_omx_aac_dec_init (GstOMXAACDec * omxaacdec) +{ +} + +static gboolean +gst_omx_aac_dec_set_format (GstOMXAudioDec * decoder, GstOMXPort * port, + GstCaps * caps) +{ + GstOMXAACDec *self = GST_OMX_AAC_DEC (decoder); + OMX_AUDIO_PARAM_AACPROFILETYPE aac_profile; + OMX_PARAM_PORTDEFINITIONTYPE port_def; + OMX_ERRORTYPE err; + + gst_omx_port_get_port_definition (port, &port_def); + port_def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; + err = gst_omx_port_update_port_definition (port, &port_def); + + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, + "Failed to update port definition of component: %s (0x%08x)", + gst_omx_error_to_string (err), err); + return FALSE; + } + + GST_OMX_INIT_STRUCT (&aac_profile); + aac_profile.nPortIndex = port->index; + + err = gst_omx_component_get_parameter (decoder->dec, OMX_IndexParamAudioAac, + &aac_profile); + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, + "Failed to get AAC parameters from component: %s (0x%08x)", + gst_omx_error_to_string (err), err); + return FALSE; + } + + if (caps) { + GstStructure *s; + gint mpegversion = 0; + const gchar *profile_string, *stream_format_string; + + if (gst_caps_is_empty (caps)) { + GST_ERROR_OBJECT (self, "Empty caps"); + return FALSE; + } + + s = gst_caps_get_structure (caps, 0); + + if (gst_structure_get_int (s, "mpegversion", &mpegversion)) { + profile_string = + gst_structure_get_string (s, + ((mpegversion == 2) ? "profile" : "base-profile")); + + if (profile_string) { + if (g_str_equal (profile_string, "main")) { + aac_profile.eAACProfile = OMX_AUDIO_AACObjectMain; + } else if (g_str_equal (profile_string, "lc")) { + aac_profile.eAACProfile = OMX_AUDIO_AACObjectLC; + } else if (g_str_equal (profile_string, "ssr")) { + aac_profile.eAACProfile = OMX_AUDIO_AACObjectSSR; + } else if (g_str_equal (profile_string, "ltp")) { + aac_profile.eAACProfile = OMX_AUDIO_AACObjectLTP; + } else { + GST_ERROR_OBJECT (self, "Unsupported profile '%s'", profile_string); + return FALSE; + } + } + } + + stream_format_string = gst_structure_get_string (s, "stream-format"); + if (stream_format_string) { + if (g_str_equal (stream_format_string, "raw")) { + aac_profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatRAW; + } else if (g_str_equal (stream_format_string, "adts")) { + if (mpegversion == 2) { + aac_profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP2ADTS; + } else { + aac_profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS; + } + } else if (g_str_equal (stream_format_string, "loas")) { + aac_profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4LOAS; + } else if (g_str_equal (stream_format_string, "latm")) { + aac_profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4LATM; + } else if (g_str_equal (stream_format_string, "adif")) { + aac_profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatADIF; + } else { + GST_ERROR_OBJECT (self, "Unsupported stream-format '%s'", + stream_format_string); + return FALSE; + } + } + + } + + err = gst_omx_component_set_parameter (decoder->dec, OMX_IndexParamAudioAac, + &aac_profile); + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, "Error setting AAC parameters: %s (0x%08x)", + gst_omx_error_to_string (err), err); + return FALSE; + } + + return TRUE; +} diff --git a/omx/gstomxaacdec.h b/omx/gstomxaacdec.h new file mode 100644 index 0000000..21190b1 --- /dev/null +++ b/omx/gstomxaacdec.h @@ -0,0 +1,49 @@ +/* GStreamer + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _GST_OMX_AAC_DEC_H_ +#define _GST_OMX_AAC_DEC_H_ + +#include <gst/gst.h> +#include "gstomxaudiodec.h" + +G_BEGIN_DECLS +#define GST_TYPE_OMX_AAC_DEC (gst_omx_aac_dec_get_type()) +#define GST_OMX_AAC_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_AAC_DEC,GstOMXAACDec)) +#define GST_OMX_AAC_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_AAC_DEC,GstOMXAACDecClass)) +#define GST_IS_OMX_AAC_DEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_AAC_DEC)) +#define GST_IS_OMX_AAC_DEC_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_AAC_DEC)) +typedef struct _GstOMXAACDec GstOMXAACDec; +typedef struct _GstOMXAACDecClass GstOMXAACDecClass; + +struct _GstOMXAACDec +{ + GstOMXAudioDec parent; + +}; + +struct _GstOMXAACDecClass +{ + GstOMXAudioDecClass parent_class; +}; + +GType gst_omx_aac_dec_get_type (void); + +G_END_DECLS +#endif diff --git a/omx/gstomxaacenc.c b/omx/gstomxaacenc.c index 1ef8ff9..40e775f 100644 --- a/omx/gstomxaacenc.c +++ b/omx/gstomxaacenc.c @@ -1,6 +1,10 @@ /* + * Copyright (c) 2009-2014, NVIDIA CORPORATION. All rights reserved. + * + * Based on code copyright/by: + * + * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. - * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/omx/gstomxaacenc.h b/omx/gstomxaacenc.h index b6c3daa..40af800 100644 --- a/omx/gstomxaacenc.h +++ b/omx/gstomxaacenc.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. - * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. + * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +26,6 @@ #include "gstomxaudioenc.h" G_BEGIN_DECLS - #define GST_TYPE_OMX_AAC_ENC \ (gst_omx_aac_enc_get_type()) #define GST_OMX_AAC_ENC(obj) \ @@ -38,7 +38,6 @@ G_BEGIN_DECLS (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_AAC_ENC)) #define GST_IS_OMX_AAC_ENC_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_AAC_ENC)) - typedef struct _GstOMXAACEnc GstOMXAACEnc; typedef struct _GstOMXAACEncClass GstOMXAACEncClass; @@ -60,6 +59,4 @@ struct _GstOMXAACEncClass GType gst_omx_aac_enc_get_type (void); G_END_DECLS - #endif /* __GST_OMX_AAC_ENC_H__ */ - diff --git a/omx/gstomxamrnbdec.c b/omx/gstomxamrnbdec.c new file mode 100644 index 0000000..b9098c0 --- /dev/null +++ b/omx/gstomxamrnbdec.c @@ -0,0 +1,120 @@ +/* GStreamer + * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Suite 500, + * Boston, MA 02110-1335, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gst/gst.h> +#include <gst/audio/gstaudiodecoder.h> +#include "gstomxamrnbdec.h" + +GST_DEBUG_CATEGORY_STATIC (gst_omx_amrnb_dec_debug_category); +#define GST_CAT_DEFAULT gst_omx_amrnb_dec_debug_category + +/* prototypes */ + +static gboolean gst_omx_amrnb_dec_set_format (GstOMXAudioDec * decoder, + GstOMXPort * port, GstCaps * caps); + +/* class initialization */ + +G_DEFINE_TYPE_WITH_CODE (GstOMXAMRNBDec, gst_omx_amrnb_dec, + GST_TYPE_OMX_AUDIO_DEC, + GST_DEBUG_CATEGORY_INIT (gst_omx_amrnb_dec_debug_category, "omxamrnbdec", 0, + "debug category for omxamrnbdec element")); + +static void +gst_omx_amrnb_dec_class_init (GstOMXAMRNBDecClass * klass) +{ + GstOMXAudioDecClass *omxdec_class = GST_OMX_AUDIO_DEC_CLASS (klass); + + omxdec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_amrnb_dec_set_format); + + omxdec_class->cdata.default_sink_template_caps = "audio/AMR"; + + gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass), + "OpenMax AMR-NB decoder", "Codec/Decoder/Audio", + "Decodes AMR-NB audio streams", "Jitendra Kumar <jitendrak@nvidia.com>"); + + gst_omx_set_default_role (&omxdec_class->cdata, "audio_decoder.amrnb"); +} + +static void +gst_omx_amrnb_dec_init (GstOMXAMRNBDec * omxamrnbdec) +{ +} + +static gboolean +gst_omx_amrnb_dec_set_format (GstOMXAudioDec * decoder, GstOMXPort * port, + GstCaps * caps) +{ + GstOMXAMRNBDec *self = GST_OMX_AMRNB_DEC (decoder); + OMX_AUDIO_PARAM_AMRTYPE amr_type; + OMX_PARAM_PORTDEFINITIONTYPE port_def; + OMX_ERRORTYPE err; + + gst_omx_port_get_port_definition (port, &port_def); + port_def.format.audio.eEncoding = OMX_AUDIO_CodingAMR; + err = gst_omx_port_update_port_definition (port, &port_def); + + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, + "Failed to update port definition of component: %s (0x%08x)", + gst_omx_error_to_string (err), err); + return FALSE; + } + + GST_OMX_INIT_STRUCT (&amr_type); + amr_type.nPortIndex = port->index; + + err = gst_omx_component_get_parameter (decoder->dec, OMX_IndexParamAudioAmr, + &amr_type); + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, + "Failed to get AMR parameters from component: %s (0x%08x)", + gst_omx_error_to_string (err), err); + return FALSE; + } + + if (caps) { + GstStructure *s; + gint channels = 0; + + if (gst_caps_is_empty (caps)) { + GST_ERROR_OBJECT (self, "Empty caps"); + return FALSE; + } + + s = gst_caps_get_structure (caps, 0); + + if (gst_structure_get_int (s, "channels", &channels)) + amr_type.nChannels = channels; + } + + err = gst_omx_component_set_parameter (decoder->dec, OMX_IndexParamAudioAmr, + &amr_type); + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, "Error setting AMR parameters: %s (0x%08x)", + gst_omx_error_to_string (err), err); + return FALSE; + } + + return TRUE; +} diff --git a/omx/gstomxamrnbdec.h b/omx/gstomxamrnbdec.h new file mode 100644 index 0000000..4c5ab70 --- /dev/null +++ b/omx/gstomxamrnbdec.h @@ -0,0 +1,49 @@ +/* GStreamer + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _GST_OMX_AMRNB_DEC_H_ +#define _GST_OMX_AMRNB_DEC_H_ + +#include <gst/gst.h> +#include "gstomxaudiodec.h" + +G_BEGIN_DECLS +#define GST_TYPE_OMX_AMRNB_DEC (gst_omx_amrnb_dec_get_type()) +#define GST_OMX_AMRNB_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_AMRNB_DEC,GstOMXAMRNBDec)) +#define GST_OMX_AMRNB_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_AMRNB_DEC,GstOMXAMRNBDecClass)) +#define GST_IS_OMX_AMRNB_DEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_AMRNB_DEC)) +#define GST_IS_OMX_AMRNB_DEC_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_AMRNB_DEC)) +typedef struct _GstOMXAMRNBDec GstOMXAMRNBDec; +typedef struct _GstOMXAMRNBDecClass GstOMXAMRNBDecClass; + +struct _GstOMXAMRNBDec +{ + GstOMXAudioDec parent; + +}; + +struct _GstOMXAMRNBDecClass +{ + GstOMXAudioDecClass parent_class; +}; + +GType gst_omx_amrnb_dec_get_type (void); + +G_END_DECLS +#endif diff --git a/omx/gstomxamrwbdec.c b/omx/gstomxamrwbdec.c new file mode 100644 index 0000000..d9d4a8f --- /dev/null +++ b/omx/gstomxamrwbdec.c @@ -0,0 +1,120 @@ +/* GStreamer + * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Suite 500, + * Boston, MA 02110-1335, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gst/gst.h> +#include <gst/audio/gstaudiodecoder.h> +#include "gstomxamrwbdec.h" + +GST_DEBUG_CATEGORY_STATIC (gst_omx_amrwb_dec_debug_category); +#define GST_CAT_DEFAULT gst_omx_amrwb_dec_debug_category + +/* prototypes */ + +static gboolean gst_omx_amrwb_dec_set_format (GstOMXAudioDec * decoder, + GstOMXPort * port, GstCaps * caps); + +/* class initialization */ + +G_DEFINE_TYPE_WITH_CODE (GstOMXAMRWBDec, gst_omx_amrwb_dec, + GST_TYPE_OMX_AUDIO_DEC, + GST_DEBUG_CATEGORY_INIT (gst_omx_amrwb_dec_debug_category, "omxamrwbdec", 0, + "debug category for omxamrwbdec element")); + +static void +gst_omx_amrwb_dec_class_init (GstOMXAMRWBDecClass * klass) +{ + GstOMXAudioDecClass *omxdec_class = GST_OMX_AUDIO_DEC_CLASS (klass); + + omxdec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_amrwb_dec_set_format); + + omxdec_class->cdata.default_sink_template_caps = "audio/AMR-WB"; + + gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass), + "OpenMax AMR-WB decoder", "Codec/Decoder/Audio", + "Decodes AMR-WB audio streams", "Jitendra Kumar <jitendrak@nvidia.com>"); + + gst_omx_set_default_role (&omxdec_class->cdata, "audio_decoder.amrwb"); +} + +static void +gst_omx_amrwb_dec_init (GstOMXAMRWBDec * omxamrwbdec) +{ +} + +static gboolean +gst_omx_amrwb_dec_set_format (GstOMXAudioDec * decoder, GstOMXPort * port, + GstCaps * caps) +{ + GstOMXAMRWBDec *self = GST_OMX_AMRWB_DEC (decoder); + OMX_AUDIO_PARAM_AMRTYPE amr_type; + OMX_PARAM_PORTDEFINITIONTYPE port_def; + OMX_ERRORTYPE err; + + gst_omx_port_get_port_definition (port, &port_def); + port_def.format.audio.eEncoding = OMX_AUDIO_CodingAMR; + err = gst_omx_port_update_port_definition (port, &port_def); + + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, + "Failed to update port definition of component: %s (0x%08x)", + gst_omx_error_to_string (err), err); + return FALSE; + } + + GST_OMX_INIT_STRUCT (&amr_type); + amr_type.nPortIndex = port->index; + + err = gst_omx_component_get_parameter (decoder->dec, OMX_IndexParamAudioAmr, + &amr_type); + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, + "Failed to get AMR parameters from component: %s (0x%08x)", + gst_omx_error_to_string (err), err); + return FALSE; + } + + if (caps) { + GstStructure *s; + gint channels = 0; + + if (gst_caps_is_empty (caps)) { + GST_ERROR_OBJECT (self, "Empty caps"); + return FALSE; + } + + s = gst_caps_get_structure (caps, 0); + + if (gst_structure_get_int (s, "channels", &channels)) + amr_type.nChannels = channels; + } + + err = gst_omx_component_set_parameter (decoder->dec, OMX_IndexParamAudioAmr, + &amr_type); + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, "Error setting AMR parameters: %s (0x%08x)", + gst_omx_error_to_string (err), err); + return FALSE; + } + + return TRUE; +} diff --git a/omx/gstomxamrwbdec.h b/omx/gstomxamrwbdec.h new file mode 100644 index 0000000..615c606 --- /dev/null +++ b/omx/gstomxamrwbdec.h @@ -0,0 +1,49 @@ +/* GStreamer + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _GST_OMX_AMRWB_DEC_H_ +#define _GST_OMX_AMRWB_DEC_H_ + +#include <gst/gst.h> +#include "gstomxaudiodec.h" + +G_BEGIN_DECLS +#define GST_TYPE_OMX_AMRWB_DEC (gst_omx_amrwb_dec_get_type()) +#define GST_OMX_AMRWB_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_AMRWB_DEC,GstOMXAMRWBDec)) +#define GST_OMX_AMRWB_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_AMRWB_DEC,GstOMXAMRWBDecClass)) +#define GST_IS_OMX_AMRWB_DEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_AMRWB_DEC)) +#define GST_IS_OMX_AMRWB_DEC_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_AMRWB_DEC)) +typedef struct _GstOMXAMRWBDec GstOMXAMRWBDec; +typedef struct _GstOMXAMRWBDecClass GstOMXAMRWBDecClass; + +struct _GstOMXAMRWBDec +{ + GstOMXAudioDec parent; + +}; + +struct _GstOMXAMRWBDecClass +{ + GstOMXAudioDecClass parent_class; +}; + +GType gst_omx_amrwb_dec_get_type (void); + +G_END_DECLS +#endif diff --git a/omx/gstomxaudiodec.c b/omx/gstomxaudiodec.c new file mode 100644 index 0000000..aadd253 --- /dev/null +++ b/omx/gstomxaudiodec.c @@ -0,0 +1,1130 @@ +/* GStreamer + * Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Suite 500, + * Boston, MA 02110-1335, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gst/gst.h> +#include <gst/audio/gstaudiodecoder.h> +#include "gstomxaudiodec.h" + +GST_DEBUG_CATEGORY_STATIC (gst_omx_audio_dec_debug_category); +#define GST_CAT_DEFAULT gst_omx_audio_dec_debug_category + +/* prototypes */ + +static void gst_omx_audio_dec_finalize (GObject * object); + +static gboolean gst_omx_audio_dec_start (GstAudioDecoder * decoder); +static gboolean gst_omx_audio_dec_stop (GstAudioDecoder * decoder); +static gboolean gst_omx_audio_dec_set_format (GstAudioDecoder * decoder, + GstCaps * caps); +static GstFlowReturn gst_omx_audio_dec_handle_frame (GstAudioDecoder * decoder, + GstBuffer * buffer); +static gboolean gst_omx_audio_dec_open (GstAudioDecoder * decoder); +static gboolean gst_omx_audio_dec_close (GstAudioDecoder * decoder); +static gboolean gst_omx_audio_dec_shutdown (GstOMXAudioDec * self); + +/* class initialization */ + +G_DEFINE_TYPE_WITH_CODE (GstOMXAudioDec, gst_omx_audio_dec, + GST_TYPE_AUDIO_DECODER, + GST_DEBUG_CATEGORY_INIT (gst_omx_audio_dec_debug_category, "omxaudiodec", 0, + "debug category for omxaudiodec element")); + + +static GstStateChangeReturn +gst_omx_audio_dec_change_state (GstElement * element, GstStateChange transition) +{ + GstOMXAudioDec *self; + GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; + + g_return_val_if_fail (GST_IS_OMX_AUDIO_DEC (element), + GST_STATE_CHANGE_FAILURE); + self = GST_OMX_AUDIO_DEC (element); + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + break; + case GST_STATE_CHANGE_READY_TO_PAUSED: + self->downstream_flow_ret = GST_FLOW_OK; + self->draining = FALSE; + self->started = FALSE; + break; + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + if (self->dec_in_port) + gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, TRUE); + if (self->dec_out_port) + gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, TRUE); + g_mutex_lock (&self->drain_lock); + self->draining = FALSE; + g_cond_broadcast (&self->drain_cond); + g_mutex_unlock (&self->drain_lock); + break; + default: + break; + } + + if (ret == GST_STATE_CHANGE_FAILURE) + return ret; + + ret = + GST_ELEMENT_CLASS (gst_omx_audio_dec_parent_class)->change_state + (element, transition); + + if (ret == GST_STATE_CHANGE_FAILURE) + return ret; + + switch (transition) { + case GST_STATE_CHANGE_PLAYING_TO_PAUSED: + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + self->downstream_flow_ret = GST_FLOW_FLUSHING; + self->started = FALSE; + + if (!gst_omx_audio_dec_shutdown (self)) + ret = GST_STATE_CHANGE_FAILURE; + break; + case GST_STATE_CHANGE_READY_TO_NULL: + break; + default: + break; + } + + return ret; +} + +static void +gst_omx_audio_dec_class_init (GstOMXAudioDecClass * klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstAudioDecoderClass *audiodec_class = GST_AUDIO_DECODER_CLASS (klass); + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + klass->cdata.type = GST_OMX_COMPONENT_TYPE_FILTER; + klass->cdata.default_src_template_caps = "audio/x-raw, " + "layout=(string) interleaved, " "format=(string) S16LE"; + + gobject_class->finalize = gst_omx_audio_dec_finalize; + + element_class->change_state = + GST_DEBUG_FUNCPTR (gst_omx_audio_dec_change_state); + + audiodec_class->start = GST_DEBUG_FUNCPTR (gst_omx_audio_dec_start); + audiodec_class->stop = GST_DEBUG_FUNCPTR (gst_omx_audio_dec_stop); + audiodec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_audio_dec_set_format); + audiodec_class->handle_frame = + GST_DEBUG_FUNCPTR (gst_omx_audio_dec_handle_frame); + audiodec_class->open = GST_DEBUG_FUNCPTR (gst_omx_audio_dec_open); + audiodec_class->close = GST_DEBUG_FUNCPTR (gst_omx_audio_dec_close); +} + +static void +gst_omx_audio_dec_init (GstOMXAudioDec * self) +{ + g_mutex_init (&self->drain_lock); + g_cond_init (&self->drain_cond); +} + +void +gst_omx_audio_dec_finalize (GObject * object) +{ + GstOMXAudioDec *self = GST_OMX_AUDIO_DEC (object); + g_mutex_clear (&self->drain_lock); + g_cond_clear (&self->drain_cond); + + G_OBJECT_CLASS (gst_omx_audio_dec_parent_class)->finalize (object); +} + +static gboolean +gst_omx_audio_dec_start (GstAudioDecoder * decoder) +{ + GstOMXAudioDec *self = GST_OMX_AUDIO_DEC (decoder); + + self->last_upstream_ts = 0; + self->eos = FALSE; + self->downstream_flow_ret = GST_FLOW_OK; + + return TRUE; +} + +static gboolean +gst_omx_audio_dec_stop (GstAudioDecoder * decoder) +{ + GstOMXAudioDec *self = GST_OMX_AUDIO_DEC (decoder); + + GST_DEBUG_OBJECT (self, "Stopping Decoder"); + + gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, TRUE); + gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, TRUE); + + gst_pad_stop_task (GST_AUDIO_DECODER_SRC_PAD (decoder)); + + if (gst_omx_component_get_state (self->dec, 0) > OMX_StateIdle) + gst_omx_component_set_state (self->dec, OMX_StateIdle); + + self->downstream_flow_ret = GST_FLOW_FLUSHING; + self->started = FALSE; + self->eos = FALSE; + + g_mutex_lock (&self->drain_lock); + self->draining = FALSE; + g_cond_broadcast (&self->drain_cond); + g_mutex_unlock (&self->drain_lock); + + gst_omx_component_get_state (self->dec, 5 * GST_SECOND); + + if (self->codec_data) + gst_buffer_replace (&self->codec_data, NULL); + + if (self->last_caps) + gst_caps_unref (self->last_caps); + + GST_DEBUG_OBJECT (self, "Stopped decoder"); + + return TRUE; +} + +static GstFlowReturn +gst_omx_audio_dec_drain (GstOMXAudioDec * self, gboolean is_eos) +{ + GstOMXAudioDecClass *klass; + GstOMXBuffer *buf; + GstOMXAcquireBufferReturn acq_ret; + OMX_ERRORTYPE err; + + GST_DEBUG_OBJECT (self, "Draining component"); + klass = GST_OMX_AUDIO_DEC_GET_CLASS (self); + + if (!self->started) { + GST_DEBUG_OBJECT (self, "Component not started yet"); + return GST_FLOW_OK; + } + self->started = FALSE; + + if (self->eos) { + GST_DEBUG_OBJECT (self, "Component is EOS already"); + return GST_FLOW_OK; + } + if (is_eos) + self->eos = TRUE; + + if ((klass->cdata.hacks & GST_OMX_HACK_NO_EMPTY_EOS_BUFFER)) { + GST_WARNING_OBJECT (self, "Component does not support empty EOS buffers"); + return GST_FLOW_OK; + } + + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + + acq_ret = gst_omx_port_acquire_buffer (self->dec_in_port, &buf); + if (acq_ret != GST_OMX_ACQUIRE_BUFFER_OK) { + GST_AUDIO_DECODER_STREAM_LOCK (self); + GST_ERROR_OBJECT (self, "Failed to acquire buffer for draining: %d", + acq_ret); + return GST_FLOW_ERROR; + } + + g_mutex_lock (&self->drain_lock); + self->draining = TRUE; + buf->omx_buf->nFilledLen = 0; + buf->omx_buf->nTimeStamp = + gst_util_uint64_scale (self->last_upstream_ts, OMX_TICKS_PER_SECOND, + GST_SECOND); + buf->omx_buf->nTickCount = 0; + buf->omx_buf->nFlags |= OMX_BUFFERFLAG_EOS; + err = gst_omx_port_release_buffer (self->dec_in_port, buf); + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, "Failed to drain component: %s (0x%08x)", + gst_omx_error_to_string (err), err); + GST_AUDIO_DECODER_STREAM_LOCK (self); + return GST_FLOW_ERROR; + } + + GST_DEBUG_OBJECT (self, "Waiting until component is drained"); + + if (G_UNLIKELY (self->dec->hacks & GST_OMX_HACK_DRAIN_MAY_NOT_RETURN)) { + gint64 wait_until = g_get_monotonic_time () + G_TIME_SPAN_SECOND / 2; + + if (!g_cond_wait_until (&self->drain_cond, &self->drain_lock, wait_until)) + GST_WARNING_OBJECT (self, "Drain timed out"); + else + GST_DEBUG_OBJECT (self, "Drained component"); + + } else { + g_cond_wait (&self->drain_cond, &self->drain_lock); + GST_DEBUG_OBJECT (self, "Drained component"); + } + + g_mutex_unlock (&self->drain_lock); + GST_AUDIO_DECODER_STREAM_LOCK (self); + + self->started = FALSE; + + return GST_FLOW_OK; +} + +static OMX_ERRORTYPE +gst_omx_audio_dec_set_output_format (GstOMXAudioDec * self) +{ + gint width, i; + gint endianess; + gboolean signed_data; + GstOMXPort *port; + GstAudioInfo info; + OMX_AUDIO_PARAM_PCMMODETYPE pcm_mode; + GstAudioFormat format; + GstAudioChannelPosition *position = NULL; + OMX_ERRORTYPE err = OMX_ErrorNone; + + port = self->dec_out_port; + + GST_AUDIO_DECODER_STREAM_LOCK (self); + + GST_OMX_INIT_STRUCT (&pcm_mode); + pcm_mode.nPortIndex = port->index; + + err = gst_omx_component_get_parameter (self->dec, OMX_IndexParamAudioPcm, + &pcm_mode); + + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, + "Failed to get PCM parameters from component: %s (0x%08x)", + gst_omx_error_to_string (err), err); + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + goto done; + } + + self->channel = pcm_mode.nChannels; + self->rate = pcm_mode.nSamplingRate; + width = pcm_mode.nBitPerSample; + endianess = pcm_mode.eEndian & OMX_EndianBig ? G_BIG_ENDIAN : G_LITTLE_ENDIAN; + signed_data = pcm_mode.eNumData == OMX_NumericalDataSigned ? TRUE : FALSE; + + position = g_new0 (GstAudioChannelPosition, self->channel); + + for (i = 0; i < self->channel; i++) { + switch (pcm_mode.eChannelMapping[i]) { + + case OMX_AUDIO_ChannelNone: + position[i] = GST_AUDIO_CHANNEL_POSITION_NONE; + break; + case OMX_AUDIO_ChannelLF: + position[i] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT; + break; + case OMX_AUDIO_ChannelRF: + position[i] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT; + break; + case OMX_AUDIO_ChannelCF: + position[i] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER; + break; + case OMX_AUDIO_ChannelLS: + position[i] = GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT; + break; + case OMX_AUDIO_ChannelRS: + position[i] = GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT; + break; + case OMX_AUDIO_ChannelLFE: + position[i] = GST_AUDIO_CHANNEL_POSITION_LFE1; + break; + case OMX_AUDIO_ChannelCS: + position[i] = GST_AUDIO_CHANNEL_POSITION_REAR_CENTER; + break; + case OMX_AUDIO_ChannelLR: + position[i] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT; + break; + case OMX_AUDIO_ChannelRR: + position[i] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT; + break; + default: + break; + } + + } + + format = + gst_audio_format_build_integer (signed_data, endianess, width, width); + + gst_audio_info_set_format (&info, format, self->rate, self->channel, + position); + gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (self), &info); + + if (position) + g_free (position); + + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + +done: + return err; +} + +static OMX_ERRORTYPE +gst_omx_audio_dec_reconfigure_output_port (GstOMXAudioDec * self) +{ + + GstOMXPort *port; + OMX_ERRORTYPE err = OMX_ErrorNone; + + port = self->dec_out_port; + + err = gst_omx_audio_dec_set_output_format (self); + if (err != OMX_ErrorNone) + goto done; + + if (!gst_omx_port_is_enabled (port)) { + err = gst_omx_port_set_enabled (port, TRUE); + if (err != OMX_ErrorNone) { + GST_INFO_OBJECT (self, + "Failed to enable port: %s (0x%08x)", + gst_omx_error_to_string (err), err); + goto done; + } + } + + err = gst_omx_port_allocate_buffers (port); + if (err != OMX_ErrorNone) + goto done; + + err = gst_omx_port_wait_enabled (port, 5 * GST_SECOND); + if (err != OMX_ErrorNone) + goto done; + + err = gst_omx_port_populate (port); + if (err != OMX_ErrorNone) + goto done; + + err = gst_omx_port_mark_reconfigured (port); + if (err != OMX_ErrorNone) + goto done; + +done: + return err; +} + +static void +gst_omx_audio_dec_loop (GstOMXAudioDec * self) +{ + GstOMXPort *port; + GstOMXBuffer *buf = NULL; + GstFlowReturn flow_ret = GST_FLOW_OK; + GstOMXAcquireBufferReturn acq_return; + OMX_ERRORTYPE err; + + port = self->dec_out_port; + acq_return = gst_omx_port_acquire_buffer (port, &buf); + if (acq_return == GST_OMX_ACQUIRE_BUFFER_ERROR) { + goto component_error; + } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_FLUSHING) { + goto flushing; + } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_EOS) { + goto eos; + } + + if (!gst_pad_has_current_caps (GST_AUDIO_DECODER_SRC_PAD (self)) || + acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) { + + GST_DEBUG_OBJECT (self, "Port settings have changed, updating caps"); + + /* Reallocate all buffers */ + if (acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE + && gst_omx_port_is_enabled (port)) { + err = gst_omx_port_set_enabled (port, FALSE); + if (err != OMX_ErrorNone) + goto reconfigure_error; + err = gst_omx_port_wait_buffers_released (port, 5 * GST_SECOND); + if (err != OMX_ErrorNone) + goto reconfigure_error; + err = gst_omx_port_deallocate_buffers (port); + if (err != OMX_ErrorNone) + goto reconfigure_error; + err = gst_omx_port_wait_enabled (port, 1 * GST_SECOND); + if (err != OMX_ErrorNone) + goto reconfigure_error; + } + + if (acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) { + err = gst_omx_audio_dec_reconfigure_output_port (self); + if (err != OMX_ErrorNone) + goto reconfigure_error; + } else { + err = gst_omx_audio_dec_set_output_format (self); + if (err != OMX_ErrorNone) + goto component_error; + } + + /* Now get a buffer */ + if (acq_return != GST_OMX_ACQUIRE_BUFFER_OK) { + return; + } + } + + g_assert (acq_return == GST_OMX_ACQUIRE_BUFFER_OK); + + if (gst_omx_port_is_flushing (port)) { + GST_DEBUG_OBJECT (self, "Flushing"); + gst_omx_port_release_buffer (port, buf); + goto flushing; + } + + GST_DEBUG_OBJECT (self, "Handling buffer: 0x%08x %" G_GUINT64_FORMAT, + (guint) buf->omx_buf->nFlags, (guint64) buf->omx_buf->nTimeStamp); + + GST_AUDIO_DECODER_STREAM_LOCK (self); + + if (buf->omx_buf->nFilledLen > 0) { + GstBuffer *outbuf; + GstMapInfo map = GST_MAP_INFO_INIT; + + GST_DEBUG_OBJECT (self, "Handling output data"); + + outbuf = + gst_audio_decoder_allocate_output_buffer (GST_AUDIO_DECODER (self), + buf->omx_buf->nFilledLen); + + gst_buffer_map (outbuf, &map, GST_MAP_WRITE); + + memcpy (map.data, + buf->omx_buf->pBuffer + buf->omx_buf->nOffset, + buf->omx_buf->nFilledLen); + gst_buffer_unmap (outbuf, &map); + + GST_BUFFER_TIMESTAMP (outbuf) = + gst_util_uint64_scale (buf->omx_buf->nTimeStamp, GST_SECOND, + OMX_TICKS_PER_SECOND); + if (buf->omx_buf->nTickCount != 0) + GST_BUFFER_DURATION (outbuf) = + gst_util_uint64_scale (buf->omx_buf->nTickCount, GST_SECOND, + OMX_TICKS_PER_SECOND); + + flow_ret = + gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (self), outbuf, 1); + + GST_DEBUG_OBJECT (self, "Finished frame: %s", gst_flow_get_name (flow_ret)); + } + + if (buf) { + err = gst_omx_port_release_buffer (port, buf); + if (err != OMX_ErrorNone) + goto release_error; + } + + self->downstream_flow_ret = flow_ret; + + if (flow_ret != GST_FLOW_OK) + goto flow_error; + + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + + return; + +component_error: + { + GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), + ("OpenMAX component in error state %s (0x%08x)", + gst_omx_component_get_last_error_string (self->dec), + gst_omx_component_get_last_error (self->dec))); + gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ()); + gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); + self->downstream_flow_ret = GST_FLOW_ERROR; + self->started = FALSE; + return; + } + +flushing: + { + GST_DEBUG_OBJECT (self, "Flushing -- stopping task"); + gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); + self->downstream_flow_ret = GST_FLOW_FLUSHING; + self->started = FALSE; + return; + } + +eos: + { + g_mutex_lock (&self->drain_lock); + if (self->draining) { + GST_DEBUG_OBJECT (self, "Drained"); + self->draining = FALSE; + g_cond_broadcast (&self->drain_cond); + flow_ret = GST_FLOW_OK; + gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); + } else { + GST_DEBUG_OBJECT (self, "Component signalled EOS"); + flow_ret = GST_FLOW_EOS; + } + g_mutex_unlock (&self->drain_lock); + + GST_AUDIO_DECODER_STREAM_LOCK (self); + self->downstream_flow_ret = flow_ret; + + /* Here we fallback and pause the task for the EOS case */ + if (flow_ret != GST_FLOW_OK) + goto flow_error; + + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + + return; + } + +flow_error: + { + if (flow_ret == GST_FLOW_EOS) { + GST_DEBUG_OBJECT (self, "EOS"); + + gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), + gst_event_new_eos ()); + gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); + } else if (flow_ret == GST_FLOW_NOT_LINKED || flow_ret < GST_FLOW_EOS) { + GST_ELEMENT_ERROR (self, STREAM, FAILED, + ("Internal data stream error."), ("stream stopped, reason %s", + gst_flow_get_name (flow_ret))); + + gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), + gst_event_new_eos ()); + gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); + } + self->started = FALSE; + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + return; + } + +reconfigure_error: + { + GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL), + ("Unable to reconfigure output port")); + gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ()); + gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); + self->downstream_flow_ret = GST_FLOW_ERROR; + self->started = FALSE; + return; + } +release_error: + { + GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL), + ("Failed to relase output buffer to component: %s (0x%08x)", + gst_omx_error_to_string (err), err)); + gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ()); + gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); + self->downstream_flow_ret = GST_FLOW_ERROR; + self->started = FALSE; + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + return; + } +} + +static gboolean +gst_omx_audio_dec_set_format (GstAudioDecoder * decoder, GstCaps * caps) +{ + GstOMXAudioDec *self = GST_OMX_AUDIO_DEC (decoder); + GstOMXAudioDecClass *klass = GST_OMX_AUDIO_DEC_GET_CLASS (decoder); + gboolean needs_disable = FALSE; + GstStructure *structure; + const GValue *codec_data; + + GST_DEBUG_OBJECT (self, "Setting new caps %" GST_PTR_FORMAT, caps); + + if (self->last_caps && gst_caps_is_equal (self->last_caps, caps)) { + GST_DEBUG_OBJECT (self, "same caps"); + return TRUE; + } + + needs_disable = gst_omx_component_get_state (self->dec, + GST_CLOCK_TIME_NONE) != OMX_StateLoaded; + + if (needs_disable) { + + GST_DEBUG_OBJECT (self, "Need to disable and drain Decoder"); + + gst_omx_audio_dec_drain (self, FALSE); + gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, TRUE); + + /* Wait until the srcpad loop is finished, + * unlock GST_AUDIO_DECODER_STREAM_LOCK to prevent deadlocks + * caused by using this lock from inside the loop function */ + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + gst_pad_stop_task (GST_AUDIO_DECODER_SRC_PAD (decoder)); + GST_AUDIO_DECODER_STREAM_LOCK (self); + + if (gst_omx_port_set_enabled (self->dec_in_port, FALSE) != OMX_ErrorNone) + return FALSE; + if (gst_omx_port_set_enabled (self->dec_out_port, FALSE) != OMX_ErrorNone) + return FALSE; + if (gst_omx_port_wait_buffers_released (self->dec_in_port, + 5 * GST_SECOND) != OMX_ErrorNone) + return FALSE; + if (gst_omx_port_wait_buffers_released (self->dec_out_port, + 1 * GST_SECOND) != OMX_ErrorNone) + return FALSE; + if (gst_omx_port_deallocate_buffers (self->dec_in_port) != OMX_ErrorNone) + return FALSE; + if (gst_omx_port_deallocate_buffers (self->dec_out_port) != OMX_ErrorNone) + return FALSE; + if (gst_omx_port_wait_enabled (self->dec_in_port, + 1 * GST_SECOND) != OMX_ErrorNone) + return FALSE; + if (gst_omx_port_wait_enabled (self->dec_out_port, + 1 * GST_SECOND) != OMX_ErrorNone) + return FALSE; + + GST_DEBUG_OBJECT (self, "Decoder drained and disabled"); + } + + if (self->codec_data) + gst_buffer_replace (&self->codec_data, NULL); + + structure = gst_caps_get_structure (caps, 0); + codec_data = gst_structure_get_value (structure, "codec_data"); + + if (codec_data && G_VALUE_TYPE (codec_data) == GST_TYPE_BUFFER) + self->codec_data = GST_BUFFER (g_value_dup_boxed (codec_data)); + + if (!gst_structure_get_int (structure, "rate", &self->rate)) { + GST_WARNING_OBJECT (self, "rate is empty"); + self->rate = 44100; + } + + if (!gst_structure_get_int (structure, "channels", &self->channel)) { + GST_WARNING_OBJECT (self, "channel is not set"); + self->channel = 2; + } + + if (klass->set_format) { + if (!klass->set_format (self, self->dec_in_port, caps)) { + GST_ERROR_OBJECT (self, "Subclass failed to set the new format"); + return FALSE; + } + } + + GST_DEBUG_OBJECT (self, "Enabling component"); + + if (needs_disable) { + if (gst_omx_port_set_enabled (self->dec_in_port, TRUE) != OMX_ErrorNone) + return FALSE; + if (gst_omx_port_allocate_buffers (self->dec_in_port) != OMX_ErrorNone) + return FALSE; + if (gst_omx_port_wait_enabled (self->dec_in_port, + 5 * GST_SECOND) != OMX_ErrorNone) + return FALSE; + if (gst_omx_port_mark_reconfigured (self->dec_in_port) != OMX_ErrorNone) + return FALSE; + + } else { + /* Disable output port */ + if (gst_omx_port_set_enabled (self->dec_out_port, FALSE) != OMX_ErrorNone) + return FALSE; + + if (gst_omx_port_wait_enabled (self->dec_out_port, + 1 * GST_SECOND) != OMX_ErrorNone) + return FALSE; + + if (gst_omx_component_set_state (self->dec, OMX_StateIdle) != OMX_ErrorNone) + return FALSE; + + /* Need to allocate buffers to reach Idle state */ + if (gst_omx_port_allocate_buffers (self->dec_in_port) != OMX_ErrorNone) + return FALSE; + + if (gst_omx_component_get_state (self->dec, + GST_CLOCK_TIME_NONE) != OMX_StateIdle) + return FALSE; + + if (gst_omx_component_set_state (self->dec, + OMX_StateExecuting) != OMX_ErrorNone) + return FALSE; + + if (gst_omx_component_get_state (self->dec, + GST_CLOCK_TIME_NONE) != OMX_StateExecuting) + return FALSE; + } + +#ifdef USE_OMX_TARGET_TEGRA + /* PortSetting change event comes only if output port has buffers allocated */ + if (gst_omx_audio_dec_reconfigure_output_port (self) != OMX_ErrorNone) + return FALSE; +#endif + + /* Unset flushing to allow ports to accept data again */ + gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, FALSE); + gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, FALSE); + + if (gst_omx_component_get_last_error (self->dec) != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, "Component in error state: %s (0x%08x)", + gst_omx_component_get_last_error_string (self->dec), + gst_omx_component_get_last_error (self->dec)); + return FALSE; + } + + /* Start the srcpad loop again */ + GST_DEBUG_OBJECT (self, "Starting task again"); + + self->downstream_flow_ret = GST_FLOW_OK; + gst_pad_start_task (GST_AUDIO_DECODER_SRC_PAD (self), + (GstTaskFunction) gst_omx_audio_dec_loop, decoder, NULL); + + return TRUE; +} + +static GstFlowReturn +gst_omx_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * buffer) +{ + GstOMXAcquireBufferReturn acq_ret = GST_OMX_ACQUIRE_BUFFER_ERROR; + GstOMXAudioDec *self; + GstOMXPort *port; + GstOMXBuffer *buf; + GstBuffer *codec_data = NULL; + guint offset = 0, size; + GstClockTime timestamp, duration; + OMX_ERRORTYPE err; + + self = GST_OMX_AUDIO_DEC (decoder); + + GST_DEBUG_OBJECT (self, "Handling frame"); + + if (self->eos) { + GST_WARNING_OBJECT (self, "Got frame after EOS"); + return GST_FLOW_EOS; + } + + if (buffer == NULL) + return GST_FLOW_OK; + + timestamp = GST_BUFFER_TIMESTAMP (buffer); + duration = GST_BUFFER_DURATION (buffer); + + if (self->downstream_flow_ret != GST_FLOW_OK) { + return self->downstream_flow_ret; + } + + port = self->dec_in_port; + + size = gst_buffer_get_size (buffer); + while (offset < size) { + /* Make sure to release the base class stream lock, otherwise + * _loop() can't call _finish_frame() and we might block forever + * because no input buffers are released */ + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + acq_ret = gst_omx_port_acquire_buffer (port, &buf); + + if (acq_ret == GST_OMX_ACQUIRE_BUFFER_ERROR) { + GST_AUDIO_DECODER_STREAM_LOCK (self); + goto component_error; + } else if (acq_ret == GST_OMX_ACQUIRE_BUFFER_FLUSHING) { + GST_AUDIO_DECODER_STREAM_LOCK (self); + goto flushing; + } else if (acq_ret == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) { + /* Reallocate all buffers */ + err = gst_omx_port_set_enabled (port, FALSE); + if (err != OMX_ErrorNone) { + GST_AUDIO_DECODER_STREAM_LOCK (self); + goto reconfigure_error; + } + + err = gst_omx_port_wait_buffers_released (port, 5 * GST_SECOND); + if (err != OMX_ErrorNone) { + GST_AUDIO_DECODER_STREAM_LOCK (self); + goto reconfigure_error; + } + + err = gst_omx_port_deallocate_buffers (port); + if (err != OMX_ErrorNone) { + GST_AUDIO_DECODER_STREAM_LOCK (self); + goto reconfigure_error; + } + + err = gst_omx_port_wait_enabled (port, 1 * GST_SECOND); + if (err != OMX_ErrorNone) { + GST_AUDIO_DECODER_STREAM_LOCK (self); + goto reconfigure_error; + } + + err = gst_omx_port_set_enabled (port, TRUE); + if (err != OMX_ErrorNone) { + GST_AUDIO_DECODER_STREAM_LOCK (self); + goto reconfigure_error; + } + + err = gst_omx_port_allocate_buffers (port); + if (err != OMX_ErrorNone) { + GST_AUDIO_DECODER_STREAM_LOCK (self); + goto reconfigure_error; + } + + err = gst_omx_port_wait_enabled (port, 5 * GST_SECOND); + if (err != OMX_ErrorNone) { + GST_AUDIO_DECODER_STREAM_LOCK (self); + goto reconfigure_error; + } + + err = gst_omx_port_mark_reconfigured (port); + if (err != OMX_ErrorNone) { + GST_AUDIO_DECODER_STREAM_LOCK (self); + goto reconfigure_error; + } + + /* Now get a new buffer and fill it */ + GST_AUDIO_DECODER_STREAM_LOCK (self); + continue; + } + + GST_AUDIO_DECODER_STREAM_LOCK (self); + + g_assert (acq_ret == GST_OMX_ACQUIRE_BUFFER_OK && buf != NULL); + + if (buf->omx_buf->nAllocLen - buf->omx_buf->nOffset <= 0) { + gst_omx_port_release_buffer (port, buf); + goto full_buffer; + } + + if (self->downstream_flow_ret != GST_FLOW_OK) { + gst_omx_port_release_buffer (port, buf); + return self->downstream_flow_ret; + } + + if (self->codec_data) { + GST_DEBUG_OBJECT (self, "Passing codec data to the component"); + + codec_data = self->codec_data; + + if (buf->omx_buf->nAllocLen - buf->omx_buf->nOffset < + gst_buffer_get_size (codec_data)) { + gst_omx_port_release_buffer (port, buf); + goto too_large_codec_data; + } + + buf->omx_buf->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; + buf->omx_buf->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + buf->omx_buf->nFilledLen = gst_buffer_get_size (codec_data);; + gst_buffer_extract (codec_data, 0, + buf->omx_buf->pBuffer + buf->omx_buf->nOffset, + buf->omx_buf->nFilledLen); + + if (GST_CLOCK_TIME_IS_VALID (timestamp)) + buf->omx_buf->nTimeStamp = + gst_util_uint64_scale (timestamp, OMX_TICKS_PER_SECOND, GST_SECOND); + else + buf->omx_buf->nTimeStamp = 0; + buf->omx_buf->nTickCount = 0; + + self->started = TRUE; + err = gst_omx_port_release_buffer (port, buf); + gst_buffer_replace (&self->codec_data, NULL); + + if (err != OMX_ErrorNone) + goto release_error; + /* Acquire new buffer for the actual frame */ + continue; + } + + /* Now handle the frame */ + GST_DEBUG_OBJECT (self, "Passing frame offset %d to the component", offset); + + /* Copy the buffer content in chunks of size as requested + * by the port */ + buf->omx_buf->nFilledLen = + MIN (size - offset, buf->omx_buf->nAllocLen - buf->omx_buf->nOffset); + gst_buffer_extract (buffer, offset, + buf->omx_buf->pBuffer + buf->omx_buf->nOffset, + buf->omx_buf->nFilledLen); + + if (timestamp != GST_CLOCK_TIME_NONE) { + buf->omx_buf->nTimeStamp = + gst_util_uint64_scale (timestamp, OMX_TICKS_PER_SECOND, GST_SECOND); + self->last_upstream_ts = timestamp; + } else { + buf->omx_buf->nTimeStamp = 0; + } + + if (duration != GST_CLOCK_TIME_NONE && offset == 0) { + buf->omx_buf->nTickCount = + gst_util_uint64_scale (buf->omx_buf->nFilledLen, duration, size); + self->last_upstream_ts += duration; + } else { + buf->omx_buf->nTickCount = 0; + } + + offset += buf->omx_buf->nFilledLen; + + if (offset == size) + buf->omx_buf->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + + self->started = TRUE; + err = gst_omx_port_release_buffer (port, buf); + if (err != OMX_ErrorNone) + goto release_error; + } + + GST_DEBUG_OBJECT (self, "Passed frame to component"); + + return self->downstream_flow_ret; + +full_buffer: + { + GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), + ("Got OpenMAX buffer with no free space (%p, %u/%u)", buf, + (guint) buf->omx_buf->nOffset, (guint) buf->omx_buf->nAllocLen)); + return GST_FLOW_ERROR; + } + +too_large_codec_data: + { + GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL), + ("codec_data larger than supported by OpenMAX port (%zu > %u)", + gst_buffer_get_size (codec_data), + (guint) self->dec_in_port->port_def.nBufferSize)); + return GST_FLOW_ERROR; + } + +component_error: + { + GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), + ("OpenMAX component in error state %s (0x%08x)", + gst_omx_component_get_last_error_string (self->dec), + gst_omx_component_get_last_error (self->dec))); + return GST_FLOW_ERROR; + } + +flushing: + { + GST_DEBUG_OBJECT (self, "Flushing -- returning FLUSHING"); + return GST_FLOW_FLUSHING; + } +reconfigure_error: + { + GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL), + ("Unable to reconfigure input port")); + return GST_FLOW_ERROR; + } +release_error: + { + GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL), + ("Failed to relase input buffer to component: %s (0x%08x)", + gst_omx_error_to_string (err), err)); + return GST_FLOW_ERROR; + } +} + +static gboolean +gst_omx_audio_dec_open (GstAudioDecoder * decoder) +{ + GstOMXAudioDec *self = GST_OMX_AUDIO_DEC (decoder); + GstOMXAudioDecClass *klass = GST_OMX_AUDIO_DEC_GET_CLASS (self); + gint in_port_index, out_port_index; + + GST_DEBUG_OBJECT (self, "opening decoder"); + + self->dec = + gst_omx_component_new (GST_OBJECT_CAST (self), klass->cdata.core_name, + klass->cdata.component_name, klass->cdata.component_role, + klass->cdata.hacks); + + self->started = FALSE; + + if (!self->dec) + return FALSE; + + if (gst_omx_component_get_state (self->dec, + GST_CLOCK_TIME_NONE) != OMX_StateLoaded) + return FALSE; + + in_port_index = klass->cdata.in_port_index; + out_port_index = klass->cdata.out_port_index; + + if (in_port_index == -1 || out_port_index == -1) { + OMX_PORT_PARAM_TYPE param; + OMX_ERRORTYPE err; + + GST_OMX_INIT_STRUCT (¶m); + + err = + gst_omx_component_get_parameter (self->dec, OMX_IndexParamAudioInit, + ¶m); + if (err != OMX_ErrorNone) { + GST_WARNING_OBJECT (self, "Couldn't get port information: %s (0x%08x)", + gst_omx_error_to_string (err), err); + /* Fallback */ + in_port_index = 0; + out_port_index = 1; + } else { + GST_DEBUG_OBJECT (self, "Detected %u ports, starting at %u", + (guint) param.nPorts, (guint) param.nStartPortNumber); + in_port_index = param.nStartPortNumber + 0; + out_port_index = param.nStartPortNumber + 1; + } + } + + self->dec_in_port = gst_omx_component_add_port (self->dec, in_port_index); + self->dec_out_port = gst_omx_component_add_port (self->dec, out_port_index); + + if (!self->dec_in_port || !self->dec_out_port) + return FALSE; + + GST_DEBUG_OBJECT (self, "Opened decoder"); + + return TRUE; +} + +static gboolean +gst_omx_audio_dec_shutdown (GstOMXAudioDec * self) +{ + OMX_STATETYPE state; + + GST_DEBUG_OBJECT (self, "Shutting down decoder"); + + state = gst_omx_component_get_state (self->dec, 0); + if (state > OMX_StateLoaded || state == OMX_StateInvalid) { + if (state > OMX_StateIdle) { + gst_omx_component_set_state (self->dec, OMX_StateIdle); + gst_omx_component_get_state (self->dec, 5 * GST_SECOND); + } + gst_omx_component_set_state (self->dec, OMX_StateLoaded); + gst_omx_port_deallocate_buffers (self->dec_in_port); + gst_omx_port_deallocate_buffers (self->dec_out_port); + + if (state > OMX_StateLoaded) + gst_omx_component_get_state (self->dec, 5 * GST_SECOND); + } + + return TRUE; +} + +static gboolean +gst_omx_audio_dec_close (GstAudioDecoder * decoder) +{ + GstOMXAudioDec *self = GST_OMX_AUDIO_DEC (decoder); + + GST_DEBUG_OBJECT (self, "closing decoder"); + + if (!gst_omx_audio_dec_shutdown (self)) + return FALSE; + + self->dec_in_port = NULL; + self->dec_out_port = NULL; + if (self->dec) + gst_omx_component_free (self->dec); + self->dec = NULL; + + + self->started = FALSE; + + GST_DEBUG_OBJECT (self, "Closed decoder"); + + return TRUE; +} diff --git a/omx/gstomxaudiodec.h b/omx/gstomxaudiodec.h new file mode 100644 index 0000000..16d57d9 --- /dev/null +++ b/omx/gstomxaudiodec.h @@ -0,0 +1,73 @@ +/* GStreamer + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _GST_OMX_AUDIO_DEC_H_ +#define _GST_OMX_AUDIO_DEC_H_ + +#include <gst/audio/gstaudiodecoder.h> +#include "gstomx.h" + +G_BEGIN_DECLS +#define GST_TYPE_OMX_AUDIO_DEC (gst_omx_audio_dec_get_type()) +#define GST_OMX_AUDIO_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_AUDIO_DEC,GstOMXAudioDec)) +#define GST_OMX_AUDIO_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_AUDIO_DEC,GstOMXAudioDecClass)) +#define GST_OMX_AUDIO_DEC_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_AUDIO_DEC,GstOMXAudioDecClass)) +#define GST_IS_OMX_AUDIO_DEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_AUDIO_DEC)) +#define GST_IS_OMX_AUDIO_DEC_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_AUDIO_DEC)) +typedef struct _GstOMXAudioDec GstOMXAudioDec; +typedef struct _GstOMXAudioDecClass GstOMXAudioDecClass; + +struct _GstOMXAudioDec +{ + GstAudioDecoder parent; + + GstOMXComponent *dec; + GstOMXPort *dec_in_port, *dec_out_port; + + GstBuffer *codec_data; + GstCaps *last_caps; + gint rate, channel; + + /* Draining state */ + GMutex drain_lock; + GCond drain_cond; + /* TRUE if EOS buffers shouldn't be forwarded */ + gboolean draining; + + gboolean started; + gboolean eos; + GstClockTime last_upstream_ts; + GstFlowReturn downstream_flow_ret; + +}; + +struct _GstOMXAudioDecClass +{ + GstAudioDecoderClass parent_class; + GstOMXClassData cdata; + + gboolean (*set_format) (GstOMXAudioDec * self, GstOMXPort * port, + GstCaps * state); +}; + +GType gst_omx_audio_dec_get_type (void); + +G_END_DECLS +#endif diff --git a/omx/gstomxaudioenc.h b/omx/gstomxaudioenc.h index f7527be..c0296a4 100644 --- a/omx/gstomxaudioenc.h +++ b/omx/gstomxaudioenc.h @@ -1,6 +1,7 @@ -/* +/* * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. - * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. + * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,7 +29,6 @@ #include "gstomx.h" G_BEGIN_DECLS - #define GST_TYPE_OMX_AUDIO_ENC \ (gst_omx_audio_enc_get_type()) #define GST_OMX_AUDIO_ENC(obj) \ @@ -41,7 +41,6 @@ G_BEGIN_DECLS (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_AUDIO_ENC)) #define GST_IS_OMX_AUDIO_ENC_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_AUDIO_ENC)) - typedef struct _GstOMXAudioEnc GstOMXAudioEnc; typedef struct _GstOMXAudioEncClass GstOMXAudioEncClass; @@ -78,13 +77,15 @@ struct _GstOMXAudioEncClass GstOMXClassData cdata; - gboolean (*set_format) (GstOMXAudioEnc * self, GstOMXPort * port, GstAudioInfo * info); - GstCaps *(*get_caps) (GstOMXAudioEnc * self, GstOMXPort * port, GstAudioInfo * info); - guint (*get_num_samples) (GstOMXAudioEnc * self, GstOMXPort * port, GstAudioInfo * info, GstOMXBuffer * buffer); + gboolean (*set_format) (GstOMXAudioEnc * self, GstOMXPort * port, + GstAudioInfo * info); + GstCaps *(*get_caps) (GstOMXAudioEnc * self, GstOMXPort * port, + GstAudioInfo * info); + guint (*get_num_samples) (GstOMXAudioEnc * self, GstOMXPort * port, + GstAudioInfo * info, GstOMXBuffer * buffer); }; GType gst_omx_audio_enc_get_type (void); G_END_DECLS - #endif /* __GST_OMX_AUDIO_ENC_H__ */ diff --git a/omx/gstomxh263dec.c b/omx/gstomxh263dec.c index 134995b..84d16ca 100644 --- a/omx/gstomxh263dec.c +++ b/omx/gstomxh263dec.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. + * Copyright (c) 2013 - 2014, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -60,8 +61,7 @@ gst_omx_h263_dec_class_init (GstOMXH263DecClass * klass) videodec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_h263_dec_set_format); videodec_class->cdata.default_sink_template_caps = "video/x-h263, " - "variant=(string) itu, " - "parsed=(boolean) true, " "width=(int) [1,MAX], " "height=(int) [1,MAX]"; + "variant=(string) itu, " "width=(int) [1,MAX], " "height=(int) [1,MAX]"; gst_element_class_set_static_metadata (element_class, "OpenMAX H.263 Video Decoder", @@ -75,6 +75,17 @@ gst_omx_h263_dec_class_init (GstOMXH263DecClass * klass) static void gst_omx_h263_dec_init (GstOMXH263Dec * self) { + GstOMXVideoDec *dec = GST_OMX_VIDEO_DEC (self); + +#ifdef USE_OMX_TARGET_TEGRA + /* "use-omxdec-res" property of decoders is FALSE by default, i.e., resolution obtained + * from upstream component is used. In case of H263, h263parse sets incorrect resolution on src + * caps. Hence, use-omxdec-res property is set to TRUE to use resolution from decoder and not + * resolution obtained from upstream element. + * This is a work-around and the actual fix should go in open-source h263parse. + */ + dec->use_omxdec_res = TRUE; +#endif } static gboolean diff --git a/omx/gstomxh263dec.h b/omx/gstomxh263dec.h index aa24c2f..ca885c8 100644 --- a/omx/gstomxh263dec.h +++ b/omx/gstomxh263dec.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. + * Copyright (c) 2013 - 2014, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +26,6 @@ #include "gstomxvideodec.h" G_BEGIN_DECLS - #define GST_TYPE_OMX_H263_DEC \ (gst_omx_h263_dec_get_type()) #define GST_OMX_H263_DEC(obj) \ @@ -38,7 +38,6 @@ G_BEGIN_DECLS (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_H263_DEC)) #define GST_IS_OMX_H263_DEC_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_H263_DEC)) - typedef struct _GstOMXH263Dec GstOMXH263Dec; typedef struct _GstOMXH263DecClass GstOMXH263DecClass; @@ -55,6 +54,4 @@ struct _GstOMXH263DecClass GType gst_omx_h263_dec_get_type (void); G_END_DECLS - #endif /* __GST_OMX_H263_DEC_H__ */ - diff --git a/omx/gstomxh263enc.h b/omx/gstomxh263enc.h index 0dbd0de..9e85b4b 100644 --- a/omx/gstomxh263enc.h +++ b/omx/gstomxh263enc.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +26,6 @@ #include "gstomxvideoenc.h" G_BEGIN_DECLS - #define GST_TYPE_OMX_H263_ENC \ (gst_omx_h263_enc_get_type()) #define GST_OMX_H263_ENC(obj) \ @@ -38,7 +38,6 @@ G_BEGIN_DECLS (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; @@ -55,6 +54,4 @@ struct _GstOMXH263EncClass GType gst_omx_h263_enc_get_type (void); G_END_DECLS - #endif /* __GST_OMX_H263_ENC_H__ */ - diff --git a/omx/gstomxh264dec.c b/omx/gstomxh264dec.c index 2581889..481addf 100644 --- a/omx/gstomxh264dec.c +++ b/omx/gstomxh264dec.c @@ -2,6 +2,8 @@ * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. * + * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. + * * 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 @@ -77,6 +79,12 @@ gst_omx_h264_dec_class_init (GstOMXH264DecClass * klass) static void gst_omx_h264_dec_init (GstOMXH264Dec * self) { + GstOMXVideoDec *dec = GST_OMX_VIDEO_DEC (self); + +#ifdef USE_OMX_TARGET_TEGRA + dec->disable_dpb = FALSE; + dec->skip_frames = GST_DECODE_ALL; +#endif } static gboolean @@ -86,6 +94,69 @@ gst_omx_h264_dec_is_format_change (GstOMXVideoDec * dec, return FALSE; } +static OMX_ERRORTYPE +gstomx_set_disable_dpb_property (OMX_HANDLETYPE omx_handle) +{ + OMX_INDEXTYPE eIndex; + OMX_ERRORTYPE eError = OMX_ErrorNone; + NVX_PARAM_H264DISABLE_DPB disable_dpb; + GST_OMX_INIT_STRUCT (&disable_dpb); + eError = + OMX_GetExtensionIndex (omx_handle, + (OMX_STRING) "OMX.Nvidia.index.param.h264disabledpb", &eIndex); + if (eError == OMX_ErrorNone) { + disable_dpb.bDisableDPB = OMX_TRUE; + OMX_SetParameter (omx_handle, eIndex, &disable_dpb); + } + return eError; +} + +static OMX_ERRORTYPE +gst_omx_h264_dec_set_skip_frame (OMX_HANDLETYPE omx_handle, + GstVideoSkipFrames skip_frames) +{ + OMX_INDEXTYPE eIndex; + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_CONFIG_BOOLEANTYPE omx_config_skip_frames; + GST_OMX_INIT_STRUCT (&omx_config_skip_frames); + + switch (skip_frames) { + case GST_DECODE_ALL: + { + /* Do nothing. Default case */ + } + break; + case GST_SKIP_NON_REF_FRAMES: + { + /* Skip non-ref frames */ + eError = + OMX_GetExtensionIndex (omx_handle, + (OMX_STRING) NVX_INDEX_SKIP_NONREF_FRAMES, &eIndex); + + if (eError == OMX_ErrorNone) { + omx_config_skip_frames.bEnabled = OMX_TRUE; + eError = OMX_SetConfig (omx_handle, eIndex, &omx_config_skip_frames); + } + } + break; + case GST_DECODE_KEY_FRAMES: + { + /* Decode only key frames */ + eError = + OMX_GetExtensionIndex (omx_handle, + (OMX_STRING) NVX_INDEX_CONFIG_DECODE_IFRAMES, &eIndex); + + if (eError == OMX_ErrorNone) { + omx_config_skip_frames.bEnabled = OMX_TRUE; + eError = OMX_SetConfig (omx_handle, eIndex, &omx_config_skip_frames); + } + } + break; + } + + return eError; +} + static gboolean gst_omx_h264_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port, GstVideoCodecState * state) @@ -95,6 +166,22 @@ gst_omx_h264_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port, gst_omx_port_get_port_definition (port, &port_def); port_def.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; + + if (dec->full_frame_data == TRUE) { + OMX_HANDLETYPE omx_handle = dec->dec->handle; + gst_omx_set_full_frame_data_property (omx_handle); + } + + if (dec->disable_dpb == TRUE) { + OMX_HANDLETYPE omx_handle = dec->dec->handle; + gstomx_set_disable_dpb_property (omx_handle); + } + + if (dec->skip_frames != GST_DECODE_ALL) { + OMX_HANDLETYPE omx_handle = dec->dec->handle; + gst_omx_h264_dec_set_skip_frame (omx_handle, dec->skip_frames); + } + ret = gst_omx_port_update_port_definition (port, &port_def) == OMX_ErrorNone; return ret; diff --git a/omx/gstomxh264dec.h b/omx/gstomxh264dec.h index 4c0ea1f..5855da4 100644 --- a/omx/gstomxh264dec.h +++ b/omx/gstomxh264dec.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +26,6 @@ #include "gstomxvideodec.h" G_BEGIN_DECLS - #define GST_TYPE_OMX_H264_DEC \ (gst_omx_h264_dec_get_type()) #define GST_OMX_H264_DEC(obj) \ @@ -38,7 +38,6 @@ G_BEGIN_DECLS (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_H264_DEC)) #define GST_IS_OMX_H264_DEC_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_H264_DEC)) - typedef struct _GstOMXH264Dec GstOMXH264Dec; typedef struct _GstOMXH264DecClass GstOMXH264DecClass; @@ -55,6 +54,4 @@ struct _GstOMXH264DecClass GType gst_omx_h264_dec_get_type (void); G_END_DECLS - #endif /* __GST_OMX_H264_DEC_H__ */ - diff --git a/omx/gstomxh264enc.c b/omx/gstomxh264enc.c index 109e173..4af175a 100644 --- a/omx/gstomxh264enc.c +++ b/omx/gstomxh264enc.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. + * Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -36,10 +37,15 @@ static GstCaps *gst_omx_h264_enc_get_caps (GstOMXVideoEnc * enc, GstOMXPort * port, GstVideoCodecState * state); static GstFlowReturn gst_omx_h264_enc_handle_output_frame (GstOMXVideoEnc * self, GstOMXPort * port, GstOMXBuffer * buf, GstVideoCodecFrame * frame); +static void gst_omx_h264_enc_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_omx_h264_enc_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec); enum { - PROP_0 + PROP_0, + PROP_INSERT_SPS_PPS }; /* class initialization */ @@ -56,12 +62,16 @@ gst_omx_h264_enc_class_init (GstOMXH264EncClass * klass) { GstElementClass *element_class = GST_ELEMENT_CLASS (klass); GstOMXVideoEncClass *videoenc_class = GST_OMX_VIDEO_ENC_CLASS (klass); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); videoenc_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_h264_enc_set_format); videoenc_class->get_caps = GST_DEBUG_FUNCPTR (gst_omx_h264_enc_get_caps); + gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_omx_h264_enc_set_property); + gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_omx_h264_enc_get_property); videoenc_class->cdata.default_src_template_caps = "video/x-h264, " - "width=(int) [ 16, 4096 ], " "height=(int) [ 16, 4096 ]"; + "width=(int) [ 16, 4096 ], " "height=(int) [ 16, 4096 ], " + "stream-format=(string) { byte-stream, avc }, " "alignment=(string) au "; videoenc_class->handle_output_frame = GST_DEBUG_FUNCPTR (gst_omx_h264_enc_handle_output_frame); @@ -72,13 +82,81 @@ gst_omx_h264_enc_class_init (GstOMXH264EncClass * klass) "Sebastian Dröge <sebastian.droege@collabora.co.uk>"); gst_omx_set_default_role (&videoenc_class->cdata, "video_encoder.avc"); + + g_object_class_install_property (gobject_class, PROP_INSERT_SPS_PPS, + g_param_spec_boolean ("insert-sps-pps", + "Insert H.264 SPS, PPS", + "Insert H.264 SPS, PPS at every IDR frame", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } static void gst_omx_h264_enc_init (GstOMXH264Enc * self) { + self->insert_sps_pps = FALSE; +} + +static OMX_ERRORTYPE +ifi_setup (GstOMXVideoEnc * enc) +{ + GstOMXH264Enc *self = GST_OMX_H264_ENC (enc); + OMX_ERRORTYPE err = OMX_ErrorNone; + + if (enc->iframeinterval != 0xffffffff) { + OMX_VIDEO_CONFIG_AVCINTRAPERIOD oIntraPeriod; + GST_OMX_INIT_STRUCT (&oIntraPeriod); + oIntraPeriod.nPortIndex = enc->enc_out_port->index; + + err = + gst_omx_component_get_config (GST_OMX_VIDEO_ENC (self)->enc, + OMX_IndexConfigVideoAVCIntraPeriod, + &oIntraPeriod); + + if (err == OMX_ErrorNone) { + if (enc->iframeinterval != 0) { + oIntraPeriod.nIDRPeriod = enc->iframeinterval; + oIntraPeriod.nPFrames = enc->iframeinterval - 1; + } + + err = + gst_omx_component_set_config (GST_OMX_VIDEO_ENC (self)->enc, + OMX_IndexConfigVideoAVCIntraPeriod, + &oIntraPeriod); + } + } + return err; } +static OMX_ERRORTYPE +gst_omx_h264_enc_set_insert_sps_pps (GstOMXVideoEnc * enc) +{ + OMX_INDEXTYPE eIndex; + OMX_ERRORTYPE eError = OMX_ErrorNone; + NVX_PARAM_VIDENCPROPERTY oEncodeProp; + GstOMXH264Enc *self = GST_OMX_H264_ENC (enc); + + if (self->insert_sps_pps) { + GST_OMX_INIT_STRUCT (&oEncodeProp); + oEncodeProp.nPortIndex = enc->enc_out_port->index; + + eError = gst_omx_component_get_index (GST_OMX_VIDEO_ENC (self)->enc, + (gpointer) NVX_INDEX_PARAM_VIDEO_ENCODE_PROPERTY, &eIndex); + + if (eError == OMX_ErrorNone) { + eError = + gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc, + eIndex, &oEncodeProp); + if (eError == OMX_ErrorNone) { + oEncodeProp.bInsertSPSPPSAtIDR = self->insert_sps_pps; + + eError = + gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc, eIndex, &oEncodeProp); + } + } + } + return eError; + } + static gboolean gst_omx_h264_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port, GstVideoCodecState * state) @@ -87,8 +165,10 @@ gst_omx_h264_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port, GstCaps *peercaps; OMX_PARAM_PORTDEFINITIONTYPE port_def; OMX_VIDEO_PARAM_PROFILELEVELTYPE param; + OMX_VIDEO_CONFIG_NALSIZE OMXNalSize; OMX_ERRORTYPE err; const gchar *profile_string, *level_string; + const gchar *out_format = NULL; gst_omx_port_get_port_definition (GST_OMX_VIDEO_ENC (self)->enc_out_port, &port_def); @@ -108,7 +188,6 @@ gst_omx_h264_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port, if (err != OMX_ErrorNone) { GST_WARNING_OBJECT (self, "Setting profile/level not supported by component"); - return TRUE; } peercaps = gst_pad_peer_query_caps (GST_VIDEO_ENCODER_SRC_PAD (enc), @@ -123,79 +202,131 @@ gst_omx_h264_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port, } s = gst_caps_get_structure (peercaps, 0); - profile_string = gst_structure_get_string (s, "profile"); - if (profile_string) { - if (g_str_equal (profile_string, "baseline")) { - param.eProfile = OMX_VIDEO_AVCProfileBaseline; - } else if (g_str_equal (profile_string, "main")) { - param.eProfile = OMX_VIDEO_AVCProfileMain; - } else if (g_str_equal (profile_string, "extended")) { - param.eProfile = OMX_VIDEO_AVCProfileExtended; - } else if (g_str_equal (profile_string, "high")) { - param.eProfile = OMX_VIDEO_AVCProfileHigh; - } else if (g_str_equal (profile_string, "high-10")) { - param.eProfile = OMX_VIDEO_AVCProfileHigh10; - } else if (g_str_equal (profile_string, "high-4:2:2")) { - param.eProfile = OMX_VIDEO_AVCProfileHigh422; - } else if (g_str_equal (profile_string, "high-4:4:4")) { - param.eProfile = OMX_VIDEO_AVCProfileHigh444; - } else { - goto unsupported_profile; + + if (err == OMX_ErrorNone) { + profile_string = gst_structure_get_string (s, "profile"); + if (profile_string) { + if (g_str_equal (profile_string, "baseline")) { + param.eProfile = OMX_VIDEO_AVCProfileBaseline; + } else if (g_str_equal (profile_string, "main")) { + param.eProfile = OMX_VIDEO_AVCProfileMain; + } else if (g_str_equal (profile_string, "extended")) { + param.eProfile = OMX_VIDEO_AVCProfileExtended; + } else if (g_str_equal (profile_string, "high")) { + param.eProfile = OMX_VIDEO_AVCProfileHigh; + } else if (g_str_equal (profile_string, "high-10")) { + param.eProfile = OMX_VIDEO_AVCProfileHigh10; + } else if (g_str_equal (profile_string, "high-4:2:2")) { + param.eProfile = OMX_VIDEO_AVCProfileHigh422; + } else if (g_str_equal (profile_string, "high-4:4:4")) { + param.eProfile = OMX_VIDEO_AVCProfileHigh444; + } else { + goto unsupported_profile; + } + } + level_string = gst_structure_get_string (s, "level"); + if (level_string) { + if (g_str_equal (level_string, "1")) { + param.eLevel = OMX_VIDEO_AVCLevel1; + } else if (g_str_equal (level_string, "1b")) { + param.eLevel = OMX_VIDEO_AVCLevel1b; + } else if (g_str_equal (level_string, "1.1")) { + param.eLevel = OMX_VIDEO_AVCLevel11; + } else if (g_str_equal (level_string, "1.2")) { + param.eLevel = OMX_VIDEO_AVCLevel12; + } else if (g_str_equal (level_string, "1.3")) { + param.eLevel = OMX_VIDEO_AVCLevel13; + } else if (g_str_equal (level_string, "2")) { + param.eLevel = OMX_VIDEO_AVCLevel2; + } else if (g_str_equal (level_string, "2.1")) { + param.eLevel = OMX_VIDEO_AVCLevel21; + } else if (g_str_equal (level_string, "2.2")) { + param.eLevel = OMX_VIDEO_AVCLevel22; + } else if (g_str_equal (level_string, "3")) { + param.eLevel = OMX_VIDEO_AVCLevel3; + } else if (g_str_equal (level_string, "3.1")) { + param.eLevel = OMX_VIDEO_AVCLevel31; + } else if (g_str_equal (level_string, "3.2")) { + param.eLevel = OMX_VIDEO_AVCLevel32; + } else if (g_str_equal (level_string, "4")) { + param.eLevel = OMX_VIDEO_AVCLevel4; + } else if (g_str_equal (level_string, "4.1")) { + param.eLevel = OMX_VIDEO_AVCLevel41; + } else if (g_str_equal (level_string, "4.2")) { + param.eLevel = OMX_VIDEO_AVCLevel42; + } else if (g_str_equal (level_string, "5")) { + param.eLevel = OMX_VIDEO_AVCLevel5; + } else if (g_str_equal (level_string, "5.1")) { + param.eLevel = OMX_VIDEO_AVCLevel51; + } else { + goto unsupported_level; + } + } + + err = + gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc, + OMX_IndexParamVideoProfileLevelCurrent, ¶m); + if (err == OMX_ErrorUnsupportedIndex) { + GST_WARNING_OBJECT (self, + "Setting profile/level not supported by component"); + } else if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, + "Error setting profile %u and level %u: %s (0x%08x)", + (guint) param.eProfile, (guint) param.eLevel, + gst_omx_error_to_string (err), err); + return FALSE; } } - level_string = gst_structure_get_string (s, "level"); - if (level_string) { - if (g_str_equal (level_string, "1")) { - param.eLevel = OMX_VIDEO_AVCLevel1; - } else if (g_str_equal (level_string, "1b")) { - param.eLevel = OMX_VIDEO_AVCLevel1b; - } else if (g_str_equal (level_string, "1.1")) { - param.eLevel = OMX_VIDEO_AVCLevel11; - } else if (g_str_equal (level_string, "1.2")) { - param.eLevel = OMX_VIDEO_AVCLevel12; - } else if (g_str_equal (level_string, "1.3")) { - param.eLevel = OMX_VIDEO_AVCLevel13; - } else if (g_str_equal (level_string, "2")) { - param.eLevel = OMX_VIDEO_AVCLevel2; - } else if (g_str_equal (level_string, "2.1")) { - param.eLevel = OMX_VIDEO_AVCLevel21; - } else if (g_str_equal (level_string, "2.2")) { - param.eLevel = OMX_VIDEO_AVCLevel22; - } else if (g_str_equal (level_string, "3")) { - param.eLevel = OMX_VIDEO_AVCLevel3; - } else if (g_str_equal (level_string, "3.1")) { - param.eLevel = OMX_VIDEO_AVCLevel31; - } else if (g_str_equal (level_string, "3.2")) { - param.eLevel = OMX_VIDEO_AVCLevel32; - } else if (g_str_equal (level_string, "4")) { - param.eLevel = OMX_VIDEO_AVCLevel4; - } else if (g_str_equal (level_string, "4.1")) { - param.eLevel = OMX_VIDEO_AVCLevel41; - } else if (g_str_equal (level_string, "4.2")) { - param.eLevel = OMX_VIDEO_AVCLevel42; - } else if (g_str_equal (level_string, "5")) { - param.eLevel = OMX_VIDEO_AVCLevel5; - } else if (g_str_equal (level_string, "5.1")) { - param.eLevel = OMX_VIDEO_AVCLevel51; + + out_format = gst_structure_get_string (s, "stream-format"); + if (out_format) { + if (g_str_equal (out_format, "avc")) { + self->stream_format = H264_AVC; + } else if (g_str_equal (out_format, "byte-stream")) { + self->stream_format = H264_BTS; } else { - goto unsupported_level; + goto unsupported_out_format; } } gst_caps_unref (peercaps); } - err = - gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc, - OMX_IndexParamVideoProfileLevelCurrent, ¶m); - if (err == OMX_ErrorUnsupportedIndex) { - GST_WARNING_OBJECT (self, - "Setting profile/level not supported by component"); - } else if (err != OMX_ErrorNone) { - GST_ERROR_OBJECT (self, - "Error setting profile %u and level %u: %s (0x%08x)", - (guint) param.eProfile, (guint) param.eLevel, - gst_omx_error_to_string (err), err); - return FALSE; + if (self->stream_format == H264_AVC) { + GST_OMX_INIT_STRUCT (&OMXNalSize); + err = + gst_omx_component_get_config (GST_OMX_VIDEO_ENC (self)->enc, + OMX_IndexConfigVideoNalSize, &OMXNalSize); + if (err == OMX_ErrorNone) { + OMXNalSize.nNaluBytes = 4; + OMXNalSize.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index; + err = + gst_omx_component_set_config (GST_OMX_VIDEO_ENC (self)->enc, + OMX_IndexConfigVideoNalSize, &OMXNalSize); + if (err != OMX_ErrorNone) { + return FALSE; + } + } + } + + if (enc->iframeinterval != 0xffffffff) { + err = ifi_setup (enc); + if (err != OMX_ErrorNone) { + GST_WARNING_OBJECT (self, + "Error setting iframeinterval %u : %s (0x%08x)", + (guint) enc->iframeinterval, + gst_omx_error_to_string (err), err); + return FALSE; + } + } + + if (self->insert_sps_pps) { + err = gst_omx_h264_enc_set_insert_sps_pps (enc); + if (err != OMX_ErrorNone) { + GST_WARNING_OBJECT (self, + "Error setting insert sps pps: %s (0x%08x)", + gst_omx_error_to_string (err), err); + return FALSE; + } } return TRUE; @@ -209,6 +340,11 @@ unsupported_level: GST_ERROR_OBJECT (self, "Unsupported level %s", level_string); gst_caps_unref (peercaps); return FALSE; + +unsupported_out_format: + GST_ERROR_OBJECT (self, "Unsupported stream-format %s", out_format); + gst_caps_unref (peercaps); + return FALSE; } static GstCaps * @@ -219,10 +355,9 @@ gst_omx_h264_enc_get_caps (GstOMXVideoEnc * enc, GstOMXPort * port, GstCaps *caps; OMX_ERRORTYPE err; OMX_VIDEO_PARAM_PROFILELEVELTYPE param; - const gchar *profile, *level; + const gchar *profile, *level, *out_format; caps = gst_caps_new_simple ("video/x-h264", - "stream-format", G_TYPE_STRING, "byte-stream", "alignment", G_TYPE_STRING, "au", NULL); GST_OMX_INIT_STRUCT (¶m); @@ -231,7 +366,8 @@ gst_omx_h264_enc_get_caps (GstOMXVideoEnc * enc, GstOMXPort * port, err = gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc, OMX_IndexParamVideoProfileLevelCurrent, ¶m); - if (err != OMX_ErrorNone && err != OMX_ErrorUnsupportedIndex) + if (err != OMX_ErrorNone && err != OMX_ErrorUnsupportedIndex + && err != OMX_ErrorNotImplemented) return NULL; if (err == OMX_ErrorNone) { @@ -315,10 +451,25 @@ gst_omx_h264_enc_get_caps (GstOMXVideoEnc * enc, GstOMXPort * port, g_assert_not_reached (); return NULL; } + gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, "level", G_TYPE_STRING, level, NULL); } + switch (self->stream_format) { + case H264_AVC: + out_format = "avc"; + break; + case H264_BTS: + out_format = "byte-stream"; + break; + default: + g_assert_not_reached (); + return NULL; + } + + gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, out_format, NULL); + return caps; } @@ -326,6 +477,8 @@ static GstFlowReturn gst_omx_h264_enc_handle_output_frame (GstOMXVideoEnc * self, GstOMXPort * port, GstOMXBuffer * buf, GstVideoCodecFrame * frame) { + GstOMXH264Enc *h264enc = GST_OMX_H264_ENC (self); + if (buf->omx_buf->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { /* The codec data is SPS/PPS with a startcode => bytestream stream format * For bytestream stream format the SPS/PPS is only in-stream and not @@ -351,6 +504,85 @@ gst_omx_h264_enc_handle_output_frame (GstOMXVideoEnc * self, GstOMXPort * port, l = g_list_append (l, hdrs); gst_video_encoder_set_headers (GST_VIDEO_ENCODER (self), l); } +#ifdef USE_OMX_TARGET_TEGRA + else { + if (h264enc->stream_format == H264_AVC) { + gsize inbuf_size; + GstBuffer *codec_data_buf; + GstMapInfo cdmap = GST_MAP_INFO_INIT; + OMX_U32 length_to_allocate, offset; + OMX_U8 *str_ptr; + OMX_U8 *pts_ptr; + OMX_U8 data[6]; + OMX_U32 *codec_data; + OMX_U32 sps_length; + + GST_DEBUG_OBJECT (self, "create codec_data caps buffer"); + + str_ptr = (buf->omx_buf->pBuffer + buf->omx_buf->nOffset); + inbuf_size = buf->omx_buf->nFilledLen; + + codec_data = + (OMX_U32 *) (buf->omx_buf->pBuffer + buf->omx_buf->nOffset); + sps_length = (codec_data[0] >> 24); + + // Need additional 7 bytes of data to indicate no of sps,pps + //and how many bytes indicate nal_length,profile etc also we + //are going to strip down 2 bytes each for the sps and pps + //length hence reducing the size by 4 + + length_to_allocate = (inbuf_size + ADDITIONAL_LENGTH); + + codec_data_buf = gst_buffer_new_and_alloc (length_to_allocate); + gst_buffer_map (codec_data_buf, &cdmap, GST_MAP_WRITE); + + data[0] = 0x01; + data[1] = 0x42; // 66 Baseline profile + data[2] = 0x40; // constrained Baseline + data[3] = 0x15; // level2.1 + data[4] = 0x03; // nal length = 4 bytes + data[5] = 0x01; // 1SPS + + // append data of 6 bytes and then the sps length and sps data + memcpy (cdmap.data, data, HEADER_DATA_LENGTH); + + // Strip down the length indicating the NAL data size from 4 bytes to 2 bytes. + // This is because the down stream qtmux are expecting this to be only 2 bytes + + memcpy ((cdmap.data + HEADER_DATA_LENGTH), (str_ptr + 2), + DOWNSTREAM_NAL_LENGTH_INDICATOR); + + // Now copy the SPS data + memcpy ((cdmap.data + HEADER_DATA_LENGTH + 2), + (str_ptr + ENCODER_NAL_LENGTH_INDICATOR), sps_length); + + offset = + HEADER_DATA_LENGTH + DOWNSTREAM_NAL_LENGTH_INDICATOR + sps_length; + + pts_ptr = cdmap.data + offset; + pts_ptr[0] = 1; // 1 pps + + offset += 1; + + // Strip down the length indicating the NAL data size from 4 bytes to 2 bytes. + // This is because the down stream qtmux are expecting this to be only 2 bytes + memcpy ((cdmap.data + offset), + (str_ptr + (ENCODER_NAL_LENGTH_INDICATOR + sps_length) + 2), + DOWNSTREAM_NAL_LENGTH_INDICATOR); + + offset += 2; + + // Now copy pps data + memcpy ((cdmap.data + offset), + (str_ptr + ((ENCODER_NAL_LENGTH_INDICATOR << 1) + sps_length)), + (inbuf_size - ((ENCODER_NAL_LENGTH_INDICATOR << 1) + sps_length))); + + gst_buffer_unmap (codec_data_buf, &cdmap); + + self->codec_data = codec_data_buf; + } + } +#endif } return @@ -358,3 +590,35 @@ gst_omx_h264_enc_handle_output_frame (GstOMXVideoEnc * self, GstOMXPort * port, (gst_omx_h264_enc_parent_class)->handle_output_frame (self, port, buf, frame); } + +static void +gst_omx_h264_enc_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstOMXH264Enc *self = GST_OMX_H264_ENC (object); + + switch (prop_id) { + case PROP_INSERT_SPS_PPS: + self->insert_sps_pps = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_omx_h264_enc_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + GstOMXH264Enc *self = GST_OMX_H264_ENC (object); + + switch (prop_id) { + case PROP_INSERT_SPS_PPS: + g_value_set_boolean (value, self->insert_sps_pps); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} diff --git a/omx/gstomxh264enc.h b/omx/gstomxh264enc.h index 5d43e5b..119f5b2 100644 --- a/omx/gstomxh264enc.h +++ b/omx/gstomxh264enc.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. + * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +26,6 @@ #include "gstomxvideoenc.h" G_BEGIN_DECLS - #define GST_TYPE_OMX_H264_ENC \ (gst_omx_h264_enc_get_type()) #define GST_OMX_H264_ENC(obj) \ @@ -38,13 +38,24 @@ G_BEGIN_DECLS (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_H264_ENC)) #define GST_IS_OMX_H264_ENC_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_H264_ENC)) - +#define ADDITIONAL_LENGTH 3 +#define HEADER_DATA_LENGTH 6 +#define ENCODER_NAL_LENGTH_INDICATOR 4 +#define DOWNSTREAM_NAL_LENGTH_INDICATOR 2 typedef struct _GstOMXH264Enc GstOMXH264Enc; typedef struct _GstOMXH264EncClass GstOMXH264EncClass; +typedef enum +{ + H264_AVC, + H264_BTS +} h264_sf; + struct _GstOMXH264Enc { GstOMXVideoEnc parent; + h264_sf stream_format; + gboolean insert_sps_pps; }; struct _GstOMXH264EncClass @@ -55,6 +66,4 @@ struct _GstOMXH264EncClass GType gst_omx_h264_enc_get_type (void); G_END_DECLS - #endif /* __GST_OMX_H264_ENC_H__ */ - diff --git a/omx/gstomxmjpegdec.h b/omx/gstomxmjpegdec.h index 8802c8d..3bb5992 100644 --- a/omx/gstomxmjpegdec.h +++ b/omx/gstomxmjpegdec.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +26,6 @@ #include "gstomxvideodec.h" G_BEGIN_DECLS - #define GST_TYPE_OMX_MJPEG_DEC \ (gst_omx_mjpeg_dec_get_type()) #define GST_OMX_MJPEG_DEC(obj) \ @@ -38,7 +38,6 @@ G_BEGIN_DECLS (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_MJPEG_DEC)) #define GST_IS_OMX_MJPEG_DEC_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_MJPEG_DEC)) - typedef struct _GstOMXMJPEGDec GstOMXMJPEGDec; typedef struct _GstOMXMJPEGDecClass GstOMXMJPEGDecClass; @@ -55,6 +54,4 @@ struct _GstOMXMJPEGDecClass GType gst_omx_mjpeg_dec_get_type (void); G_END_DECLS - #endif /* __GST_OMX_MJPEG_DEC_H__ */ - diff --git a/omx/gstomxmpeg2videodec.h b/omx/gstomxmpeg2videodec.h index ff86bcd..0d88289 100644 --- a/omx/gstomxmpeg2videodec.h +++ b/omx/gstomxmpeg2videodec.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +26,6 @@ #include "gstomxvideodec.h" G_BEGIN_DECLS - #define GST_TYPE_OMX_MPEG2_VIDEO_DEC \ (gst_omx_mpeg2_video_get_type()) #define GST_OMX_MPEG2_VIDEO_DEC(obj) \ @@ -38,7 +38,6 @@ G_BEGIN_DECLS (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_MPEG2_VIDEO_DEC)) #define GST_IS_OMX_MPEG2_VIDEO_DEC_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_MPEG2_VIDEO_DEC)) - typedef struct _GstOMXMPEG2VideoDec GstOMXMPEG2VideoDec; typedef struct _GstOMXMPEG2VideoDecClass GstOMXMPEG2VideoDecClass; @@ -55,5 +54,4 @@ struct _GstOMXMPEG2VideoDecClass GType gst_omx_mpeg2_video_dec_get_type (void); G_END_DECLS - #endif /* __GST_OMX_MPEG2_VIDEO_DEC_H__ */ diff --git a/omx/gstomxmpeg4videodec.c b/omx/gstomxmpeg4videodec.c index d912d74..5a852d6 100644 --- a/omx/gstomxmpeg4videodec.c +++ b/omx/gstomxmpeg4videodec.c @@ -64,7 +64,9 @@ gst_omx_mpeg4_video_dec_class_init (GstOMXMPEG4VideoDecClass * klass) videodec_class->cdata.default_sink_template_caps = "video/mpeg, " "mpegversion=(int) 4, " "systemstream=(boolean) false, " - "parsed=(boolean) true, " "width=(int) [1,MAX], " "height=(int) [1,MAX]"; + "parsed=(boolean) true, " "width=(int) [1,MAX], " "height=(int) [1,MAX];" + "video/x-divx, " "divxversion=(int) [4,5], " + "width=(int) [1,MAX], " "height=(int) [1,MAX]"; gst_element_class_set_static_metadata (element_class, "OpenMAX MPEG4 Video Decoder", diff --git a/omx/gstomxmpeg4videodec.h b/omx/gstomxmpeg4videodec.h index 73a68d5..ef16b5c 100644 --- a/omx/gstomxmpeg4videodec.h +++ b/omx/gstomxmpeg4videodec.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +26,6 @@ #include "gstomxvideodec.h" G_BEGIN_DECLS - #define GST_TYPE_OMX_MPEG4_VIDEO_DEC \ (gst_omx_mpeg4_video_dec_get_type()) #define GST_OMX_MPEG4_VIDEO_DEC(obj) \ @@ -38,7 +38,6 @@ G_BEGIN_DECLS (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_MPEG4_VIDEO_DEC)) #define GST_IS_OMX_MPEG4_VIDEO_DEC_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_MPEG4_VIDEO_DEC)) - typedef struct _GstOMXMPEG4VideoDec GstOMXMPEG4VideoDec; typedef struct _GstOMXMPEG4VideoDecClass GstOMXMPEG4VideoDecClass; @@ -55,6 +54,4 @@ struct _GstOMXMPEG4VideoDecClass GType gst_omx_mpeg4_video_dec_get_type (void); G_END_DECLS - #endif /* __GST_OMX_MPEG4_VIDEO_DEC_H__ */ - diff --git a/omx/gstomxmpeg4videoenc.h b/omx/gstomxmpeg4videoenc.h index 01d6698..5519d11 100644 --- a/omx/gstomxmpeg4videoenc.h +++ b/omx/gstomxmpeg4videoenc.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +26,6 @@ #include "gstomxvideoenc.h" G_BEGIN_DECLS - #define GST_TYPE_OMX_MPEG4_VIDEO_ENC \ (gst_omx_mpeg4_video_enc_get_type()) #define GST_OMX_MPEG4_VIDEO_ENC(obj) \ @@ -38,7 +38,6 @@ G_BEGIN_DECLS (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_MPEG4_VIDEO_ENC)) #define GST_IS_OMX_MPEG4_VIDEO_ENC_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_MPEG4_VIDEO_ENC)) - typedef struct _GstOMXMPEG4VideoEnc GstOMXMPEG4VideoEnc; typedef struct _GstOMXMPEG4VideoEncClass GstOMXMPEG4VideoEncClass; @@ -55,6 +54,4 @@ struct _GstOMXMPEG4VideoEncClass GType gst_omx_mpeg4_video_enc_get_type (void); G_END_DECLS - #endif /* __GST_OMX_MPEG4_VIDEO_ENC_H__ */ - diff --git a/omx/gstomxmpegaudiodec.c b/omx/gstomxmpegaudiodec.c new file mode 100644 index 0000000..e23e419 --- /dev/null +++ b/omx/gstomxmpegaudiodec.c @@ -0,0 +1,134 @@ +/* GStreamer + * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Suite 500, + * Boston, MA 02110-1335, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gst/gst.h> +#include <gst/audio/gstaudiodecoder.h> +#include "gstomxmpegaudiodec.h" + +GST_DEBUG_CATEGORY_STATIC (gst_omx_mpegaudio_dec_debug_category); +#define GST_CAT_DEFAULT gst_omx_mpegaudio_dec_debug_category + +/* prototypes */ + +static gboolean gst_omx_mpegaudio_dec_set_format (GstOMXAudioDec * decoder, + GstOMXPort * port, GstCaps * caps); + +/* class initialization */ + +G_DEFINE_TYPE_WITH_CODE (GstOMXMPEGAUDIODec, gst_omx_mpegaudio_dec, + GST_TYPE_OMX_AUDIO_DEC, + GST_DEBUG_CATEGORY_INIT (gst_omx_mpegaudio_dec_debug_category, + "omxmpegaudiodec", 0, "debug category for omxmpegaudiodec element")); + +static void +gst_omx_mpegaudio_dec_class_init (GstOMXMPEGAUDIODecClass * klass) +{ + GstOMXAudioDecClass *omxdec_class = GST_OMX_AUDIO_DEC_CLASS (klass); + + omxdec_class->set_format = + GST_DEBUG_FUNCPTR (gst_omx_mpegaudio_dec_set_format); + + omxdec_class->cdata.default_sink_template_caps = "audio/mpeg, " + "mpegversion = (int) 1, " "layer = (int) [1, 3]"; + + gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass), + "OpenMax MP3/MP2 decoder", "Codec/Decoder/Audio", + "Decodes MP3 and MP2 audio streams", + "Jitendra Kumar <jitendrak@nvidia.com>"); + + gst_omx_set_default_role (&omxdec_class->cdata, "audio_decoder.mp3"); +} + +static void +gst_omx_mpegaudio_dec_init (GstOMXMPEGAUDIODec * omxmpegaudiodec) +{ +} + +static gboolean +gst_omx_mpegaudio_dec_set_format (GstOMXAudioDec * decoder, GstOMXPort * port, + GstCaps * caps) +{ + GstOMXMPEGAUDIODec *self = GST_OMX_MPEGAUDIO_DEC (decoder); + OMX_AUDIO_PARAM_MP3TYPE mp3_type; + OMX_PARAM_PORTDEFINITIONTYPE port_def; + OMX_ERRORTYPE err; + + gst_omx_port_get_port_definition (port, &port_def); + port_def.format.audio.eEncoding = OMX_AUDIO_CodingMP3; + err = gst_omx_port_update_port_definition (port, &port_def); + + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, + "Failed to update port definition of component: %s (0x%08x)", + gst_omx_error_to_string (err), err); + return FALSE; + } + + GST_OMX_INIT_STRUCT (&mp3_type); + mp3_type.nPortIndex = port->index; + + err = gst_omx_component_get_parameter (decoder->dec, OMX_IndexParamAudioMp3, + &mp3_type); + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, + "Failed to get MP3/MP2 parameters from component: %s (0x%08x)", + gst_omx_error_to_string (err), err); + return FALSE; + } + + if (caps) { + GstStructure *s; + gint mpegaudioversion = 0, channels = 0, sample_rate = 0, layer = 0; + + if (gst_caps_is_empty (caps)) { + GST_ERROR_OBJECT (self, "Empty caps"); + return FALSE; + } + + s = gst_caps_get_structure (caps, 0); + + if (gst_structure_get_int (s, "mpegaudioversion", &mpegaudioversion)) { + + if (gst_structure_get_int (s, "layer", &layer) && layer == 3) { + if (mpegaudioversion == 1) + mp3_type.eFormat = OMX_AUDIO_MP3StreamFormatMP1Layer3; + else if (mpegaudioversion == 2) + mp3_type.eFormat = OMX_AUDIO_MP3StreamFormatMP2Layer3; + } + } + if (gst_structure_get_int (s, "channels", &channels)) + mp3_type.nChannels = channels; + + if (gst_structure_get_int (s, "rate", &sample_rate)) + mp3_type.nSampleRate = sample_rate; + } + + err = gst_omx_component_set_parameter (decoder->dec, OMX_IndexParamAudioMp3, + &mp3_type); + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, "Error setting MP3/MP2 parameters: %s (0x%08x)", + gst_omx_error_to_string (err), err); + return FALSE; + } + return TRUE; +} diff --git a/omx/gstomxmpegaudiodec.h b/omx/gstomxmpegaudiodec.h new file mode 100644 index 0000000..b4a1381 --- /dev/null +++ b/omx/gstomxmpegaudiodec.h @@ -0,0 +1,49 @@ +/* GStreamer + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _GST_OMX_MPEGAUDIO_DEC_H_ +#define _GST_OMX_MPEGAUDIO_DEC_H_ + +#include <gst/gst.h> +#include "gstomxaudiodec.h" + +G_BEGIN_DECLS +#define GST_TYPE_OMX_MPEGAUDIO_DEC (gst_omx_mpegaudio_dec_get_type()) +#define GST_OMX_MPEGAUDIO_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_MPEGAUDIO_DEC,GstOMXMPEGAUDIODec)) +#define GST_OMX_MPEGAUDIO_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_MPEGAUDIO_DEC,GstOMXMPEGAUDIODecClass)) +#define GST_IS_OMX_MPEGAUDIO_DEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_MPEGAUDIO_DEC)) +#define GST_IS_OMX_MPEGAUDIO_DEC_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_MPEGAUDIO_DEC)) +typedef struct _GstOMXMPEGAUDIODec GstOMXMPEGAUDIODec; +typedef struct _GstOMXMPEGAUDIODecClass GstOMXMPEGAUDIODecClass; + +struct _GstOMXMPEGAUDIODec +{ + GstOMXAudioDec parent; + +}; + +struct _GstOMXMPEGAUDIODecClass +{ + GstOMXAudioDecClass parent_class; +}; + +GType gst_omx_mpegaudio_dec_get_type (void); + +G_END_DECLS +#endif diff --git a/omx/gstomxtheoradec.h b/omx/gstomxtheoradec.h index 4b5a2fa..5db27e4 100644 --- a/omx/gstomxtheoradec.h +++ b/omx/gstomxtheoradec.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2013, Collabora Ltd. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +26,6 @@ #include "gstomxvideodec.h" G_BEGIN_DECLS - #define GST_TYPE_OMX_THEORA_DEC \ (gst_omx_theora_dec_get_type()) #define GST_OMX_THEORA_DEC(obj) \ @@ -38,7 +38,6 @@ G_BEGIN_DECLS (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_THEORA_DEC)) #define GST_IS_OMX_THEORA_DEC_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_THEORA_DEC)) - typedef struct _GstOMXTheoraDec GstOMXTheoraDec; typedef struct _GstOMXTheoraDecClass GstOMXTheoraDecClass; @@ -56,6 +55,4 @@ struct _GstOMXTheoraDecClass GType gst_omx_theora_dec_get_type (void); G_END_DECLS - #endif /* __GST_OMX_THEORA_DEC_H__ */ - diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c index 74a71d4..9b9d6ec 100644 --- a/omx/gstomxvideodec.c +++ b/omx/gstomxvideodec.c @@ -3,6 +3,7 @@ * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. * Copyright (C) 2013, Collabora Ltd. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> + * Copyright (c) 2013 - 2015, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -38,7 +39,7 @@ #pragma GCC optimize ("gnu89-inline") #endif -#if defined (USE_OMX_TARGET_RPI) && defined (HAVE_GST_EGL) +#if (defined (USE_OMX_TARGET_RPI) || defined (USE_OMX_TARGET_TEGRA)) && defined (HAVE_GST_EGL) #include <gst/egl/egl.h> #endif @@ -54,6 +55,10 @@ GST_DEBUG_CATEGORY_STATIC (gst_omx_video_dec_debug_category); #define GST_CAT_DEFAULT gst_omx_video_dec_debug_category +#ifdef USE_OMX_TARGET_TEGRA +#define DEFAULT_USE_OMXDEC_RES FALSE +#endif + typedef struct _GstOMXMemory GstOMXMemory; typedef struct _GstOMXMemoryAllocator GstOMXMemoryAllocator; typedef struct _GstOMXMemoryAllocatorClass GstOMXMemoryAllocatorClass; @@ -76,6 +81,28 @@ struct _GstOMXMemoryAllocatorClass }; #define GST_OMX_MEMORY_TYPE "openmax" +#define GST_OMX_SINK_MEMORY_TYPE "omxsink" + +#define DEFAULT_SKIP_FRAME_TYPE GST_DECODE_ALL +#define GST_TYPE_OMX_VID_DEC_SKIP_FRAMES (gst_video_dec_skip_frames ()) +static GType +gst_video_dec_skip_frames (void) +{ + static GType qtype = 0; + + if (qtype == 0) { + static const GEnumValue values[] = { + {GST_DECODE_ALL, "GST_OMX_DECODE_ALL_FRAMES", "DECODE_ALL_Frames"}, + {GST_SKIP_NON_REF_FRAMES, "GST_OMX_DECODE_SKIP_NON_REF_FRAMES", + "SKIP_NON_REF_FRAMES"}, + {GST_DECODE_KEY_FRAMES, "GST_OMX_DECODE_KEY_FRAMES", "DECODE_KEY_FRAMES"}, + {0, NULL, NULL} + }; + + qtype = g_enum_register_static ("H264SkipFrame", values); + } + return qtype; +} static GstMemory * gst_omx_memory_allocator_alloc_dummy (GstAllocator * allocator, gsize size, @@ -214,6 +241,7 @@ gst_omx_memory_allocator_alloc (GstAllocator * allocator, GstMemoryFlags flags, */ static GQuark gst_omx_buffer_data_quark = 0; +extern GQuark gst_omx_sink_data_quark; #define GST_OMX_BUFFER_POOL(pool) ((GstOMXBufferPool *) pool) typedef struct _GstOMXBufferPool GstOMXBufferPool; @@ -265,6 +293,9 @@ GType gst_omx_buffer_pool_get_type (void); G_DEFINE_TYPE (GstOMXBufferPool, gst_omx_buffer_pool, GST_TYPE_BUFFER_POOL); +static void +gst_omx_buffer_pool_free_buffer (GstBufferPool * bpool, GstBuffer * buffer); + static gboolean gst_omx_buffer_pool_start (GstBufferPool * bpool) { @@ -287,8 +318,14 @@ static gboolean gst_omx_buffer_pool_stop (GstBufferPool * bpool) { GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool); + GstBuffer *buf; + guint i; /* Remove any buffers that are there */ + for (i = 0; i < pool->port->buffers->len; i++) { + buf = g_ptr_array_index (pool->buffers, i); + gst_omx_buffer_pool_free_buffer (bpool, buf); + } g_ptr_array_set_size (pool->buffers, 0); if (pool->caps) @@ -437,30 +474,58 @@ gst_omx_buffer_pool_alloc_buffer (GstBufferPool * bpool, gsize offset[4] = { 0, }; gint stride[4] = { 0, }; - switch (pool->video_info.finfo->format) { - case GST_VIDEO_FORMAT_I420: - offset[0] = 0; - stride[0] = pool->port->port_def.format.video.nStride; - offset[1] = - stride[0] * pool->port->port_def.format.video.nSliceHeight; - stride[1] = pool->port->port_def.format.video.nStride / 2; - offset[2] = - offset[1] + - stride[1] * (pool->port->port_def.format.video.nSliceHeight / 2); - stride[2] = pool->port->port_def.format.video.nStride / 2; - break; - case GST_VIDEO_FORMAT_NV12: +#ifdef USE_OMX_TARGET_TEGRA + OMX_INDEXTYPE eIndex; + GstOMXVideoDec *self = (GstOMXVideoDec *) pool->element; + OMX_ERRORTYPE eError = OMX_ErrorUndefined; + + eError = OMX_GetExtensionIndex (self->dec->handle, + (OMX_STRING) NVX_INDEX_CONFIG_VIDEOPLANESINFO, &eIndex); + + if (eError == OMX_ErrorNone) { + NVX_CONFIG_VIDEOPLANESINFO oInfo; + + GST_OMX_INIT_STRUCT (&oInfo); + + eError = OMX_GetConfig (self->dec->handle, eIndex, &oInfo); + + if (eError == OMX_ErrorNone) { offset[0] = 0; - stride[0] = pool->port->port_def.format.video.nStride; - offset[1] = - stride[0] * pool->port->port_def.format.video.nSliceHeight; - stride[1] = pool->port->port_def.format.video.nStride; - break; - default: - g_assert_not_reached (); - break; + stride[0] = oInfo.nAlign[0][0]; + offset[1] = oInfo.nAlign[0][0] * oInfo.nAlign[0][1]; + stride[1] = oInfo.nAlign[1][0] << 1; + offset[2] = offset[1] + stride[1] * oInfo.nAlign[1][1]; + stride[2] = oInfo.nAlign[2][0]; + } } + if (eError != OMX_ErrorNone) +#endif + switch (pool->video_info.finfo->format) { + case GST_VIDEO_FORMAT_I420: + offset[0] = 0; + stride[0] = pool->port->port_def.format.video.nStride; + offset[1] = + stride[0] * pool->port->port_def.format.video.nSliceHeight; + stride[1] = pool->port->port_def.format.video.nStride / 2; + offset[2] = + offset[1] + + stride[1] * (pool->port->port_def.format.video.nSliceHeight / + 2); + stride[2] = pool->port->port_def.format.video.nStride / 2; + break; + case GST_VIDEO_FORMAT_NV12: + offset[0] = 0; + stride[0] = pool->port->port_def.format.video.nStride; + offset[1] = + stride[0] * pool->port->port_def.format.video.nSliceHeight; + stride[1] = pool->port->port_def.format.video.nStride; + break; + default: + g_assert_not_reached (); + break; + } + gst_buffer_add_video_meta_full (buf, GST_VIDEO_FRAME_FLAG_NONE, GST_VIDEO_INFO_FORMAT (&pool->video_info), GST_VIDEO_INFO_WIDTH (&pool->video_info), @@ -524,6 +589,23 @@ gst_omx_buffer_pool_acquire_buffer (GstBufferPool * bpool, && g_strcmp0 (mem->allocator->mem_type, GST_OMX_MEMORY_TYPE) == 0); mem->size = ((GstOMXMemory *) mem)->buf->omx_buf->nFilledLen; mem->offset = ((GstOMXMemory *) mem)->buf->omx_buf->nOffset; + } else { +#ifdef USE_OMX_TARGET_TEGRA + GstMemory *mem = gst_buffer_peek_memory (buf, 0); + if (mem + && g_strcmp0 (mem->allocator->mem_type, + GST_OMX_SINK_MEMORY_TYPE) == 0) { + GstOMXBuffer *omxbuf = + gst_mini_object_get_qdata (GST_MINI_OBJECT_CAST (buf), + gst_omx_buffer_data_quark); + mem->size = omxbuf->omx_buf->nFilledLen; + mem->offset = omxbuf->omx_buf->nOffset; + omxbuf = + gst_mini_object_get_qdata (GST_MINI_OBJECT_CAST (buf), + gst_omx_sink_data_quark); + omxbuf->omx_buf->nFlags |= OMX_BUFFERFLAG_NV_BUFFER; + } +#endif } } else { /* Acquire any buffer that is available to be filled by upstream */ @@ -689,7 +771,13 @@ static OMX_ERRORTYPE gst_omx_video_dec_deallocate_output_buffers (GstOMXVideoDec enum { - PROP_0 + PROP_0, +#ifdef USE_OMX_TARGET_TEGRA + PROP_USE_OMXDEC_RES, + PROP_USE_FULL_FRAME, + PROP_DISABLE_DPB, + PROP_SKIP_FRAME +#endif }; /* class initialization */ @@ -703,6 +791,60 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstOMXVideoDec, gst_omx_video_dec, GST_TYPE_VIDEO_DECODER, DEBUG_INIT); static void +gst_omx_video_dec_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec) +{ + GstOMXVideoDec *self = GST_OMX_VIDEO_DEC (object); + + switch (prop_id) { +#ifdef USE_OMX_TARGET_TEGRA + case PROP_USE_OMXDEC_RES: + self->use_omxdec_res = g_value_get_boolean (value); + break; + case PROP_USE_FULL_FRAME: + self->full_frame_data = g_value_get_boolean (value); + break; + case PROP_DISABLE_DPB: + self->disable_dpb = g_value_get_boolean (value); + break; + case PROP_SKIP_FRAME: + self->skip_frames = g_value_get_enum (value); + break; +#endif + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_omx_video_dec_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec) +{ + GstOMXVideoDec *self = GST_OMX_VIDEO_DEC (object); + + switch (prop_id) { +#ifdef USE_OMX_TARGET_TEGRA + case PROP_USE_OMXDEC_RES: + g_value_set_boolean (value, self->use_omxdec_res); + break; + case PROP_USE_FULL_FRAME: + g_value_set_boolean (value, self->full_frame_data); + break; + case PROP_DISABLE_DPB: + g_value_set_boolean (value, self->disable_dpb); + break; + case PROP_SKIP_FRAME: + g_value_set_enum (value, self->skip_frames); + break; +#endif + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void gst_omx_video_dec_class_init (GstOMXVideoDecClass * klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); @@ -711,6 +853,38 @@ gst_omx_video_dec_class_init (GstOMXVideoDecClass * klass) gobject_class->finalize = gst_omx_video_dec_finalize; + gobject_class->set_property = gst_omx_video_dec_set_property; + gobject_class->get_property = gst_omx_video_dec_get_property; + +#ifdef USE_OMX_TARGET_TEGRA + g_object_class_install_property (gobject_class, PROP_USE_OMXDEC_RES, + g_param_spec_boolean ("use-omxdec-res", + "Use resolution from omx decoder(for debugging purpose)", + "Omx decoder resolution to be used(for debugging purpose)", + DEFAULT_USE_OMXDEC_RES, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_USE_FULL_FRAME, + g_param_spec_boolean ("full-frame", + "Full Frame data", + "Whether or not the data is full framed", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_DISABLE_DPB, + g_param_spec_boolean ("disable-dpb", + "Disable H.264 DPB buffer", + "Set to disable H.264 DPB buffer for low latency", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_SKIP_FRAME, + g_param_spec_enum ("skip-frames", + "Skip frames", + "Which type of frames to skip during decoding", + GST_TYPE_OMX_VID_DEC_SKIP_FRAMES, + DEFAULT_SKIP_FRAME_TYPE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | + GST_PARAM_MUTABLE_PLAYING)); +#endif + element_class->change_state = GST_DEBUG_FUNCPTR (gst_omx_video_dec_change_state); @@ -733,11 +907,33 @@ gst_omx_video_dec_class_init (GstOMXVideoDecClass * klass) "height = " GST_VIDEO_SIZE_RANGE ", " "framerate = " GST_VIDEO_FPS_RANGE; } +OMX_ERRORTYPE +gst_omx_set_full_frame_data_property (OMX_HANDLETYPE omx_handle) +{ + OMX_INDEXTYPE eIndex; + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_CONFIG_BOOLEANTYPE full_frame_data; + GST_OMX_INIT_STRUCT (&full_frame_data); + eError = + OMX_GetExtensionIndex (omx_handle, + (OMX_STRING) "OMX.Nvidia.index.param.vdecfullframedata", &eIndex); + if (eError == OMX_ErrorNone) { + full_frame_data.bEnabled = OMX_TRUE; + OMX_SetParameter (omx_handle, eIndex, &full_frame_data); + } + return eError; +} + static void gst_omx_video_dec_init (GstOMXVideoDec * self) { gst_video_decoder_set_packetized (GST_VIDEO_DECODER (self), TRUE); +#ifdef USE_OMX_TARGET_TEGRA + self->use_omxdec_res = DEFAULT_USE_OMXDEC_RES; + self->full_frame_data = FALSE; +#endif + g_mutex_init (&self->drain_lock); g_cond_init (&self->drain_cond); } @@ -797,6 +993,16 @@ gst_omx_video_dec_open (GstVideoDecoder * decoder) GST_DEBUG_OBJECT (self, "Opened decoder"); +#ifdef USE_OMX_TARGET_TEGRA + { + OMX_PARAM_PORTDEFINITIONTYPE port_def; + + gst_omx_port_get_port_definition (self->dec_in_port, &port_def); + port_def.format.video.nFrameWidth = port_def.format.video.nFrameHeight = 0; + gst_omx_port_update_port_definition (self->dec_in_port, &port_def); + } +#endif + #if defined (USE_OMX_TARGET_RPI) && defined (HAVE_GST_EGL) GST_DEBUG_OBJECT (self, "Opening EGL renderer"); self->egl_render = @@ -876,7 +1082,7 @@ gst_omx_video_dec_shutdown (GstOMXVideoDec * self) } } - /* Otherwise we didn't use EGL and just fall back to + /* Otherwise we didn't use EGL and just fall back to * shutting down the decoder */ #endif @@ -1136,6 +1342,10 @@ gst_omx_video_dec_fill_buffer (GstOMXVideoDec * self, } /* Different strides */ +#ifdef USE_OMX_TARGET_TEGRA + /*TODO: get videoplanesinfo() for TEGRA, currently this path is not used */ + return FALSE; +#endif switch (vinfo->finfo->format) { case GST_VIDEO_FORMAT_I420:{ @@ -1259,6 +1469,7 @@ gst_omx_video_dec_allocate_output_buffers (GstOMXVideoDec * self) GstBufferPool *pool; GstStructure *config; gboolean eglimage = FALSE, add_videometa = FALSE; + gboolean shared_buffer = FALSE; GstCaps *caps = NULL; guint min = 0, max = 0; GstVideoCodecState *state = @@ -1292,13 +1503,18 @@ gst_omx_video_dec_allocate_output_buffers (GstOMXVideoDec * self) add_videometa = gst_buffer_pool_config_has_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); -#if defined (USE_OMX_TARGET_RPI) && defined (HAVE_GST_EGL) +#if (defined (USE_OMX_TARGET_RPI) || defined (USE_OMX_TARGET_TEGRA)) && defined (HAVE_GST_EGL) eglimage = self->eglimage && (allocator && g_strcmp0 (allocator->mem_type, GST_EGL_IMAGE_MEMORY_TYPE) == 0); -#else - /* TODO: Implement something that works for other targets too */ - eglimage = FALSE; #endif + +#if defined (USE_OMX_TARGET_TEGRA) + if (!eglimage) { + shared_buffer = (allocator + && g_strcmp0 (allocator->mem_type, GST_OMX_SINK_MEMORY_TYPE) == 0); + } +#endif + caps = caps ? gst_caps_ref (caps) : NULL; GST_DEBUG_OBJECT (self, "Trying to use pool %p with caps %" GST_PTR_FORMAT @@ -1460,10 +1676,165 @@ gst_omx_video_dec_allocate_output_buffers (GstOMXVideoDec * self) } } } +#elif defined (USE_OMX_TARGET_TEGRA) + if (eglimage || shared_buffer) { + GList *buffers = NULL; + GList *pBuffers = NULL; + GList *l; + gint i; + GstBufferPoolAcquireParams params = { 0, }; + GstMapInfo map = GST_MAP_INFO_INIT; + GList *images = NULL; + + if (eglimage) { + GST_DEBUG_OBJECT (self, "Trying to allocate %d EGLImages", min); + + for (i = 0; i < min; i++) { + GstBuffer *buffer; + GstMemory *mem; + + if (gst_buffer_pool_acquire_buffer (pool, &buffer, + ¶ms) != GST_FLOW_OK || gst_buffer_n_memory (buffer) != 1 + || !(mem = gst_buffer_peek_memory (buffer, 0)) + || g_strcmp0 (mem->allocator->mem_type, + GST_EGL_IMAGE_MEMORY_TYPE) != 0) { + GST_INFO_OBJECT (self, "Failed to allocated %d-th EGLImage", i); + g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref); + g_list_free (images); + buffers = NULL; + images = NULL; + err = OMX_ErrorUndefined; + goto done; + } + + buffers = g_list_append (buffers, buffer); + gst_egl_image_memory_set_orientation (mem, + GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_FLIP); + images = g_list_append (images, gst_egl_image_memory_get_image (mem)); + } + + GST_DEBUG_OBJECT (self, "Allocated %d EGLImages successfully", min); + } else { + GST_DEBUG_OBJECT (self, "Trying to Use %d OMX Buffers", min); + + for (i = 0; i < min; i++) { + GstBuffer *buffer; + GstMemory *mem = NULL; + + if (gst_buffer_pool_acquire_buffer (pool, &buffer, + ¶ms) != GST_FLOW_OK || gst_buffer_n_memory (buffer) != 1 + || !(mem = gst_buffer_peek_memory (buffer, 0)) + || !(gst_memory_map (mem, &map, GST_MAP_WRITE)) + || g_strcmp0 (mem->allocator->mem_type, + GST_OMX_SINK_MEMORY_TYPE) != 0) { + GST_INFO_OBJECT (self, "Failed to use %d-th OMX Buffer", i); + g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref); + g_list_free (pBuffers); + buffers = NULL; + pBuffers = NULL; + if (map.memory == mem) + gst_memory_unmap (mem, &map); + err = OMX_ErrorUndefined; + goto done; + } + + buffers = g_list_append (buffers, buffer); + pBuffers = g_list_append (pBuffers, map.data); + gst_memory_unmap (mem, &map); + } + + GST_DEBUG_OBJECT (self, "Allocated %d OMX Buffers", min); + } + + if (min != port->port_def.nBufferCountActual) { + err = gst_omx_port_update_port_definition (port, NULL); + if (err == OMX_ErrorNone) { + port->port_def.nBufferCountActual = min; + err = gst_omx_port_update_port_definition (port, &port->port_def); + } + + if (err != OMX_ErrorNone) { + GST_INFO_OBJECT (self, + "Failed to configure %u output buffers: %s (0x%08x)", min, + gst_omx_error_to_string (err), err); + g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref); + goto done; + } + } + + if (!gst_omx_port_is_enabled (port)) { + + NVX_PARAM_USENVBUFFER param; + OMX_INDEXTYPE eIndex; + + GST_DEBUG_OBJECT (self, "Setting decoder to use Nvmm buffer"); + + err = gst_omx_component_get_index (self->dec, + (char *) NVX_INDEX_CONFIG_USENVBUFFER, &eIndex); + + if (!eglimage) { + if (err == OMX_ErrorNone) { + GST_OMX_INIT_STRUCT (¶m); + param.nPortIndex = self->dec_out_port->index; + param.bUseNvBuffer = OMX_TRUE; + err = gst_omx_component_set_parameter (self->dec, eIndex, ¶m); + } else { + GST_WARNING_OBJECT (self, "Coudn't get extension index for %s", + (char *) NVX_INDEX_CONFIG_USENVBUFFER); + goto done; + } + } + + if (err != OMX_ErrorNone) { + GST_WARNING_OBJECT (self, "Couldn't use HW Accelerated path"); + goto done; + } + + err = gst_omx_port_set_enabled (port, TRUE); + if (err != OMX_ErrorNone) { + GST_INFO_OBJECT (self, + "Failed to enable port: %s (0x%08x)", + gst_omx_error_to_string (err), err); + g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref); + goto done; + } + } + + if (eglimage) + err = gst_omx_port_use_eglimages (port, images); + else + err = gst_omx_port_use_buffers (port, pBuffers); + + if (err != OMX_ErrorNone) { + GST_INFO_OBJECT (self, + "Failed to pass OMX Buffers to port: %s (0x%08x)", + gst_omx_error_to_string (err), err); + g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref); + goto done; + } + + err = gst_omx_port_wait_enabled (port, 2 * GST_SECOND); + if (err != OMX_ErrorNone) { + GST_INFO_OBJECT (self, + "Failed to wait until port is enabled: %s (0x%08x)", + gst_omx_error_to_string (err), err); + g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref); + goto done; + } + + GST_DEBUG_OBJECT (self, "Populating internal buffer pool"); + GST_OMX_BUFFER_POOL (self->out_port_pool)->other_pool = + GST_BUFFER_POOL (gst_object_ref (pool)); + for (l = buffers; l; l = l->next) { + g_ptr_array_add (GST_OMX_BUFFER_POOL (self->out_port_pool)->buffers, + l->data); + } + g_list_free (buffers); + } #endif /* If not using EGLImage or trying to use EGLImage failed */ - if (!eglimage) { + if (!eglimage && !shared_buffer) { gboolean was_enabled = TRUE; if (min != port->port_def.nBufferCountActual) { @@ -1615,6 +1986,74 @@ gst_omx_video_dec_deallocate_output_buffers (GstOMXVideoDec * self) return err; } +#if defined (USE_OMX_TARGET_TEGRA) && defined (HAVE_GST_EGL) +static NvBufType +gst_omx_video_dec_negotiate_nv_caps (GstOMXVideoDec * self, + GstVideoCodecState * state) +{ + GstPad *peer = NULL; + OMX_ERRORTYPE err = OMX_ErrorNone; + + peer = gst_pad_get_peer (GST_VIDEO_DECODER_SRC_PAD (self)); + + if (peer) { + GstCaps *icaps; + GstCapsFeatures *ift; + + icaps = gst_video_info_to_caps (&state->info); + icaps = gst_caps_make_writable (icaps); + + ift = gst_caps_features_new ("memory:EGLImage"); + gst_caps_set_features (icaps, 0, ift); + + if (gst_pad_query_accept_caps (peer, icaps)) { + gst_caps_unref (icaps); + gst_object_unref (peer); + return BUF_EGL; + } else { + gst_caps_features_add (ift, "memory:NVMM"); + gst_caps_features_remove (ift, "memory:EGLImage"); + + if (gst_pad_query_accept_caps (peer, icaps)) { + gst_caps_unref (icaps); + gst_object_unref (peer); + if (!gst_omx_port_is_enabled (self->dec_out_port)) { + NVX_PARAM_USENVBUFFER param; + OMX_INDEXTYPE eIndex; + + GST_DEBUG_OBJECT (self, "Setting decoder to use Nvmm buffer"); + + err = gst_omx_component_get_index (self->dec, + (char *) NVX_INDEX_CONFIG_USENVBUFFER, &eIndex); + + if (err == OMX_ErrorNone) { + GST_OMX_INIT_STRUCT (¶m); + param.nPortIndex = self->dec_out_port->index; + param.bUseNvBuffer = OMX_TRUE; + err = gst_omx_component_set_parameter (self->dec, eIndex, ¶m); + } else { + GST_WARNING_OBJECT (self, "Coudn't get extension index for %s", + (char *) NVX_INDEX_CONFIG_USENVBUFFER); + goto done; + } + + if (err != OMX_ErrorNone) { + GST_WARNING_OBJECT (self, "Couldn't use HW Accelerated path"); + goto done; + } + } + return BUF_NVMM; + } + } + + gst_caps_unref (icaps); + gst_object_unref (peer); + } +done: + return BUF_NB; +} +#endif + static OMX_ERRORTYPE gst_omx_video_dec_reconfigure_output_port (GstOMXVideoDec * self) { @@ -1624,6 +2063,10 @@ gst_omx_video_dec_reconfigure_output_port (GstOMXVideoDec * self) OMX_PARAM_PORTDEFINITIONTYPE port_def; GstVideoFormat format; +#if defined (USE_OMX_TARGET_TEGRA) && defined (HAVE_GST_EGL) + NvBufType nv_buf = BUF_NB; +#endif + /* At this point the decoder output port is disabled */ #if defined (USE_OMX_TARGET_RPI) && defined (HAVE_GST_EGL) @@ -1750,7 +2193,6 @@ gst_omx_video_dec_reconfigure_output_port (GstOMXVideoDec * self) if (err != OMX_ErrorNone) goto no_egl; - err = gst_omx_port_mark_reconfigured (self->dec_out_port); if (err != OMX_ErrorNone) goto no_egl; @@ -1817,6 +2259,68 @@ gst_omx_video_dec_reconfigure_output_port (GstOMXVideoDec * self) break; } +#ifdef USE_OMX_TARGET_TEGRA + if (!self->use_omxdec_res) { + OMX_INDEXTYPE eIndex; + OMX_ERRORTYPE eError; + OMX_U32 frame_size; + + eError = OMX_GetExtensionIndex (self->dec->handle, + (OMX_STRING) NVX_INDEX_CONFIG_VIDEOPLANESINFO, &eIndex); + + if (eError == OMX_ErrorNone) { + NVX_CONFIG_VIDEOPLANESINFO oInfo; + + GST_OMX_INIT_STRUCT (&oInfo); + + eError = OMX_GetConfig (self->dec->handle, eIndex, &oInfo); + if (eError == OMX_ErrorNone) { + GstOMXPort *iport = self->dec_in_port; + OMX_PARAM_PORTDEFINITIONTYPE iport_def; + + GST_OMX_INIT_STRUCT (&iport_def); + gst_omx_port_get_port_definition (iport, &iport_def); + + if (iport_def.format.video.nFrameWidth && + iport_def.format.video.nFrameHeight) { + switch (format) { + case GST_VIDEO_FORMAT_NV12: + oInfo.nAlign[0][0] = + GST_ROUND_UP_4 (iport_def.format.video.nFrameWidth); + oInfo.nAlign[0][1] = + GST_ROUND_UP_2 (iport_def.format.video.nFrameHeight); + oInfo.nAlign[1][0] = + (GST_ROUND_UP_4 (iport_def.format.video.nFrameWidth)) >> 1; + oInfo.nAlign[1][1] = + (GST_ROUND_UP_2 (iport_def.format.video.nFrameHeight)) >> 1; + frame_size = + oInfo.nAlign[0][0] * oInfo.nAlign[0][1] + + oInfo.nAlign[1][0] * oInfo.nAlign[1][1]; + break; + default: + eError = OMX_ErrorUnsupportedSetting; + break; + } + + if (eError == OMX_ErrorNone) + eError = OMX_SetConfig (self->dec->handle, eIndex, &oInfo); + } else + eError = OMX_ErrorUnsupportedSetting; + } + } + + if (eError == OMX_ErrorNone) { + port_def.nBufferSize = frame_size; + gst_omx_port_update_port_definition (port, &port_def); + gst_omx_port_get_port_definition (port, &port_def); + + } else + g_warning ("omxvideodec: failed to set output video alignment %x", + eError); + + } +#endif + GST_DEBUG_OBJECT (self, "Setting output state: format %s, width %u, height %u", gst_video_format_to_string (format), @@ -1833,6 +2337,23 @@ gst_omx_video_dec_reconfigure_output_port (GstOMXVideoDec * self) err = OMX_ErrorUndefined; goto done; } +#if defined (USE_OMX_TARGET_TEGRA) && defined (HAVE_GST_EGL) + { + nv_buf = gst_omx_video_dec_negotiate_nv_caps (self, state); + if (nv_buf == BUF_EGL) { + state = gst_video_decoder_set_output_state (GST_VIDEO_DECODER (self), + GST_VIDEO_FORMAT_RGBA, port_def.format.video.nFrameWidth, + port_def.format.video.nFrameHeight, self->input_state); + + if (gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) { + self->eglimage = TRUE; + } else { + GST_ERROR_OBJECT (self, "Failed to negotiate RGBA for EGLImage"); + self->eglimage = FALSE; + } + } + } +#endif gst_video_codec_state_unref (state); @@ -1895,6 +2416,10 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self) /* Reallocate all buffers */ if (acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE && gst_omx_port_is_enabled (port)) { + gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), + gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, + gst_structure_new_empty("ReleaseLastBuffer"))); + err = gst_omx_port_set_enabled (port, FALSE); if (err != OMX_ErrorNone) goto reconfigure_error; @@ -2353,6 +2878,7 @@ gst_omx_video_dec_get_supported_colorformats (GstOMXVideoDec * self) if (err == OMX_ErrorNone || err == OMX_ErrorNoMore) { switch (param.eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: case OMX_COLOR_FormatYUV420PackedPlanar: m = g_slice_new (VideoNegotiationMap); @@ -2538,6 +3064,7 @@ gst_omx_video_dec_set_format (GstVideoDecoder * decoder, GST_DEBUG_OBJECT (self, "Need to disable and drain decoder"); gst_omx_video_dec_drain (self, FALSE); + gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, TRUE); gst_omx_port_set_flushing (out_port, 5 * GST_SECOND, TRUE); /* Wait until the srcpad loop is finished, @@ -2568,23 +3095,26 @@ gst_omx_video_dec_set_format (GstVideoDecoder * decoder, if (gst_omx_port_set_enabled (self->dec_in_port, FALSE) != OMX_ErrorNone) return FALSE; - if (gst_omx_port_set_enabled (out_port, FALSE) != OMX_ErrorNone) - return FALSE; if (gst_omx_port_wait_buffers_released (self->dec_in_port, 5 * GST_SECOND) != OMX_ErrorNone) return FALSE; - if (gst_omx_port_wait_buffers_released (out_port, - 1 * GST_SECOND) != OMX_ErrorNone) - return FALSE; if (gst_omx_port_deallocate_buffers (self->dec_in_port) != OMX_ErrorNone) return FALSE; - if (gst_omx_video_dec_deallocate_output_buffers (self) != OMX_ErrorNone) - return FALSE; if (gst_omx_port_wait_enabled (self->dec_in_port, 1 * GST_SECOND) != OMX_ErrorNone) return FALSE; + +#ifndef USE_OMX_TARGET_TEGRA + if (gst_omx_port_set_enabled (out_port, FALSE) != OMX_ErrorNone) + return FALSE; + if (gst_omx_port_wait_buffers_released (out_port, + 1 * GST_SECOND) != OMX_ErrorNone) + return FALSE; + if (gst_omx_video_dec_deallocate_output_buffers (self) != OMX_ErrorNone) + return FALSE; if (gst_omx_port_wait_enabled (out_port, 1 * GST_SECOND) != OMX_ErrorNone) return FALSE; +#endif #if defined (USE_OMX_TARGET_RPI) && defined (HAVE_GST_EGL) if (self->eglimage) { @@ -2792,10 +3322,12 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder, return GST_FLOW_EOS; } +#ifndef USE_OMX_TARGET_TEGRA if (!self->started && !GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)) { gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame); return GST_FLOW_OK; } +#endif timestamp = frame->pts; duration = frame->duration; @@ -2950,6 +3482,8 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder, buf->omx_buf->nTimeStamp = gst_util_uint64_scale (timestamp, OMX_TICKS_PER_SECOND, GST_SECOND); self->last_upstream_ts = timestamp; + } else if (duration != GST_CLOCK_TIME_NONE) { + buf->omx_buf->nTimeStamp = self->last_upstream_ts + duration; } else { buf->omx_buf->nTimeStamp = 0; } @@ -3155,8 +3689,13 @@ gst_omx_video_dec_decide_allocation (GstVideoDecoder * bdec, GstQuery * query) { GstBufferPool *pool; GstStructure *config; + GstCaps *caps; + guint max = 0, min = 0, size; + GstOMXPort *port; + GstOMXVideoDec *self = GST_OMX_VIDEO_DEC (bdec); + OMX_ERRORTYPE err = OMX_ErrorNone; -#if defined (USE_OMX_TARGET_RPI) && defined (HAVE_GST_EGL) +#if (defined (USE_OMX_TARGET_RPI) || defined (USE_OMX_TARGET_TEGRA)) && defined (HAVE_GST_EGL) { GstCaps *caps; gint i, n; @@ -3193,6 +3732,32 @@ gst_omx_video_dec_decide_allocation (GstVideoDecoder * bdec, GstQuery * query) gst_query_parse_nth_allocation_pool (query, 0, &pool, NULL, NULL, NULL); g_assert (pool != NULL); +#ifdef USE_OMX_TARGET_TEGRA + port = self->dec_out_port; + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_get_params (config, &caps, &size, &min, &max); + + min = MAX (MAX (min, port->port_def.nBufferCountMin), 4); + + if (min != port->port_def.nBufferCountActual) { + err = gst_omx_port_update_port_definition (port, NULL); + if (err == OMX_ErrorNone) { + port->port_def.nBufferCountActual = min; + err = gst_omx_port_update_port_definition (port, &port->port_def); + } + if (err == OMX_ErrorNone) { + gst_buffer_pool_config_set_params (config, caps, size, min, max); + if (!gst_buffer_pool_set_config (pool, config)) { + GST_INFO_OBJECT (self, "Failed to set config on internal pool"); + } + } else { + gst_structure_free (config); + } + } else { + gst_structure_free (config); + } +#endif + config = gst_buffer_pool_get_config (pool); if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) { gst_buffer_pool_config_add_option (config, diff --git a/omx/gstomxvideodec.h b/omx/gstomxvideodec.h index 3978865..c3601dc 100644 --- a/omx/gstomxvideodec.h +++ b/omx/gstomxvideodec.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. + * Copyright (c) 2013 - 2015, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -32,7 +33,6 @@ #include "gstomx.h" G_BEGIN_DECLS - #define GST_TYPE_OMX_VIDEO_DEC \ (gst_omx_video_dec_get_type()) #define GST_OMX_VIDEO_DEC(obj) \ @@ -45,10 +45,19 @@ G_BEGIN_DECLS (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_VIDEO_DEC)) #define GST_IS_OMX_VIDEO_DEC_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_VIDEO_DEC)) - typedef struct _GstOMXVideoDec GstOMXVideoDec; typedef struct _GstOMXVideoDecClass GstOMXVideoDecClass; + +#ifdef USE_OMX_TARGET_TEGRA +typedef enum +{ + BUF_EGL, + BUF_NVMM, + BUF_NB +} NvBufType; +#endif + struct _GstOMXVideoDec { GstVideoDecoder parent; @@ -56,7 +65,7 @@ struct _GstOMXVideoDec /* < protected > */ GstOMXComponent *dec; GstOMXPort *dec_in_port, *dec_out_port; - + GstBufferPool *in_port_pool, *out_port_pool; /* < private > */ @@ -78,9 +87,20 @@ struct _GstOMXVideoDec gboolean eos; GstFlowReturn downstream_flow_ret; + +#ifdef USE_OMX_TARGET_TEGRA + gboolean use_omxdec_res; + gboolean full_frame_data; + gboolean disable_dpb; + guint32 skip_frames; +#endif + #ifdef USE_OMX_TARGET_RPI GstOMXComponent *egl_render; GstOMXPort *egl_in_port, *egl_out_port; +#endif + +#if defined (USE_OMX_TARGET_RPI) || defined (USE_OMX_TARGET_TEGRA) gboolean eglimage; #endif }; @@ -91,13 +111,24 @@ struct _GstOMXVideoDecClass GstOMXClassData cdata; - gboolean (*is_format_change) (GstOMXVideoDec * self, GstOMXPort * port, GstVideoCodecState * state); - gboolean (*set_format) (GstOMXVideoDec * self, GstOMXPort * port, GstVideoCodecState * state); - GstFlowReturn (*prepare_frame) (GstOMXVideoDec * self, GstVideoCodecFrame *frame); + gboolean (*is_format_change) (GstOMXVideoDec * self, GstOMXPort * port, + GstVideoCodecState * state); + gboolean (*set_format) (GstOMXVideoDec * self, GstOMXPort * port, + GstVideoCodecState * state); + GstFlowReturn (*prepare_frame) (GstOMXVideoDec * self, + GstVideoCodecFrame * frame); }; GType gst_omx_video_dec_get_type (void); -G_END_DECLS +OMX_ERRORTYPE gst_omx_set_full_frame_data_property (OMX_HANDLETYPE omx_handle); + +typedef enum +{ + GST_DECODE_ALL, + GST_SKIP_NON_REF_FRAMES, + GST_DECODE_KEY_FRAMES +} GstVideoSkipFrames; +G_END_DECLS #endif /* __GST_OMX_VIDEO_DEC_H__ */ diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c index a399c07..1e5ddea 100644 --- a/omx/gstomxvideoenc.c +++ b/omx/gstomxvideoenc.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. + * Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,28 +32,28 @@ GST_DEBUG_CATEGORY_STATIC (gst_omx_video_enc_debug_category); #define GST_CAT_DEFAULT gst_omx_video_enc_debug_category -#define GST_TYPE_OMX_VIDEO_ENC_CONTROL_RATE (gst_omx_video_enc_control_rate_get_type ()) +#define GST_TYPE_OMX_VID_ENC_RCMODE (gst_omx_videnc_rc_mode_get_type ()) static GType -gst_omx_video_enc_control_rate_get_type (void) +gst_omx_videnc_rc_mode_get_type (void) { - static GType qtype = 0; - - if (qtype == 0) { - static const GEnumValue values[] = { - {OMX_Video_ControlRateDisable, "Disable", "disable"}, - {OMX_Video_ControlRateVariable, "Variable", "variable"}, - {OMX_Video_ControlRateConstant, "Constant", "constant"}, - {OMX_Video_ControlRateVariableSkipFrames, "Variable Skip Frames", - "variable-skip-frames"}, - {OMX_Video_ControlRateConstantSkipFrames, "Constant Skip Frames", - "constant-skip-frames"}, - {0xffffffff, "Component Default", "default"}, - {0, NULL, NULL} - }; - - qtype = g_enum_register_static ("GstOMXVideoEncControlRate", values); + static volatile gsize rcmode_type_type = 0; + static const GEnumValue rcmode_type[] = { + {NVX_VIDEO_RateControlMode_CBR, "GST_OMX_VIDENC_RCMODE_TYPE_CONSTANT", + "cbr"}, + {NVX_VIDEO_RateControlMode_VBR, "GST_OMX_VIDENC_RCMODE_TYPE_VARIABLE", + "vbr"}, + {NVX_VIDEO_RateControlMode_VBR2, "GST_OMX_VIDENC_RCMODE_TYPE_VARIABLE2", + "vbr2"}, + {0, NULL, NULL} + }; + + if (g_once_init_enter (&rcmode_type_type)) { + GType tmp = + g_enum_register_static ("GstOmxVideoEncRCModeType", rcmode_type); + g_once_init_leave (&rcmode_type_type, tmp); } - return qtype; + + return (GType) rcmode_type_type; } typedef struct _BufferIdentification BufferIdentification; @@ -101,22 +102,35 @@ static GstFlowReturn gst_omx_video_enc_drain (GstOMXVideoEnc * self, static GstFlowReturn gst_omx_video_enc_handle_output_frame (GstOMXVideoEnc * self, GstOMXPort * port, GstOMXBuffer * buf, GstVideoCodecFrame * frame); +static GstCaps *gst_omx_video_enc_negotiate_caps (GstVideoEncoder * encoder, + GstCaps * caps, GstCaps * filter); + +static void +gst_omx_video_enc_check_nvfeatures (GstOMXVideoEnc * self, + GstVideoCodecState * state); + enum { PROP_0, - PROP_CONTROL_RATE, - PROP_TARGET_BITRATE, + PROP_RC_MODE, + PROP_BITRATE, PROP_QUANT_I_FRAMES, PROP_QUANT_P_FRAMES, - PROP_QUANT_B_FRAMES + PROP_QUANT_B_FRAMES, + PROP_INTRA_FRAME_INTERVAL }; /* FIXME: Better defaults */ -#define GST_OMX_VIDEO_ENC_CONTROL_RATE_DEFAULT (0xffffffff) -#define GST_OMX_VIDEO_ENC_TARGET_BITRATE_DEFAULT (0xffffffff) +#define DEFAULT_RC_MODE NVX_VIDEO_RateControlMode_VBR2 +#define GST_OMX_VIDEO_ENC_BITRATE_DEFAULT (4000000) #define GST_OMX_VIDEO_ENC_QUANT_I_FRAMES_DEFAULT (0xffffffff) #define GST_OMX_VIDEO_ENC_QUANT_P_FRAMES_DEFAULT (0xffffffff) #define GST_OMX_VIDEO_ENC_QUANT_B_FRAMES_DEFAULT (0xffffffff) +#define DEFAULT_INTRA_FRAME_INTERVAL 60 + +#ifdef USE_OMX_TARGET_TEGRA +#define ENCODER_CONF_LOCATION "/etc/enctune.conf" +#endif /* class initialization */ @@ -127,6 +141,10 @@ enum G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstOMXVideoEnc, gst_omx_video_enc, GST_TYPE_VIDEO_ENCODER, DEBUG_INIT); +#ifdef USE_OMX_TARGET_TEGRA +#define FORMATS "I420, NV12" +#endif + static void gst_omx_video_enc_class_init (GstOMXVideoEncClass * klass) { @@ -139,18 +157,17 @@ gst_omx_video_enc_class_init (GstOMXVideoEncClass * klass) gobject_class->set_property = gst_omx_video_enc_set_property; gobject_class->get_property = gst_omx_video_enc_get_property; - g_object_class_install_property (gobject_class, PROP_CONTROL_RATE, - g_param_spec_enum ("control-rate", "Control Rate", - "Bitrate control method", - GST_TYPE_OMX_VIDEO_ENC_CONTROL_RATE, - GST_OMX_VIDEO_ENC_CONTROL_RATE_DEFAULT, + g_object_class_install_property (gobject_class, PROP_RC_MODE, + g_param_spec_enum ("rc-mode", "rc-mode", + "Encoding rate control mode", + GST_TYPE_OMX_VID_ENC_RCMODE, DEFAULT_RC_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_READY)); - g_object_class_install_property (gobject_class, PROP_TARGET_BITRATE, - g_param_spec_uint ("target-bitrate", "Target Bitrate", - "Target bitrate (0xffffffff=component default)", - 0, G_MAXUINT, GST_OMX_VIDEO_ENC_TARGET_BITRATE_DEFAULT, + g_object_class_install_property (gobject_class, PROP_BITRATE, + g_param_spec_uint ("bitrate", "Target Bitrate", + "Target bitrate", + 0, G_MAXUINT, GST_OMX_VIDEO_ENC_BITRATE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_PLAYING)); @@ -175,6 +192,13 @@ gst_omx_video_enc_class_init (GstOMXVideoEncClass * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_READY)); + g_object_class_install_property (gobject_class, PROP_INTRA_FRAME_INTERVAL, + g_param_spec_uint ("iframeinterval", "Intra Frame interval", + "Encoding Intra Frame occurance frequency", + 0, G_MAXUINT, DEFAULT_INTRA_FRAME_INTERVAL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | + GST_PARAM_MUTABLE_READY)); + element_class->change_state = GST_DEBUG_FUNCPTR (gst_omx_video_enc_change_state); @@ -193,7 +217,16 @@ gst_omx_video_enc_class_init (GstOMXVideoEncClass * klass) video_encoder_class->getcaps = GST_DEBUG_FUNCPTR (gst_omx_video_enc_getcaps); klass->cdata.type = GST_OMX_COMPONENT_TYPE_FILTER; - klass->cdata.default_sink_template_caps = "video/x-raw, " + klass->cdata.default_sink_template_caps = "video/x-raw(memory:NVMM), " +#ifdef USE_OMX_TARGET_TEGRA + "format = (string) { " FORMATS " }, " +#endif + "width = " GST_VIDEO_SIZE_RANGE ", " + "height = " GST_VIDEO_SIZE_RANGE ", " "framerate = " GST_VIDEO_FPS_RANGE + ";" "video/x-raw, " +#ifdef USE_OMX_TARGET_TEGRA + "format = (string) { " FORMATS " }, " +#endif "width = " GST_VIDEO_SIZE_RANGE ", " "height = " GST_VIDEO_SIZE_RANGE ", " "framerate = " GST_VIDEO_FPS_RANGE; @@ -204,11 +237,12 @@ gst_omx_video_enc_class_init (GstOMXVideoEncClass * klass) static void gst_omx_video_enc_init (GstOMXVideoEnc * self) { - self->control_rate = GST_OMX_VIDEO_ENC_CONTROL_RATE_DEFAULT; - self->target_bitrate = GST_OMX_VIDEO_ENC_TARGET_BITRATE_DEFAULT; + self->bitrate = GST_OMX_VIDEO_ENC_BITRATE_DEFAULT; + self->rc_mode = DEFAULT_RC_MODE; self->quant_i_frames = GST_OMX_VIDEO_ENC_QUANT_I_FRAMES_DEFAULT; self->quant_p_frames = GST_OMX_VIDEO_ENC_QUANT_P_FRAMES_DEFAULT; self->quant_b_frames = GST_OMX_VIDEO_ENC_QUANT_B_FRAMES_DEFAULT; + self->hw_path = FALSE; g_mutex_init (&self->drain_lock); g_cond_init (&self->drain_cond); @@ -270,50 +304,36 @@ gst_omx_video_enc_open (GstVideoEncoder * encoder) { OMX_ERRORTYPE err; - if (self->control_rate != 0xffffffff || self->target_bitrate != 0xffffffff) { - OMX_VIDEO_PARAM_BITRATETYPE bitrate_param; +#ifdef USE_OMX_TARGET_TEGRA - GST_OMX_INIT_STRUCT (&bitrate_param); - bitrate_param.nPortIndex = self->enc_out_port->index; + OMX_INDEXTYPE eIndex; + NVX_PARAM_TEMPFILEPATH enc_conf_loc; + gchar *location = g_strdup (ENCODER_CONF_LOCATION); - err = gst_omx_component_get_parameter (self->enc, - OMX_IndexParamVideoBitrate, &bitrate_param); + GST_DEBUG_OBJECT (self, "Setting encoder to use default configurations"); - if (err == OMX_ErrorNone) { -#ifdef USE_OMX_TARGET_RPI - /* FIXME: Workaround for RPi returning garbage for this parameter */ - if (bitrate_param.nVersion.nVersion == 0) { - GST_OMX_INIT_STRUCT (&bitrate_param); - bitrate_param.nPortIndex = self->enc_out_port->index; - } -#endif - if (self->control_rate != 0xffffffff) - bitrate_param.eControlRate = self->control_rate; - if (self->target_bitrate != 0xffffffff) - bitrate_param.nTargetBitrate = self->target_bitrate; + err = gst_omx_component_get_index (self->enc, + (char *) NVX_INDEX_PARAM_TEMPFILEPATH, &eIndex); + if (err == OMX_ErrorNone) { + if (location != NULL) { + GST_OMX_INIT_STRUCT (&enc_conf_loc); + enc_conf_loc.pTempPath = location; err = - gst_omx_component_set_parameter (self->enc, - OMX_IndexParamVideoBitrate, &bitrate_param); - if (err == OMX_ErrorUnsupportedIndex) { - GST_WARNING_OBJECT (self, - "Setting a bitrate not supported by the component"); - } else if (err == OMX_ErrorUnsupportedSetting) { - GST_WARNING_OBJECT (self, - "Setting bitrate settings %u %u not supported by the component", - self->control_rate, self->target_bitrate); - } else if (err != OMX_ErrorNone) { - GST_ERROR_OBJECT (self, - "Failed to set bitrate parameters: %s (0x%08x)", - gst_omx_error_to_string (err), err); - return FALSE; - } - } else { - GST_ERROR_OBJECT (self, "Failed to get bitrate parameters: %s (0x%08x)", - gst_omx_error_to_string (err), err); + gst_omx_component_set_parameter (self->enc, eIndex, &enc_conf_loc); } + } else { + GST_WARNING_OBJECT (self, "Coudn't get extension index for %s", + (char *) NVX_INDEX_PARAM_TEMPFILEPATH); } + if (err != OMX_ErrorNone) + GST_WARNING_OBJECT (self, "Couldn't set configurations"); + + g_free (location); + +#endif + if (self->quant_i_frames != 0xffffffff || self->quant_p_frames != 0xffffffff || self->quant_b_frames != 0xffffffff) { @@ -422,18 +442,18 @@ gst_omx_video_enc_set_property (GObject * object, guint prop_id, GstOMXVideoEnc *self = GST_OMX_VIDEO_ENC (object); switch (prop_id) { - case PROP_CONTROL_RATE: - self->control_rate = g_value_get_enum (value); + case PROP_RC_MODE: + self->rc_mode = g_value_get_enum (value); break; - case PROP_TARGET_BITRATE: - self->target_bitrate = g_value_get_uint (value); + case PROP_BITRATE: + self->bitrate = g_value_get_uint (value); if (self->enc) { OMX_VIDEO_CONFIG_BITRATETYPE config; OMX_ERRORTYPE err; GST_OMX_INIT_STRUCT (&config); config.nPortIndex = self->enc_out_port->index; - config.nEncodeBitrate = self->target_bitrate; + config.nEncodeBitrate = self->bitrate; err = gst_omx_component_set_config (self->enc, OMX_IndexConfigVideoBitrate, &config); @@ -452,6 +472,9 @@ gst_omx_video_enc_set_property (GObject * object, guint prop_id, case PROP_QUANT_B_FRAMES: self->quant_b_frames = g_value_get_uint (value); break; + case PROP_INTRA_FRAME_INTERVAL: + self->iframeinterval = g_value_get_uint (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -465,11 +488,11 @@ gst_omx_video_enc_get_property (GObject * object, guint prop_id, GValue * value, GstOMXVideoEnc *self = GST_OMX_VIDEO_ENC (object); switch (prop_id) { - case PROP_CONTROL_RATE: - g_value_set_enum (value, self->control_rate); + case PROP_RC_MODE: + g_value_set_enum (value, self->rc_mode); break; - case PROP_TARGET_BITRATE: - g_value_set_uint (value, self->target_bitrate); + case PROP_BITRATE: + g_value_set_uint (value, self->bitrate); break; case PROP_QUANT_I_FRAMES: g_value_set_uint (value, self->quant_i_frames); @@ -480,6 +503,9 @@ gst_omx_video_enc_get_property (GObject * object, guint prop_id, GValue * value, case PROP_QUANT_B_FRAMES: g_value_set_uint (value, self->quant_b_frames); break; + case PROP_INTRA_FRAME_INTERVAL: + g_value_set_uint (value, self->iframeinterval); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -662,13 +688,17 @@ gst_omx_video_enc_handle_output_frame (GstOMXVideoEnc * self, GstOMXPort * port, GST_DEBUG_OBJECT (self, "Handling codec data"); caps = klass->get_caps (self, self->enc_out_port, self->input_state); - codec_data = gst_buffer_new_and_alloc (buf->omx_buf->nFilledLen); + if (self->codec_data) { + codec_data = self->codec_data; + } else { + codec_data = gst_buffer_new_and_alloc (buf->omx_buf->nFilledLen); - gst_buffer_map (codec_data, &map, GST_MAP_WRITE); - memcpy (map.data, - buf->omx_buf->pBuffer + buf->omx_buf->nOffset, - buf->omx_buf->nFilledLen); - gst_buffer_unmap (codec_data, &map); + gst_buffer_map (codec_data, &map, GST_MAP_WRITE); + memcpy (map.data, + buf->omx_buf->pBuffer + buf->omx_buf->nOffset, + buf->omx_buf->nFilledLen); + gst_buffer_unmap (codec_data, &map); + } state = gst_video_encoder_set_output_state (GST_VIDEO_ENCODER (self), caps, self->input_state); @@ -1099,12 +1129,149 @@ gst_omx_video_enc_get_supported_colorformats (GstOMXVideoEnc * self) return negotiation_map; } +static OMX_ERRORTYPE +gst_omx_video_enc_reconfigure_output_port (GstOMXVideoEnc * self) +{ + + GstOMXPort *port; + OMX_ERRORTYPE err = OMX_ErrorNone; + + port = self->enc_out_port; + + if (!gst_omx_port_is_enabled (port)) { + err = gst_omx_port_set_enabled (port, TRUE); + if (err != OMX_ErrorNone) { + GST_INFO_OBJECT (self, + "Failed to enable port: %s (0x%08x)", + gst_omx_error_to_string (err), err); + goto done; + } + } + + err = gst_omx_port_allocate_buffers (port); + if (err != OMX_ErrorNone) + goto done; + + err = gst_omx_port_wait_enabled (port, 5 * GST_SECOND); + if (err != OMX_ErrorNone) + goto done; + + err = gst_omx_port_populate (port); + if (err != OMX_ErrorNone) + goto done; + + err = gst_omx_port_mark_reconfigured (port); + if (err != OMX_ErrorNone) + goto done; + +done: + return err; +} + +static void +gst_omx_video_enc_check_nvfeatures (GstOMXVideoEnc * self, + GstVideoCodecState * state) +{ + GstCapsFeatures *feature; + + feature = gst_caps_get_features (state->caps, 0); + if (gst_caps_features_contains (feature, "memory:NVMM")) { + OMX_ERRORTYPE err = OMX_ErrorNone; + NVX_PARAM_USENVBUFFER param; + OMX_INDEXTYPE eIndex; + + GST_DEBUG_OBJECT (self, "Setting encoder to use Nvmm buffer"); + + err = gst_omx_component_get_index (self->enc, + (char *) NVX_INDEX_CONFIG_USENVBUFFER, &eIndex); + + if (err == OMX_ErrorNone) { + GST_OMX_INIT_STRUCT (¶m); + param.nPortIndex = self->enc_in_port->index; + param.bUseNvBuffer = OMX_TRUE; + err = gst_omx_component_set_parameter (self->enc, eIndex, ¶m); + } else { + GST_WARNING_OBJECT (self, "Coudn't get extension index for %s", + (char *) NVX_INDEX_CONFIG_USENVBUFFER); + } + + if (err != OMX_ErrorNone) { + GST_WARNING_OBJECT (self, "Couldn't use HW Accelerated path"); + } else { + self->hw_path = TRUE; + } + } +} + +static OMX_ERRORTYPE +gstomx_set_rc_mode (GstOMXVideoEnc * self) +{ + OMX_INDEXTYPE eIndex; + OMX_ERRORTYPE eError = OMX_ErrorNone; + NVX_PARAM_RATECONTROLMODE oRCMode; + + GST_OMX_INIT_STRUCT (&oRCMode); + oRCMode.nPortIndex = 0; + eError = + gst_omx_component_get_index (self->enc, (gpointer) NVX_INDEX_PARAM_RATECONTROLMODE, + &eIndex); + if (eError == OMX_ErrorNone) { + switch (self->rc_mode) { + case NVX_VIDEO_RateControlMode_CBR: + oRCMode.eRateCtrlMode = NVX_VIDEO_RateControlMode_CBR; + break; + case NVX_VIDEO_RateControlMode_VBR: + oRCMode.eRateCtrlMode = NVX_VIDEO_RateControlMode_VBR; + break; + case NVX_VIDEO_RateControlMode_VBR2: + oRCMode.eRateCtrlMode = NVX_VIDEO_RateControlMode_VBR2; + break; + default: + oRCMode.eRateCtrlMode = NVX_VIDEO_RateControlMode_VBR2; + break; + } + + eError = gst_omx_component_set_parameter (self->enc, eIndex, &oRCMode); + if (eError != OMX_ErrorNone) + GST_ERROR_OBJECT (self, + "Failed to set rc_mode parameter: %s (0x%08x)", + gst_omx_error_to_string (eError), eError); + } + return eError; +} + +static OMX_ERRORTYPE +gstomx_set_bitrate (GstOMXVideoEnc * self) +{ + OMX_VIDEO_CONFIG_BITRATETYPE oBitrate; + OMX_ERRORTYPE err = OMX_ErrorNone; + + GST_OMX_INIT_STRUCT (&oBitrate); + + err = + gst_omx_component_get_config (self->enc, + OMX_IndexConfigVideoBitrate, &oBitrate); + + oBitrate.nEncodeBitrate = self->bitrate; + + err = + gst_omx_component_set_config (self->enc, + OMX_IndexConfigVideoBitrate, &oBitrate); + if (err != OMX_ErrorNone) + GST_ERROR_OBJECT (self, + "Failed to set bitrate parameter: %s (0x%08x)", + gst_omx_error_to_string (err), err); + + return err; +} + static gboolean gst_omx_video_enc_set_format (GstVideoEncoder * encoder, GstVideoCodecState * state) { GstOMXVideoEnc *self; GstOMXVideoEncClass *klass; + OMX_ERRORTYPE err; gboolean needs_disable = FALSE; OMX_PARAM_PORTDEFINITIONTYPE port_def; GstVideoInfo *info = &state->info; @@ -1117,6 +1284,7 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder, gst_video_format_to_string (info->finfo->format)); gst_omx_port_get_port_definition (self->enc_in_port, &port_def); + gst_omx_video_enc_check_nvfeatures (self, state); needs_disable = gst_omx_component_get_state (self->enc, @@ -1242,6 +1410,22 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder, } } + err = gstomx_set_rc_mode (self); + if (err != OMX_ErrorNone) { + GST_WARNING_OBJECT (self, + "Error setting rc_mode %u : %s (0x%08x)", + (guint) self->rc_mode, gst_omx_error_to_string (err), err); + return FALSE; + } + + err = gstomx_set_bitrate (self); + if (err != OMX_ErrorNone) { + GST_WARNING_OBJECT (self, + "Error setting bitrate %u : %s (0x%08x)", + (guint) self->bitrate, gst_omx_error_to_string (err), err); + return FALSE; + } + GST_DEBUG_OBJECT (self, "Updating outport port definition"); if (gst_omx_port_update_port_definition (self->enc_out_port, NULL) != OMX_ErrorNone) @@ -1287,6 +1471,12 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder, return FALSE; } +#ifdef USE_OMX_TARGET_TEGRA + /* PortSetting change event comes only if output port has buffers allocated */ + if (gst_omx_video_enc_reconfigure_output_port (self) != OMX_ErrorNone) + return FALSE; +#endif + /* Unset flushing to allow ports to accept data again */ gst_omx_port_set_flushing (self->enc_in_port, 5 * GST_SECOND, FALSE); gst_omx_port_set_flushing (self->enc_out_port, 5 * GST_SECOND, FALSE); @@ -1362,7 +1552,12 @@ gst_omx_video_enc_fill_buffer (GstOMXVideoEnc * self, GstBuffer * inbuf, } /* Same strides and everything */ - if (gst_buffer_get_size (inbuf) == + /* + * If component is using HW acceleration path, No need for this check. + * Because contents are not actual data but structures. + * We can copy content of buffer directly. + */ + if (self->hw_path || gst_buffer_get_size (inbuf) == outbuf->omx_buf->nAllocLen - outbuf->omx_buf->nOffset) { outbuf->omx_buf->nFilledLen = gst_buffer_get_size (inbuf); @@ -1662,6 +1857,10 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder, gst_buffer_get_size (frame->input_buffer)); self->last_upstream_ts += duration; } +#ifdef USE_OMX_TARGET_TEGRA + if (self->hw_path) + buf->omx_buf->nFlags |= OMX_BUFFERFLAG_RETAIN_OMX_TS; +#endif id = g_slice_new0 (BufferIdentification); id->timestamp = buf->omx_buf->nTimeStamp; @@ -1829,35 +2028,122 @@ gst_omx_video_enc_propose_allocation (GstVideoEncoder * encoder, (gst_omx_video_enc_parent_class)->propose_allocation (encoder, query); } +GstCaps * +gst_omx_video_enc_negotiate_caps (GstVideoEncoder * encoder, GstCaps * caps, + GstCaps * filter) +{ + GstCaps *templ_caps; + GstCaps *allowed; + GstCaps *fcaps, *filter_caps; + GstCapsFeatures *feature; + gint i, j; + + /* Allow downstream to specify width/height/framerate/PAR constraints + * and forward them upstream for video converters to handle + */ + templ_caps = + caps ? gst_caps_ref (caps) : + gst_pad_get_pad_template_caps (encoder->sinkpad); + allowed = gst_pad_get_allowed_caps (encoder->srcpad); + + if (!allowed || gst_caps_is_empty (allowed) || gst_caps_is_any (allowed)) { + fcaps = templ_caps; + goto done; + } + + GST_LOG_OBJECT (encoder, "template caps %" GST_PTR_FORMAT, templ_caps); + GST_LOG_OBJECT (encoder, "allowed caps %" GST_PTR_FORMAT, allowed); + + filter_caps = gst_caps_new_empty (); + + for (i = 0; i < gst_caps_get_size (templ_caps); i++) { + GQuark q_name = + gst_structure_get_name_id (gst_caps_get_structure (templ_caps, i)); + gchar *f_name = + gst_caps_features_to_string (gst_caps_get_features (templ_caps, i)); + + for (j = 0; j < gst_caps_get_size (allowed); j++) { + const GstStructure *allowed_s = gst_caps_get_structure (allowed, j); + const GValue *val; + GstStructure *s; + + s = gst_structure_new_id_empty (q_name); + feature = gst_caps_features_new (f_name, NULL); + if ((val = gst_structure_get_value (allowed_s, "width"))) + gst_structure_set_value (s, "width", val); + if ((val = gst_structure_get_value (allowed_s, "height"))) + gst_structure_set_value (s, "height", val); + if ((val = gst_structure_get_value (allowed_s, "framerate"))) + gst_structure_set_value (s, "framerate", val); + if ((val = gst_structure_get_value (allowed_s, "pixel-aspect-ratio"))) + gst_structure_set_value (s, "pixel-aspect-ratio", val); + + filter_caps = gst_caps_merge_structure_full (filter_caps, s, feature); + } + } + + fcaps = gst_caps_intersect (filter_caps, templ_caps); + gst_caps_unref (filter_caps); + gst_caps_unref (templ_caps); + + if (filter) { + GST_LOG_OBJECT (encoder, "intersecting with %" GST_PTR_FORMAT, filter); + filter_caps = gst_caps_intersect (fcaps, filter); + gst_caps_unref (fcaps); + fcaps = filter_caps; + } + +done: + gst_caps_replace (&allowed, NULL); + + GST_LOG_OBJECT (encoder, "proxy caps %" GST_PTR_FORMAT, fcaps); + + return fcaps; +} + static GstCaps * gst_omx_video_enc_getcaps (GstVideoEncoder * encoder, GstCaps * filter) { GstOMXVideoEnc *self = GST_OMX_VIDEO_ENC (encoder); GList *negotiation_map = NULL, *l; GstCaps *comp_supported_caps; + GstCaps *ret; + GstStructure *str; + gint n; + GValue list = G_VALUE_INIT; + GValue val = G_VALUE_INIT; if (!self->enc) - return gst_video_encoder_proxy_getcaps (encoder, NULL, filter); + return gst_omx_video_enc_negotiate_caps (encoder, NULL, filter); negotiation_map = gst_omx_video_enc_get_supported_colorformats (self); - comp_supported_caps = gst_caps_new_empty (); + comp_supported_caps = gst_pad_get_pad_template_caps (encoder->sinkpad); + comp_supported_caps = gst_caps_make_writable (comp_supported_caps); + + g_value_init (&list, GST_TYPE_LIST); + g_value_init (&val, G_TYPE_STRING); + for (l = negotiation_map; l; l = l->next) { VideoNegotiationMap *map = l->data; - gst_caps_append_structure (comp_supported_caps, - gst_structure_new ("video/x-raw", - "format", G_TYPE_STRING, - gst_video_format_to_string (map->format), NULL)); + g_value_set_static_string (&val, gst_video_format_to_string (map->format)); + gst_value_list_append_value (&list, &val); } if (!gst_caps_is_empty (comp_supported_caps)) { - GstCaps *ret = - gst_video_encoder_proxy_getcaps (encoder, comp_supported_caps, filter); - + for (n = 0; n < gst_caps_get_size (comp_supported_caps); n++) { + str = gst_caps_get_structure (comp_supported_caps, n); + gst_structure_set_value (str, "format", &list); + } + ret = + gst_omx_video_enc_negotiate_caps (encoder, comp_supported_caps, filter); gst_caps_unref (comp_supported_caps); - return ret; } else { gst_caps_unref (comp_supported_caps); - return gst_video_encoder_proxy_getcaps (encoder, NULL, filter); + ret = gst_omx_video_enc_negotiate_caps (encoder, NULL, filter); } + + g_value_unset (&val); + g_value_unset (&list); + return ret; } diff --git a/omx/gstomxvideoenc.h b/omx/gstomxvideoenc.h index e266537..7eab91f 100644 --- a/omx/gstomxvideoenc.h +++ b/omx/gstomxvideoenc.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. + * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,7 +29,6 @@ #include "gstomx.h" G_BEGIN_DECLS - #define GST_TYPE_OMX_VIDEO_ENC \ (gst_omx_video_enc_get_type()) #define GST_OMX_VIDEO_ENC(obj) \ @@ -41,7 +41,6 @@ G_BEGIN_DECLS (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_VIDEO_ENC)) #define GST_IS_OMX_VIDEO_ENC_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_VIDEO_ENC)) - typedef struct _GstOMXVideoEnc GstOMXVideoEnc; typedef struct _GstOMXVideoEncClass GstOMXVideoEncClass; @@ -49,6 +48,8 @@ struct _GstOMXVideoEnc { GstVideoEncoder parent; + GstBuffer *codec_data; + /* < protected > */ GstOMXComponent *enc; GstOMXPort *enc_in_port, *enc_out_port; @@ -69,13 +70,15 @@ struct _GstOMXVideoEnc /* TRUE if upstream is EOS */ gboolean eos; + gboolean hw_path; /* properties */ - guint32 control_rate; - guint32 target_bitrate; + guint32 rc_mode; + guint32 bitrate; guint32 quant_i_frames; guint32 quant_p_frames; guint32 quant_b_frames; + guint32 iframeinterval; GstFlowReturn downstream_flow_ret; }; @@ -86,13 +89,15 @@ struct _GstOMXVideoEncClass GstOMXClassData cdata; - gboolean (*set_format) (GstOMXVideoEnc * self, GstOMXPort * port, GstVideoCodecState * state); - GstCaps *(*get_caps) (GstOMXVideoEnc * self, GstOMXPort * port, GstVideoCodecState * state); - GstFlowReturn (*handle_output_frame) (GstOMXVideoEnc * self, GstOMXPort * port, GstOMXBuffer * buffer, GstVideoCodecFrame * frame); + gboolean (*set_format) (GstOMXVideoEnc * self, GstOMXPort * port, + GstVideoCodecState * state); + GstCaps *(*get_caps) (GstOMXVideoEnc * self, GstOMXPort * port, + GstVideoCodecState * state); + GstFlowReturn (*handle_output_frame) (GstOMXVideoEnc * self, + GstOMXPort * port, GstOMXBuffer * buffer, GstVideoCodecFrame * frame); }; GType gst_omx_video_enc_get_type (void); G_END_DECLS - #endif /* __GST_OMX_VIDEO_ENC_H__ */ diff --git a/omx/gstomxvideosink.c b/omx/gstomxvideosink.c new file mode 100644 index 0000000..54326f2 --- /dev/null +++ b/omx/gstomxvideosink.c @@ -0,0 +1,1452 @@ +/* GStreamer + * Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Suite 500, + * Boston, MA 02110-1335, USA. + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gst/gst.h> +#include <gst/video/gstvideosink.h> +#include <gst/video/gstvideometa.h> +#include <gst/video/gstvideopool.h> + +#include "gstomxvideosink.h" + +GST_DEBUG_CATEGORY_STATIC (gst_omx_video_sink_debug_category); +#define GST_CAT_DEFAULT gst_omx_video_sink_debug_category + +#define GST_OMX_SINK_MEMORY_TYPE "omxsink" + +/* OpenMax memory allocator Implementation */ + +typedef struct _GstOmxSinkMemory GstOmxSinkMemory; +typedef struct _GstOmxSinkMemoryAllocator GstOmxSinkMemoryAllocator; +typedef struct _GstOmxSinkMemoryAllocatorClass GstOmxSinkMemoryAllocatorClass; + +struct _GstOmxSinkMemory +{ + GstMemory mem; + + GstOMXBuffer *buf; +}; + +struct _GstOmxSinkMemoryAllocator +{ + GstAllocator parent; +}; + +struct _GstOmxSinkMemoryAllocatorClass +{ + GstAllocatorClass parent_class; +}; + +static GstMemory * +gst_omx_sink_memory_allocator_alloc_dummy (GstAllocator * allocator, gsize size, + GstAllocationParams * params) +{ + g_assert_not_reached (); + return NULL; +} + +static void +gst_omx_sink_memory_allocator_free (GstAllocator * allocator, GstMemory * mem) +{ + GstOmxSinkMemory *omem = (GstOmxSinkMemory *) mem; + g_slice_free (GstOmxSinkMemory, omem); +} + +static gpointer +gst_omx_sink_memory_map (GstMemory * mem, gsize maxsize, GstMapFlags flags) +{ + GstOmxSinkMemory *omem = (GstOmxSinkMemory *) mem; + return omem->buf->omx_buf->pBuffer + omem->mem.offset; +} + +static void +gst_omx_sink_memory_unmap (GstMemory * mem) +{ +} + +static GstMemory * +gst_omx_sink_memory_share (GstMemory * mem, gssize offset, gssize size) +{ + g_assert_not_reached (); + return NULL; +} + +GType gst_omx_sink_memory_allocator_get_type (void); +G_DEFINE_TYPE (GstOmxSinkMemoryAllocator, gst_omx_sink_memory_allocator, + GST_TYPE_ALLOCATOR); + +#define GST_TYPE_OMX_SINK_MEMORY_ALLOCATOR (gst_omx_sink_memory_allocator_get_type()) +#define GST_IS_OMX_SINK_MEMORY_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_OMX_SINK_MEMORY_ALLOCATOR)) + +#define DEFAULT_OVERLAY 1 +#define DEFAULT_OVERLAY_DEPTH 0 +#define DEFAULT_OVERLAY_X 0 +#define DEFAULT_OVERLAY_Y 0 +#define DEFAULT_OVERLAY_W 0 +#define DEFAULT_OVERLAY_H 0 + +enum +{ + PROP_0, + PROP_OVERLAY, + PROP_OVERLAY_DEPTH, + PROP_OVERLAY_X, + PROP_OVERLAY_Y, + PROP_OVERLAY_W, + PROP_OVERLAY_H +}; + +static void +gst_omx_sink_memory_allocator_class_init (GstOmxSinkMemoryAllocatorClass * + klass) +{ + GstAllocatorClass *allocator_class; + + allocator_class = (GstAllocatorClass *) klass; + + allocator_class->alloc = gst_omx_sink_memory_allocator_alloc_dummy; + allocator_class->free = gst_omx_sink_memory_allocator_free; +} + +static void +gst_omx_sink_memory_allocator_init (GstOmxSinkMemoryAllocator * allocator) +{ + GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator); + + alloc->mem_type = GST_OMX_SINK_MEMORY_TYPE; + alloc->mem_map = gst_omx_sink_memory_map; + alloc->mem_unmap = gst_omx_sink_memory_unmap; + alloc->mem_share = gst_omx_sink_memory_share; + + GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC); +} + +static GstMemory * +gst_omx_sink_memory_allocator_alloc (GstAllocator * allocator, + GstMemoryFlags flags, GstOMXBuffer * buf) +{ + GstOmxSinkMemory *mem; + + mem = g_slice_new (GstOmxSinkMemory); + /* the shared memory is always readonly */ + gst_memory_init (GST_MEMORY_CAST (mem), flags, allocator, NULL, + buf->omx_buf->nAllocLen, buf->port->port_def.nBufferAlignment, + 0, buf->omx_buf->nAllocLen); + + mem->buf = buf; + + return GST_MEMORY_CAST (mem); +} + +/* Buffer Pool of openmax buffers */ + +GQuark gst_omx_sink_data_quark = 0; +typedef struct _GstOmxSinkBufferPool GstOmxSinkBufferPool; +typedef struct _GstOmxSinkBufferPoolClass GstOmxSinkBufferPoolClass; +#define GST_OMX_SINK_BUFFER_POOL(pool) ((GstOmxSinkBufferPool *) pool) + +struct _GstOmxSinkBufferPool +{ + GstBufferPool parent; + + GstElement *element; + + GstCaps *caps; + gboolean add_videometa; + GstVideoInfo video_info; + + GstOMXComponent *component; + GstOMXPort *port; + + GstAllocator *allocator; + + /* Used during alloc to specify + * which buffer has to be wrapped. + */ + guint current_buffer_index; +}; + +struct _GstOmxSinkBufferPoolClass +{ + GstBufferPoolClass parent_class; +}; + +GType gst_omx_sink_buffer_pool_get_type (void); + +G_DEFINE_TYPE (GstOmxSinkBufferPool, gst_omx_sink_buffer_pool, + GST_TYPE_BUFFER_POOL); + +#define GST_TYPE_OMX_SINK_BUFFER_POOL (gst_omx_sink_buffer_pool_get_type()) + + +static void +gst_omx_sink_buffer_pool_finalize (GObject * object) +{ + GstOmxSinkBufferPool *pool = GST_OMX_SINK_BUFFER_POOL (object); + + if (pool->element) + gst_object_unref (pool->element); + pool->element = NULL; + + if (pool->allocator) + gst_object_unref (pool->allocator); + pool->allocator = NULL; + + if (pool->caps) + gst_caps_unref (pool->caps); + pool->caps = NULL; + + G_OBJECT_CLASS (gst_omx_sink_buffer_pool_parent_class)->finalize (object); +} + +static gboolean +gst_omx_sink_buffer_pool_start (GstBufferPool * bpool) +{ + GstOmxSinkBufferPool *pool = GST_OMX_SINK_BUFFER_POOL (bpool); + GstOmxVideoSink *self = GST_OMX_VIDEO_SINK (pool->element); + GstCaps *caps; + guint min, max; + GstStructure *config; + GstOMXPort *port = pool->port; + OMX_ERRORTYPE err = OMX_ErrorNone; + + + /* Only allow to start the pool if we still are attached + * to a component and port */ + GST_OBJECT_LOCK (pool); + if (!pool->component || !pool->port) { + GST_OBJECT_UNLOCK (pool); + return FALSE; + } + + config = gst_buffer_pool_get_config (bpool); + gst_buffer_pool_config_get_params (config, &caps, NULL, &min, &max); + gst_structure_free (config); + + min = MAX (min, max); + + if (min > port->port_def.nBufferCountActual) { + err = gst_omx_port_update_port_definition (port, NULL); + if (err == OMX_ErrorNone) { + port->port_def.nBufferCountActual = min; + err = gst_omx_port_update_port_definition (port, &port->port_def); + } + } + if (!gst_omx_port_is_enabled (port)) { + err = gst_omx_port_set_enabled (port, TRUE); + if (err != OMX_ErrorNone) { + GST_INFO_OBJECT (self, + "Failed to enable port: %s (0x%08x)", + gst_omx_error_to_string (err), err); + GST_OBJECT_UNLOCK (pool); + return FALSE; + } + if (gst_omx_port_allocate_buffers (self->sink_in_port) != OMX_ErrorNone) { + GST_OBJECT_UNLOCK (pool); + return FALSE; + } + if (gst_omx_port_wait_enabled (self->sink_in_port, + 5 * GST_SECOND) != OMX_ErrorNone) { + GST_OBJECT_UNLOCK (pool); + return FALSE; + } + } + + GST_OBJECT_UNLOCK (pool); + + return + GST_BUFFER_POOL_CLASS (gst_omx_sink_buffer_pool_parent_class)->start + (bpool); +} + +static gboolean +gst_omx_sink_buffer_pool_stop (GstBufferPool * bpool) +{ + GstOmxSinkBufferPool *pool = GST_OMX_SINK_BUFFER_POOL (bpool); + + if (pool->caps) + gst_caps_unref (pool->caps); + pool->caps = NULL; + + pool->add_videometa = FALSE; + + return + GST_BUFFER_POOL_CLASS (gst_omx_sink_buffer_pool_parent_class)->stop + (bpool); +} + +static const gchar ** +gst_omx_sink_buffer_pool_get_options (GstBufferPool * bpool) +{ + static const gchar *raw_video_options[] = + { GST_BUFFER_POOL_OPTION_VIDEO_META, NULL }; + static const gchar *options[] = { NULL }; + GstOmxSinkBufferPool *pool = GST_OMX_SINK_BUFFER_POOL (bpool); + + GST_OBJECT_LOCK (pool); + if (pool->port && pool->port->port_def.eDomain == OMX_PortDomainVideo + && pool->port->port_def.format.video.eCompressionFormat == + OMX_VIDEO_CodingUnused) { + GST_OBJECT_UNLOCK (pool); + return raw_video_options; + } + GST_OBJECT_UNLOCK (pool); + + return options; +} + +static gboolean +gst_omx_sink_buffer_pool_set_config (GstBufferPool * bpool, + GstStructure * config) +{ + GstOmxSinkBufferPool *pool = GST_OMX_SINK_BUFFER_POOL (bpool); + GstCaps *caps; + + GST_OBJECT_LOCK (pool); + + if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL)) + goto wrong_config; + + if (caps == NULL) + goto no_caps; + + if (pool->port && pool->port->port_def.eDomain == OMX_PortDomainVideo + && pool->port->port_def.format.video.eCompressionFormat == + OMX_VIDEO_CodingUnused) { + GstVideoInfo info; + + /* now parse the caps from the config */ + if (!gst_video_info_from_caps (&info, caps)) + goto wrong_video_caps; + + /* enable metadata based on config of the pool */ + pool->add_videometa = + gst_buffer_pool_config_has_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_META); + + pool->video_info = info; + } + + if (pool->caps) + gst_caps_unref (pool->caps); + pool->caps = gst_caps_ref (caps); + + GST_OBJECT_UNLOCK (pool); + + return + GST_BUFFER_POOL_CLASS (gst_omx_sink_buffer_pool_parent_class)->set_config + (bpool, config); + + /* ERRORS */ +wrong_config: + { + GST_OBJECT_UNLOCK (pool); + GST_WARNING_OBJECT (pool, "invalid config"); + return FALSE; + } +no_caps: + { + GST_OBJECT_UNLOCK (pool); + GST_WARNING_OBJECT (pool, "no caps in config"); + return FALSE; + } +wrong_video_caps: + { + GST_OBJECT_UNLOCK (pool); + GST_WARNING_OBJECT (pool, + "failed getting geometry from caps %" GST_PTR_FORMAT, caps); + return FALSE; + } +} + +static GstFlowReturn +gst_omx_sink_buffer_pool_alloc_buffer (GstBufferPool * bpool, + GstBuffer ** buffer, GstBufferPoolAcquireParams * params) +{ + GstOmxSinkBufferPool *pool = GST_OMX_SINK_BUFFER_POOL (bpool); + GstBuffer *buf; + GstOMXBuffer *omx_buf; + GstMemory *mem; + + omx_buf = g_ptr_array_index (pool->port->buffers, pool->current_buffer_index); + g_return_val_if_fail (omx_buf != NULL, GST_FLOW_ERROR); + + mem = gst_omx_sink_memory_allocator_alloc (pool->allocator, 0, omx_buf); + buf = gst_buffer_new (); + gst_buffer_append_memory (buf, mem); + + if (pool->add_videometa) { + gsize offset[4] = { 0, }; + gint stride[4] = { 0, }; + + switch (pool->video_info.finfo->format) { + case GST_VIDEO_FORMAT_I420: + offset[0] = 0; + stride[0] = pool->port->port_def.format.video.nStride; + offset[1] = stride[0] * pool->port->port_def.format.video.nSliceHeight; + stride[1] = pool->port->port_def.format.video.nStride / 2; + offset[2] = + offset[1] + + stride[1] * (pool->port->port_def.format.video.nSliceHeight / 2); + stride[2] = pool->port->port_def.format.video.nStride / 2; + break; + case GST_VIDEO_FORMAT_NV12: + offset[0] = 0; + stride[0] = pool->port->port_def.format.video.nStride; + offset[1] = stride[0] * pool->port->port_def.format.video.nSliceHeight; + stride[1] = pool->port->port_def.format.video.nStride; + break; + default: + g_assert_not_reached (); + break; + } + + gst_buffer_add_video_meta_full (buf, GST_VIDEO_FRAME_FLAG_NONE, + GST_VIDEO_INFO_FORMAT (&pool->video_info), + GST_VIDEO_INFO_WIDTH (&pool->video_info), + GST_VIDEO_INFO_HEIGHT (&pool->video_info), + GST_VIDEO_INFO_N_PLANES (&pool->video_info), offset, stride); + } + + gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (buf), + gst_omx_sink_data_quark, omx_buf, NULL); + + *buffer = buf; + + pool->current_buffer_index++; + + return GST_FLOW_OK; +} + +static void +gst_omx_sink_buffer_pool_free_buffer (GstBufferPool * bpool, GstBuffer * buffer) +{ + GstOmxSinkBufferPool *pool = GST_OMX_SINK_BUFFER_POOL (bpool); + + gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (buffer), + gst_omx_sink_data_quark, NULL, NULL); + + GST_BUFFER_POOL_CLASS (gst_omx_sink_buffer_pool_parent_class)->free_buffer + (bpool, buffer); + + pool->current_buffer_index--; +} + +static void +gst_omx_sink_buffer_pool_class_init (GstOmxSinkBufferPoolClass * klass) +{ + GObjectClass *gobject_class = (GObjectClass *) klass; + GstBufferPoolClass *gstbufferpool_class = (GstBufferPoolClass *) klass; + + gst_omx_sink_data_quark = g_quark_from_static_string ("GstOmxSinkBufferData"); + + gobject_class->finalize = gst_omx_sink_buffer_pool_finalize; + gstbufferpool_class->start = gst_omx_sink_buffer_pool_start; + gstbufferpool_class->stop = gst_omx_sink_buffer_pool_stop; + gstbufferpool_class->get_options = gst_omx_sink_buffer_pool_get_options; + gstbufferpool_class->set_config = gst_omx_sink_buffer_pool_set_config; + gstbufferpool_class->alloc_buffer = gst_omx_sink_buffer_pool_alloc_buffer; + gstbufferpool_class->free_buffer = gst_omx_sink_buffer_pool_free_buffer; +} + +static void +gst_omx_sink_buffer_pool_init (GstOmxSinkBufferPool * pool) +{ + pool->allocator = + g_object_new (gst_omx_sink_memory_allocator_get_type (), NULL); + pool->current_buffer_index = 0; +} + +static GstBufferPool * +gst_omx_sink_buffer_pool_new (GstElement * element, GstOMXComponent * component, + GstOMXPort * port) +{ + GstOmxSinkBufferPool *pool; + + pool = g_object_new (GST_TYPE_OMX_SINK_BUFFER_POOL, NULL); + pool->element = gst_object_ref (element); + pool->component = component; + pool->port = port; + + return GST_BUFFER_POOL (pool); +} + +/* prototypes */ + +static GstFlowReturn +gst_omx_video_sink_show_frame (GstVideoSink * video_sink, GstBuffer * buf); + +static void +gst_omx_video_sink_check_nvfeatures (GstOmxVideoSink * self, GstCaps * caps); + +gboolean gst_omx_video_sink_start (GstBaseSink * sink); +gboolean gst_omx_video_sink_stop (GstBaseSink * videosink); +gboolean gst_omx_video_sink_setcaps (GstBaseSink * sink, GstCaps * caps); +GstCaps *gst_omx_video_sink_getcaps (GstBaseSink * sink, GstCaps * filter); +gboolean gst_omx_video_sink_propose_allocation (GstBaseSink * sink, + GstQuery * query); +void gst_omx_video_sink_get_times (GstBaseSink * sink, GstBuffer * buffer, + GstClockTime * start, GstClockTime * end); +static gboolean gst_omx_video_sink_shutdown (GstOmxVideoSink * self); +static gboolean +gst_omx_video_sink_event (GstBaseSink * sink, GstEvent * event); + +static void +gst_omx_video_sink_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void +gst_omx_video_sink_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + +/* class initialization */ + +#define gst_omx_video_sink_parent_class parent_class + +G_DEFINE_TYPE_WITH_CODE (GstOmxVideoSink, gst_omx_video_sink, + GST_TYPE_VIDEO_SINK, + GST_DEBUG_CATEGORY_INIT (gst_omx_video_sink_debug_category, "omxvideosink", + 0, "debug category for omxvideosink element")); + + +static OMX_ERRORTYPE +Update_Overlay_PlaneBlend (GstOmxVideoSink * self) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_CONFIG_PLANEBLENDTYPE odepth; + + GST_OMX_INIT_STRUCT (&odepth); + odepth.nPortIndex = self->sink_in_port->index; + + eError = + gst_omx_component_get_config (GST_OMX_VIDEO_SINK (self)->sink, + OMX_IndexConfigCommonPlaneBlend, + &odepth); + if (eError == OMX_ErrorNone) { + odepth.nDepth = self->overlay_depth; + eError = + gst_omx_component_set_config (GST_OMX_VIDEO_SINK (self)->sink, + OMX_IndexConfigCommonPlaneBlend, + &odepth); + } + + return eError; +} + + +static OMX_ERRORTYPE +Update_Overlay_Position (GstOmxVideoSink * self) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_CONFIG_POINTTYPE position; + + if (self->update_pos) { + GST_OMX_INIT_STRUCT (&position); + position.nPortIndex = self->sink_in_port->index; + + eError = + gst_omx_component_get_config (GST_OMX_VIDEO_SINK (self)->sink, + OMX_IndexConfigCommonOutputPosition, + &position); + if (eError == OMX_ErrorNone) { + position.nX = self->overlay_x; + position.nY = self->overlay_y; + eError = + gst_omx_component_set_config (GST_OMX_VIDEO_SINK (self)->sink, + OMX_IndexConfigCommonOutputPosition, + &position); + self->update_pos = FALSE; + } + } + + return eError; +} + +static OMX_ERRORTYPE +Update_Overlay_Size (GstOmxVideoSink * self) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_FRAMESIZETYPE osize; + + if (self->update_size) { + GST_OMX_INIT_STRUCT (&osize); + osize.nPortIndex = self->sink_in_port->index; + + eError = + gst_omx_component_get_config (GST_OMX_VIDEO_SINK (self)->sink, + OMX_IndexConfigCommonOutputSize, + &osize); + if (eError == OMX_ErrorNone) { + osize.nWidth = self->overlay_w; + osize.nHeight = self->overlay_h; + eError = + gst_omx_component_set_config (GST_OMX_VIDEO_SINK (self)->sink, + OMX_IndexConfigCommonOutputSize, + &osize); + self->update_size = FALSE; + } + } + + return eError; +} + +static GstStateChangeReturn +gst_omx_video_sink_change_state (GstElement * element, + GstStateChange transition) +{ + GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; + GstOmxVideoSink *omxsink; + + omxsink = GST_OMX_VIDEO_SINK (element); + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + break; + case GST_STATE_CHANGE_READY_TO_PAUSED: + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + omxsink->fps_n = 0; + omxsink->fps_d = 1; + GST_VIDEO_SINK_WIDTH (omxsink) = 0; + GST_VIDEO_SINK_HEIGHT (omxsink) = 0; + + g_mutex_lock (&omxsink->flow_lock); + if (omxsink->pool) + gst_buffer_pool_set_active (omxsink->pool, FALSE); + g_mutex_unlock (&omxsink->flow_lock); + + if (omxsink->sink_in_port) + gst_omx_port_set_flushing (omxsink->sink_in_port, 5 * GST_SECOND, TRUE); + break; + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + break; + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + + switch (transition) { + case GST_STATE_CHANGE_PLAYING_TO_PAUSED: + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + /* + * When running a stream in loop, the pipeline is set in READY state. + * In this state we need to ensure that buffers on input port of + * sink are deallocated without the sink going in NULL state. + * reconfigure flag is set here which is checked in setcaps function + * to reconfigure sink's input port incase setcaps is called again. + */ + omxsink->sink_in_port->reconfigure = TRUE; + break; + case GST_STATE_CHANGE_READY_TO_NULL: + break; + default: + break; + } + + return ret; +} + +static void +gst_omx_video_sink_class_init (GstOmxVideoSinkClass * klass) +{ + GstElementClass *gstelement_class = (GstElementClass *) klass; + GstVideoSinkClass *videosink_class = GST_VIDEO_SINK_CLASS (klass); + GstBaseSinkClass *basesink_class = GST_BASE_SINK_CLASS (klass); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gstelement_class->change_state = gst_omx_video_sink_change_state; + + gobject_class->set_property = gst_omx_video_sink_set_property; + gobject_class->get_property = gst_omx_video_sink_get_property; + + basesink_class->start = GST_DEBUG_FUNCPTR (gst_omx_video_sink_start); + basesink_class->stop = GST_DEBUG_FUNCPTR (gst_omx_video_sink_stop); + basesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_omx_video_sink_setcaps); + basesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_omx_video_sink_getcaps); + basesink_class->get_times = GST_DEBUG_FUNCPTR (gst_omx_video_sink_get_times); + basesink_class->propose_allocation = + GST_DEBUG_FUNCPTR (gst_omx_video_sink_propose_allocation); + basesink_class->event = GST_DEBUG_FUNCPTR (gst_omx_video_sink_event); + + videosink_class->show_frame = + GST_DEBUG_FUNCPTR (gst_omx_video_sink_show_frame); + + /* + * Overlay Index. + */ + g_object_class_install_property (gobject_class, PROP_OVERLAY, + g_param_spec_uint ("overlay", "overlay", + "Overlay index", 1, 2, + DEFAULT_OVERLAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /* + * Overlay Depth. + */ + g_object_class_install_property (gobject_class, PROP_OVERLAY_DEPTH, + g_param_spec_uint ("overlay-depth", "overlay-depth", + "Overlay depth", 0, 2, + DEFAULT_OVERLAY_DEPTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /* + * Overlay X coordinate. + */ + g_object_class_install_property (gobject_class, PROP_OVERLAY_X, + g_param_spec_uint ("overlay-x", "overlay-x", + "Overlay X coordinate", 0, G_MAXUINT, + DEFAULT_OVERLAY_X, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /* + * Overlay Y coordinate. + */ + g_object_class_install_property (gobject_class, PROP_OVERLAY_Y, + g_param_spec_uint ("overlay-y", "overlay-y", + "Overlay Y coordinate", 0, G_MAXUINT, + DEFAULT_OVERLAY_Y, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /* + * Overlay Width. + */ + g_object_class_install_property (gobject_class, PROP_OVERLAY_W, + g_param_spec_uint ("overlay-w", "overlay-w", + "Overlay Width", 0, G_MAXUINT, + DEFAULT_OVERLAY_W, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /* + * Overlay Height. + */ + g_object_class_install_property (gobject_class, PROP_OVERLAY_H, + g_param_spec_uint ("overlay-h", "overlay-h", + "Overlay Height", 0, G_MAXUINT, + DEFAULT_OVERLAY_H, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +} + +static void +gst_omx_video_sink_init (GstOmxVideoSink * omxvideosink) +{ + omxvideosink->fps_n = 0; + omxvideosink->fps_d = 1; + omxvideosink->cur_buf = NULL; + omxvideosink->hw_path = FALSE; + + omxvideosink->overlay = DEFAULT_OVERLAY; + omxvideosink->overlay_depth = DEFAULT_OVERLAY_DEPTH; + omxvideosink->overlay_x = DEFAULT_OVERLAY_X; + omxvideosink->overlay_y = DEFAULT_OVERLAY_Y; + omxvideosink->overlay_w = DEFAULT_OVERLAY_W; + omxvideosink->overlay_h = DEFAULT_OVERLAY_H; + + omxvideosink->update_pos = FALSE; + omxvideosink->update_size = FALSE; +} + +static void +gst_omx_video_sink_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstOmxVideoSink * self = GST_OMX_VIDEO_SINK (object); + + switch (prop_id) { + case PROP_OVERLAY: + self->overlay = g_value_get_uint (value); + break; + case PROP_OVERLAY_DEPTH: + self->overlay_depth = g_value_get_uint (value); + break; + case PROP_OVERLAY_X: + { + guint x = g_value_get_uint (value); + if (self->overlay_x != x) + self->update_pos = TRUE; + self->overlay_x = x; + } + break; + case PROP_OVERLAY_Y: + { + guint y = g_value_get_uint (value); + if (self->overlay_y != y) + self->update_pos = TRUE; + self->overlay_y = y; + } + break; + case PROP_OVERLAY_W: + { + guint w = g_value_get_uint (value); + if (self->overlay_w != w) + self->update_size = TRUE; + self->overlay_w = w; + } + break; + case PROP_OVERLAY_H: + { + guint h = g_value_get_uint (value); + if (self->overlay_h != h) + self->update_size = TRUE; + self->overlay_h = h; + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_omx_video_sink_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstOmxVideoSink * self = GST_OMX_VIDEO_SINK (object); + + switch (prop_id) { + case PROP_OVERLAY: + g_value_set_uint (value, self->overlay); + break; + case PROP_OVERLAY_DEPTH: + g_value_set_uint (value, self->overlay_depth); + break; + case PROP_OVERLAY_X: + g_value_set_uint (value, self->overlay_x); + break; + case PROP_OVERLAY_Y: + g_value_set_uint (value, self->overlay_y); + break; + case PROP_OVERLAY_W: + g_value_set_uint (value, self->overlay_w); + break; + case PROP_OVERLAY_H: + g_value_set_uint (value, self->overlay_h); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +gboolean +gst_omx_video_sink_start (GstBaseSink * videosink) +{ + GstOmxVideoSink *self = GST_OMX_VIDEO_SINK (videosink); + GstOmxVideoSinkClass *klass = GST_OMX_VIDEO_SINK_GET_CLASS (self); + gint in_port_index; + + GST_DEBUG_OBJECT (self, "opening video renderer"); + + self->sink = + gst_omx_component_new (GST_OBJECT_CAST (self), klass->cdata.core_name, + klass->cdata.component_name, klass->cdata.component_role, + klass->cdata.hacks); + + if (!self->sink) + return FALSE; + + if (gst_omx_component_get_state (self->sink, + GST_CLOCK_TIME_NONE) != OMX_StateLoaded) + return FALSE; + + in_port_index = klass->cdata.in_port_index; + + if (in_port_index == -1) { + OMX_PORT_PARAM_TYPE param; + OMX_ERRORTYPE err; + + GST_OMX_INIT_STRUCT (¶m); + + err = + gst_omx_component_get_parameter (self->sink, OMX_IndexParamVideoInit, + ¶m); + if (err != OMX_ErrorNone) { + GST_WARNING_OBJECT (self, "Couldn't get port information: %s (0x%08x)", + gst_omx_error_to_string (err), err); + /* Fallback */ + in_port_index = 0; + } else { + GST_DEBUG_OBJECT (self, "Detected %lu ports, starting at %lu", + param.nPorts, param.nStartPortNumber); + in_port_index = param.nStartPortNumber + 0; + } + } + self->sink_in_port = gst_omx_component_add_port (self->sink, in_port_index); + + if (!self->sink_in_port) + return FALSE; + + GST_DEBUG_OBJECT (self, "Opened the video renderer"); + + return TRUE; +} + +static gboolean +gst_omx_video_sink_shutdown (GstOmxVideoSink * self) +{ + OMX_STATETYPE state; + + GST_DEBUG_OBJECT (self, "Shutting down renderer"); + + state = gst_omx_component_get_state (self->sink, 0); + + if (state > OMX_StateLoaded || state == OMX_StateInvalid) { + if (state > OMX_StateIdle) { + gst_omx_component_set_state (self->sink, OMX_StateIdle); + gst_omx_component_get_state (self->sink, 5 * GST_SECOND); + } + gst_omx_component_set_state (self->sink, OMX_StateLoaded); + gst_omx_port_deallocate_buffers (self->sink_in_port); + + if (state > OMX_StateLoaded) + gst_omx_component_get_state (self->sink, 5 * GST_SECOND); + } + + return TRUE; +} + +gboolean +gst_omx_video_sink_stop (GstBaseSink * videosink) +{ + GstOmxVideoSink *self = GST_OMX_VIDEO_SINK (videosink); + + GST_DEBUG_OBJECT (self, "Closing renderer"); + + if (!gst_omx_video_sink_shutdown (self)) + return FALSE; + + self->sink_in_port = NULL; + if (self->sink) + gst_omx_component_free (self->sink); + + self->sink = NULL; + + if (self->pool) + gst_object_unref (self->pool); + self->pool = NULL; + + GST_DEBUG_OBJECT (self, "Closed renderer"); + + return TRUE; +} + +static void +gst_omx_video_sink_check_nvfeatures (GstOmxVideoSink * self, GstCaps * caps) +{ + GstCapsFeatures *feature; + feature = gst_caps_get_features (caps, 0); + if (gst_caps_features_contains (feature, "memory:NVMM")) { + self->hw_path = TRUE; + } +} + +static OMX_ERRORTYPE +gstomx_use_allow_secondary_window_extension (GstOmxVideoSink * self) +{ + NVX_CONFIG_ALLOWSECONDARYWINDOW param; + OMX_INDEXTYPE eIndex; + OMX_ERRORTYPE eError = OMX_ErrorNone; + + eError = gst_omx_component_get_index (GST_OMX_VIDEO_SINK (self)->sink, + (char *) NVX_INDEX_CONFIG_ALLOWSECONDARYWINDOW, &eIndex); + if (eError == OMX_ErrorNone) { + GST_OMX_INIT_STRUCT (¶m); + param.nPortIndex = self->sink_in_port->index; + param.bAllow = OMX_TRUE; + eError = + gst_omx_component_set_config (GST_OMX_VIDEO_SINK (self)->sink, + eIndex, + ¶m); + } + + if (eError != OMX_ErrorNone) { + g_error ("Couldnt use the Vendor Extension %s \n", + (char *) NVX_INDEX_CONFIG_ALLOWSECONDARYWINDOW); + } + + return eError; +} + +static OMX_ERRORTYPE +gstomx_use_overlay_index_extension (GstOmxVideoSink * self) +{ + NVX_CONFIG_OVERLAYINDEX param; + OMX_INDEXTYPE eIndex; + OMX_ERRORTYPE eError = OMX_ErrorNone; + + eError = gst_omx_component_get_index (GST_OMX_VIDEO_SINK (self)->sink, + (char *) NVX_INDEX_CONFIG_OVERLAYINDEX, &eIndex); + if (eError == OMX_ErrorNone) { + GST_OMX_INIT_STRUCT (¶m); + param.nPortIndex = self->sink_in_port->index; + param.index = self->overlay; + eError = + gst_omx_component_set_config (GST_OMX_VIDEO_SINK (self)->sink, + eIndex, + ¶m); + } + + if (eError != OMX_ErrorNone) { + g_error ("Couldnt use the Vendor Extension %s \n", + (char *) NVX_INDEX_CONFIG_OVERLAYINDEX); + } + + return eError; +} + +gboolean +gst_omx_video_sink_setcaps (GstBaseSink * sink, GstCaps * caps) +{ + GstOmxVideoSink *self = GST_OMX_VIDEO_SINK (sink); + GstVideoInfo info; + GstBufferPool *newpool, *oldpool; + GstStructure *config; + gint size, min; + gboolean is_format_change = FALSE; + gboolean needs_disable = FALSE; + OMX_PARAM_PORTDEFINITIONTYPE port_def; + + if (!gst_video_info_from_caps (&info, caps)) + goto invalid_format; + + GST_DEBUG_OBJECT (self, "Setting new caps %" GST_PTR_FORMAT, caps); + + gst_omx_port_get_port_definition (self->sink_in_port, &port_def); + gst_omx_video_sink_check_nvfeatures (self, caps); + + /* Check if the caps change is a real format change or if only irrelevant + * parts of the caps have changed or nothing at all. + */ + is_format_change |= port_def.format.video.nFrameWidth != info.width; + is_format_change |= port_def.format.video.nFrameHeight != info.height; + + is_format_change |= (port_def.format.video.xFramerate == 0 && info.fps_n != 0) + || (port_def.format.video.xFramerate != + (info.fps_n << 16) / (info.fps_d)); + + needs_disable = + gst_omx_component_get_state (self->sink, + GST_CLOCK_TIME_NONE) != OMX_StateLoaded; + + if (needs_disable && !is_format_change && !self->sink_in_port->reconfigure) { + GST_DEBUG_OBJECT (self, + "Already running and caps did not change the format"); + return TRUE; + } + + if (needs_disable && (is_format_change || self->sink_in_port->reconfigure)) { + + GstOMXPort *in_port = self->sink_in_port; + + GST_DEBUG_OBJECT (self, "Need to disable renderer"); + + self->sink_in_port->reconfigure = FALSE; + gst_omx_port_set_flushing (in_port, 5 * GST_SECOND, TRUE); + + if (gst_omx_port_set_enabled (self->sink_in_port, FALSE) != OMX_ErrorNone) + return FALSE; + + if (gst_omx_port_wait_buffers_released (self->sink_in_port, + 5 * GST_SECOND) != OMX_ErrorNone) + return FALSE; + + if (gst_omx_port_deallocate_buffers (self->sink_in_port) != OMX_ErrorNone) + return FALSE; + + if (gst_omx_port_wait_enabled (self->sink_in_port, + 1 * GST_SECOND) != OMX_ErrorNone) + return FALSE; + } + + GST_VIDEO_SINK_WIDTH (self) = info.width; + GST_VIDEO_SINK_HEIGHT (self) = info.height; + self->fps_n = info.fps_n; + self->fps_d = info.fps_d; + + port_def.format.video.nFrameWidth = info.width; + port_def.format.video.nFrameHeight = info.height; + if (info.fps_n == 0) + port_def.format.video.xFramerate = 0; + else + port_def.format.video.xFramerate = (info.fps_n << 16) / (info.fps_d); + + port_def.nBufferSize = info.size; + size = info.size; + min = MAX (port_def.nBufferCountMin, 4); + port_def.nBufferCountActual = min; + + GST_DEBUG_OBJECT (self, "Setting inport port definition"); + + if (gst_omx_port_update_port_definition (self->sink_in_port, + &port_def) != OMX_ErrorNone) + return FALSE; + + GST_DEBUG_OBJECT (self, "Enabling component"); + + if (needs_disable) { + if (gst_omx_port_mark_reconfigured (self->sink_in_port) != OMX_ErrorNone) + return FALSE; + } else { + if (gst_omx_port_set_enabled (self->sink_in_port, FALSE) != OMX_ErrorNone) + return FALSE; + + if (gst_omx_port_wait_enabled (self->sink_in_port, + 1 * GST_SECOND) != OMX_ErrorNone) + return FALSE; + + if (gst_omx_component_set_state (self->sink, + OMX_StateIdle) != OMX_ErrorNone) + return FALSE; + + if (gst_omx_component_get_state (self->sink, + GST_CLOCK_TIME_NONE) != OMX_StateIdle) + return FALSE; + + if (gst_omx_component_set_state (self->sink, + OMX_StateExecuting) != OMX_ErrorNone) + return FALSE; + + if (gst_omx_component_get_state (self->sink, + GST_CLOCK_TIME_NONE) != OMX_StateExecuting) + return FALSE; + } + + /* Unset flushing to allow ports to accept data again */ + gst_omx_port_set_flushing (self->sink_in_port, 5 * GST_SECOND, FALSE); + + if (gst_omx_component_get_last_error (self->sink) != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, "Component in error state: %s (0x%08x)", + gst_omx_component_get_last_error_string (self->sink), + gst_omx_component_get_last_error (self->sink)); + return FALSE; + } + + g_mutex_lock (&self->flow_lock); + newpool = + gst_omx_sink_buffer_pool_new (GST_ELEMENT_CAST (self), self->sink, + self->sink_in_port); + + config = gst_buffer_pool_get_config (newpool); + gst_buffer_pool_config_set_params (config, caps, size, min, min); + gst_buffer_pool_config_set_allocator (config, + ((GstOmxSinkBufferPool *) newpool)->allocator, NULL); + if (!gst_buffer_pool_set_config (newpool, config)) + goto config_failed; + + oldpool = self->pool; + self->pool = newpool; + g_mutex_unlock (&self->flow_lock); + + /* unref the old sink */ + if (oldpool) { + gst_object_unref (oldpool); + } + +#ifdef USE_OMX_TARGET_TEGRA + gstomx_use_allow_secondary_window_extension (self); + gstomx_use_overlay_index_extension (self); +#endif + + if (OMX_ErrorNone != Update_Overlay_PlaneBlend (self)) + GST_ERROR_OBJECT (self, "Failed to set Overlay depth"); + + if (OMX_ErrorNone != Update_Overlay_Position (self)) + GST_ERROR_OBJECT (self, "Failed to set Overlay Position"); + + if (OMX_ErrorNone != Update_Overlay_Size (self)) + GST_ERROR_OBJECT (self, "Failed to set Overlay Width"); + + return TRUE; + +config_failed: + { + GST_ERROR_OBJECT (self, "failed to set config."); + g_mutex_unlock (&self->flow_lock); + return FALSE; + } +invalid_format: + { + GST_ERROR_OBJECT (self, "caps invalid"); + return FALSE; + } +} + +GstCaps * +gst_omx_video_sink_getcaps (GstBaseSink * sink, GstCaps * filter) +{ + GstCaps *caps = NULL; + GstOmxVideoSink *self = GST_OMX_VIDEO_SINK (sink); + + caps = gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD (self)); + + if (filter) { + GstCaps *intersection; + + intersection = + gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (caps); + caps = intersection; + } + + return caps; +} + +static GstFlowReturn +gst_omx_video_sink_show_frame (GstVideoSink * video_sink, GstBuffer * buf) +{ + + GstOmxVideoSink *self = GST_OMX_VIDEO_SINK (video_sink); + GstOMXBuffer *omxbuf; + GstMemory *mem; + GstFlowReturn res = GST_FLOW_OK; + GstClockTime bufpts = GST_BUFFER_PTS (buf); + OMX_ERRORTYPE err = OMX_ErrorNone; + + GST_DEBUG_OBJECT (self, "Received the frame"); + + /* + if (buf && self->cur_buf != buf) { + if (self->cur_buf) { + GST_LOG_OBJECT (self, "unreffing %p", self->cur_buf); + gst_buffer_unref (self->cur_buf); + } + GST_LOG_OBJECT (self, "reffing %p as our current buffer", buf); + self->cur_buf = gst_buffer_ref (buf); + } + */ + + mem = gst_buffer_peek_memory (buf, 0); + + if (mem + && g_strcmp0 (mem->allocator->mem_type, GST_OMX_SINK_MEMORY_TYPE) == 0) { + /* Buffer from our pool, can be directly released without copy */ + + omxbuf = gst_mini_object_get_qdata (GST_MINI_OBJECT_CAST (buf), + gst_omx_sink_data_quark); + + gst_omx_handle_messages (self->sink); + + /* + * The number of buffers in the decoder output pool is maintained + * using the length of the pending_buffers queue + */ + g_queue_pop_head (&self->sink_in_port->pending_buffers); + + /* + * To prevent deadlock when no buffers are available in the + * decoder output buffer pool, we make sure there is at least + * one buffer in the pool + */ + while (g_queue_get_length (&self->sink_in_port->pending_buffers) == 0) { + g_mutex_lock (&self->sink->messages_lock); + g_cond_wait (&self->sink->messages_cond, &self->sink->messages_lock); + g_mutex_unlock (&self->sink->messages_lock); + gst_omx_handle_messages (self->sink); + } + res = GST_FLOW_OK; + } else { +/* Buffer is not from our pool, copy data */ + + GstMapInfo map = GST_MAP_INFO_INIT; + GstOMXPort *port = self->sink_in_port; + + if (!gst_omx_port_is_enabled (port)) { + err = gst_omx_port_set_enabled (port, TRUE); + if (err != OMX_ErrorNone) { + GST_INFO_OBJECT (self, + "Failed to enable port: %s (0x%08x)", + gst_omx_error_to_string (err), err); + res = GST_FLOW_ERROR; + goto done; + } + + if (gst_omx_port_allocate_buffers (self->sink_in_port) != OMX_ErrorNone) { + res = GST_FLOW_ERROR; + goto done; + } + + if (gst_omx_port_wait_enabled (self->sink_in_port, + 5 * GST_SECOND) != OMX_ErrorNone) { + res = GST_FLOW_ERROR; + goto done; + } + } + + if (gst_omx_port_acquire_buffer (self->sink_in_port, + &omxbuf) != GST_OMX_ACQUIRE_BUFFER_OK) { + res = GST_FLOW_ERROR; + goto done; + } + gst_buffer_map (buf, &map, GST_MAP_READ); + memcpy (omxbuf->omx_buf->pBuffer + omxbuf->omx_buf->nOffset, + map.data, map.size); + gst_buffer_unmap (buf, &map); + } + omxbuf->omx_buf->nFilledLen = mem->size; + omxbuf->gst_buf = gst_buffer_ref (buf); + + if (self->hw_path) + omxbuf->omx_buf->nFlags |= OMX_BUFFERFLAG_NV_BUFFER; + + if (GST_CLOCK_TIME_IS_VALID (bufpts)) + omxbuf->omx_buf->nTimeStamp = + gst_util_uint64_scale (bufpts, OMX_TICKS_PER_SECOND, GST_SECOND); + else + omxbuf->omx_buf->nTimeStamp = 0; + + gst_omx_port_release_buffer (self->sink_in_port, omxbuf); + +done: + + return res; +} + +gboolean +gst_omx_video_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query) +{ + GstOmxVideoSink *omxsink = GST_OMX_VIDEO_SINK (bsink); + GstBufferPool *pool; + GstStructure *config; + GstCaps *caps; + guint size; + gboolean need_pool; + + gst_query_parse_allocation (query, &caps, &need_pool); + + if (caps == NULL) + goto no_caps; + + g_mutex_lock (&omxsink->flow_lock); + if ((pool = omxsink->pool)) + gst_object_ref (pool); + g_mutex_unlock (&omxsink->flow_lock); + + if (pool != NULL) { + GstCaps *pcaps; + + /* we had a pool, check caps */ + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_get_params (config, &pcaps, &size, NULL, NULL); + + GST_DEBUG_OBJECT (omxsink, + "we had a pool with caps %" GST_PTR_FORMAT, pcaps); + if (!gst_caps_is_equal (caps, pcaps)) { + /* different caps, we can't use this pool */ + GST_DEBUG_OBJECT (omxsink, "pool has different caps"); + gst_object_unref (pool); + pool = NULL; + } + gst_structure_free (config); + } + if (pool == NULL && need_pool) { + GstVideoInfo info; + + if (!gst_video_info_from_caps (&info, caps)) + goto invalid_caps; + + GST_DEBUG_OBJECT (omxsink, "create new pool"); + pool = + gst_omx_sink_buffer_pool_new (GST_ELEMENT_CAST (omxsink), omxsink->sink, + omxsink->sink_in_port); + + /* the normal size of a frame */ + size = info.size; + + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_set_params (config, caps, size, 2, 4); + gst_buffer_pool_config_set_allocator (config, + ((GstOmxSinkBufferPool *) pool)->allocator, NULL); + if (!gst_buffer_pool_set_config (pool, config)) + goto config_failed; + } + if (pool) { + gst_query_add_allocation_pool (query, pool, size, 2, 4); + gst_query_add_allocation_param (query, + ((GstOmxSinkBufferPool *) pool)->allocator, NULL); + gst_object_unref (pool); + } + gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); + + return TRUE; + + /* ERRORS */ +no_caps: + { + GST_DEBUG_OBJECT (bsink, "no caps specified"); + return FALSE; + } +invalid_caps: + { + GST_DEBUG_OBJECT (bsink, "invalid caps specified"); + return FALSE; + } +config_failed: + { + GST_DEBUG_OBJECT (bsink, "failed setting config"); + gst_object_unref (pool); + return FALSE; + } +} + +void +gst_omx_video_sink_get_times (GstBaseSink * sink, GstBuffer * buffer, + GstClockTime * start, GstClockTime * end) +{ + GstOmxVideoSink *self; + + self = GST_OMX_VIDEO_SINK (sink); + + if (GST_BUFFER_PTS_IS_VALID (buffer)) { + *start = GST_BUFFER_PTS (buffer); + if (GST_BUFFER_DURATION_IS_VALID (buffer)) { + *end = *start + GST_BUFFER_DURATION (buffer); + } else { + if (self->fps_n > 0) { + *end = *start + + gst_util_uint64_scale_int (GST_SECOND, self->fps_d, self->fps_n); + } + } + } +} + +static gboolean +gst_omx_video_sink_event (GstBaseSink * sink, GstEvent * event) +{ + + GstOmxVideoSink *omxsink = GST_OMX_VIDEO_SINK (sink); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_CUSTOM_DOWNSTREAM: { + if (gst_event_has_name (event, "ReleaseLastBuffer")) { + GstOMXBuffer *omxbuf; + gst_omx_port_acquire_buffer (omxsink->sink_in_port, &omxbuf); + omxbuf->gst_buf = NULL; + + if (G_LIKELY (omxbuf)) { + omxbuf->omx_buf->nFilledLen = 0; + omxbuf->omx_buf->nFlags |= OMX_BUFFERFLAG_EOS; + gst_omx_port_release_buffer (omxsink->sink_in_port, omxbuf); + } + if (gst_base_sink_is_last_sample_enabled (sink)) { + gst_base_sink_set_last_sample_enabled(sink, FALSE); + gst_base_sink_set_last_sample_enabled(sink, TRUE); + } + gst_omx_port_wait_buffers_released (omxsink->sink_in_port, + 5 * GST_SECOND); + } + break; + } + default: + break; + } + return GST_BASE_SINK_CLASS (parent_class)->event (sink, event); +} diff --git a/omx/gstomxvideosink.h b/omx/gstomxvideosink.h new file mode 100644 index 0000000..7fe812d --- /dev/null +++ b/omx/gstomxvideosink.h @@ -0,0 +1,76 @@ +/* GStreamer + * Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GST_OMX_VIDEO_SINK_H_ +#define _GST_OMX_VIDEO_SINK_H_ + +#include <gst/video/gstvideosink.h> +#include "gstomx.h" +#include <gst/video/video.h> +#include <gst/video/gstvideodecoder.h> + +G_BEGIN_DECLS +#define GST_TYPE_OMX_VIDEO_SINK (gst_omx_video_sink_get_type()) +#define GST_OMX_VIDEO_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_VIDEO_SINK,GstOmxVideoSink)) +#define GST_OMX_VIDEO_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_VIDEO_SINK,GstOmxVideoSinkClass)) +#define GST_OMX_VIDEO_SINK_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_VIDEO_SINK,GstOmxVideoSinkClass)) +#define GST_IS_OMX_VIDEO_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_VIDEO_SINK)) +#define GST_IS_OMX_VIDEO_SINK_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_VIDEO_SINK)) +typedef struct _GstOmxVideoSink GstOmxVideoSink; +typedef struct _GstOmxVideoSinkClass GstOmxVideoSinkClass; + +struct _GstOmxVideoSink +{ + GstVideoSink parent; + + GstOMXComponent *sink; + GstOMXPort *sink_in_port; + + /* Framerate numerator and denominator */ + gint fps_n; + gint fps_d; + + GstBufferPool *pool; + GstBuffer *cur_buf; + gboolean hw_path; + + guint overlay; + guint overlay_depth; + guint overlay_x; + guint overlay_y; + guint overlay_w; + guint overlay_h; + + gboolean update_pos; + gboolean update_size; + + GMutex flow_lock; +}; + +struct _GstOmxVideoSinkClass +{ + GstVideoSinkClass parent_class; + GstOMXClassData cdata; +}; + +GType gst_omx_video_sink_get_type (void); + +G_END_DECLS +#endif diff --git a/omx/gstomxvp8dec.c b/omx/gstomxvp8dec.c index 61886b8..f1b2145 100644 --- a/omx/gstomxvp8dec.c +++ b/omx/gstomxvp8dec.c @@ -91,7 +91,7 @@ gst_omx_vp8_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port, OMX_PARAM_PORTDEFINITIONTYPE port_def; gst_omx_port_get_port_definition (port, &port_def); - port_def.format.video.eCompressionFormat = OMX_VIDEO_CodingVP8; + port_def.format.video.eCompressionFormat = OMX_VIDEO_CodingAutoDetect; ret = gst_omx_port_update_port_definition (port, &port_def) == OMX_ErrorNone; return ret; diff --git a/omx/gstomxvp8dec.h b/omx/gstomxvp8dec.h index 4c4d40c..d48105f 100644 --- a/omx/gstomxvp8dec.h +++ b/omx/gstomxvp8dec.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2013, Collabora Ltd. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +26,6 @@ #include "gstomxvideodec.h" G_BEGIN_DECLS - #define GST_TYPE_OMX_VP8_DEC \ (gst_omx_VP8_dec_get_type()) #define GST_OMX_VP8_DEC(obj) \ @@ -38,7 +38,6 @@ G_BEGIN_DECLS (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_VP8_DEC)) #define GST_IS_OMX_VP8_DEC_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_VP8_DEC)) - typedef struct _GstOMXVP8Dec GstOMXVP8Dec; typedef struct _GstOMXVP8DecClass GstOMXVP8DecClass; @@ -55,6 +54,4 @@ struct _GstOMXVP8DecClass GType gst_omx_vp8_dec_get_type (void); G_END_DECLS - #endif /* __GST_OMX_VP8_DEC_H__ */ - diff --git a/omx/gstomxvp8enc.c b/omx/gstomxvp8enc.c new file mode 100644 index 0000000..b1995e3 --- /dev/null +++ b/omx/gstomxvp8enc.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved. + * + * 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 <gst/gst.h> + +#include "gstomxvp8enc.h" + +GST_DEBUG_CATEGORY_STATIC (gst_omx_vp8_enc_debug_category); +#define GST_CAT_DEFAULT gst_omx_vp8_enc_debug_category + +/* prototypes */ +static gboolean gst_omx_vp8_enc_set_format (GstOMXVideoEnc * enc, + GstOMXPort * port, GstVideoCodecState * state); +static GstCaps *gst_omx_vp8_enc_get_caps (GstOMXVideoEnc * enc, + GstOMXPort * port, GstVideoCodecState * state); + +enum +{ + PROP_0 +}; + +/* class initialization */ + +#define DEBUG_INIT \ + GST_DEBUG_CATEGORY_INIT (gst_omx_vp8_enc_debug_category, "omxvp8enc", 0, \ + "debug category for gst-omx video encoder base class"); + +G_DEFINE_TYPE_WITH_CODE (GstOMXVP8Enc, gst_omx_vp8_enc, + GST_TYPE_OMX_VIDEO_ENC, DEBUG_INIT); + +static void +gst_omx_vp8_enc_class_init (GstOMXVP8EncClass * klass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + GstOMXVideoEncClass *videoenc_class = GST_OMX_VIDEO_ENC_CLASS (klass); + + videoenc_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_vp8_enc_set_format); + videoenc_class->get_caps = GST_DEBUG_FUNCPTR (gst_omx_vp8_enc_get_caps); + + videoenc_class->cdata.default_src_template_caps = "video/x-vp8, " + "width=(int) [ 16, 4096 ], " "height=(int) [ 16, 4096 ]"; + + gst_element_class_set_static_metadata (element_class, + "OpenMAX VP8 Video Encoder", + "Codec/Encoder/Video", + "Encode VP8 video streams", "Jitendra Kumar <jitendrak@nvidia.com>"); + + gst_omx_set_default_role (&videoenc_class->cdata, "video_encoder.vp8"); +} + +static void +gst_omx_vp8_enc_init (GstOMXVP8Enc * self) +{ +} + +static gboolean +gst_omx_vp8_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port, + GstVideoCodecState * state) +{ + GstOMXVP8Enc *self = GST_OMX_VP8_ENC (enc); + OMX_PARAM_PORTDEFINITIONTYPE port_def; + OMX_ERRORTYPE err; + + gst_omx_port_get_port_definition (GST_OMX_VIDEO_ENC (self)->enc_out_port, + &port_def); + port_def.format.video.eCompressionFormat = OMX_VIDEO_CodingAutoDetect; + err = + gst_omx_port_update_port_definition (GST_OMX_VIDEO_ENC + (self)->enc_out_port, &port_def); + if (err != OMX_ErrorNone) + return FALSE; + + return TRUE; +} + +static GstCaps * +gst_omx_vp8_enc_get_caps (GstOMXVideoEnc * self, GstOMXPort * port, + GstVideoCodecState * state) +{ + GstCaps *caps; + gint profile = 0; + + caps = gst_caps_new_empty_simple ("video/x-vp8"); + +#ifdef USE_OMX_TARGET_TEGRA +{ + OMX_INDEXTYPE eIndex; + OMX_ERRORTYPE err; + NVX_VIDEO_PARAM_VP8TYPE param; + + err = gst_omx_component_get_index (self->enc, + (char *) NVX_INDEX_PARAM_VP8TYPE, &eIndex); + + if (err == OMX_ErrorNone) { + GST_OMX_INIT_STRUCT (¶m); + param.nPortIndex = self->enc_out_port->index; + err = gst_omx_component_get_parameter (self->enc, eIndex, ¶m); + + } else { + GST_WARNING_OBJECT (self, "Coudn't get extension index for %s", + (char *) NVX_INDEX_PARAM_VP8TYPE); + } + + if (err == OMX_ErrorNone) { + switch (param.eLevel) { + case NVX_VIDEO_VP8Level_Version0: + profile = 0; + break; + case NVX_VIDEO_VP8Level_Version1: + profile = 1; + break; + case NVX_VIDEO_VP8Level_Version2: + profile = 2; + break; + case NVX_VIDEO_VP8Level_Version3: + profile = 3; + break; + default: + profile = 0; + break; + } + + gst_caps_set_simple (caps, "profile", G_TYPE_INT, profile, NULL); + } +} +#endif + + return caps; +} diff --git a/omx/gstomxvp8enc.h b/omx/gstomxvp8enc.h new file mode 100644 index 0000000..595ba34 --- /dev/null +++ b/omx/gstomxvp8enc.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. + * + * 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_VP8_ENC_H__ +#define __GST_OMX_VP8_ENC_H__ + +#include <gst/gst.h> +#include "gstomxvideoenc.h" + +G_BEGIN_DECLS +#define GST_TYPE_OMX_VP8_ENC \ + (gst_omx_vp8_enc_get_type()) +#define GST_OMX_VP8_ENC(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_VP8_ENC,GstOMXVP8Enc)) +#define GST_OMX_VP8_ENC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_VP8_ENC,GstOMXVP8EncClass)) +#define GST_OMX_VP8_ENC_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_VP8_ENC,GstOMXVP8EncClass)) +#define GST_IS_OMX_VP8_ENC(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_VP8_ENC)) +#define GST_IS_OMX_VP8_ENC_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_VP8_ENC)) +typedef struct _GstOMXVP8Enc GstOMXVP8Enc; +typedef struct _GstOMXVP8EncClass GstOMXVP8EncClass; + +struct _GstOMXVP8Enc +{ + GstOMXVideoEnc parent; +}; + +struct _GstOMXVP8EncClass +{ + GstOMXVideoEncClass parent_class; +}; + +GType gst_omx_vp8_enc_get_type (void); + +G_END_DECLS +#endif /* __GST_OMX_VP8_ENC_H__ */ diff --git a/omx/gstomxwmvdec.c b/omx/gstomxwmvdec.c index 64460d9..e21b87b 100644 --- a/omx/gstomxwmvdec.c +++ b/omx/gstomxwmvdec.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd. + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -35,6 +36,11 @@ static gboolean gst_omx_wmv_dec_is_format_change (GstOMXVideoDec * dec, static gboolean gst_omx_wmv_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port, GstVideoCodecState * state); +#ifdef USE_OMX_TARGET_TEGRA +static GstFlowReturn gst_omx_wmv_dec_prepare_frame (GstOMXVideoDec * self, + GstVideoCodecFrame * frame); +#endif + enum { PROP_0 @@ -49,6 +55,7 @@ enum G_DEFINE_TYPE_WITH_CODE (GstOMXWMVDec, gst_omx_wmv_dec, GST_TYPE_OMX_VIDEO_DEC, DEBUG_INIT); + static void gst_omx_wmv_dec_class_init (GstOMXWMVDecClass * klass) { @@ -58,8 +65,14 @@ gst_omx_wmv_dec_class_init (GstOMXWMVDecClass * klass) videodec_class->is_format_change = GST_DEBUG_FUNCPTR (gst_omx_wmv_dec_is_format_change); videodec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_wmv_dec_set_format); +#ifdef USE_OMX_TARGET_TEGRA + videodec_class->prepare_frame = + GST_DEBUG_FUNCPTR (gst_omx_wmv_dec_prepare_frame); +#endif videodec_class->cdata.default_sink_template_caps = "video/x-wmv, " + "wmvversion= (int) 3, " + "format = (string) {WMV3, WVC1}, " "width=(int) [1,MAX], " "height=(int) [1,MAX]"; gst_element_class_set_static_metadata (element_class, @@ -74,6 +87,7 @@ gst_omx_wmv_dec_class_init (GstOMXWMVDecClass * klass) static void gst_omx_wmv_dec_init (GstOMXWMVDec * self) { + self->wvc1 = FALSE; } static gboolean @@ -90,9 +104,94 @@ gst_omx_wmv_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port, gboolean ret; OMX_PARAM_PORTDEFINITIONTYPE port_def; +#ifdef USE_OMX_TARGET_TEGRA + GstBuffer *buf; + gint size, width, height, index = 0; + const gchar *format_string; + GstMapInfo read_map = GST_MAP_INFO_INIT; + GstMapInfo write_map = GST_MAP_INFO_INIT; + GstOMXWMVDec *self = GST_OMX_WMV_DEC (dec); + GstCaps *caps = state->caps; + GstStructure *structure = gst_caps_get_structure (caps, 0); + format_string = gst_structure_get_string (structure, "format"); + size = gst_buffer_get_size (state->codec_data); + + if (!strcmp (format_string, "WVC1") || !strcmp (format_string, "wvc1")) { + self->wvc1 = TRUE; + buf = gst_buffer_make_writable (state->codec_data); + /*openmax decoder want first byte to be skipped */ + gst_buffer_resize (buf, 1, -1); + gst_buffer_replace (&state->codec_data, buf); + g_print ("New buffer size = %d\n", gst_buffer_get_size (buf)); + } else if (size > 3) { + gst_buffer_map (state->codec_data, &read_map, GST_MAP_READ); + if (read_map.data[3] != 0xc5) { + //Lets code Annex J and L of the SMPTE VC-1 specification + char seq_l1[] = { 0xff, 0xff, 0xff, 0xc5 }; + char seq_l2[] = { 0x4, 0, 0, 0 }; + char seq_l3[] = { 0xc, 0, 0, 0 }; + + gst_structure_get_int (structure, "width", &width); + gst_structure_get_int (structure, "height", &height); + + buf = gst_buffer_new_allocate (NULL, size + 32, NULL); + gst_buffer_map (buf, &write_map, GST_MAP_WRITE); + memcpy (write_map.data + index, seq_l1, 4); + index += 4; + memcpy (write_map.data + index, seq_l2, 4); + index += 4; + memcpy (write_map.data + index, read_map.data, 4); + index += 4; + memcpy (write_map.data + index, &height, 4); + index += 4; + memcpy (write_map.data + index, &width, 4); + index += 4; + memcpy (write_map.data + index, seq_l3, 4); + index += 4; + memset (write_map.data + index, 0, 12); + gst_buffer_replace (&state->codec_data, buf); + gst_buffer_unmap (buf, &write_map); + } + gst_buffer_unmap (state->codec_data, &read_map); + } +#endif gst_omx_port_get_port_definition (port, &port_def); port_def.format.video.eCompressionFormat = OMX_VIDEO_CodingWMV; ret = gst_omx_port_update_port_definition (port, &port_def) == OMX_ErrorNone; return ret; } + +#ifdef USE_OMX_TARGET_TEGRA +static GstFlowReturn +gst_omx_wmv_dec_prepare_frame (GstOMXVideoDec * dec, GstVideoCodecFrame * frame) +{ + GstOMXWMVDec *self = GST_OMX_WMV_DEC (dec); + GstMemory *mem = NULL; + GstMapInfo read_map = GST_MAP_INFO_INIT; + GstMapInfo write_map = GST_MAP_INFO_INIT; + guint32 start_code; + + if (self->wvc1) { + //Handle WVC1 format + gst_buffer_map (frame->input_buffer, &read_map, GST_MAP_READ); + start_code = + (read_map.data[0] << 24) | (read_map.data[1] << 16) | (read_map. + data[2] << 8) | read_map.data[3]; + gst_buffer_unmap (frame->input_buffer, &read_map); + + if (start_code != 0x10D && start_code != 0x10E) { + mem = gst_allocator_alloc (NULL, 4, NULL); + gst_memory_map (mem, &write_map, GST_MAP_WRITE); + write_map.data[0] = 0; + write_map.data[1] = 0; + write_map.data[2] = 1; + write_map.data[3] = 0xD; + gst_memory_unmap (mem, &write_map); + gst_buffer_prepend_memory (frame->input_buffer, mem); + } + + } + return GST_FLOW_OK; +} +#endif diff --git a/omx/gstomxwmvdec.h b/omx/gstomxwmvdec.h index 9375dc5..7dfd565 100644 --- a/omx/gstomxwmvdec.h +++ b/omx/gstomxwmvdec.h @@ -25,7 +25,6 @@ #include "gstomxvideodec.h" G_BEGIN_DECLS - #define GST_TYPE_OMX_WMV_DEC \ (gst_omx_wmv_dec_get_type()) #define GST_OMX_WMV_DEC(obj) \ @@ -38,13 +37,13 @@ G_BEGIN_DECLS (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_WMV_DEC)) #define GST_IS_OMX_WMV_DEC_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_WMV_DEC)) - typedef struct _GstOMXWMVDec GstOMXWMVDec; typedef struct _GstOMXWMVDecClass GstOMXWMVDecClass; struct _GstOMXWMVDec { GstOMXVideoDec parent; + gboolean wvc1; }; struct _GstOMXWMVDecClass @@ -55,6 +54,4 @@ struct _GstOMXWMVDecClass GType gst_omx_wmv_dec_get_type (void); G_END_DECLS - #endif /* __GST_OMX_WMV_DEC_H__ */ - diff --git a/omx/openmax/NVOMX_CameraExtensions.h b/omx/openmax/NVOMX_CameraExtensions.h new file mode 100644 index 0000000..052c558 --- /dev/null +++ b/omx/openmax/NVOMX_CameraExtensions.h @@ -0,0 +1,1781 @@ +/* + * Copyright (c) 2009-2014, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file + * <b>NVIDIA Tegra: OpenMAX Camera Extension Interface</b> + * + */ + +/** + * @defgroup nv_omx_il_camera Camera + * + * This is the NVIDIA OpenMAX camera class extension interface. + * + * These extensions include auto-focus, auto-exposure, auto-whitebalance, half-press, + * focus regions, sharpness, hue, framerate, encoder control, edge enhancement and more. + * + * @ingroup nvomx_camera_extension + * @{ + */ + +#ifndef NVOMX_CameraExtensions_h_ +#define NVOMX_CameraExtensions_h_ + +#include "NVOMX_ColorFormatExtensions.h" + +typedef float NVX_F32; + +/** Holds a floating point rectangle */ +typedef struct NVX_RectF32 +{ + NVX_F32 left; + NVX_F32 top; + NVX_F32 right; + NVX_F32 bottom; +} NVX_RectF32; + +#define NVX_MAX_FOCUS_REGIONS 8 +#define NVX_MAX_EXPOSURE_REGIONS 8 +#define NVX_MAX_DIRECT_FOCUSER_CONTROL_LENGTH 16 +#define NVX_VIDEOENC_DCI_SIZE 80 +#define MAX_NUM_SENSOR_MODES 30 +#define NVX_MAX_CAMERACONFIGURATION_LENGTH 64 +#define NVX_MAX_FD_OUTPUT_LENGTH 1024 +#define NVX_MAX_FUSE_ID_SIZE 16 +#define NVX_MAX_EXPOSURE_COUNT 2 + +typedef enum NVX_WHITEBALCONTROLTYPE { + NVX_WhiteBalControlVendorStartUnused = OMX_WhiteBalControlVendorStartUnused, + NVX_WhiteBalControlWarmFluorescent, + NVX_WhiteBalControlTwilight, + NVX_WhiteBalControlMax = 0x7FFFFFFF +} NVX_WHITEBALCONTROLTYPE; + +typedef enum NVX_VIDEO_ERROR_RESILIENCY_LEVEL_TYPE { + NVX_VIDEO_ErrorResiliency_None = 0, + NVX_VIDEO_ErrorResiliency_Low, + NVX_VIDEO_ErrorResiliency_High, + NVX_VIDEO_ErrorResiliency_Invalid = 0x7FFFFFFF +} NVX_VIDEO_ERROR_RESILIENCY_LEVEL_TYPE; + +typedef enum NVX_VIDEO_APPLICATION_TYPE { + NVX_VIDEO_Application_Camcorder = 0, /**< Timestamps set for camcorder */ + NVX_VIDEO_Application_VideoTelephony, /**< Timestamps set for telephony */ + NVX_VIDEO_Application_Invalid = 0x7FFFFFFF +} NVX_VIDEO_APPLICATION_TYPE; + +typedef enum NVX_VIDEO_RATECONTROL_MODE{ + NVX_VIDEO_RateControlMode_CBR = 0, + NVX_VIDEO_RateControlMode_VBR, + NVX_VIDEO_RateControlMode_VBR2, + NVX_VIDEO_RateControlMode_Invalid = 0x7FFFFFFF +}NVX_VIDEO_RATECONTROL_MODE; + +/** Param extension index to fine tune video encoder configuration. + * See ::NVX_PARAM_VIDENCPROPERTY + */ +#define NVX_INDEX_PARAM_VIDEO_ENCODE_PROPERTY "OMX.Nvidia.index.param.video.encode.prop" +/** Holds data to fine tune video encoder configuration. */ +typedef struct NVX_PARAM_VIDENCPROPERTY +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + + NVX_VIDEO_APPLICATION_TYPE eApplicationType; /**< Application Type */ + NVX_VIDEO_ERROR_RESILIENCY_LEVEL_TYPE eErrorResiliencyLevel; /**< Error Resiliency Level */ + OMX_BOOL bSvcEncodeEnable; /**< Boolean to enable H.264 Scalable Video Codec mode */ + OMX_BOOL bSetMaxEncClock; /**< Set Maximum clock for encoder hardware */ + OMX_BOOL bFrameSkip; /**< Enable skipping of Frames */ + OMX_BOOL bAllIFrames; /**< Encode all frames as I Frame */ + OMX_BOOL bBitBasedPacketization; /**< Packet size is based upon Number Of bits */ + OMX_BOOL bInsertSPSPPSAtIDR; /**< Insert SPS/PPS at IDR */ + OMX_BOOL bUseConstrainedBP; /**< Use Constrained BP */ + OMX_BOOL bInsertVUI; /**< Insert VUI in the bitstream */ + OMX_BOOL bInsertAUD; /**< Insert AUD in the bitstream */ + OMX_U32 nPeakBitrate; /**< Peak Bitrate for VBR, if set to 0, encoder derive it from Level Idc */ + OMX_BOOL bEnableStuffing; /**< Enable byte stuffing to maintain bitrate */ + OMX_BOOL bLowLatency; /**< Reduce latency by lowering peak frame size (for both I and P frames) */ + OMX_BOOL bSliceLevelEncode; /**< Reduce latency by delivering packet size based slices (for both I and P frames) */ + OMX_BOOL bSliceIntraRefreshEnable; /**< Enable Slice Intra Refresh Wave */ + OMX_U32 SliceIntraRefreshInterval; /**< Slice Intra Refresh Interval in number of frames */ + OMX_U32 nVirtualBufferSize; /**< Virtual Buffer Size specified by the app in bits */ + OMX_BOOL bEnableTwopassCBR; /**< Enable two pass cbr mode if RC mode set is CBR*/ +} NVX_PARAM_VIDENCPROPERTY; +/** Param extension index to set video encoder rate control mode. + * See ::NVX_PARAM_RATECONTROLMODE + */ + #define NVX_INDEX_PARAM_RATECONTROLMODE "OMX.Nvidia.index.param.ratecontrolmode" +/** Holds data to set video encoder rate control mode. + * See ::NVX_IndexParamRateControlMode + */ +typedef struct NVX_PARAM_RATECONTROLMODE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + + NVX_VIDEO_RATECONTROL_MODE eRateCtrlMode; +}NVX_PARAM_RATECONTROLMODE; + +/** Holds boolean parameter. + */ +typedef struct NVX_PARAM_BOOLEAN +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL enable; /**< on/off */ +} NVX_PARAM_BOOLEAN; + +/** Param extension index to configure the video encode quantization range. + * See ::NVX_CONFIG_VIDENC_QUANTIZATION_RANGE + */ +#define NVX_INDEX_CONFIG_VIDEO_ENCODE_QUANTIZATION_RANGE "OMX.Nvidia.index.config.video.encode.quantizationrange" +/** + * Holds information for configuring video compression quantization parameter limits + * parameter values. Codecs may support different Min/Max QP values for different + * frame types. Default value used by all MinQp/MaxQp should be set to some invalid + * value. So that it will not affect encoder rate control parameter. If some control + * is required for MinQp or MaxQp or Both, then set valid value for that param. + */ +typedef struct NVX_CONFIG_VIDENC_QUANTIZATION_RANGE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version info */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_U32 nMinQpI; /**< Minimum QP value to use for index frames */ + OMX_U32 nMaxQpI; /**< Maximum QP value to use for index frames */ + OMX_U32 nMinQpP; /**< Minimum QP value to use for P frames */ + OMX_U32 nMaxQpP; /**< Maximum QP value to use for P frames */ + OMX_U32 nMinQpB; /**< Minimum QP value to use for B frames */ + OMX_U32 nMaxQpB; /**< Maximum QP value to use for B frames */ +} NVX_CONFIG_VIDENC_QUANTIZATION_RANGE; + +/** Param extension index to get the quantization index used for last frame encoding + * See ::NVX_INDEX_CONFIG_VIDEO_ENCODE_LAST_FRAME_QP + **/ +#define NVX_INDEX_CONFIG_VIDEO_ENCODE_LAST_FRAME_QP "OMX.Nvidia.index.config.video.encode.lastframeqp" +/** Holds Quantization Index used in last frame encoding. + */ +typedef struct NVX_PARAM_LASTFRAMEQP +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 LastFrameQP; /**< on/off */ +} NVX_PARAM_LASTFRAMEQP; + +/** Param extension index to configure the h264 encoder quality parameters. + * See ::NVX_CONFIG_VIDENC_H264_QUALITY_PARAMS + */ +#define NVX_INDEX_PARAM_VIDENC_H264_QUALITY_PARAMS "OMX.Nvidia.index.param.video.encode.h264qualityparams" +/** + * Holds information for configuring h264 quality control parameters + * \a nFavorInterBias is used for giving bias towards Inter macroblocks for Intra/Inter mode decision + * \a nFavorIntraBias is used for giving bias towards Intra macroblocks for Intra/Inter mode decision. + * \a nFavorIntraBias_16X16 is used for giving bias towards Intra16x16 macroblocks for I16x16/I4x4 mode decision. + */ +typedef struct NVX_PARAM_VIDENC_H264_QUALITY_PARAMS { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version info */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_U32 nFavorInterBias; /**< To set bias towards Inter Macroblocks for I/P mode decision */ + OMX_U32 nFavorIntraBias; /**< To set bias towards Intra macroblocks for I/P mode decision */ + OMX_U32 nFavorIntraBias_16X16; /**< To set bias toward Intra16x16 macroblocks for Intra16x16/Intra4x4 mode decision */ +} NVX_PARAM_VIDENC_H264_QUALITY_PARAMS; + + +/** Param extension index to enable/disable stringent bitrate for encoder. + * See ::OMX_CONFIG_BOOLEANTYPE + */ +#define NVX_INDEX_PARAM_VIDEO_ENCODE_STRINGENTBITRATE "OMX.Nvidia.index.param.video.encode.stringentbitrate" + +/** + * Config extension index to set/get stereo metadata. + */ +#define NVX_INDEX_CONFIG_VIDEO_STEREOINFO "OMX.Nvidia.index.config.videostereoinfo" + +#define NVX_INDEX_CONFIG_VIDEO_MVCINFO "OMX.Nvidia.index.config.videomvcinfo" + +// TODO: Need to finalize on the exact defines to expose to the app +// Frame Packing Format +typedef enum _NVX_VIDEO_FRAMEPACK_TYPE { + NVX_VIDEO_FRAMEPACK_Type_Checker = 0, // Checkerboard + NVX_VIDEO_FRAMEPACK_Type_ColInt = 1, // Column Interleaved + NVX_VIDEO_FRAMEPACK_Type_RowInt = 2, // Row Interleaved + NVX_VIDEO_FRAMEPACK_Type_SbS = 3, // Side by Side + NVX_VIDEO_FRAMEPACK_Type_TB = 4, // Top Bottom + NVX_VIDEO_FRAMEPACK_Type_FrameInt = 5, // Temporal Frame Interleaved + NVX_VIDEO_FRAMEPACK_TypeInvalid = 0x7FFFFFFF +} NVX_VIDEO_FRAMEPACK_TYPE; + +// Content Interpretation Type +typedef enum _NVX_VIDEO_CONTENT_TYPE { + NVX_VIDEO_CONTENT_Type_Undef = 0, // Undefined + NVX_VIDEO_CONTENT_Type_LR = 1, // Left first + NVX_VIDEO_CONTENT_Type_RL = 2, // Right first + NVX_VIDEO_CONTENT_TypeInvalid = 0x7FFFFFFF +} NVX_VIDEO_CONTENT_TYPE; + +// Stereo Metadata structure +typedef struct NVX_CONFIG_VIDEO_STEREOINFO +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + + OMX_U32 stereoEnable; /**< Stereo Enable / Disable for this buffer */ + NVX_VIDEO_FRAMEPACK_TYPE fpType; /**< Stereo Frame-packing type */ + NVX_VIDEO_CONTENT_TYPE contentType; /**< Stereo Content Type */ +} NVX_CONFIG_VIDEO_STEREOINFO; + +// Stitch MVC views +typedef struct NVX_CONFIG_VIDEO_MVC_INFO +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + + OMX_BOOL stitch_MVCViews_Flag; /**< Specifies if the 2 MVC views should be stitched*/ +} NVX_CONFIG_VIDEO_MVC_INFO; + +/** Param extension index to configure slice level encode. +* see: NVX_CONFIG_VIDEO_SLICELEVELENCODE +*/ +#define NVX_INDEX_CONFIG_VIDEO_SLICELEVELENCODE "OMX.Nvidia.index.config.video.slicelevelencode" +/** Holds flag to enable/disable slice level encode +*/ +typedef struct NVX_CONFIG_VIDEO_SLICELEVELENCODE { + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /** NVX extensions specification versions information */ + OMX_U32 nPortIndex; /** Port that this struct applies to */ + OMX_BOOL SliceLevelEncode; /** Slice level encode turn on/off */ +} NVX_CONFIG_VIDEO_SLICELEVELENCODE; + +/** Param extension index to configure time stamp calculated framerate. +* see: NVX_CONFIG_VIDEO_TIMESTAMPCALCFRAMERATE +*/ +#define NVX_INDEX_CONFIG_VIDEO_TIMESTAMPCALCFRAMERATE "OMX.Nvidia.index.config.video.timestampcalcframerate" +/** Holds flag to enable/disable time stamp based frame rate calculation +*/ +typedef struct NVX_CONFIG_VIDEO_TIMESTAMPCALCFRAMERATE { + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /** NVX extensions specification versions information */ + OMX_U32 nPortIndex; /** Port that this struct applies to */ + OMX_BOOL TimeStampCalcFrameRate; /** time stamp based frame rate turn on/off */ +} NVX_CONFIG_VIDEO_TIMESTAMPCALCFRAMERATE; + +/** Param extension index to enable the video protected mode. + * See ::OMX_CONFIG_BOOLEANTYPE + */ +#define NVX_INDEX_CONFIG_VIDEO_PROTECT "OMX.Nvidia.index.config.video.protect" + +/** Config extension index to enable camera test pattern. + * See ::NVX_CONFIG_CAMERATESTPATTERN + */ +#define NVX_INDEX_CONFIG_CAMERATESTPATTERN "OMX.Nvidia.index.config.cameratestpattern" +/** Holds data to enable camera test pattern. */ +typedef struct NVX_CONFIG_CAMERATESTPATTERN +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 TestPatternIndex; /**< Boolean to enable test pattern */ +}NVX_CONFIG_CAMERATESTPATTERN; + +/** Config extension index to set duration in milliseconds for smooth zooming. + * See ::OMX_PARAM_U32TYPE + */ +#define NVX_INDEX_CONFIG_SMOOTHZOOMTIME "OMX.Nvidia.index.config.smoothzoomtime" + +/** Config extension index to trigger sensor power up. + * See ::OMX_CONFIG_BOOLEANTYPE + */ +#define NVX_INDEX_CONFIG_SENSORPOWERON "OMX.Nvidia.index.config.sensorpoweron" + +/** Config extension index to set THS-Settle time for camera connected via MIPI CSI. + * See ::OMX_PARAM_U32TYPE + */ +#define NVX_INDEX_CONFIG_CILTHRESHOLD "OMX.Nvidia.index.config.cilthreshold" + +/** Config extension index to abort zooming. + * See ::OMX_CONFIG_BOOLEANTYPE + */ +#define NVX_INDEX_CONFIG_ZOOMABORT "OMX.Nvidia.index.config.zoomabort" + +/** Config extension index to set scale factor multiplier in digital zoom. + * See ::NVX_CONFIG_DZSCALEFACTORMULTIPLIER + */ +#define NVX_INDEX_CONFIG_DZSCALEFACTORMULTIPLIER "OMX.Nvidia.index.config.dzscalefactormultiplier" +/** Holds data to set scale factor multiplier in digital zoom. */ +typedef struct NVX_CONFIG_DZSCALEFACTORMULTIPLIER +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_S32 ZoomFactorMultiplier; /**< Scale factor from 100 to 800 (1.0-8.0) up to 8x digital */ +}NVX_CONFIG_DZSCALEFACTORMULTIPLIER; + +/** Config extension index to enable/disable camera preview. + * See ::OMX_CONFIG_BOOLEANTYPE + */ +#define NVX_INDEX_CONFIG_PREVIEWENABLE "OMX.Nvidia.index.config.previewenable" + +/** Config extension index to enable/disable force camera postview output. + * See ::OMX_CONFIG_BOOLEANTYPE + */ +#define NVX_INDEX_CONFIG_FORCEPOSTVIEW "OMX.Nvidia.index.config.forcepostview" + +/** Config extension index to start camera preview without outputing preview + * pictures. This allows AE/AWB converge and stay converged as soon as the + * preview window appears. + * See ::OMX_CONFIG_BOOLEANTYPE + * + * AlgorithmWarmup is a command (not a state change) to start up nvmm + * camera. When nvmm camera receives this command, it starts preview + * capture and does AE/AWB converging. And it does not output either + * buffers or EOS to DZ. Then it puts the nvmm camera into a preview + * paused state. + * + * AlgorithmWarmup is independent of PreviewEnable. 1. After Preview is + * enabled, there should be no need for AlgorithmWarmup. 2. PreviewEnable + * may be sent without preceeded by AlgorithmWarmup. The nvmm camera warms up + * AE/AWB by itself. + * + */ +#define NVX_INDEX_CONFIG_ALGORITHMWARMUP "OMX.Nvidia.index.config.algorithmwarmup" + +/** Config extension index to enable/disable capture pause. + * See ::OMX_CONFIG_BOOLEANTYPE + */ +#define NVX_INDEX_CONFIG_CAPTUREPAUSE "OMX.Nvidia.index.config.capturepause" + + +/** Config extension index to setup converge and lock (half-press). + * When this extension is called, the camera component will start + * converging (achieving) auto focus, auto exposure, and/or auto + * white balance. If the camera component achieves one or + * more of these properties then it will lock settings of those + * properties. If the camera component was unable to achieve one or + * more of those properties in a certain time then it times out + * for that property. + * + * The camera component notifies the application about + * those properties that were achieved and those that timed out + * using events. The following lists shows the different + * events that are sent. + * - Auto focus achieved (See ::NVX_EventCamera_AutoFocusAchieved) + * - Auto focus timed out (See ::NVX_EventCamera_AutoFocusTimedOut) + * - Auto exposure achieved (See ::NVX_EventCamera_AutoExposureAchieved) + * - Auto exposure timed out (See ::NVX_EventCamera_AutoExposureTimedOut) + * - Auto white balance achieved (See + * ::NVX_EventCamera_AutoWhiteBalanceAchieved) + * - Auto white balance timed out (See + * ::NVX_EventCamera_AutoWhiteBalanceTimedOut) + * + * Although converge and lock is used with auto focus, auto exposure, and + * auto white balance properties, an application can choose to + * enable any one or any combination of these properties. When + * any of these properties is disabled then half press will not + * attempt to achieve that property. + * + * See ::NVX_CONFIG_CONVERGEANDLOCK + */ +#define NVX_INDEX_CONFIG_CONVERGEANDLOCK "OMX.Nvidia.index.config.convergeandlock" + + +/** Algorithm subtypes + * Has subtype of the algorithm that is used. + */ +#define NvxAlgSubType_None 0 /**< Algorithm does nothave subtype */ +#define NvxAlgSubType_AFFullRange (1 << 0) /**< AF that uses entire range */ +#define NvxAlgSubType_AFInfMode (1 << 1) /**< AF only in the Infinity range */ +#define NvxAlgSubType_AFMacroMode (1 << 2) /**< AF only in the Macro range */ +#define NvxAlgSubType_TorchDisable (1 << 3) /**< Disable torch */ + +/** Holds data to setup converge and lock. */ +typedef struct NVX_CONFIG_CONVERGEANDLOCK +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL bUnlock; /**< Boolean to unlock AF, AE, AWB settings */ + OMX_BOOL bAutoFocus; /**< Boolean to enable auto focus */ + OMX_BOOL bAutoExposure; /**< Boolean to enable auto exposure */ + OMX_BOOL bAutoWhiteBalance; /**< Boolean to enable auto white balance */ + OMX_U32 nTimeOutMS; /**< Timeout in milliseconds */ + OMX_BOOL bRelock; /**< Boolean hint to restore previous alg settings during lock */ + OMX_U32 algSubType; +} NVX_CONFIG_CONVERGEANDLOCK; + +/** Config extension index to setup pre-capture converge. + * @deprecated This index is deprecated. + */ +#define NVX_INDEX_CONFIG_PRECAPTURECONVERGE "OMX.Nvidia.index.config.precaptureconverge" +/** Holds data to setup pre-capture converge. */ +typedef struct NVX_CONFIG_PRECAPTURECONVERGE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL bPrecaptureConverge; /**< Boolean to enable pre-capture converge */ + OMX_BOOL bContinueDuringCapture; /**< Boolean to enable continous converge during capture */ + OMX_U32 nTimeOutMS; /**< Timeout in milliseconds */ +} NVX_CONFIG_PRECAPTURECONVERGE; + +#define NVX_INDEX_CONFIG_AEOVERRIDE "OMX.Nvidia.index.config.aeoverride" +/** Holds data to specify exposure time ratio for camera AOHDR. */ +typedef struct NVX_CONFIG_AEOVERRIDE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL analog_gains_en; /**< Indicates we are setting analog bayer gains */ + NVX_F32 analog_gains[4]; /**< Specifies per-channel analog gains + [0]: gain for R, [1]: gain for GR, + [2]: gain for GB, [3]: gain for B. */ + OMX_BOOL digital_gains_en; /**< Indicates we are setting digital bayer gains */ + NVX_F32 digital_gains[4]; /**< Specifies per-channel digital gains + [0]: gain for R, [1]: gain for GR, + [2]: gain for GB, [3]: gain for B. */ + OMX_BOOL exposure_en; /**< Indicates we are setting exposure time(s) */ + OMX_U32 no_of_exposures; /**< Number of exposures passed > */ + NVX_F32 exposures[NVX_MAX_EXPOSURE_COUNT]; /**< Exposure Times */ +} NVX_CONFIG_AEOVERRIDE; + +/** Config extension index to setup min and max frame rate for camera. + * See ::NVX_CONFIG_AUTOFRAMERATE + */ +#define NVX_INDEX_CONFIG_AUTOFRAMERATE "OMX.Nvidia.index.config.autoframerate" +/** Holds data to setup auto frame rate for camera. */ +typedef struct NVX_CONFIG_AUTOFRAMERATE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL bEnabled; /**< Boolean to enable auto frame rate */ + OMX_S32 low; /**< Lowest frame rate allowed */ + OMX_S32 high; /**< Highest frame rate allowed */ +} NVX_CONFIG_AUTOFRAMERATE; + +/** Config extension index to setup burst skip count. + */ +#define NVX_INDEX_CONFIG_BURSTSKIPCOUNT "OMX.Nvidia.index.config.burstskipcount" + +/** Config extension index to control exposure regions. + * The rectangle coordinates are normalized to -1.0 to 1.0 on the + * X and Y axis, and given in fixed-point representation. + * The weights should be positive floating-point values. + * Auto exposure region will work only when auto exposure is enabled. + * Setting nRegions to 0 will clear out any existing exposure regions + * and restore the driver's default exposure algorithm. + * + * See ::NVX_CONFIG_ExposureRegionsRect + */ +#define NVX_INDEX_CONFIG_EXPOSUREREGIONSRECT "OMX.Nvidia.index.config.exposureregionsrect" +/** Holds data to control exposure regions. */ + +typedef struct NVX_CONFIG_ExposureRegionsRect +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nRegions; /**< Number of regions */ + NVX_RectF32 regions[NVX_MAX_EXPOSURE_REGIONS]; /**< Array of NVX_RectF32 to specify each exposure region */ + NVX_F32 weights[NVX_MAX_EXPOSURE_REGIONS]; /**< Array of the relative weightings to apply to each exposure region */ +} NVX_CONFIG_ExposureRegionsRect; + +/** Config extension index to specify exposure time range for camera. + * + * Sets the minimum and maximum exposure time or ISO sensitivty from which the + * capture component's auto exposure picks values. + * + * The camera component supports auto exposure, where it + * dynamically changes exposure time and sensor's sensitivty between a + * minimum value and a maximum value specified + * by config property data structure. + * Minimum and maximum possible exposure times and ISO gains are dependent + * on the camera sensor. Values above the maximum and below the minimum + * supported by the camera sensor are clipped. + * + * Values are in units of milliseconds. To limit the exposure to nothing + * slower than 1/30 second, a setting like {0, 33} would be used. 0 would + * be replaced with the sensors fastest exposure limit by the driver. + * + * To limit the exposure to nothing faster than 1/30 second, set the + * range to {33, 0}. The 0 for "high" would be replaced with the + * sensor's slowest exposer limit. + * + * See ::NVX_CONFIG_EXPOSURETIME_RANGE + */ +#define NVX_INDEX_CONFIG_EXPOSURETIMERANGE "OMX.Nvidia.index.config.exposuretimerange" +/** Holds data to specify exposure time range for camera. */ +typedef struct NVX_CONFIG_EXPOSURETIME_RANGE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 low; /**< Shortest exposure time allowed */ + OMX_U32 high; /**< Longest exposure time allowed */ +} NVX_CONFIG_EXPOSURETIME_RANGE; + +#define NVX_INDEX_CONFIG_SENSORETRANGE "OMX.Nvidia.index.config.sensoretrange" +typedef struct NVX_CONFIG_SENSOR_ET_RANGE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + NVX_F32 low; /**< Shortest exposure time allowed */ + NVX_F32 high; /**< Longest exposure time allowed */ +} NVX_CONFIG_SENSOR_ET_RANGE; + +/** Config extension index to set/get exposure time in float seconds. */ +#define NVX_INDEX_CONFIG_EXPOSURETIME "OMX.Nvidia.index.config.exposuretime" +typedef struct NVX_CONFIG_EXPOSURETIME +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + NVX_F32 nExposureTime; /**< Exposure time in seconds */ + OMX_BOOL bAutoShutterSpeed; /**< Whether shutter speed is defined automatically */ +} NVX_CONFIG_EXPOSURETIME; + +#define NVX_INDEX_CONFIG_FUSEID "OMX.Nvidia.index.config.fuseid" +typedef struct NVX_CONFIG_SENSOR_FUSE_ID +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 fidSize; /**< Number of fuse ID bytes populated */ + OMX_U8 fidBytes[NVX_MAX_FUSE_ID_SIZE]; /**< Fuse ID bytes */ +} NVX_CONFIG_SENSOR_FUSE_ID; + +/** Config extension index to set/get focus postion. */ +#define NVX_INDEX_CONFIG_FOCUSPOSITION "OMX.Nvidia.index.config.focusposition" + +/** Config extension index to set/get color correction matrix. */ +#define NVX_INDEX_CONFIG_COLORCORRECTIONMATRIX "OMX.Nvidia.index.config.colorcorrectionmatrix" +typedef struct NVX_CONFIG_COLORCORRECTIONMATRIX +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + float ccMatrix[16]; /**< Color Correction Matrix */ +} NVX_CONFIG_COLORCORRECTIONMATRIX; + +/** Config extension index to specify ISO sensitivity range for camera. + * + * Sets the minimum and maximum exposure time or ISO sensitivty from which the + * capture component's auto exposure picks values. + * + * The camera component supports auto exposure, where it + * dynamically changes exposure time and sensor's sensitivty between a + * minimum value and a maximum value specified + * by config property data structure. + * Minimum and maximum possible exposure times and ISO gains are dependent + * on the camera sensor. Values above the maximum and below the minimum + * supported by the camera sensor are clipped. + * + * Values are in units of ISO. To limit the ISO gain to nothing more + * than ISO400, a setting like {0, 400} would be used. 0 would be + * replaced with the sensor's lowest supported gain limit by the + * driver. To limit the ISO gain to nothing less than ISO400, a + * setting like {400, 0} would be used. 0 would be replaced with the + * sensor's highest supported gain limit by the driver. To reset to + * initialization value, set to {0, 0}. + * + * Since the Auto exposure algorithm is 'exposure time priority', limiting + * the ISO range will only dim the image if the ISO is limited by setting + * the range. The exposure time is not recalculated based off of the + * ISO range limit. + * + * See ::NVX_CONFIG_ISOSENSITIVITY_RANGE + */ +#define NVX_INDEX_CONFIG_ISOSENSITIVITYRANGE "OMX.Nvidia.index.config.isosensitivityrange" +/** Holds data to specify ISO sensitivity range for camera. */ +typedef struct NVX_CONFIG_ISOSENSITIVITY_RANGE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 low; /**< Lowest ISO value allowed */ + OMX_U32 high; /**< Highest ISO value allowed */ +} NVX_CONFIG_ISOSENSITIVITY_RANGE; + +/** Config extension index to specify white balance correlated color + * temperature (CCT) range for camera. + * + * Auto white balance will normally search a large set of illuminants to + * estimate the CCT of a scene. This range can be limited to a subset + * of the defined illuminants by setting this parameter. + * The config property's low and high values in the range + * specify the minimum and maximum CCT values to be searched. Legal values + * are integers in units of degrees K. To select a specific illuminant, + * the low and high members should be set to identical values. By default, + * the low range value is 0, and the high value is MAX_INT. + * + * See ::NVX_CONFIG_CCTWHITEBALANCE_RANGE + */ +#define NVX_INDEX_CONFIG_CCTWHITEBALANCERANGE "OMX.Nvidia.index.config.cctwhitebalancerange" +/** Holds data to specify whitebalance CCT range for camera. */ +typedef struct NVX_CONFIG_CCTWHITEBALANCE_RANGE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 low; /**< Low CCT range value */ + OMX_U32 high; /**< High CCT range value */ +} NVX_CONFIG_CCTWHITEBALANCE_RANGE; + +/** Config extension index to setup raw capture. + * See ::NVX_CONFIG_CAMERARAWCAPTURE + */ +#define NVX_INDEX_CONFIG_CAMERARAWCAPTURE "OMX.Nvidia.index.config.camera.rawcapture" +/** Holds data to setup raw capture. */ +typedef struct NVX_CONFIG_CAMERARAWCAPTURE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 nCaptureCount; /**< Number of frames to capture */ + OMX_STRING Filename; /**< File name to store into */ +} NVX_CONFIG_CAMERARAWCAPTURE; + +/** Config extension index to enable/disable concurrent raw dump. + * See ::OMX_CONFIG_BOOLEANTYPE + */ +#define NVX_INDEX_CONFIG_CONCURRENTRAWDUMPFLAG "OMX.Nvidia.index.config.concurrentrawdumflag" + +typedef enum +{ + NvxFlicker_Off, + NvxFlicker_Auto, + NvxFlicker_50HZ, + NvxFlicker_60HZ +} ENvxFlickerType; + +/** Config extension index to setup flicker. + * See ::NVX_CONFIG_FLICKER + */ +#define NVX_INDEX_CONFIG_FLICKER "OMX.Nvidia.index.config.flicker" +/** Holds data to setup flicker. */ +typedef struct NVX_CONFIG_FLICKER +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + ENvxFlickerType eFlicker; /**< Flicker type */ +} NVX_CONFIG_FLICKER; + +typedef enum NVX_IMAGEFILTERTYPE { + NVX_ImageFilterPosterize = 0x30000000, + NVX_ImageFilterSepia, + NVX_ImageFilterBW, + NVX_ImageFilterManual, + NVX_ImageFilterAqua, + NVX_ImageFilterMax = 0x7FFFFFFF +} NVX_IMAGEFILTERTYPE; + +/** Config extension index to setup hue. + * See ::NVX_CONFIG_HUETYPE + */ +#define NVX_INDEX_CONFIG_HUE "OMX.Nvidia.index.config.hue" +/** Holds data to setup hue. */ +typedef struct NVX_CONFIG_HUETYPE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_S32 nHue; /**< Hue in degrees, 0 to 359 */ +} NVX_CONFIG_HUETYPE; + + +/** Config extension index to control focus regions. + * The rectangle coordinates are normalized to -1.0 to 1.0 on the + * X and Y axis. + * Auto focus region will work only when auto focus is enabled. + * + * See ::NVX_CONFIG_FocusRegionsRect + */ +#define NVX_INDEX_CONFIG_FOCUSREGIONSRECT "OMX.Nvidia.index.config.focusregionsrect" +/** Holds data to control focus regions. */ +typedef struct NVX_CONFIG_FocusRegionsRect +{ + OMX_U32 nRegions; /**< Number of regions */ + NVX_RectF32 regions[NVX_MAX_FOCUS_REGIONS]; /**< Array of NVX_RectF32 to specify each focus region */ +} NVX_CONFIG_FocusRegionsRect; + +/** Config extension index to control camera focusing regions sharpness values. + * You can use this interface to measure focus sharpness in manual mode. + * This interface fills in an ::NVX_CONFIG_FOCUSREGIONS_SHARPNESS structure. + * @note NVIDIA currently supports only one region, so the value of interest will be in: + * ::NVX_CONFIG_FOCUSREGIONS_SHARPNESS.nSharpness[0] + */ +#define NVX_INDEX_CONFIG_FOCUSREGIONSSHARPNESS "OMX.Nvidia.index.config.focusregionssharpness" +/** Holds data to control camera focusing regions sharpness values. + * @sa NVX_INDEX_CONFIG_FOCUSREGIONSSHARPNESS + */ +typedef struct NVX_CONFIG_FOCUSREGIONS_SHARPNESS +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 nRegions; /**< Number of currently active focusing regions */ + NVX_F32 nSharpness[NVX_MAX_FOCUS_REGIONS]; /**< Sharpness values for active focusing regions. @note Currently, NVIDIA supports only one region, so the value of interest will be in \c NVX_CONFIG_FOCUSREGIONS_SHARPNESS.nSharpness[0]. You can use the ::NVX_INDEX_CONFIG_FOCUSREGIONSSHARPNESS interface to measure focus sharpness in manual mode. This interface fills in an ::NVX_CONFIG_FOCUSREGIONS_SHARPNESS structure. */ +} NVX_CONFIG_FOCUSREGIONS_SHARPNESS; + +/** Config extension index for direct focuser control. + * @note This extension is deprecated. What you probably want is + * OMX_IndexConfigFocusControl. + */ +#define NVX_INDEX_CONFIG_DIRECTFOCUSERCONTROL "OMX.Nvidia.index.config.directfocusercontrol" +/** Holds a direct focuser control. */ +typedef struct NVX_CONFIG_DIRECT_FOCUSERCONTROL +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 nLength; /**< Length of focuser control sequence */ + OMX_U32 nControl[NVX_MAX_DIRECT_FOCUSER_CONTROL_LENGTH]; /**< Focuser control sequence */ +} NVX_CONFIG_DIRECT_FOCUSERCONTROL; + +/** Config extension for querying camera focusing parameters. + * + * See ::NVX_CONFIG_FOCUSER_PARAMETERS + */ +#define NVX_INDEX_CONFIG_FOCUSERPARAMETERS "OMX.Nvidia.index.config.focuserparameters" + +typedef struct NVX_CONFIG_FOCUSER_PARAMETERS +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_S32 minPosition; /**< Minimum focus position supported by Camera */ + OMX_S32 maxPosition; /**< Maximum focus position supported by Camera */ + OMX_S32 hyperfocal; /**< Hyperfocal focus position */ + OMX_S32 macro; /**< Macro focus position */ + OMX_S32 powerSaving; /**< Most power-efficient focus position */ + /**< (-1) if any position is good */ + OMX_BOOL sensorispAFsupport; + OMX_BOOL infModeAF; /**< AF support in Infinity mode */ + OMX_BOOL macroModeAF; /**< AF support in Macro mode */ +} NVX_CONFIG_FOCUSER_PARAMETERS; + +/** Config extension for querying camera focusing parameters. + * Following variables map to the coresponding variables in structure NvIspAfConfigParams + * File camera/core/camera/alg/af/autofocus_common.h + * + * See ::NVX_CONFIG_FOCUSER_INFO + */ +#define NVX_INDEX_CONFIG_FOCUSER_INFO "OMX.Nvidia.index.config.focuserinfo" + +typedef struct NVX_CONFIG_FOCUSER_INFO +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_S32 positionPhysicalLow; + OMX_S32 positionPhysicalHigh; + OMX_S32 positionInf; + OMX_S32 positionInfOffset; + OMX_S32 positionMacro; + OMX_S32 positionMacroOffset; + OMX_S32 positionHyperFocal; + OMX_S32 positionResting; + OMX_S32 infMin; /**< Percentage value of the working range */ + OMX_S32 macroMax; /**< Percentage value of the working range */ + OMX_S32 infInitSearch; /**< Percentage value of the working range */ + OMX_S32 macroInitSearch; /**< Percentage value of the working range */ + OMX_BOOL rangeEndsReversed; + OMX_S32 hysteresis; + OMX_S32 slewRate; + OMX_S32 settleTime; +} NVX_CONFIG_FOCUSER_INFO; + +/** Config extension for querying camera flash parameters. + * + * See ::NVX_CONFIG_FLASH_PARAMETERS + */ +#define NVX_INDEX_CONFIG_FLASHPARAMETERS "OMX.Nvidia.index.config.flashparameters" + +typedef struct NVX_CONFIG_FLASH_PARAMETERS +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL bPresent; /**< Flash available for this sensor. */ +} NVX_CONFIG_FLASH_PARAMETERS; + +/** Config extension for querying camera low-level focuser device capabilities. + * See ::NVX_CONFIG_FOCUSER_CAPABILITIES + */ +#define NVX_INDEX_CONFIG_FOCUSERCAPABILITIES "OMX.Nvidia.index.config.focusercapabilities" +/** Holds a querying focuser capabilities. */ +typedef struct NVX_CONFIG_FOCUSER_CAPABILITIES +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 nRange; /**< Range of focuser movement in device-dependent steps */ + NVX_F32 directionFactor; /**< Scaling factor for focuser device movement in "infinity" and "macro" directions */ + OMX_U32 nSettleTime; /**< Guaranteed settling time in millisecs */ +} NVX_CONFIG_FOCUSER_CAPABILITIES; + +/** Config extension to set the AF auto focusing speed. Fast is potentially + * less accurate; not fast is accurate but potentially quite slow. + */ +#define NVX_INDEX_CONFIG_AUTOFOCUS_SPEED "OMX.Nvidia.index.config.autofocusspeed" +typedef struct { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL bFast; /**< OMX_TRUE if you want fast focusing mode + @note Slow mode may take several seconds + to settle. */ +} NVX_CONFIG_AUTOFOCUS_SPEED; + +/** Holds a sensor mode configuration. */ +typedef struct NVX_SENSORMODE +{ + OMX_S32 width; + OMX_S32 height; + NVX_F32 FrameRate; +} NVX_SENSORMODE; + +/** Config extension index to control sensor mode list of supported resolution and frame rate. + * See ::NVX_CONFIG_SENSORMODELIST + */ +#define NVX_INDEX_CONFIG_SENSORMODELIST "OMX.Nvidia.index.config.sensormodelist" +/** Holds sensor modes. */ +typedef struct NVX_CONFIG_SENSORMODELIST +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + + OMX_U32 nSensorModes; /**< Number of sensor modes */ + NVX_SENSORMODE SensorModeList[MAX_NUM_SENSOR_MODES]; /**< Array of sensor modes */ +} NVX_CONFIG_SENSORMODELIST; + +#define NVX_INDEX_CONFIG_CAPTUREMODE "OMX.Nvidia.index.config.capturemode" +/** Holds Capture Sensor Mode . */ +typedef struct NVX_CONFIG_CAPTUREMODE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + + NVX_SENSORMODE mMode; /** Sensor Mode */ +} NVX_CONFIG_CAPTUREMODE; + +#define NVX_INDEX_PARAM_PREVIEWMODE "OMX.Nvidia.index.param.previewmode" +/** Holds Preview Sensor Mode . */ +typedef struct NVX_PARAM_PREVIEWMODE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + + NVX_SENSORMODE mMode; /** Sensor Mode */ +} NVX_PARAM_PREVIEWMODE; + +/** Config extension index to get sensor ID. + * See ::OMX_PARAM_U32TYPE + */ +#define NVX_INDEX_PARAM_SENSORID "OMX.Nvidia.index.config.sensorid" + +/** Param extension index to set full 64-bit sensor GUID + * See ::NVX_PARAM_SENSOR_GUID + */ +#define NVX_INDEX_PARAM_SENSOR_GUID "OMX.Nvidia.index.param.sensorguid" + +/** Config/Param extension index to get number of available sensors on current platform. + * (Read-only) + * See ::OMX_PARAM_U32TYPE + */ +#define NVX_INDEX_PARAM_AVAILABLESENSORS "OMX.Nvidia.index.param.availablesensors" + +/** Param extension index to set sensor mode. + * Sets the user-selected sensor mode (width, height, and frame rate). + * The default sensor mode is auto, i.e., \a WxHxFramerate is 0x0x0. + * The default auto mode (0x0x0) basically implies that the camera + * driver picks up the correct sensor mode using its own justification. + * Once the user-selected sensor mode is set using this interface, + * the default auto mode can be achieved again by setting 0x0x0 as + * sensor mode. + * See ::NVX_PARAM_SENSORMODE + */ +#define NVX_INDEX_PARAM_SENSORMODE "OMX.Nvidia.index.config.sensormode" + +/** Holds the data for sensor mode setting. */ +typedef struct NVX_PARAM_SENSORMODE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + NVX_SENSORMODE SensorMode; /**< Sensor mode */ +}NVX_PARAM_SENSORMODE; + +/** Param extension index to set the video speed on camera component. + * Sets the user-selected video speed (0.25x/0.5x/1x/2x/3x/4x). + * The default speed on the video port of camera is 1. + * See ::NVX_PARAM_VIDEOSPEED + */ +#define NVX_INDEX_CONFIG_VIDEOSPEED "OMX.Nvidia.index.config.videospeed" + +/** Holds the data for camera frame speed setting on video port. */ +typedef struct NVX_PARAM_VIDEOSPEED +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL bEnable; /**< Boolean to enable/disable recording speed */ + NVX_F32 nVideoSpeed; /**< Video speed*/ +}NVX_PARAM_VIDEOSPEED; + +/** Config extension index to enable custom postview processing. + * See ::OMX_PARAM_U32TYPE + */ +#define NVX_INDEX_CONFIG_CUSTOMPOSTVIEW "OMX.Nvidia.index.config.custompostview" +typedef struct NVX_PARAM_CUSTOMPOSTVIEW +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL bEnable; /**< Boolean to enable/disable recording speed */ +}NVX_PARAM_CUSTOMPOSTVIEW; + + +/** + * Defines the stereo camera modes. + */ +typedef enum { + NvxLeftOnly = 0x01, /**< Only the sensor on the left is on. */ + NvxRightOnly = 0x02, /**< Only the sensor on the right is on. */ + NvxStereo = (NvxLeftOnly | NvxRightOnly), /**< Sets the stereo camera to stereo mode. */ + NvxStereoCameraForce32 = 0x7FFFFFFF +} ENvxCameraStereoCameraMode; + +/** Param extension index to set camera mode, if the camera is stereo. + Must be set before sensor power on. + Has no effect for non-stereo cameras. +*/ +#define NVX_INDEX_PARAM_STEREOCAMERAMODE "OMX.Nvidia.index.param.stereocameramode" +/** Holds the data for stereo mode setting. */ +typedef struct NVX_PARAM_STEREOCAMERAMODE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + ENvxCameraStereoCameraMode StereoCameraMode; /**< ENvxCameraStereoCameraMode to select stereo camera mode */ +}NVX_PARAM_STEREOCAMERAMODE; + +/** + * Defines the stereo camera capture type. + */ +typedef enum { + NvxCameraCaptureType_None, // No capture. + NvxCameraCaptureType_Video, // Video capture. + NvxCameraCaptureType_Still, // Photo capture. + NvxCameraCaptureType_StillBurst, // Photo burst capture. + NvxCameraCaptureType_VideoSquashed, // Video capture (Sqashed frame). + NvxCameraCaptureType_Force32 = 0x7FFFFFFFL +} ENvxCameraCaptureType; + +/** + * Defines the stereo camera type. + */ +typedef enum { + Nvx_BufferFlag_Stereo_None, + Nvx_BufferFlag_Stereo_LeftRight, + Nvx_BufferFlag_Stereo_RightLeft, + Nvx_BufferFlag_Stereo_TopBottom, + Nvx_BufferFlag_Stereo_BottomTop, + Nvx_BufferFlag_Stereo_SeparateLR, + Nvx_BufferFlag_Stereo_SeparateRL +} ENvxCameraStereoType; + +/** Holds the stereo camera information. */ +typedef struct NVX_STEREOCAPTUREINFO +{ + ENvxCameraCaptureType CameraCaptureType; + ENvxCameraStereoType CameraStereoType; +} NVX_STEREOCAPTUREINFO; + +/** Param extension index to set camera mode, if the camera is stereo. + Must be set before sensor power on. + Has no effect for non-stereo cameras. +*/ +#define NVX_INDEX_PARAM_STEREOCAPTUREINFO "OMX.Nvidia.index.param.stereocaptureinfo" +/** Holds the data for stereo info setting. */ +typedef struct NVX_PARAM_STEREOCAPTUREINFO +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + NVX_STEREOCAPTUREINFO StCaptureInfo; +} NVX_PARAM_STEREOCAPTUREINFO; + +/** Param extension index to set use native handle (for camera preview) +*/ +#define NVX_INDEX_PARAM_USE_NBH "OMX.Nvidia.index.param.useNativeBufferHandles" +/** Holds the data for stereo mode setting. */ +typedef struct NVX_PARAM_USENATIVEBUFFERHANDLE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BUFFERHEADERTYPE **bufferHeader; + OMX_PTR oNativeBufferHandlePtr; /**< pointer to native buffer handle */ +}NVX_PARAM_USENATIVEBUFFERHANDLE; + + +/** Config extension index to setup edge enhancement. + * Edge enhancement increases the apparent sharpness of full + * resolution images. It has no effect on downscaled images. + * + * See ::NVX_CONFIG_EDGEENHANCEMENT + */ +#define NVX_INDEX_CONFIG_EDGEENHANCEMENT "OMX.Nvidia.index.config.edgeenhancement" +/** Holds data to setup edge enhancement. */ +typedef struct NVX_CONFIG_EDGEENHANCEMENT +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + + OMX_BOOL bEnable; /**< Boolean to enable/disable edge enhancement */ + NVX_F32 strengthBias; /**< Bias the Strength of edge enhancement (float: -1 to 1) */ +} NVX_CONFIG_EDGEENHANCEMENT; + +/** Config extension index for ISP data dump. + * @deprecated This index is deprecated. + */ +#define NVX_INDEX_CONFIG_ISPDATA "OMX.Nvidia.index.config.ispdata" +/** @deprecated This structure is deprecated. */ +typedef struct NVX_CONFIG_ISPDATA +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + NVX_F32 ilData; /**< ilData */ + NVX_F32 ilData2; /**< ilData2 */ +} NVX_CONFIG_ISPDATA; + +/** Config extension index to set temporal tradeoff level for video encoder. + * + * For example: + * - 0 = Encoder delivers frames as fast as possible + * - 1 = Encoder drops 1 in 5 frames + * - 2 = Encoder drops 1 in 3 frames + * - 3 = Encoder drops 1 in 2 frames + * - 4 = Encoder drops 2 in 3 frames + * + * See ::NVX_ENCODE_VIDEOTEMPORALTRADEOFF for values for video encode + * temporal tradeoff level. + * + * @sa ::NVX_CONFIG_TEMPORALTRADEOFF + */ +#define NVX_INDEX_CONFIG_VIDEO_ENCODE_TEMPORALTRADEOFF "OMX.Nvidia.index.config.video.encode.temporaltradeoff" +/** Holds data to set temporal tradeoff. */ +typedef struct NVX_CONFIG_TEMPORALTRADEOFF +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 TemporalTradeOffLevel; /**< Temporal tradeoff level */ +} NVX_CONFIG_TEMPORALTRADEOFF; + +/** Defines the encode video temporal tradeoff types used to + * set the video temporal tradeoff level. + * @sa ::NVX_CONFIG_TEMPORALTRADEOFF + */ +typedef enum NVX_ENCODE_VIDEOTEMPORALTRADEOFF{ + NVX_ENCODE_VideoEncTemporalTradeoffLevel_DropNone= 0, + NVX_ENCODE_VideoEncTemporalTradeoffLevel_Drop1in5, + NVX_ENCODE_VideoEncTemporalTradeoffLevel_Drop1in3, + NVX_ENCODE_VideoEncTemporalTradeoffLevel_Drop1in2, + NVX_ENCODE_VideoEncTemporalTradeoffLevel_Drop2in3, + NVX_ENCODE_VideoEncTemporalTradeoffLevel_Force32 = 0x7FFFFFFF +} NVX_ENCODE_VIDEOTEMPORALTRADEOFF; + +/** Config extension index to get decoder configartion information from video encoder. + * See ::NVX_CONFIG_DecoderConfigInfo + */ +#define NVX_INDEX_CONFIG_VIDEO_ENCODE_DCI "OMX.Nvidia.index.config.video.encode.dci" +/** Holds data to get decoder configuration. */ +typedef struct NVX_CONFIG_DecoderConfigInfo +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U8 DecoderConfigInfo[NVX_VIDEOENC_DCI_SIZE]; /**< Decoder configuration info*/ + OMX_U8 SizeOfDecoderConfigInfo; /**< Size of decoder configuration info*/ +}NVX_CONFIG_DecoderConfigInfo; + + +/** Config extension index for enabling per-frame user-space copies of the preview buffer. + * + * See ::NVX_CONFIG_PREVIEW_FRAME_COPY + */ +#define NVX_INDEX_CONFIG_PREVIEW_FRAME_COPY "OMX.Nvidia.index.config.previewframecopy" +/** Holds data to enable/disable copying of preview frames */ +typedef struct NVX_CONFIG_PREVIEW_FRAME_COPY +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL enable; /**< enable/disable bit */ + OMX_U32 skipCount; /**< skipcount : Number of frame to be skip for preview frame copy */ +} NVX_CONFIG_PREVIEW_FRAME_COPY; + +/** Config extension index for enabling per-still user-space copies of the + * still confirmation buffer. + * + * See ::NVX_CONFIG_STILL_CONFIRMATION_FRAME_COPY + */ +#define NVX_INDEX_CONFIG_STILL_CONFIRMATION_FRAME_COPY "OMX.Nvidia.index.config.stillconfirmationframecopy" +/** Holds data to enable/disable copying of still-confirmation frames */ +typedef struct NVX_CONFIG_STILL_CONFIRMATION_FRAME_COPY +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL enable; /**< enable/disable bit */ +} NVX_CONFIG_STILL_CONFIRMATION_FRAME_COPY; + +/** Config extension index to set the camera configuration + * + * The ConfigString can be one of the below specified strings: + * + * - "ae.ConvergeSpeed=%f" + * - "awb.ConvergeSpeed=%f" + * - "ispFunction.lensShading=%s" + * + * where: + * - %f is a float value + * - %s is a string + * + * The float value for + * - ae.ConvergeSpeed must be [0.01-1.0] + * - awb.ConvergeSpeed must be [0.01-1.0] + * + * The string value for ispFunction.lensShading must be: + * - TRUE/true to enable lens shading + * - FALSE/false to disable lens shading + * For ex : "ispFunction.lensShading=TRUE" + * "ispFunction.lensShading=FALSE" + * + * If the ConfigString passed does not "EXACTLY" match any of the above three strings, then + * an error is returned. + * + * See ::NVX_CONFIG_CAMERACONFIGURATION + */ +#define NVX_INDEX_CONFIG_CAMERACONFIGURATION "OMX.Nvidia.index.config.cameraconfiguration" +/** Holds camera configuration string */ +typedef struct NVX_CONFIG_CAMERACONFIGURATION +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_STRING ConfigString; /**< Camera Configuration string */ +} NVX_CONFIG_CAMERACONFIGURATION; + +/** Config extension index for enabling per-still, user-space copies of the + * still YUV. + * + * See ::NVX_CONFIG_STILL_YUV_FRAME_COPY + */ +#define NVX_INDEX_CONFIG_STILL_YUV_FRAME_COPY "OMX.Nvidia.index.config.stillYUVframecopy" +/** Holds data to enable/disable copying of still YUV frames. */ +typedef struct NVX_CONFIG_STILL_YUV_FRAME_COPY +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL enable; /**< Enable/disable bit */ +} NVX_CONFIG_STILL_YUV_FRAME_COPY; + +/** Config extension index to querying if the camera is stereo. + */ +#define NVX_INDEX_CONFIG_STEREOCAPABLE "OMX.Nvidia.index.config.stereocapable" +/** Holds the data from stereo capability query. */ +typedef struct NVX_CONFIG_STEREOCAPABLE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL StereoCapable; /**< Boolean to indicate if this is a stereo camera */ +} NVX_CONFIG_STEREOCAPABLE; + +/** Config extension index for querying the scene brightness. + * The brightness of the scene is the average scene luminance divided by the exposure value. + * The higher the value, the brighter the scene. + * + * Read-only + */ +#define NVX_INDEX_CONFIG_SCENEBRIGHTNESS "OMX.Nvidia.index.config.scenebrightness" +/** Holds the data from scene brightness query. */ +typedef struct NVX_CONFIG_SCENEBRIGHTNESS +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + NVX_F32 SceneBrightness; /**< Scene brightness level */ + OMX_BOOL FlashNeeded; /**< If flash light is needed for next capture */ +} NVX_CONFIG_SCENEBRIGHTNESS; + +/** Holds the custom block info from imager. */ +typedef struct NVX_CUSTOMINFO +{ + OMX_U32 SizeofData; + OMX_STRING Data; +} NVX_CUSTOMINFO; + +/** Config extension index to query custom block info from imager. + */ +#define NVX_INDEX_CONFIG_CUSTOMIZEDBLOCKINFO "OMX.Nvidia.index.config.customizedblockinfo" +/** Holds custom block info from imager. */ +typedef struct NVX_CONFIG_CUSTOMIZEDBLOCKINFO +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + NVX_CUSTOMINFO CustomInfo; /**< Custom info from imager */ +} NVX_CONFIG_CUSTOMIZEDBLOCKINFO; + +/** Config extension index for enabling advanced noise reduction. + * + * See ::NVX_CONFIG_ADVANCED_NOISE_REDUCTION + */ +#define NVX_INDEX_CONFIG_ADVANCED_NOISE_REDUCTION "OMX.Nvidia.index.config.advancedNoiseReduction" +/** Holds data to control advanced noise reduction. + + The thresholds below are used to control the shape of the data + Gaussian use to measure similarity between colors. Useful values + will be between 0 and 0.2. The smaller the value, the more picky + we are about considering something similar. The value of 0 means + to disable filtering altogether for the corresponding channels. + + For each of luma, chroma: + threshold[0] is used for horizontal filtering + threshold[1] is used for vertical filtering + */ +typedef struct NVX_CONFIG_ADVANCED_NOISE_REDUCTION { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL enable; /**< Enable/disable bit */ + NVX_F32 lumaThreshold[2]; /**< Filter parameters for luma */ + NVX_F32 chromaThreshold[2]; /**< Filter parameters for chroma */ + OMX_U32 lumaIsoThreshold; /**< Disable luma filtering if ISO below this thresh */ + OMX_U32 chromaIsoThreshold; /**< Disable chroma filtering if ISO below this thresh */ +} NVX_CONFIG_ADVANCED_NOISE_REDUCTION; + +// Post-processing noise reduction stuff + +#define NVX_INDEX_CONFIG_NOISE_REDUCTION_V1 "OMX.Nvidia.index.config.nr.V1" +#define NVX_INDEX_CONFIG_NOISE_REDUCTION_V2 "OMX.Nvidia.index.config.nr.V2" + +enum { NVX_NR_V2_PRESET_LEVELS = 5 }; +enum { NVX_NR_V2_GAIN_INDEX_SIZE = 16 }; +enum { NVX_NR_V2_REDUCTION_DEPTH = 3 }; // Pyramid depth (not counting top band) +enum { NVX_NR_V2_DOWNSCALE_TAPS = 2 }; + +typedef struct { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + + // Enables the Bilateral Noise reduction + OMX_BOOL lumaEnable; + OMX_BOOL chromaEnable; + + // Turns on the noise reduction only above specified ISO + OMX_U32 lumaIsoThreshold; + OMX_U32 chromaIsoThreshold; + + // Threshold parameters used to control how picky we are about + // what a similar pixel is. Used to control the width of the + // gaussian tent function. Useful values will be between 0 and 0.2. + // If 0, then the corresponding planes will not be filtered. + // Only the horizontal (1st pass) filtering is specified; + // the vertical (2nd pass) is now forced to 0.58 * horizontal + NVX_F32 lumaThreshold; + NVX_F32 chromaThreshold; + + // Controls how we increase the thresholds as a function of the + // gain applied by AE. Thresholds specified above apply when the + // gain = 1.0, and increase with gain according to these values. + NVX_F32 lumaSlope; + NVX_F32 chromaSlope; +} NVX_CONFIG_NOISE_REDUCTION_V1; + +typedef struct { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + + // Enables the Pyramid Noise reduction + OMX_BOOL chromaEnable; + + // Turns on the chroma noise reduction only above specified ISO + OMX_U32 chromaIsoThreshold; + + // Adjusts for sensor gain for gain index computation + NVX_F32 chromaThreshold; + NVX_F32 chromaSlope; + + // chromaSpeed == FALSE then disable 3x3 downsampler and use averaging downsampler + OMX_BOOL chromaSpeed; + + // Enables the 5x5 luma convolution + OMX_BOOL lumaConvolutionEnable; +} NVX_CONFIG_NOISE_REDUCTION_V2; + +#define NVX_INDEX_CONFIG_BAYERGAINS "OMX.Nvidia.index.config.bayergains" +/** Reserved. Adjusts the per-channel bayer gains. */ +typedef struct NVX_CONFIG_BAYERGAINS +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + NVX_F32 gains[4]; /**< Gains per Bayer channel */ +} NVX_CONFIG_BAYERGAINS; + +/** Config extension index to get gain range of sensor mode. */ +#define NVX_INDEX_CONFIG_GAINRANGE "OMX.Nvidia.index.config.gainrange" +typedef struct NVX_CONFIG_GAINRANGE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + NVX_F32 low; /**< Minimum gain of mode */ + NVX_F32 high; /**< Maximum gain of mode */ +} NVX_CONFIG_GAINRANGE; + +#define NVX_INDEX_CONFIG_VIDEOFRAME_CONVERSION "OMX.Nvidia.index.config.videoframeconversion" +/** Reserved. Produces video frame data in user-specified format from OMX buffer. */ + +typedef enum NVX_VIDEOFRAME_FORMAT { + NVX_VIDEOFRAME_FormatYUV420 = 0, + NVX_VIDEOFRAME_FormatNV21, + NVX_VIDEOFRAME_FormatInvalid = 0x7FFFFFFF +} NVX_VIDEOFRAME_FORMAT; + +typedef struct NVX_CONFIG_VIDEOFRAME_CONVERSION +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + NVX_VIDEOFRAME_FORMAT userFormat; /**< Requested YUV data format */ + OMX_PTR omxBuffer; /**< OMX buffer to take data from */ + OMX_U32 nDataSize; /**< Converted data size in bytes */ + OMX_PTR data; /**< Pointer to data */ +} NVX_CONFIG_VIDEOFRAME_CONVERSION; + +/** Config extension index for enabling capture priority. + * In capture priority mode, still/video capture has a higher priority than + * preview, so still/video frame rate may increase while preview frame rate + * may decrease. + */ +#define NVX_INDEX_CONFIG_CAPTURE_PRIORITY "OMX.Nvidia.index.config.capturepriority" +/** Holds data to enable/disable capture priority. */ +typedef struct NVX_CONFIG_CAPTURE_PRIORITY +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL Enable; /**< Enable/disable bit */ +} NVX_CONFIG_CAPTURE_PRIORITY; + +#define NVX_INDEX_CONFIG_LENS_PHYSICAL_ATTR "OMX.Nvidia.index.config.lensPhysicalAttr" +/** Config extension index for getting focal length. */ +typedef struct NVX_CONFIG_LENS_PHYSICAL_ATTR +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + NVX_F32 eFocalLength; /**< Focal length */ + NVX_F32 eHorizontalAngle; /**< Horizontal view angle */ + NVX_F32 eVerticalAngle; /**< Vertical view angle */ +} NVX_CONFIG_LENS_PHYSICAL_ATTR; + +/** Config extension index to get focus distances. + * Gets the distances from the camera to where an object appears to be + * in focus. The object is sharpest at the optimal focus distance. The + * depth of field is the far focus distance minus near focus distance. + * See ::NVX_CONFIG_FOCUSDISTANCES + */ +#define NVX_INDEX_CONFIG_FOCUSDISTANCES "OMX.Nvidia.index.config.focusdistances" +/** Holds data to setup focus distance. */ +typedef struct NVX_CONFIG_FOCUSDISTANCES +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version + information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + NVX_F32 NearDistance; /**< Near distance */ + NVX_F32 OptimalDistance; /**< Optimal distance */ + NVX_F32 FarDistance; /**< Far distance */ +} NVX_CONFIG_FOCUSDISTANCES; + +/** Config extension index to set a exposure bracket capture. + * This capture returns a burst of images each with a specified + * AE adjustment. The avaliable range is (-3.0, +3.0) + * See ::NVX_INDEX_CONFIG_BRACKETCAPTURE + */ +#define NVX_INDEX_CONFIG_BRACKETCAPTURE "OMX.Nvidia.index.config.bracketcapture" +/** Holds data to setup focus distance. */ +typedef struct NVX_CONFIG_EXPOSUREBRACKETCAPTURE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version + information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 NumberOfCaptures; /**< Number of valid adjustments */ + NVX_F32 FStopAdjustments[32]; /**< Array of adjustments*/ +} NVX_CONFIG_EXPOSUREBRACKETCAPTURE; + +/** Config extension index to set a continuous autofocus. + * See ::OMX_CONFIG_BOOLEANTYPE + */ +#define NVX_INDEX_CONFIG_CONTINUOUSAUTOFOCUS "OMX.Nvidia.index.config.continuousautofocus" + +/** Config extension index to set a face-assisted (continuous) autofocus. + * See ::NVX_INDEX_CONFIG_FACEAUTOFOCUS + */ +#define NVX_INDEX_CONFIG_FACEAUTOFOCUS "OMX.Nvidia.index.config.faceautofocus" + +/** Config extension index to pause continuous autofocus. + * See ::OMX_CONFIG_BOOLEANTYPE + */ +#define NVX_INDEX_CONFIG_CONTINUOUSAUTOFOCUS_PAUSE "OMX.Nvidia.index.config.continuousautofocuspause" + +/** Config extension index to query the continuous autofocus alg state. + * See ::NVX_CONFIG_CONTINUOUSAUTOFOCUS_STATE + */ +#define NVX_INDEX_CONFIG_CONTINUOUSAUTOFOCUS_STATE "OMX.Nvidia.index.config.continuousautofocusstate" +/** Holds information about the CAF alg state */ +typedef struct NVX_CONFIG_CONTINUOUSAUTOFOCUS_STATE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version + information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL bConverged; /**< Tells whether the alg is converged */ +} NVX_CONFIG_CONTINUOUSAUTOFOCUS_STATE; + +#define NVX_INDEX_CONFIG_MANUALTORCHAMOUNT "OMX.Nvidia.index.config.manualtorchamount" +#define NVX_INDEX_CONFIG_MANUALFLASHAMOUNT "OMX.Nvidia.index.config.manualflashamount" +#define NVX_INDEX_CONFIG_AUTOFLASHAMOUNT "OMX.Nvidia.index.config.autoflashamount" + +/** Holds data to specify the amount of manual torch, manual flash, or auto flash for camera. */ +typedef struct NVX_CONFIG_FLASHTORCHAMOUNT +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + NVX_F32 value; /**< Flash/torch value */ +} NVX_CONFIG_FLASHTORCHAMOUNT; + +/** + * Defines the Camera ScaleTypes + */ +typedef enum NVX_CAMERA_SCALETYPE +{ + /** + * Don't preserve aspect ratio. Output may be stretched if input does + * not have the same aspect ratio as output. + */ + NVX_CAMERA_ScaleType_Normal=0x1, + + /** + * Preserve aspect ratio. Stretch the input image to the center + * of output surface. Pad black color on output surface outside the + * stretched input image. + */ + NVX_CAMERA_ScaleType_Pad, + + /** + * Preserve aspect ratio. Crop input image to fit output surface so + * the whole output surface will be filled with cropped input image. + */ + NVX_CAMERA_ScaleType_Crop, + + /** + * Don't preserve aspect ratio. Output may be stretched if input does + * not have the same aspect ratio as output. For rotation involving + * XY swap like 90/270, the output surface doesn't get transformed. + */ + NVX_CAMERA_ScaleType_Stretched, + + NVX_CAMERA_ScaleType_Force32 = 0x7FFFFFFF +}NVX_CAMERA_SCALETYPE; + +#define NVX_INDEX_CONFIG_COMMONSCALETYPE "OMX.Nvidia.index.config.commonscaletype" + +/** Holds scale type for preview, still and video output. */ +typedef struct NVX_CONFIG_COMMONSCALETYPE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + NVX_CAMERA_SCALETYPE type; /**< NVX_CAMERA_SCALETYPE */ +} NVX_CONFIG_COMMONSCALETYPE; + +/** Param extension index to enable/disable VI/ISP pre-scaling in camera for + * capture output. + * Several of the Tegra ISP features need to be disabled when pre-scaling is + * ON. For instance, EdgeEnhancement and Emboss. + * By default, pre-scaling is turned ON. + */ +#define NVX_INDEX_PARAM_PRESCALER_ENABLE_FOR_CAPTURE "OMX.Nvidia.index.param.prescalerenableforcapture" + +/** Holds data to enable/disable VI/ISP pre-scaling in camera for capture output. */ +typedef struct NVX_PARAM_PRESCALER_ENABLE_FOR_CAPTURE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL Enable; /**< Enable/disable bit */ +} NVX_PARAM_PRESCALER_ENABLE_FOR_CAPTURE; + +/** Param extension index to fine tune video encoder and decoder buffer configuration. + * See ::NVX_PARAM_USELOWBUFFER + */ +#define NVX_INDEX_PARAM_USELOWBUFFER "OMX.Nvidia.index.param.uselowbuffer" +/** Holds data to fine tune video encoder and decoder buffer configuration. */ +typedef struct NVX_PARAM_USELOWBUFFER +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL bUseLowBuffer; /**< Boolean to enable low buffer configuration */ +} NVX_PARAM_USELOWBUFFER; + +#define NVX_INDEX_CONFIG_FRAME_COPY_COLOR_FORMAT "OMX.Nvidia.index.config.framecopycolorformat" + +/** Holds data to specify the color formats of preview, still confirmation, + * and still raw frame copies + */ +typedef struct NVX_CONFIG_FRAME_COPY_COLOR_FORMAT +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + NVX_IMAGE_COLOR_FORMATTYPE PreviewFrameCopy; /**< preview frame copy format */ + NVX_IMAGE_COLOR_FORMATTYPE StillConfirmationFrameCopy; /**< still confirmation frame copy format */ + NVX_IMAGE_COLOR_FORMATTYPE StillFrameCopy; /**< still frame copy format */ +} NVX_CONFIG_FRAME_COPY_COLOR_FORMAT; + +#define NVX_INDEX_CONFIG_NSLBUFFERS "OMX.Nvidia.index.config.nslbuffers" +/** Holds data to specify the number of buffers to use for negative shutter lag */ +typedef struct NVX_CONFIG_NSLBUFFERS +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 numBuffers; /**< Number of buffers to use for NSL */ +} NVX_CONFIG_NSLBUFFERS; + +#define NVX_INDEX_CONFIG_NSLSKIPCOUNT "OMX.Nvidia.index.config.nslskipcount" +/** Holds data to specify the number of buffers to skip between each buffer that + * is saved to the NSL buffer list. + */ +typedef struct NVX_CONFIG_NSLSKIPCOUNT +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 skipCount; /**< Number of buffers to skip before the next saved buffer */ +} NVX_CONFIG_NSLSKIPCOUNT; + + +#define NVX_INDEX_CONFIG_COMBINEDCAPTURE "OMX.Nvidia.index.config.combinedcapture" +/** Holds data to specify the capture request parameters */ +typedef struct NVX_CONFIG_COMBINEDCAPTURE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 nNslImages; /**< Number of images to pull from NSL buffer. + Only applies to still port.*/ + OMX_U32 nNslPreFrames; /**< Number of most-recent NSL frames to discard + before sending frames to encoder. + Only applies to still port.*/ + OMX_U32 nNslSkipCount; /**< Number of NSL frames to skip between frames + that are sent to encoder. THIS FIELD IS + DEPRECATED, NVX_CONFIG_NSLSKIPCOUNT should be + used instead.*/ + OMX_U64 nNslTimestamp; /**< Latest "valid" NSL capture time. Driver + will never give a frame that is newer + than this as part of the NSL capture. + Units of microseconds. + Only applies to still port.*/ + OMX_U32 nImages; /**< When this config is set on the still port, this + sets the number of burst frames to capture and send + to the encoder. When this config is set on the + video port, a nonzero value will start capture, + and a zero value will stop capture.*/ + OMX_U32 nSkipCount; /**< Number of frames to skip between frames + that are sent to encoder. + Only applies to still port.*/ + +} NVX_CONFIG_COMBINEDCAPTURE; + +#define NVX_INDEX_CONFIG_SENSORISPSUPPORT "OMX.Nvidia.index.config.sensorispsupport" +/** Config extension for querying sensor ISP support */ +typedef struct NVX_CONFIG_SENSORISPSUPPORT +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL bIspSupport; /**< Boolean to signify whether the sensor uses ISP */ +} NVX_CONFIG_SENSORISPSUPPORT; + +#define NVX_INDEX_CONFIG_THUMBNAILENABLE "OMX.Nvidia.index.config.thumnailenable" +/** Holds data to enable and to disable thumbnails */ +typedef struct NVX_CONFIG_THUMBNAILENABLE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + + OMX_BOOL bThumbnailEnabled; /**< Boolean to enable/disable thumbnails */ +} NVX_CONFIG_THUMBNAILENABLE; + +#define NVX_INDEX_CONFIG_REMAININGSTILLIMAGES "OMX.Nvidia.index.config.remainingstillimages" + +#define NVX_INDEX_CONFIG_LOWLIGHTTHRESHOLD "OMX.Nvidia.index.config.lowlightthreshold" +typedef struct NVX_CONFIG_LOWLIGHTTHRESHOLD +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_S32 nLowLightThreshold; /**< Low light threshold in microseconds (exposure time) */ +} NVX_CONFIG_LOWLIGHTTHRESHOLD; + +#define NVX_INDEX_CONFIG_MACROMODETHRESHOLD "OMX.Nvidia.index.config.macromodethreshold" +typedef struct NVX_CONFIG_MACROMODETHRESHOLD +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_S32 nMacroModeThreshold; /**< macro mode threshold in percents */ +} NVX_CONFIG_MACROMODETHRESHOLD; + +#define NVX_INDEX_CONFIG_FOCUSMOVEMSG "OMX.Nvidia.index.config.focusmovemsg" + +typedef struct NVX_CONFIG_FDLIMIT +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_S32 limit; /**< Number of faces FD can detect at most */ +} NVX_CONFIG_FDLIMIT; +#define NVX_INDEX_CONFIG_FDLIMIT "OMX.Nvidia.index.config.fdlimit" +#define NVX_INDEX_CONFIG_FDMAXLIMIT "OMX.Nvidia.index.config.fdmaxlimit" + +typedef struct NVX_CONFIG_FDRESULT +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_S32 num; /**< Tell how many faces are detected. */ + OMX_S8 fdResult[NVX_MAX_FD_OUTPUT_LENGTH]; /**< FD results will be copied here. */ +} NVX_CONFIG_FDRESULT; +#define NVX_INDEX_CONFIG_FDRESULT "OMX.Nvidia.index.config.fdresult" + +typedef struct NVX_CONFIG_BOOLEAN +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL enable; /**< on/off */ +} NVX_CONFIG_BOOLEAN; + +typedef NVX_CONFIG_BOOLEAN NVX_CONFIG_FDDEBUG; +#define NVX_INDEX_CONFIG_FDDEBUG "OMX.Nvidia.index.config.fddebug" + + +/** Config extension index for bypassing Dz. + * See ::OMX_CONFIG_BOOLEANTYPE + */ +#define NVX_INDEX_CONFIG_STILLPASSTHROUGH "OMX.Nvidia.index.config.stillpassthrough" + +/** Config extension index for giving preference to capture mode. +* See ::OMX_CONFIG_BOOLEANTYPE +*/ +#define NVX_INDEX_CONFIG_CAPTURESENSORMODEPREF "OMX.Nvidia.index.config.capturesensormodepref" + +typedef struct NVX_CONFIG_FASTBURSTEN +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL enable; +} NVX_CONFIG_FASTBURSTEN; +#define NVX_INDEX_CONFIG_FASTBURSTEN "OMX.Nvidia.index.config.fastburst" + +#define NVX_INDEX_CONFIG_CAMERAMODE "OMX.Nvidia.index.config.cameramode" +/** Param extension index to enable/disable RAW output. + * When RAW ouput is enabled preview port should be disabled. + * See ::OMX_CONFIG_BOOLEANTYPE + */ +#define NVX_INDEX_PARAM_RAWOUTPUT "OMX.Nvidia.index.param.rawoutput" + +/** Config extension index for programming device rotation. Write-only. + * + * See: OMX_CONFIG_ROTATIONTYPE + */ +#define NVX_INDEX_CONFIG_DEVICEROTATE "OMX.Nvidia.index.config.devicerotate" + +/** Config extension index for to set concurrent capture requests sent to VI HW. +* Must not be called when capture is active. Call only when camera component is in idle state. +* See ::OMX_PARAM_U32TYPE +*/ +#define NVX_INDEX_CONFIG_CONCURRENTCAPTUREREQUESTS "OMX.Nvidia.index.config.concurrentcapturerequests" + +/**Config extension index for allocating remaining buffers during runtime +* @deprecated This index is deprecated. +*/ +#define NVX_INDEX_CONFIG_ALLOCATEREMAININGBUFFERS "OMX.Nvidia.index.config.allocateremainingbuffers" +typedef struct NVX_CONFIG_REMAININGBUFFERTYPE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL enableAllocateBuffers; /**< Flag to enable or disable */ + OMX_U32 numBuffers; /**< number of remaining Buffers to be allocated */ +} NVX_CONFIG_REMAININGBUFFERTYPE; + +typedef struct NVX_CONFIG_STILLPASSTHROUGH +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL enablePassThrough; /**< Still Pass Through mode on/off */ +} NVX_CONFIG_STILLPASSTHROUGH; + +#endif + +/** @} */ +/* File EOF */ diff --git a/omx/openmax/NVOMX_ColorFormatExtensions.h b/omx/openmax/NVOMX_ColorFormatExtensions.h new file mode 100644 index 0000000..682ae87 --- /dev/null +++ b/omx/openmax/NVOMX_ColorFormatExtensions.h @@ -0,0 +1,59 @@ +/* Copyright (c) 2011 NVIDIA Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file + * <b>NVIDIA Tegra: OpenMAX Color Format Extension Interface</b> + */ + +/** + * @defgroup nv_omx_il_index General Index + * + * This is the NVIDIA OpenMAX color format extensions interface. + * + * These extend custom formats. + * + * @ingroup nvomx_general_extension + * @{ + */ + +#ifndef _NVOMX_ColorFormatExtensions_h_ +#define _NVOMX_ColorFormatExtensions_h_ + +/** android opaque colorformat. Tells the encoder that + * the actual colorformat will be relayed by the + * Gralloc Buffers + */ +#define OMX_COLOR_FormatAndroidOpaque 0x7F000789 + +/** Defines custom error extensions. */ +typedef enum NVX_IMAGE_COLOR_FORMATTYPE { + NVX_IMAGE_COLOR_FormatYV12 = OMX_COLOR_FormatVendorStartUnused + 1, + NVX_IMAGE_COLOR_FormatNV21, + NVX_IMAGE_COLOR_FormatInvalid = 0x7FFFFFFF +} NVX_IMAGE_COLOR_FORMATTYPE; + + +#endif + +/** @} */ + +/* File EOF */ diff --git a/omx/openmax/NVOMX_ComponentBase.h b/omx/openmax/NVOMX_ComponentBase.h new file mode 100644 index 0000000..fa5efeb --- /dev/null +++ b/omx/openmax/NVOMX_ComponentBase.h @@ -0,0 +1,404 @@ +/* Copyright (c) 2007 - 2010 NVIDIA Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file + * <b>NVIDIA Tegra: OpenMAX Component Base Interface</b> + * + */ + +/** + * @defgroup nv_omx_il_comp_base Component Base Interface + * + * This is the NVIDIA OpenMAX component base interface. + * + * @ingroup nvomx_custom + * @{ + */ + +#ifndef _NVOMX_ComponentBase_h_ +#define _NVOMX_ComponentBase_h_ + +#include <OMX_Core.h> +#include <OMX_Component.h> + +#define NVOMX_COMPONENT_MAX_PORTS 8 /** Max number of ports NVOMX_Component may have. */ + +/** + Holds definition of a simple port abstraction used in NVOMX_Component. + */ +typedef struct NVOMX_Port +{ + OMX_PARAM_PORTDEFINITIONTYPE *pPortDef; /**< Holds a pointer to the OMX port definition + for this port. */ + OMX_AUDIO_PARAM_PCMMODETYPE *pPCMMode; /**< Holds a pointer to the PCM description of this component, if pertinent. */ + OMX_BUFFERHEADERTYPE *pCurrentBufferHdr; /**< Holds a pointer to the current + buffer on this port, if any. */ +} NVOMX_Port; + +/** + Defines a simple OMX component template that abstracts most of the + complexity away from the user. + + To use: + -# Call NVOMX_CreateComponent() from the OMX component's init functions to create this + structure. + -# Call NVOMX_AddRole() to set what OMX roles this component will fill. + -# Call NVOMX_InitPort() once for each port on this component to setup the ports. + -# Fill in the function pointers in the NVOMX_Component structure as + appropriate -- at a minimum _NVOMX_Component::WorkerFunction and + _NVOMX_Component::DeInit must point to valid functions. + */ +typedef struct _NVOMX_Component NVOMX_Component; +/** + Holds a simple OMX component. + */ +struct _NVOMX_Component +{ + OMX_PTR pBase; /**< Internal pointer, do not touch. */ + + OMX_U32 nPorts; /**< Holds the number of valid ports for this component. */ + NVOMX_Port pPorts[NVOMX_COMPONENT_MAX_PORTS]; /**< Holds an array of port structures + for this component. */ + + OMX_PTR pComponentData; /**< An opaque pointer to any data this component desires + to keep track of. */ + + /** + Frees any remaining memory/resources + allocated by the component. + + @param [in] pComp + A pointer to the NVOMX_Component structure. + @retval OMX_ERRORTYPE + This generally should not have an error, but should return as appropriate. + */ + OMX_ERRORTYPE (*DeInit)(NVOMX_Component *pComp); + + /** + Called whenever an OMX_GetParameter has been done on the + component. + + @param [in] pComp + A pointer to the NVOMX_Component structure. + @param [in] nIndex + Specifies what type of configuration this is. + @param [inout] pComponentParameterStructure + Any data associated with this parameter call. + @param [out] bHandled + OMX_TRUE if this call was processed, otherwise OMX_FALSE. + @retval OMX_ERRORTYPE + Returns an appropriate error. + */ + OMX_ERRORTYPE (*GetParameter)(NVOMX_Component *pComp, + OMX_INDEXTYPE nParamIndex, + OMX_PTR pComponentParameterStructure, + OMX_BOOL *bHandled); + + /** + Called whenever an OMX_SetParameter has been done on the + component. + + @param [in] pComp + A pointer to the NVOMX_Component structure. + @param [in] nIndex + Specifies what type of configuration this is. + @param [in] pComponentParameterStructure + Any data associated with this parameter call. + @param [out] bHandled + OMX_TRUE if this call was processed, otherwise OMX_FALSE. + @retval OMX_ERRORTYPE + Returns an appropriate error. + */ + OMX_ERRORTYPE (*SetParameter)(NVOMX_Component *pComp, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentParameterStructure, + OMX_BOOL *bHandled); + + /** + Called whenever an OMX_GetConfig has been done on the component. + + @param [in] pComp + A pointer to the NVOMX_Component structure. + @param [in] nIndex + Specifies what type of configuration this is. + @param [inout] pComponentConfigStructure + Any data associated with this config call. + @param [out] bHandled + OMX_TRUE if this call was processed, otherwise OMX_FALSE. + @retval OMX_ERRORTYPE + Returns an appropriate error. + */ + OMX_ERRORTYPE (*GetConfig)(NVOMX_Component *pComp, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure, + OMX_BOOL *bHandled); + + /** + Called whenever an OMX_SetConfig has been done on the component. + + @param [in] pComp + A pointer to the NVOMX_Component structure. + @param [in] nIndex + Specifies what type of configuration this is. + @param [in] pComponentConfigStructure + Any data associated with this config call. + @param [out] bHandled + OMX_TRUE if this call was processed, otherwise OMX_FALSE. + @retval OMX_ERRORTYPE + Returns an appropriate error. + */ + OMX_ERRORTYPE (*SetConfig)(NVOMX_Component *pComp, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure, + OMX_BOOL *bHandled); + + /** + Called whenever all ports of this component have a + valid buffer and there needs to be work done to process them. + + @param [in] pComp + A pointer to the NVOMX_Component structure. + @param [out] pbMoreWork + OMX_TRUE if there is still more work to be done on a given + input buffer. + @retval OMX_ERRORTYPE + This generally should not fail, but returns an appropriate error type. + */ + OMX_ERRORTYPE (*WorkerFunction)(NVOMX_Component *pComp, + OMX_BOOL *pbMoreWork); + + /** + Called on the transition to OMX_StateIdle (from Loaded). + Allocates/acquires any resources in this function. + + @param [in] pComp + A pointer to the NVOMX_Component structure. + @retval OMX_ERRORTYPE + This generally should not fail, but returns an appropriate error type. + @retval OMX_ErrorNotReady + If OMX_ErrorNotReady is returned, the component core will retry the + transtion periodically until it succeeds. If any other error than + OMX_ErrorNone is returned, the error will be sent back to the component. + */ + OMX_ERRORTYPE (*AcquireResources)(NVOMX_Component *pComp); + + /** + Called when this component needs to release its hold + on any resources acquired by _NVOMX_Component::AcquireResources. + + @param [in] pComp + A pointer to the NVOMX_Component structure. + @retval OMX_ERRORTYPE + This generally should not fail, but returns an appropriate error type. + */ + OMX_ERRORTYPE (*ReleaseResources)(NVOMX_Component *pComp); + + /** + Called when this component needs to flush. + + @param [in] pComp + A pointer to the NVOMX_Component structure. + @param [in] nPort + Port to flush, or OMX_ALL for all. + @retval OMX_ERRORTYPE + This should not fail, but returns an appropriate error type. + */ + OMX_ERRORTYPE (*Flush)(NVOMX_Component *pComp, OMX_U32 nPort); + + /** + Called before a component is changing state for informative purposes. + + @param [in] pComp + A pointer to the NVOMX_Component structure. + @param [in] oCurState + The current state we're in. + @param [in] oNewState + The new state we're transitioning to. + @retval OMX_ERRORTYPE + This should not fail, but returns an appropriate error type. + */ + OMX_ERRORTYPE (*ChangeState)(NVOMX_Component *pComp, + OMX_STATETYPE oCurState, + OMX_STATETYPE oNewState); +}; + +/** + Creates an NVOMX_Component. + + @param [in] hComponent + A pointer to the OMX handle passed into the component's init function. + @param [in] nPorts + Specifies how many ports this component will have. + @param [in] name + The name of this component, must be unique + @param [out] ppComp + A pointer to the created NVOMX_Component; use this for calling any other + NVOMX_Component functions. + @retval OMX_ERRORTYPE + Returns an appropriate error. + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY NVOMX_CreateComponent( + OMX_HANDLETYPE hComponent, + OMX_U32 nPorts, + OMX_STRING name, + NVOMX_Component **ppComp); + +/** + Adds a role name to this component. + + @param [in] pComp + A pointer to the NVOMX_Component structure. + @param [in] roleName + A pointer to a static char string with the role name. + @retval OMX_ERRORTYPE + Returns an appropriate error. + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY NVOMX_AddRole( + NVOMX_Component *pComp, + OMX_STRING roleName); + +/** + Registers an index extension with this component. + + @param [in] pComp + A pointer to the NVOMX_Component structure. + @param [in] indexName + A pointer to a static char string with the role name. + @param [in] indexType + The index to register + @retval OMX_ERRORTYPE + Returns an appropriate error. + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY NVOMX_AddExtensionIndex( + NVOMX_Component *pComp, + OMX_STRING indexName, + OMX_INDEXTYPE indexType); + +/** + Creates a port structure. + + @param [in] pComp + A pointer to the NVOMX_Component structure. + @param [in] nPort + Specifies the port number to create. + @param [in] eDir + Specifies the direction (input/output) of the port. + @param [in] nBufferCount + Specifies the minimum number of buffers to create on this port. + @param [in] nBufferSize + Specifies the minimum buffer size to create. + @param [in] eDomain + Specifies what port type (other, image, video, audio) this port will be. + @param [in] pFormat + A pointer to the format type of the port. May be one of type + OMX_OTHER_FORMATTYPE, OMX_AUDIO_CODINGTYPE, OMX_VIDEO_CODINGTYPE, or + OMX_IMAGE_CODINGTYPE. + @retval OMX_ERRORTYPE + Returns an appropriate error. + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY NVOMX_InitPort( + NVOMX_Component *pComp, + OMX_U32 nPort, + OMX_DIRTYPE eDir, + OMX_U32 nBufferCount, + OMX_U32 nBufferSize, + OMX_PORTDOMAINTYPE eDomain, + OMX_PTR pFormat); + +/** + Copies any buffer metadata (flags, marks, etc.) from one port to another. + + @param [in] pComp + A pointer to the NVOMX_Component structure. + @param [in] nSourcePort + Specifies the source port from which to copy metadata. + @param [in] nDestPort + Specifies the port to which to copy metadata. + @retval OMX_ERRORTYPE + Returns an appropriate error. + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY NVOMX_CopyBufferMetadata( + NVOMX_Component *pComp, + OMX_U32 nSourcePort, + OMX_U32 nDestPort); + +/** + Gets an empty buffer to an input port. + The buffer will be queued for delivery either to the tunneled component + associated with the given port, or back to the IL client via the + EmptyBufferDone callback. + + @param [in] pComp + A pointer to the NVOMX_Component structure. + @param [in] nPort + Specifies the input port in which to return the buffer. + @param [in] pBuffer + Specifies the buffer to return to the input port. + @retval OMX_ERRORTYPE + Returns an appropriate error. + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY NVOMX_ReleaseEmptyBuffer( + NVOMX_Component *pComp, + OMX_U32 nPort, + OMX_BUFFERHEADERTYPE *pBuffer); + +/** + Delivers a full buffer to an output port. + The buffer will be queued for delivery either to the tunneled component + associated with the given port, or back to the IL client via the + FillBufferDone callback. + + @param [in] pComp + A pointer to the NVOMX_Component structure. + @param [in] nPort + Specifies the output port in which to deliver the buffer. + @param [in] pBuffer + Specifies the buffer to deliver to the output port. + @retval OMX_ERRORTYPE + Returns an appropriate error. + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY NVOMX_DeliverFullBuffer( + NVOMX_Component *pComp, + OMX_U32 nPort, + OMX_BUFFERHEADERTYPE *pBuffer); + +/** + Sends an audio master-time update to the clock. + + @param [in] pComp + A pointer to the NVOMX_Component structure. + @param [in] nPortClock + The port number of the clock component. + @param [in] nAudioTime + The current audio time. + @retval OMX_ERRORTYPE + Returns an appropriate error. + */ + +OMX_API OMX_ERRORTYPE OMX_APIENTRY NVOMX_SendClockUpdate( + NVOMX_Component *pComp, + OMX_U32 nPortClock, + OMX_TICKS nAudioTime); + +#endif +/** @} */ + diff --git a/omx/openmax/NVOMX_ComponentRegister.h b/omx/openmax/NVOMX_ComponentRegister.h new file mode 100644 index 0000000..0f88163 --- /dev/null +++ b/omx/openmax/NVOMX_ComponentRegister.h @@ -0,0 +1,85 @@ +/* Copyright (c) 2007 NVIDIA Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file + * <b>NVIDIA Tegra: OpenMAX Component Register Interface</b> + * + */ + +/** + * @defgroup nv_omx_il_comp_reg Component Register Interface + * + * This is the NVIDIA OpenMAX component register interface. + * + * @ingroup nvomx_custom + * @{ + */ + +#ifndef NVOMX_ComponentRegister_h +#define NVOMX_ComponentRegister_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include <OMX_Core.h> + +/** + * Dynamically registers a component with the core. + * The core should return from this call in 20 msec. + * + * @pre OMX_Init() + * + * @param [in] pComponentReg A pointer to a component register + * structure. Both \c pName and \c pInitialize values of this structure + * shall be non-null. The \c pName value must be unique, otherwise an + * error is returned. + * @retval OMX_ErrorNone If successful, or the appropriate OMX error code. + * @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY NVOMX_RegisterComponent( + OMX_IN OMX_COMPONENTREGISTERTYPE *pComponentReg); + +/** + * Deregisters a component with the core. + * A dynamically registered component is not required to be deregistered + * with a call to this function. OMX_DeInit() will deregister + * all components. + * The core should return from this call in 20 msec. + * + * @pre OMX_Init() + * + * @param [in] pComponentName The name of the component to deregister. + * @retval OMX_ErrorNone If successful, or the appropriate OMX error code. + * @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY NVOMX_DeRegisterComponent( + OMX_IN OMX_STRING pComponentName); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/** @} */ +/* File EOF */ + diff --git a/omx/openmax/NVOMX_CustomProtocol.h b/omx/openmax/NVOMX_CustomProtocol.h new file mode 100644 index 0000000..1987c6d --- /dev/null +++ b/omx/openmax/NVOMX_CustomProtocol.h @@ -0,0 +1,65 @@ +/* Copyright (c) 2008 NVIDIA Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file + * <b>NVIDIA Tegra: OpenMAX Custom Protocol Registration Interface</b> + * + */ + +/** + * @defgroup nv_omx_il_protocol Custom Protocol Plug-in Interface + * + * This interface is meant to allow registering of a custom set of file I/O + * operations that are then associated with a URI protocol. This can be used + * to implement various network streaming protocols or simple forms of + * full-file DRM decryption. See \c NVOMX_RegisterNVCustomProtoReader() + * for how to register a protocol. + * + * This is essentially a simplified version of an OpenMAX ContentPipe. + * + * @ingroup nvomx_plugins + * @{ + */ + +#ifndef NVOMX_CUSTOMPROTOCOL_H_ +#define NVOMX_CUSTOMPROTOCOL_H_ + +#include "OMX_Types.h" +#include "OMX_ContentPipe.h" +#include "nvcustomprotocol.h" + +/** Registers an NV_CUSTOM_PROTOCOL interface to handle protocol \a szProto. + * + * Associates a protocol (eg, "drm://") with an ::NVMM_CUSTOM_PROTOCOL + * structure. Any files then opened with the protocol prefix will use the + * functions in \a pProtocol for all file access. + * + * @param szProto The protocol name to register, must include '://' + * @param pProtocol A pointer to an NVMM_CUSTOM_PROTOCOL implementation. + */ +CPresult NVOMX_RegisterNVCustomProtocol(OMX_STRING szProto, + NV_CUSTOM_PROTOCOL *pProtocol); + +#endif + +/** @} */ +/* File EOF */ diff --git a/omx/openmax/NVOMX_DecoderExtensions.h b/omx/openmax/NVOMX_DecoderExtensions.h new file mode 100644 index 0000000..d276d6f --- /dev/null +++ b/omx/openmax/NVOMX_DecoderExtensions.h @@ -0,0 +1,437 @@ +/* Copyright (c) 2009-2013 NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file + * <b>NVIDIA Tegra: OpenMAX Decoder Extension Interface</b> + * + */ + +/** + * @defgroup nv_omx_il_decoder Decoder + * + * This is the NVIDIA OpenMAX decoder class extensions interface. + * + * These extensions include ultra low power (ULP) mode, video de-interlacing, JPEG EXIF info, + * thumbnail generation and more. + * + * @ingroup nvomx_decoder_extension + * @{ + */ + +#ifndef NVOMX_DecoderExtensions_h_ +#define NVOMX_DecoderExtensions_h_ + +#define NVX_EXIF_MAKE_LENGTH 16 +#define NVX_EXIF_MODEL_LENGTH 32 +#if 0 +#define NVX_EXIF_APP1_DATE_TIME_ORIGINAL_LENGTH 32 +#define NVX_EXIF_APP1_DATE_TIME_DIGITIZED_LENGTH 32 +#define NVX_EXIF_APP1_SOFTWARE_LENGTH 64 +#define NVX_EXIF_APP1_DATE_TIME_LENGTH 21 +#define NVX_EXIF_APP1_YCBCR_POSITIONING_LENGTH 32 +#define NVX_EXIF_APP1_METERING_MODE_LENGTH 22 +#define NVX_EXIF_APP1_COMPONENTS_CONFIGURATION_LENGTH 10 +#define NVX_EXIF_APP1_FLASH_PIX_VERSION_LENGTH 28 +#define NVX_EXIF_APP1_COLOR_SPACE_LENGTH 13 +#define NVX_EXIF_APP1_ORIENTATION_LENGTH 17 +#define NVX_EXIF_APP1_FLASH_FIRING_LENGTH 13 +#define NVX_EXIF_APP1_FLASH_RETURN_LENGTH 36 +#define NVX_EXIF_APP1_SCENE_CAPTURE_TYPE_LENGTH 30 +#define NVX_EXIF_APP1_LIGHT_SOURCE_LENGTH 16 +#define NVX_EXIF_APP1_LIGHT_WHITE_BALANCE_LENGTH 7 +#define NVX_EXIF_APP1_CUSTOM_RENDERED_LENGTH 7 +#define NVX_EXIF_APP1_EXPOSURE_MODE_LENGTH 16 +#define NVX_EXIF_APP1_DIGITAL_ZOOM_RATIO_LENGTH 8 +#define NVX_EXIF_APP1_EXPOSURE_TIME_LENGTH 8 +#define NVX_EXIF_APP1_SUBJECT_DISTANCE_RANGE_LENGTH 8 +#define NVX_EXIF_APP1_EXPOSURE_BIAS_VALUE_LENGTH 8 +#define NVX_EXIF_APP1_INTEROPERABILITY_IFD_POINTER_LENGTH 2 +#define NVX_EXIF_APP1_EXIF_VERSION_LENGTH 4 +#define NVX_EXIF_APP1_ISO_SPEED_RATINGS_LENGTH 2 +#define NVX_EXIF_APP1_EXIF_OFFSET_LENGTH 4 +#define NVX_EXIF_APP1_FNUMBER_LENGTH 8 +#endif + +/* General decoder extensions */ + +/** Param extension index to enable low memory mode by disabling meta-data buffers. + * See ::NVX_PARAM_LOWMEMMODE + */ +#define NVX_INDEX_PARAM_LOWMEMMODE "OMX.Nvidia.index.param.lowmemmode" +/** Holds information to enable low memory mode. */ +typedef struct NVX_PARAM_LOWMEMMODE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_BOOL bLowMemMode; /**< Boolean to enable low memory mode */ +} NVX_PARAM_LOWMEMMODE; + +/** Param extension index to enable synchronized decode mode. + * This is a higher performance decoding mode that processes buffers on the same thread + * as the decoder core. However, this can potentially cause compability problems with + * other OpenMAX components. + * See ::NVX_PARAM_SYNCDECODE + */ +#define NVX_INDEX_PARAM_SYNCDECODE "OMX.Nvidia.index.param.syncdecode" +/** Holds information to enable synchronized decode mode. */ +typedef struct NVX_PARAM_SYNCDECODE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_BOOL bSyncDecodeMode; /**< Boolean to enable synchronized decode mode */ +} NVX_PARAM_SYNCDECODE; + + +/** Param extension index to enable low resource mode in case of thumbnail extraction. + * See ::NVX_PARAM_LOWRESOURCEMODE + */ +#define NVX_INDEX_PARAM_LOWRESOURCEMODE "OMX.Nvidia.index.param.lowresourcemode" +/** Holds information to enable low resource mode. */ +typedef struct NVX_PARAM_LOWRESOURCEMODE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_BOOL bLowMemMode; /**< Boolean to enable low memory mode */ +} NVX_PARAM_LOWRESOURCEMODE; + + +/** Param extension index to set the filtering of timestamps at the decoder + * See: NVX_PARAM_FILTER_TIMESTAMPS + */ +#define NVX_INDEX_PARAM_FILTER_TIMESTAMPS "OMX.Nvidia.index.param.filtertimestamps" + +typedef struct NVX_PARAM_FILTER_TIMESTAMPS { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_BOOL bFilterTimestamps; /**< Boolean to enable/disable filtering of timestamps */ +} NVX_PARAM_FILTER_TIMESTAMPS; + +/** Config extension index to allow checking for sufficient + * resources to decode prior to sending input buffers. This + * will return failure if not enough resources. See + * \c OMX_VIDEO_PARAM_PROFILELEVELTYPE + */ +#define NVX_INDEX_CONFIG_CHECKRESOURCES "OMX.Nvidia.index.config.checkresources" + +/** Param extension index to disable DPB logic for H264 in case client knows that + * decode and display order are same. Don't use this for other cases. + * See ::NVX_PARAM_H264DISABLE_DPB + */ +#define NVX_INDEX_PARAM_H264_DISABLE_DPB "OMX.Nvidia.index.param.h264disabledpb" +typedef struct NVX_PARAM_H264DISABLE_DPB { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_BOOL bDisableDPB; /**< Boolean to disable DPB logic of H264 */ +} NVX_PARAM_H264DISABLE_DPB; + +/** Config extension index to enable ultra low power mode. + * See ::NVX_CONFIG_ULPMODE + */ +#define NVX_INDEX_CONFIG_ULPMODE "OMX.Nvidia.index.config.ulpmode" +/** Holds information to enable ultra low power mode. */ +typedef struct NVX_CONFIG_ULPMODE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_BOOL enableUlpMode; /**< Boolean to enable ultra low power mode */ + OMX_U32 kpiMode; /**< Reserved for internal use */ +} NVX_CONFIG_ULPMODE; + +/* Audio decoder extensions */ + +/** Config extension index to enable audio only hints (audio decoder classes only). + * See ::NVX_CONFIG_AUDIOONLYHINT + */ +#define NVX_INDEX_CONFIG_AUDIOONLYHINT "OMX.Nvidia.index.config.audioonlyhint" +/** Holds information to enable audio-only hints. */ +typedef struct NVX_CONFIG_AUDIOONLYHINT { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_BOOL bAudioOnlyHint; /**< Boolean to enable ultra low power mode for audio decoder only */ +} NVX_CONFIG_AUDIOONLYHINT; + +/** Config extension index to select ouput format in dual mono mode (audio decoder classes only). + */ +#define NVX_INDEX_CONFIG_DUALMONO_OUPUTMODE "OMX.Nvidia.index.config.dualmonooutputmode" + +typedef enum +{ + OMX_DualMonoOutputMode_Default, /**< Output channel 1 to the left speaker and channel 2 to the right speaker. */ + OMX_DualMonoOutputMode_Left, /**< Output channel 1 to the left speaker and right speaker. */ + OMX_DualMonoOutputMode_Right /**< Output channel 2 to the left speaker and right speaker. */ +} OMX_DualMonoOutputMode; + +/* Video decoder extensions */ + +typedef enum +{ + OMX_DeintMethod_NoDeinterlacing, /**< NO deinterlacing */ + OMX_DeintMethod_BobAtFrameRate, /**< Bob on full frame. Two fields output one frame. */ + OMX_DeintMethod_BobAtFieldRate, /**< Bob on full frame. Two fields output two frames. */ + OMX_DeintMethod_WeaveAtFrameRate, /**< Weave on full frame. Two fields output one frame. (This is same as NO deinterlacing) */ + OMX_DeintMethod_WeaveAtFieldRate, /**< Weave on full frame. Two fields output two frames. (This is same as NO deinterlacing) */ + OMX_DeintMethod_Advanced1AtFrameRate, /**< Advanced1. Method decided at MB level. Two field output one frame. */ + OMX_DeintMethod_Advanced1AtFieldRate, /**< Advanced1. Method decided at MB level. Two field output two frames. */ + OMX_DeintMethod_Force32 = 0x7FFFFFFF +} OMX_DeinterlaceMethod; + +/** Nvidia specific extended video coding types **/ +typedef enum +{ + NVX_VIDEO_CodingVP8 = (OMX_VIDEO_CodingMJPEG + 1), /**< Google VP8, formerly known as On2 VP8 */ + NVX_VIDEO_CodingVP9 = (NVX_VIDEO_CodingVP8 + 1), /**< Google VP9, formerly known as On2 VP9 */ + NVX_VIDEO_CodingHEVC = (NVX_VIDEO_CodingVP9 + 1) /**< H265 aka HEVC */ +} NVX_VIDEO_CODINGTYPE; + +/** Param extension index to configure the deinterlacing mode (video decoder classes only). + * See ::NVX_PARAM_DEINTERLACE + */ +#define NVX_INDEX_PARAM_DEINTERLACING "OMX.Nvidia.index.param.deinterlacing" +/** Holds information to configure the deinterlacing mode. */ +typedef struct +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 DeinterlaceMethod; /**< Deinterlace method, see ::OMX_DeinterlaceMethod */ +}NVX_PARAM_DEINTERLACE; + +/* JPG decoder extensions */ + +/** Config extension index to setup thumbnail generation (image decoder classes only). + * See ::NVX_CONFIG_THUMBNAIL + */ +#define NVX_INDEX_CONFIG_THUMBNAIL "OMX.Nvidia.index.config.thumbnail" +/** Holds information to setup thumbnail generation. */ +typedef struct NVX_CONFIG_THUMBNAIL +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL bEnabled; /**< Boolean to enable thumbnail output */ + OMX_U32 nWidth; /**< Width of thumbnail */ + OMX_U32 nHeight; /**< Height of thumbnail */ +} NVX_CONFIG_THUMBNAIL; + +/** Config extension index to query decoded EXIF information (image decoder classes only). + * See ::NVX_CONFIG_EXIFINFO + */ +#define NVX_INDEX_CONFIG_EXIFINFO "OMX.Nvidia.index.config.exifinfo" +/** Holds information to query decoded EXIF information. */ +typedef struct NVX_CONFIG_EXIFINFO +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U8 isEXIFPresent; /**< Flag to indicate presence of EXIF data in image */ + OMX_U8 Make[NVX_EXIF_MAKE_LENGTH]; /**< Name of camera manufracturer */ + OMX_U8 Model[NVX_EXIF_MODEL_LENGTH]; /**< Name of camera model */ + OMX_U32 ThumbnailCompression; /**< Thumbnail compression type */ + OMX_U32 ThumbnailOffset; /**< Offset in bytes to thumbnail data */ + OMX_U32 ThumbnailLength; /**< Length in bytes of thumbnail data */ + OMX_U32 ThumbnailImageWidth; /**< Thumbnail image width */ + OMX_U32 ThumbnailImageHeight; /**< Thumbnail image height */ + OMX_U32 PrimaryImageWidth; /**< Primary image width */ + OMX_U32 PrimaryImageHeight; /**< Primary image height */ + OMX_U8 ResolutionUnit; /**< Resolution units */ + OMX_U64 XResolution; /**< X resolution */ + OMX_U64 YResolution; /**< Y resolution */ + OMX_U8 bpp; /**< Bits per pixel */ + OMX_U8 ImageDescription[32]; /**< Description text */ +#if 0 + OMX_U16 ISOSpeedRatings; + OMX_U8 Software[NVX_EXIF_APP1_SOFTWARE_LENGTH]; + OMX_U8 DateTime[NVX_EXIF_APP1_DATE_TIME_LENGTH]; + OMX_U8 YCbCrPositioning[NVX_EXIF_APP1_YCBCR_POSITIONING_LENGTH]; + OMX_U8 ExifVersion[NVX_EXIF_APP1_EXIF_VERSION_LENGTH]; + OMX_U8 DateTimeOriginal[NVX_EXIF_APP1_DATE_TIME_ORIGINAL_LENGTH]; + OMX_U8 DateTimeDigitized[NVX_EXIF_APP1_DATE_TIME_DIGITIZED_LENGTH]; + OMX_U8 ComponentsConfiguration[NVX_EXIF_APP1_COMPONENTS_CONFIGURATION_LENGTH]; + OMX_U8 MeteringMode[NVX_EXIF_APP1_METERING_MODE_LENGTH]; + OMX_U8 FlashPixVersion[NVX_EXIF_APP1_FLASH_PIX_VERSION_LENGTH]; + OMX_U8 ColorSpace[NVX_EXIF_APP1_COLOR_SPACE_LENGTH]; + OMX_U8 Orientation[NVX_EXIF_APP1_ORIENTATION_LENGTH]; + OMX_S64 ExposureBiasValue; //[NVX_EXIF_APP1_EXPOSURE_BIAS_VALUE_LENGTH]; + OMX_U8 FNumber[NVX_EXIF_APP1_FNUMBER_LENGTH]; + OMX_U8 FlashFiring[NVX_EXIF_APP1_FLASH_FIRING_LENGTH]; + OMX_U8 FlashReturn[NVX_EXIF_APP1_FLASH_RETURN_LENGTH]; + OMX_U8 SceneCaptureType[NVX_EXIF_APP1_SCENE_CAPTURE_TYPE_LENGTH]; + OMX_U8 LightSource[NVX_EXIF_APP1_LIGHT_SOURCE_LENGTH]; + OMX_U64 SubjectDistanceRange; + OMX_U8 WhiteBalance[NVX_EXIF_APP1_LIGHT_WHITE_BALANCE_LENGTH]; + OMX_U8 CustomRendered[NVX_EXIF_APP1_CUSTOM_RENDERED_LENGTH]; + OMX_U64 ExposureTime; + OMX_U8 ExposureMode[NVX_EXIF_APP1_EXPOSURE_MODE_LENGTH]; + OMX_U64 DigitalZoomRatio; + OMX_U16 InteroperabilityIFDPointer; +#endif +} NVX_CONFIG_EXIFINFO; + +/** Holds stream information to find the appropriate component. */ +typedef struct { + OMX_BOOL bUseSPSAndPPS; /**< Use SPS and PPS as input */ + OMX_BOOL bHasCABAC; /**< Does stream use CABAC encoding */ + OMX_U32 nWidth; /**< Width of stream */ + OMX_U32 nHeight; /**< Height of stream */ + OMX_U32 nSPSCount; /**< Number of SPS NALU's */ + OMX_U8 **SPSNAUL; /**< Pointer to SPS NALU's array */ + OMX_U32 *SPSNAULLen; /**< Pointer to length of SPS NALU array */ + OMX_U32 nPPSCount; /**< Number of PPS NALU's */ + OMX_U8 **PPSNAUL; /**< Pointer to PPS NALU's array */ + OMX_U32 *PPSNAULLen; /**< Pointer to length of PPS NALU array */ +} NVX_H264_DECODE_INFO; + +/** Holds platform and stream information. */ +typedef struct +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_U32 nPlatform; /**< Platform related info */ + ENvxStreamType eStreamType; /**< Stream type */ + union { + NVX_H264_DECODE_INFO h264; /**< Additional data for H.264 streams */ + } streamInfo; + +} NVX_STREAM_PLATFORM_INFO; + +/** + Finds an component name based on stream and platform information. + + @param [in] pStreamInfo + A pointer to the structure containing stream and platform information. + @param [out] compName + A pointer to the found component name + @retval OMX_ERRORTYPE + Returns an appropriate error. + */ +OMX_API OMX_ERRORTYPE NVOMX_FindComponentName( + OMX_IN NVX_STREAM_PLATFORM_INFO *pStreamInfo, + OMX_OUT OMX_STRING *compName); + +/* OMX extension index to get decoded jpeg information. */ +#define NVX_INDEX_CONFIG_JPEGINFO \ + "OMX.Nvidia.index.config.jpeginfo" /**< reference: NVX_CONFIG_JPEGINFO */ +typedef struct NVX_CONFIG_JPEGINFO +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version info */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + + OMX_U32 PrimaryImageWidth; + OMX_U32 PrimaryImageHeight; + OMX_COLOR_FORMATTYPE ColorFormat; +} NVX_CONFIG_JPEGINFO; + +/* OMX extension index to get/set video decoded surface layout. */ +#define NVX_INDEX_PARAM_SURFACE_LAYOUT \ + "OMX.Nvidia.index.param.surfacelayout" /**< reference: NVX_PARAM_SURFACE_LAYOUT */ +typedef struct NVX_PARAM_SURFACELAYOUT +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version info */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + + OMX_BOOL bTiledMode; /**< Surface Layout, True for Tiled mode, False for Pitch(Linear) Mode */ +} NVX_PARAM_SURFACELAYOUT; + + +/* OMX extension index to set maxoutchannels information. */ +/**< reference: NVX_INDEX_CONFIG_MAXOUTPUTCHANNELS */ +#define NVX_INDEX_CONFIG_MAXOUTPUTCHANNELS \ + "OMX.Nvidia.index.config.maxoutchannels" + +/** Nvidia specific extended audio coding types **/ +typedef enum NVX_AUDIO_CODINGTYPE { + NVX_AUDIO_CodingAC3 = (OMX_AUDIO_CodingVendorStartUnused + 1), /**< Any variant of AC3 encoded data */ + NVX_AUDIO_CodingDTS = (OMX_AUDIO_CodingVendorStartUnused + 2), /**< Any variant of DTS encoded data */ +} NVX_AUDIO_CODINGTYPE; + +/** AC3 params */ +typedef struct NVX_AUDIO_PARAM_AC3TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nSampleRate; /**< Sampling rate of the data. */ +} NVX_AUDIO_PARAM_AC3TYPE; + +/* OMX extension index to get AC3 parameters */ +/**< reference: NVX_INDEX_PARAM_AC3 + * Use NVX_AUDIO_PARAM_AC3TYPE +*/ +#define NVX_INDEX_PARAM_AC3 "OMX.Nvidia.index.param.ac3" + +/** DTS params */ +typedef struct NVX_AUDIO_PARAM_DTSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nSampleRate; /**< Sampling rate of the data. */ +} NVX_AUDIO_PARAM_DTSTYPE; + +/* OMX extension index to get DTS parameters */ +/**< reference: NVX_INDEX_PARAM_DTS + * Use NVX_AUDIO_PARAM_DTSTYPE +*/ +#define NVX_INDEX_PARAM_DTS "OMX.Nvidia.index.param.dts" + +/** Audio caps config */ +typedef struct NVX_AUDIO_CONFIG_CAPS { + OMX_BOOL supportAc3; + OMX_BOOL supportEac3; + OMX_BOOL supportDts; +} NVX_AUDIO_CONFIG_CAPS; +/* OMX extension index to retrieve audio capabilities */ +/**< reference: NVX_INDEX_CONFIG_AUDIO_CAPS + * Use NVX_AUDIO_CONFIG_CAPS + */ +#define NVX_INDEX_CONFIG_AUDIO_CAPS "OMX.Nvidia.index.config.audio_caps" + +/* OMX extension index to set silence output of audio decoder */ +/**< reference: NVX_INDEX_CONFIG_AUDIO_SILENCE_OUTPUT + * Use OMX_CONFIG_BOOLEANTYPE +*/ +#define NVX_INDEX_CONFIG_SILENCE_OUTPUT "OMX.Nvidia.index.config.silence" + +/* Decoder itself will wait on the fence and will give the complete decoded buffer*/ +/**< reference: NVX_INDEX_CONFIG_WAIT_ON_FENCE + * Use OMX_CONFIG_BOOLEANTYPE +*/ +#define NVX_INDEX_CONFIG_WAIT_ON_FENCE "OMX.Nvidia.index.config.waitOnFence" + +/* Openmax component created for thumbnail generation*/ +/**< reference: NVX_INDEX_CONFIG_THUMBNAIL_MODE + * Use OMX_CONFIG_BOOLEANTYPE +*/ +#define NVX_INDEX_CONFIG_THUMBNAIL_MODE "OMX.Nvidia.index.config.thumbnailMode" + + +/** + * Added to protect slice based decoding. + * nAuthentication authenticates the identity of APP + */ +typedef struct NVX_VIDEO_PARAM_SLICE_DECODE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nAuthentication; + OMX_BOOL bEnabled; +} NVX_VIDEO_PARAM_SLICE_DECODE; + +#endif +/** @} */ +/* File EOF */ diff --git a/omx/openmax/NVOMX_DrmExtensions.h b/omx/openmax/NVOMX_DrmExtensions.h new file mode 100644 index 0000000..e626095 --- /dev/null +++ b/omx/openmax/NVOMX_DrmExtensions.h @@ -0,0 +1,154 @@ +/* Copyright (c) 2009 NVIDIA Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file + * <b>NVIDIA Tegra: OpenMAX Container Extension Interface</b> + * + */ + +#ifndef NVOMX_DrmExtensions_h_ +#define NVOMX_DrmExtensions_h_ + +/** @} */ + +/** + * @defgroup nv_omx_il_parser_drm Types + * + * This is the NVIDIA OpenMAX DRM class extension interface. + * + * These extensions include types of DRM, get and set license info + * and cleaning teh license store and more. + * + * @ingroup nvomx_container_extension + * @{ + */ + +typedef enum +{ + NvxDRMType_WMDRM10= 1, + NvxDRMType_PlayReady, + NvxDRMType_Force32 = 0x7FFFFFFF +} EDrmType; + +#define DRM_INDEX_CONFIG_SET_SURFACE "DRM.index.config.setsurface" +typedef struct DRM_CONFIG_SET_SURFACE{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 displayWidth; // display width of display area + OMX_U32 displayHeight; // display height of display area + OMX_U32 displayX; // display X coordinate of top left corner of display area + OMX_U32 displayY; // display Y coordinate of top left corner of display area + OMX_U32 componentNameSize; // (actual data size send from IL component to IL Client) + OMX_U8 componentName[1]; // Variable length array of component name(send from IL client to IL component) +}DRM_CONFIG_SET_SURFACE; + + +/** @} */ + +/** Get license URL and challange config + * See ::DRM_INDEX_CONFIG_LICENSE_CHALLENGE + */ +#define DRM_INDEX_CONFIG_LICENSE_CHALLENGE "DRM.index.config.licensechallenge" +/** Holds url data and challenge.query */ +typedef struct DRM_CONFIG_LICENSE_CHALLENGE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + EDrmType DrmType; /**< Type of DRM */ + union + { + OMX_U32 nPsiObjectSize; /**< actual data size send from IL client to Il component*/ + OMX_U32 nLicenseQuerySize; /**< actual data size send from IL component to IL Client */ + }size; + union + { + OMX_U8 pPsiObject[1]; /**< PSI object data*/ + OMX_U8 pLicenseQuery[1]; /**< challenge query to be sent to the license server */ + }data; +}DRM_CONFIG_LICENSE_CHALLENGE; + +/** @} */ + +/** Process license response config + * See ::DRM_INDEX_CONFIG_LICENSE_RESPONSE + */ +#define DRM_INDEX_CONFIG_LICENSE_RESPONSE "DRM.index.config.licenseresponse" +/** Holds the license response recieved from license server */ +typedef struct DRM_CONFIG_LICENSE_RESPONSE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + EDrmType DrmType; /**< Type of DRM */ + OMX_U32 pLicenseHandle; /**< Handle to the license */ + OMX_U32 nResponseSize; /**< Size of Response */ + OMX_U8 pLicenseResponse[1]; /**< Response recieved from license server */ +}DRM_CONFIG_LICENSE_RESPONSE; + + +/** Delete a license config + * See ::DRM_INDEX_CONFIG_DELETE_LICENSE + */ +#define DRM_INDEX_CONFIG_DELETE_LICENSE "DRM.index.config.deletelicense" +/** Holds the license info to be deleted */ +typedef struct DRM_CONFIG_DELETE_LICENSE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + EDrmType DrmType; /**< Type of DRM */ + OMX_U32 pLicenseHandle; /**< Handle to the license */ +}DRM_CONFIG_DELETE_LICENSE; + +/** Setting InitializationVector config + * See ::DRM_BUFFER_HEADER_EXTRADATA_INITIALIZATION_VECTOR + */ +#define DRM_BUFFER_HEADER_EXTRADATA_INITIALIZATION_VECTOR "DRM.buffer.header.extradata.initializationvector" +typedef struct DRM_IVDATA +{ + OMX_U64 qwInitializationVector; + OMX_U64 qwBlockOffset; + OMX_U8 bByteOffset; +}DRM_IVDATA; + +/** Setting Decryptr offset config + * See ::DRM_BUFFER_HEADER_EXTRADATA_ENCRYPTION + */ +#define DRM_BUFFER_HEADER_EXTRADATA_ENCRYPTION_OFFSET "DRM.buffer.header.extradata.encryptionoffset" +typedef struct DRM_ENCRYPTION_OFFSET +{ + OMX_U32 encryptionOffset; +}DRM_ENCRYPTION_OFFSET; + +/** Setting Decryptr offset config + * See ::DRM_BUFFER_HEADER_EXTRADATA_ENCRYPTION_METADATA + */ +#define DRM_BUFFER_HEADER_EXTRADATA_ENCRYPTION_METADATA "DRM.buffer.header.extradata.encryptionmetadata" +typedef struct DRM_EXTRADATA_ENCRYPTION_METADATA +{ + OMX_U32 encryptionOffset; + OMX_U32 encryptionSize; + DRM_IVDATA ivData; +}DRM_EXTRADATA_ENCRYPTION_METADATA; + +/** @} */ + +#endif +/* File EOF */ diff --git a/omx/openmax/NVOMX_EncoderExtensions.h b/omx/openmax/NVOMX_EncoderExtensions.h new file mode 100644 index 0000000..15f24f6 --- /dev/null +++ b/omx/openmax/NVOMX_EncoderExtensions.h @@ -0,0 +1,213 @@ +/* Copyright (c) 2010-2013 NVIDIA Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file + * <b>NVIDIA Tegra: OpenMAX Encoder Extension Interface</b> + * + */ + +/** + * @defgroup nv_omx_il_encoder Encoder + * + * This is the NVIDIA OpenMAX encoder class extensions interface. + * + * These extensions include ultra low power (ULP) mode, video de-interlacing, JPEG EXIF info, + * thumbnail generation and more. + * + * @ingroup nvomx_encoder_extension + * @{ + */ + +#ifndef NVOMX_EncoderExtensions_h_ +#define NVOMX_EncoderExtensions_h_ + +#define MAX_EXIF_STRING_IN_BYTES (200) +#define MAX_GPS_STRING_IN_BYTES (32) +#define GPS_DATESTAMP_LENGTH (11) +#define MAX_INTEROP_STRING_IN_BYTES (32) +#define MAX_GPS_PROCESSING_METHOD_IN_BYTES (40) + +/* General encoder extensions */ + +/* Audio encoder extensions */ + +/* Video encoder extensions */ + +/* JPEG encoder extensions */ + +/** Config extension index to set EXIF information (image encoder classes only). + * See ::NVX_CONFIG_ENCODEEXIFINFO + */ +#define NVX_INDEX_CONFIG_ENCODEEXIFINFO "OMX.Nvidia.index.config.encodeexifinfo" +/** Holds information to set EXIF information. */ +typedef struct NVX_CONFIG_ENCODEEXIFINFO +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + + OMX_S8 ImageDescription[MAX_EXIF_STRING_IN_BYTES]; /**< String describing image */ + OMX_S8 Make[MAX_EXIF_STRING_IN_BYTES]; /**< String of image make */ + OMX_S8 Model[MAX_EXIF_STRING_IN_BYTES]; /**< String of image model */ + OMX_S8 Copyright[MAX_EXIF_STRING_IN_BYTES]; /**< String of image copyright */ + OMX_S8 Artist[MAX_EXIF_STRING_IN_BYTES]; /**< String of image artist */ + OMX_S8 Software[MAX_EXIF_STRING_IN_BYTES]; /**< String of software creating image */ + OMX_S8 DateTime[MAX_EXIF_STRING_IN_BYTES]; /**< String of date and time */ + OMX_S8 DateTimeOriginal[MAX_EXIF_STRING_IN_BYTES]; /**< String of original date and time */ + OMX_S8 DateTimeDigitized[MAX_EXIF_STRING_IN_BYTES]; /**< String of digitized date and time */ + OMX_U16 filesource; /**< File source */ + OMX_S8 UserComment[MAX_EXIF_STRING_IN_BYTES]; /**< String user comments */ + OMX_U16 Orientation; /**< Orientation of the image: 0,90,180,270*/ +} NVX_CONFIG_ENCODEEXIFINFO; + +/** OMX Encode GpsBitMap Type + * Enable and disable the exif gps fields individually + * See also NVX_CONFIG_ENCODEGPSINFO.GPSBitMapInfo + */ +typedef enum OMX_ENCODE_GPSBITMAPTYPE { + OMX_ENCODE_GPSBitMapLatitudeRef = 0x01, + OMX_ENCODE_GPSBitMapLongitudeRef = 0x02, + OMX_ENCODE_GPSBitMapAltitudeRef = 0x04, + OMX_ENCODE_GPSBitMapTimeStamp = 0x08, + OMX_ENCODE_GPSBitMapSatellites = 0x10, + OMX_ENCODE_GPSBitMapStatus = 0x20, + OMX_ENCODE_GPSBitMapMeasureMode = 0x40, + OMX_ENCODE_GPSBitMapDOP = 0x80, + OMX_ENCODE_GPSBitMapImgDirectionRef = 0x100, + OMX_ENCODE_GPSBitMapMapDatum = 0x200, + OMX_ENCODE_GPSBitMapProcessingMethod = 0x400, + OMX_ENCODE_GPSBitMapDateStamp = 0x800, + OMX_ENCODE_GPSBitMapMax = 0x7FFFFFFF +} OMX_ENCODE_GPSBITMAPTYPE; + + + +/** Config extension index to set GPS information (image encoder classes only). + * See ::NVX_CONFIG_ENCODEGPSINFO + */ +#define NVX_INDEX_CONFIG_ENCODEGPSINFO "OMX.Nvidia.index.config.encodegpsinfo" +/** Holds information to set GPS information. */ +typedef struct NVX_CONFIG_ENCODEGPSINFO +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + + OMX_U32 GPSBitMapInfo; + OMX_U32 GPSVersionID; /**< Version identifier */ + OMX_S8 GPSLatitudeRef[2]; /**< Latitude reference */ + OMX_U32 GPSLatitudeNumerator[3]; /**< Latitude numerator */ + OMX_U32 GPSLatitudeDenominator[3]; /**< Latitude denominator */ + OMX_S8 GPSLongitudeRef[2]; /**< Longitude reference */ + OMX_U32 GPSLongitudeNumerator[3]; /**< Longitude numerator */ + OMX_U32 GPSLongitudeDenominator[3]; /**< Longitude denominator */ + OMX_U8 GPSAltitudeRef; /**< Altitude reference */ + OMX_U32 GPSAltitudeNumerator; /**< Altitude numerator */ + OMX_U32 GPSAltitudeDenominator; /**< Altitude denominator */ + OMX_U32 GPSTimeStampNumerator[3]; /**< Timestamp numerator */ + OMX_U32 GPSTimeStampDenominator[3]; /**< Timestamp denominator */ + OMX_S8 GPSSatellites[MAX_GPS_STRING_IN_BYTES]; + OMX_S8 GPSStatus[2]; + OMX_S8 GPSMeasureMode[2]; + OMX_U32 GPSDOPNumerator; + OMX_U32 GPSDOPDenominator; + OMX_S8 GPSImgDirectionRef[2]; + OMX_U32 GPSImgDirectionNumerator; + OMX_U32 GPSImgDirectionDenominator; + OMX_S8 GPSMapDatum[MAX_GPS_STRING_IN_BYTES]; + OMX_S8 GPSDateStamp[GPS_DATESTAMP_LENGTH]; + OMX_S8 GPSProcessingMethod[MAX_GPS_PROCESSING_METHOD_IN_BYTES]; +} NVX_CONFIG_ENCODEGPSINFO; + + +/** Config extension index to set Interoperability IFD information (image encoder classes only). + * See ::NVX_CONFIG_ENCODE_INTEROPERABILITYINFO + */ +#define NVX_INDEX_CONFIG_ENCODE_INTEROPINFO "OMX.Nvidia.index.config.encodeinteropinfo" +/** Holds information to set GPS information. */ + +typedef struct NVX_CONFIG_ENCODE_INTEROPINFO +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + + OMX_S8 Index[MAX_INTEROP_STRING_IN_BYTES]; +} NVX_CONFIG_ENCODE_INTEROPINFO; + +/** Config extension to mirror ::OMX_IndexParamQuantizationTable. + * See: ::OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE + */ +#define NVX_INDEX_CONFIG_ENCODE_QUANTIZATIONTABLE \ + "OMX.NVidia.index.config.encodequantizationtable" + +/** Config extension index to set thumbnail quality factor for JPEG encoder (image encoder classes only). + */ +#define NVX_INDEX_CONFIG_THUMBNAILQF "OMX.Nvidia.index.config.thumbnailqf" + +/** Param extension index to set/get quantization table (luma and chroma) for thumbnail image. + * (jpeg image encoder class only) + * See OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE + */ +#define NVX_INDEX_PARAM_THUMBNAILIMAGEQUANTTABLE "OMX.Nvidia.index.param.thumbnailquanttable" + +typedef enum NVX_VIDEO_VP8PROFILETYPE { + NVX_VIDEO_VP8ProfileMain = 0x01, + NVX_VIDEO_VP8ProfileMax = 0x7FFFFFFF +} NVX_VIDEO_VP8PROFILETYPE; + +typedef enum NVX_VIDEO_VP8LEVELTYPE { + NVX_VIDEO_VP8Level_Version0 = 0x0, + NVX_VIDEO_VP8Level_Version1 = 0x1, + NVX_VIDEO_VP8Level_Version2 = 0x2, + NVX_VIDEO_VP8Level_Version3 = 0x3, + NVX_VIDEO_VP8LevelMax = 0x7FFFFFFF +} NVX_VIDEO_VP8LEVELTYPE; + +/** Config extension index to set VP8 encoding parameters + */ +#define NVX_INDEX_PARAM_VP8TYPE "OMX.Nvidia.index.param.vp8type" + +typedef struct NVX_VIDEO_PARAM_VP8TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + NVX_VIDEO_VP8PROFILETYPE eProfile; + NVX_VIDEO_VP8LEVELTYPE eLevel; + OMX_U32 nDCTPartitions; + OMX_BOOL bErrorResilientMode; + OMX_U32 nPFrames; + OMX_U32 filter_level; + OMX_U32 sharpness_level; +} NVX_VIDEO_PARAM_VP8TYPE; + +/* OMX extension index to configure encoder to send - P frame with all skipped MBs */ +/**< reference: NVX_INDEX_PARAM_VIDENC_GEN_SKIP_MB_FRAMES + * Use OMX_CONFIG_BOOLEANTYPE + */ +#define NVX_INDEX_PARAM_VIDENC_SKIP_FRAME "OMX.Nvidia.index.param.videncskipframe" + +#endif +/** @} */ +/* File EOF */ + + diff --git a/omx/openmax/NVOMX_IndexExtensions.h b/omx/openmax/NVOMX_IndexExtensions.h new file mode 100644 index 0000000..fa25641 --- /dev/null +++ b/omx/openmax/NVOMX_IndexExtensions.h @@ -0,0 +1,660 @@ +/* Copyright (c) 2007-2014 NVIDIA Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file + * <b>NVIDIA Tegra: OpenMAX Index Extension Interface</b> + */ + +/** + * @defgroup nv_omx_il_index General Index + * + * This is the NVIDIA OpenMAX index extensions interface. + * + * These extend custom events and error codes. + * + * @ingroup nvomx_general_extension + * @{ + */ + +#ifndef _NVOMX_IndexExtensions_h_ +#define _NVOMX_IndexExtensions_h_ + +#include <OMX_Core.h> +#include <OMX_Component.h> + +#include "OMX_Core.h" + +#include "NVOMX_RendererExtensions.h" +#include "NVOMX_ParserExtensions.h" +#include "NVOMX_CameraExtensions.h" +#include "NVOMX_DecoderExtensions.h" +#include "NVOMX_EncoderExtensions.h" +#include "NVOMX_DrmExtensions.h" +#include "NVOMX_ColorFormatExtensions.h" + +struct NvOsSemaphoreRec; + +/** Representation of timeout values, in milliseconds. */ +typedef OMX_U32 NvxTimeMs; + +/** Maximum timeout value (Never timeout). */ +#define NVX_TIMEOUT_NEVER 0xffffffff +/** Minimum timeout value. */ +#define NVX_TIMEOUT_MIN 0 + +/** color extension */ +typedef enum NVX_COLORFORMATTYPE_ENUM { + NVX_ColorFormatVendorStartUnused = 0x70000000, + + NVX_ColorFormatYUV422T, + NVX_ColorFormatYUV444, + NVX_ColorFormatYV16x2, + + NVX_ColorFormatMax = OMX_COLOR_FormatMax +} NVX_COLORFORMATTYPE; + +/* Specifies the type of data pointed to by buffer header's pBuffer */ +typedef enum +{ + NVX_BUFFERTYPE_NORMAL = 1, + + /* pBuffer is an NvxEglImageSiblingHandle */ + NVX_BUFFERTYPE_EGLIMAGE, + + /* pBuffer is an android_native_buffer_t */ + NVX_BUFFERTYPE_ANDROID_NATIVE_BUFFER_T, + + /* Below 2 types are required for stagefright playback */ + NVX_BUFFERTYPE_NEEDRMSURFACE, + NVX_BUFFERTYPE_HASRMSURFACE, + + /*This indicates source component that it can send a NVDIA specific buffer embedded within the OMX Buffer Payload Data */ + NVX_BUFFERTYPE_NEEDNVBUFFER, + + /* pBuffer is an android buffer_handle_t */ + NVX_BUFFERTYPE_ANDROID_BUFFER_HANDLE_T, + + NVX_BUFFERTYPE_MAX = 0x7FFFFFFF +}NvxBufferType; + +/* OpenMAX internal data associated with a buffer */ +typedef struct NvxBufferPlatformPrivateStruct +{ + /* Specifies the type of data pointed to by buffer header's pBuffer */ + NvxBufferType eType; + /* Specifies display coordinates */ + OMX_CONFIG_RECTTYPE croprect; + + void *nvmmBuffer; + OMX_BOOL nvmmBufIsPinned; + /* Stereo layout info */ + OMX_U32 StereoInfo; + OMX_U32 rawHeaderOffset; + void *pData; +} NvxBufferPlatformPrivate; + +/** Defines custom event extensions. */ +typedef enum NVX_EVENTTYPE_ENUM { + /** Start of extended OpenMAX camera event types */ + NVX_EventVendorStartUnused = 0x70000000, + + /** Image capture started */ + NVX_EventImageStart = (NVX_EventVendorStartUnused | 0xB00000), + /** Image EXIF information ready */ + NVX_EventImage_EXIFInfo = NVX_EventImageStart + 1, + NVX_EventImage_JPEGInfo = NVX_EventImageStart + 2, + + /** Camera component started */ + NVX_EventCameraStart = (NVX_EventVendorStartUnused | 0xD00000), + /** Camera AE, AF, AWB locked */ + NVX_EventCamera_AlgorithmsLocked = NVX_EventCameraStart, + /** Camera auto focus achieved */ + NVX_EventCamera_AutoFocusAchieved, + /** Camera auto exposure achieved */ + NVX_EventCamera_AutoExposureAchieved, + /** Camera auto white balance achieved */ + NVX_EventCamera_AutoWhiteBalanceAchieved, + /** Camera auto focus timed out */ + NVX_EventCamera_AutoFocusTimedOut, + /** Camera auto exposure timed out */ + NVX_EventCamera_AutoExposureTimedOut, + /** Camera auto white balance timed out */ + NVX_EventCamera_AutoWhiteBalanceTimedOut, + /** Camera capture aborted */ + NVX_EventCamera_CaptureAborted, + /** Camera capture started */ + NVX_EventCamera_CaptureStarted, + /** Camera still capture completed */ + NVX_EventCamera_StillCaptureReady, + /** Camera still capture in process */ + NVX_EventCamera_StillCaptureProcessing, + /** Copy of camera preview frame */ + NVX_EventCamera_PreviewFrameCopy, + /** Copy of camera still confirmation frame */ + NVX_EventCamera_StillConfirmationFrameCopy, + /** Copy of camera Still YUV frame*/ + NVX_EventCamera_StillYUVFrameCopy, + /** Copy of camera Raw Bayer frame*/ + NVX_EventCamera_RawFrameCopy, + /** Preview paused after still capture */ + NVX_EventCamera_PreviewPausedAfterStillCapture, + /** Zoom factor during smooth zoom */ + NVX_EventCamera_SmoothZoomFactor, + /** Sensor resolution mode changed */ + NVX_EventCamera_SensorModeChanged, + NVX_EventCamera_EnterLowLight, + NVX_EventCamera_ExitLowLight, + NVX_EventCamera_EnterMacroMode, + NVX_EventCamera_ExitMacroMode, + NVX_EventCamera_FocusStartMoving, + NVX_EventCamera_FocusStopped, + + /** Face detection result */ + NVX_EventCamera_FaceInfo, + + /** Start of extended OpenMAX renderer event types */ + NVX_EventRendererStart = (NVX_EventVendorStartUnused | 0xE00000), + /** First video frame displayed */ + NVX_EventFirstFrameDisplayed, + /** First audio sample played */ + NVX_EventFirstAudioFramePlayed, + + /** Start of extended OpenMAX other event types */ + NVX_EventOtherStart = (NVX_EventVendorStartUnused | 0xF00000), + /** NVIDIA multimedia block warning */ + NVX_EventBlockWarning, + NVX_EventForBuffering, + + NVX_EventDRM_DirectLicenseAcquisition, + NVX_EventDRM_DrmFailure, + NVX_StreamChangeEvent, + + NVX_EventCamera_PowerOnComplete, + /** Limit of extended OpenMAX event types */ + NVX_EventMax = OMX_EventMax, +} NVX_EVENTTYPE; + +/** Defines custom error extensions. */ +typedef enum +{ + /** Start of extended OpenMAX error types */ + NvxError_ExtendedCodesStart = 0x80004000, + + /** Parser returns DRM license not found for particular track */ + NvxError_ParserDRMLicenseNotFound = 0x80004001, + + /** Parser returns DRM license error */ + NvxError_ParserDRMFailure = 0x80004002, + + /** Parser returns DRM license error */ + NvxError_ParserCorruptedStream = 0x80004003, + + /** Parser returns Seek Unsupported */ + NvxError_ParserSeekUnSupported = 0x80004004, + + /** Parser returns Trickmode Unsupported */ + NvxError_ParserTrickModeUnSupported = 0x80004005, + + /** Writer returns insufficient memory */ + NvxError_WriterInsufficientMemory = 0x80004006, + + /** Writer returns file write failed */ + NvxError_FileWriteFailed = 0x80004007, + + /** Writer returns write failure */ + NvxError_WriterFailure = 0x80004008, + + /** Writer returns unsupported stream */ + NvxError_WriterUnsupportedStream = 0x80004009, + + /** Writer returns unsupported user data */ + NvxError_WriterUnsupportedUserData = 0x8000400A, + + /** Writer returns 2GB limit exceeded */ + NvxError_WriterFileSizeLimitExceeded = 0x8000400B, + + /** Writer returns time limit exceeded */ + NvxError_WriterTimeLimitExceeded = 0x8000400C, + + /** Video Decoder does not need multiple nvmm blocks configuration */ + NvxError_VideoDecNormalConfig = 0x8000400D, + + /** Camera HW is not responding */ + NvxError_CameraHwNotResponding = 0x8000400E, + + /** Limit of extended OpenMAX error types */ + NvxError_Max = 0x7FFFFFFF +} NvxError; + +/** Profiling config for internal use only. */ +#define NVX_INDEX_CONFIG_PROFILE "OMX.Nvidia.index.config.profile" +/** Holds a profiling information. */ +typedef struct NVX_CONFIG_PROFILE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + + OMX_BOOL bProfile; +#define PROFILE_FILE_NAME_LENGTH 256 + char ProfileFileName[PROFILE_FILE_NAME_LENGTH]; + OMX_BOOL bVerbose; + OMX_BOOL bStubOutput; + OMX_U32 nForceLocale; // 0 - no, 1 -cpu, 2 - avp + OMX_U32 nNvMMProfile; + OMX_BOOL bNoAVSync; + OMX_BOOL enableUlpMode; + OMX_U32 ulpkpiMode; + OMX_S32 nAVSyncOffset; + OMX_BOOL bFlip; + OMX_U32 nFrameDrop; + + OMX_BOOL bSanity; + OMX_U32 nAvgFPS; + OMX_U32 nTotFrameDrops; + OMX_BOOL bDisableRendering; + + /// For camera: + OMX_U64 nTSPreviewStart; + OMX_U64 nTSCaptureStart; + OMX_U64 nTSCaptureEnd; + OMX_U64 nTSPreviewEnd; + OMX_U64 nTSStillConfirmationFrame; + OMX_U64 nTSFirstPreviewFrameAfterStill; + OMX_U32 nPreviewStartFrameCount; + OMX_U32 nPreviewEndFrameCount; + OMX_U32 nCaptureStartFrameCount; + OMX_U32 nCaptureEndFrameCount; + OMX_S32 xExposureTime; + OMX_S32 nExposureISO; + OMX_U32 nBadFrameCount; +} NVX_CONFIG_PROFILE; + + +#define NVX_INDEX_PARAM_EMBEDRMSURACE \ + "OMX.Nvidia.index.param.embedrmsurface" + +/** Config extension index NV-specific (i.e., OEM-specific) buffers within OMX_Buffer header. + * OMX extension index to EMBED. + * See ::NVX_PARAM_USENVBUFFER + */ +#define NVX_INDEX_CONFIG_USENVBUFFER \ + "OMX.Nvidia.index.config.usenvbuffer" /**< Reference: OMX_PARAM_BOOLEANTYPE */ + +/** Config extension index NV-specific (i.e., OEM-specific) buffers and memory FD within OMX_Buffer header. + * This requires NVX_INDEX_CONFIG_USENVBUFFER to be set as well. + */ +#define NVX_INDEX_CONFIG_USENVBUFFER2 \ + "OMX.Nvidia.index.config.usenvbuffer2" /**< Reference: OMX_PARAM_BOOLEANTYPE */ + +/** Indicates the config changed on a port (buffer flag version). */ +#define NVX_BUFFERFLAG_CONFIGCHANGED 0x00040000 + +/** Indicates the omx buffer payload holding buffer fd for vpr case */ +#define OMX_BUFFERFLAG_NV_BUFFER2 0x00100000 + +/** MVC flag. + * Indicates Multiview Video Codec Encoding + * @ingroup buf + */ +#define OMX_BUFFERFLAG_MVC 0x01000000 + +/** Skipped data flag. + * Indicates buffer contains frame data that needs to be skipped + * @ingroup buf + */ +#define OMX_BUFFERFLAG_SKIP_FRAME 0x02000000 + +/** Compressed data flag. + * Indicates buffer contains compressed data + * @ingroup buf + */ +#define OMX_BUFFERFLAG_COMPRESSED 0x04000000 + +/** Timestamp flag. + * Indicates to retain the OMX Buffer timestamp in Nvmm + * @ingroup buf + */ +#define OMX_BUFFERFLAG_RETAIN_OMX_TS 0x08000000 + +/** NVIDIA-specific buffer flag. + * + * A component sets OMX_BUFFERFLAG_NV_BUFFER to indicate a NVIDIA (i.e., OEM ) specific Buffer + * is embedded within the OMX Buffer Payload Data. This Buffer Flag is intended to be used across + * two NVIDIA openmax components in non-Tunneled mode (e.g., Video Capture on Android Camcorder app). + * @ingroup buf + */ + +#define OMX_BUFFERFLAG_NV_BUFFER 0x10000000 + +/** End-of-track flag. + * A component sets EOT when it has reached the end of a track for an + * output port. The component may continue emitting data on that output + * port from next track. + * @ingroup buf + */ +#define OMX_BUFFERFLAG_EOT 0x20000000 + +/** PTS computation required + * @ingroup buf + */ +#define OMX_BUFFERFLAG_NEED_PTS 0x40000000 + +/** Post view flag. + * Indicates image data is for post view image + * @ingroup buf + */ +#define OMX_BUFFERFLAG_POSTVIEW 0x80000000 + + +/** Holds data to enable proprietary buffer transfers. */ +typedef struct NVX_PARAM_USENVBUFFER +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version info */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL bUseNvBuffer; +} NVX_PARAM_USENVBUFFER; + +/** Holds data to transfer settings to OMX.Nvidia.odm.comp. */ +typedef struct NVX_CONFIG_ODM +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version info */ + OMX_U32 nConfigSize; /**< Size of pConfig */ + void *pConfig; /**< Pointer to customer defined config */ +} NVX_CONFIG_ODM; + +/** Holds the imager GUID. */ +typedef struct NVX_PARAM_SENSOR_GUID +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version info */ + OMX_U64 imagerGuid; /**< GUID for the selected imager */ +} NVX_PARAM_SENSOR_GUID; + +#define NVX_INDEX_CONFIG_STEREORENDMODE "OMX.Nvidia.index.config.stereorendmode" +/** Enumerate the properietary stereo mode presence in incoming YUV frames. */ +typedef enum OMX_STEREORENDMODETYPE { + OMX_STEREORENDERING_OFF = 0, /**< Default mode, when OMX operates in Mono channel mode */ + OMX_STEREORENDERING_HOR_STITCHED, /**< When OMX expected the decoded surfaces to be horizontally stitched */ +} OMX_STEREORENDMODETYPE; + +/** Holds the stereo mode of the component. */ +typedef struct OMX_CONFIG_STEREORENDMODETYPE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_STEREORENDMODETYPE eType; /**< The stereo mode */ +} OMX_CONFIG_STEREORENDMODETYPE; + + +#define SetAudioSourceParamExt (OMX_IndexVendorStartUnused | 0xFAFAFE) +typedef struct OMX_PARAM_SETAUDIOSOURCE{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + int AudioSourceParam; +} OMX_PARAM_SETAUDIOSOURCE; + +/** Param extension index to get video encoder and decoder capability based on index + * See ::NVX_PARAM_CODECCAPABILITY + */ +#define NVX_INDEX_PARAM_CODECCAPABILITY "OMX.Nvidia.index.param.codeccapability" + +/** Holds data to fine tune video encoder and decoder buffer configuration. */ +typedef struct NVX_PARAM_CODECCAPABILITY +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 nCapIndex; /**< (In) Value should be 0 to N*/ + OMX_U32 nMaxProfile; /**< Type is OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263PROFILETYPE, + or OMX_VIDEO_MPEG4PROFILETYPE depending on context */ + OMX_U32 nMaxLevel; /**< Type is OMX_VIDEO_AVCLEVELTYPE, OMX_VIDEO_H263LEVELTYPE, + or OMX_VIDEO_MPEG4PROFILETYPE depending on context */ + OMX_U32 nMaxWidth; /**< Maximum frame width supported (in pixels) */ + OMX_U32 nMaxHeight; /**< Maximum frame height supported (in pixels) */ + OMX_U32 nFrameRate; /**< Framerate supported for Max res.(in per sec.) */ + OMX_U32 nMaxBitRate; /**< Maximum bitrate supported (in kbps) */ +}NVX_PARAM_CODECCAPABILITY; + +/** Param extension index to get audio decoder capability based on index + * See ::NVX_PARAM_AUDIOCODECCAPABILITY + */ +#define NVX_INDEX_PARAM_AUDIOCODECCAPABILITY "OMX.Nvidia.index.param.audiocodeccapability" + +/** + * @brief Defines the structure for holding the configuartion for the audio decoder + * capabilities. These are stream independent properties. Decoder fills this + * structure and pass to the IL-Client. + */ +typedef struct +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nMaxChannels; /**< Holds maximum number of channels supported by decoder */ + OMX_U32 nMinBitsPerSample; /**< Holds minimum number of bits required for each sample supported by decoder */ + OMX_U32 nMaxBitsPerSample; /**< Holds maximum number of bits required for each sample supported by decoder */ + OMX_U32 nMinSampleRate; /**< Holds maximum ample rate supported by decoder */ + OMX_U32 nMaxSampleRate; /**< Holds maximum ample rate supported by decoder */ + + OMX_BOOL isFreqRangeContinuous; /**< Returns XA_BOOLEAN_TRUE if the device supports a continuous range of + sampling rates between minSampleRate and maxSampleRate */ + OMX_U32 * pSampleRatesSupported; /**< Indexed array containing the supported sampling rates. Ignored if + isFreqRangeContinuous is XA_BOOLEAN_TRUE */ + OMX_U32 nSampleRatesSupported; /**< Size of the pSamplingRatesSupported array */ + OMX_U32 nMinBitRate; /**< Holds minimum bitrate supported by decoder in bps */ + OMX_U32 nMaxBitRate; /**< Holds maximum bitrate supported by decoder in bps */ + + OMX_BOOL isBitrateRangeContinuous;/**< Returns XA_BOOLEAN_TRUE if the device supports a continuous range of + bitrates between minBitRate and maxBitRate */ + OMX_U32 * pBitratesSupported; /**< Indexed array containing the supported bitrates. Ignored if + isBitrateRangeContinuous is XA_BOOLEAN_TRUE */ + OMX_U32 nBitratesSupported; /**< Size of the pBitratesSupported array. Ignored if + isBitrateRangeContinuous is XA_BOOLEAN_TRUE */ + OMX_U32 nProfileType; /**< Holds profile type */ + OMX_U32 nModeType; /**< Hold Mode type */ + OMX_U32 nStreamFormatType; /**< Hold StreamFormat type */ +} NVX_PARAM_AUDIOCODECCAPABILITY; + + +/** Blocks/unblocks socket activity. + * + * @param block Specify 1 to block all socket communication, 0 to unblock. + */ +void NVOMX_BlockAllSocketActivity(int block); + +/** Param extension to get the actual video width, height and aspect ratio for + * ARIB and similar use-cases + */ +#define NVX_INDEX_CONFIG_ARIBCONSTRAINTS "OMX.Nvidia.index.config.aribconstraints" + +typedef struct OMX_CONFIG_ARIBCONSTRAINTS +{ + OMX_U32 nWidth; + OMX_U32 nHeight; +} OMX_CONFIG_ARIBCONSTRAINTS; + +#define NVX_INDEX_PARAM_VPP "OMX.Nvidia.index.param.vpp" + +typedef enum { + NV_VPP_TYPE_CPU = 0, + NV_VPP_TYPE_EGL, + NV_VPP_TYPE_CUDA, + NV_VPP_TYPE_MAX = 0xFFFFFF, +}NVX_VPP_TYPE; + +typedef enum { + NV_VPP_EFFECT_TYPE_NOEFFECT = 0, + NV_VPP_EFFECT_TYPE_NEGATIVE, + NV_VPP_EFFECT_TYPE_DEBLOCK, + NV_VPP_EFFECT_TYPE_MAX = 0xFFFFFF, +}NVX_VPP_EFFECT_TYPE; + +typedef struct OMX_PARAM_VPP +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + NVX_VPP_TYPE nVppType; + NVX_VPP_EFFECT_TYPE nVppEffectType; + OMX_BOOL bVppEnable; +} NVX_PARAM_VPP; + + +/** Config extension index based on the OMX-AL Video Post Processing interface + * which will insert a 2D processing stage. + * See ::NVX_CONFIG_VIDEO2DPROCESSING + */ +#define NVX_INDEX_CONFIG_VIDEO2DPROC "OMX.Nvidia.index.config.video2dprocessing" + +/** Indicates that Rotation is specified */ +#define NVX_V2DPROC_FLAG_ROTATION 0x1 + +/** Indicates that ScalingOptions, background color and Rendering Hints are specified */ +#define NVX_V2DPROC_FLAG_SCALEOPTIONS 0x2 + +/** Indicates that Source Rectangle is specified */ +#define NVX_V2DPROC_FLAG_SOURCERECTANGLE 0x4 + +/** Indicates that Destination Rectangle is specified */ +#define NVX_V2DPROC_FLAG_DESTINATIONRECTANGLE 0x8 + +/** Indicates that Mirror mode is specified */ +#define NVX_V2DPROC_FLAG_MIRROR 0x10 + +/** Indicates that Video is stretched to the Destination Rectangle */ +#define NVX_V2DPROC_VIDEOSCALE_STRETCH 1 + +/** Indicates that Video is fit in the Destination Rectangle */ +#define NVX_V2DPROC_VIDEOSCALE_FIT 2 + +/** Indicates that Video is cropped to fit into the Destination Rectangle */ +#define NVX_V2DPROC_VIDEOSCALE_CROP 3 + +/** Holds Data to setup the 2D processing stage */ +typedef struct NVX_CONFIG_VIDEO2DPROCESSING +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + + OMX_U32 nPortIndex; /**< Port that this structure applies to. + Input Port => Pre process, Output Port => Post Process */ + OMX_U32 nSetupFlags; /**< See:NVX_V2DPROC_FLAG_XX */ + OMX_U32 nRotation; /**< Integer Rotation. Valid if NVX_V2DPROC_FLAG_ROTATION present. + Allowed Values: 0, 90, 180, 270 */ + OMX_MIRRORTYPE eMirror; /**< Mirror mode. Valid if NVX_V2DPROC_FLAG_MIRROR present */ + OMX_U32 nScaleOption; /**< Scaling of Video into Destionation rectangle. + Refer to NVX_V2DPROC_VIDEOSCALE_XX. + Valid only if NVX_V2DPROC_FLAG_SCALEOPTIONS present.*/ + OMX_U32 nBackgroundColor; /**< Refers to RGBA value for the background color outside of + the video in the destination rectangle. + Valid only if NVX_V2DPROC_FLAG_SCALEOPTIONS present */ + OMX_U32 nRenderingHint; /**< Unused. Valid only if NVX_V2DPROC_FLAG_SCALEOPTIONS present */ + + /**< Source Rectangle coords; Valid only if + NVX_V2DPROC_FLAG_SOURCERECTANGLE is present */ + OMX_U32 nSrcLeft; /**< X coord of top left of Source Rectangle */ + OMX_U32 nSrcTop; /**< Y coord of top left of Source Rectangle */ + OMX_U32 nSrcWidth; /**< Width of Source Rectangle */ + OMX_U32 nSrcHeight; /**< Height of Source Rectangle */ + + /**< Destionation Rectangle coords; Valid only if + NVX_V2DPROC_FLAG_DESTINATIONRECTANGLE is present*/ + OMX_U32 nDstLeft; /**< X coord of top left of Dest Rectangle */ + OMX_U32 nDstTop; /**< Y coord of top left of Dest Rectangle */ + OMX_U32 nDstWidth; /**< Width of Dest Rectangle */ + OMX_U32 nDstHeight; /**< Height of Dest Rectangle */ + +} NVX_CONFIG_VIDEO2DPROCESSING; + +/* OMX extension index to tell decoder to decode only IFrames */ +/**< reference: NVX_INDEX_CONFIG_DECODE_IFRAMES + * Use OMX_CONFIG_BOOLEANTYPE + */ +#define NVX_INDEX_CONFIG_DECODE_IFRAMES "OMX.Nvidia.index.config.decodeiframes" + +/* OMX extension index to tell decoder to decode Normally or skip all frames till next IDR*/ +#define NVX_INDEX_CONFIG_VIDEO_DECODESTATE "OMX.Nvidia.index.config.video.decodestate" +typedef struct OMX_CONFIG_VIDEODECODESTATE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_BOOL bDecodeState; +} OMX_CONFIG_VIDEODECODESTATE; + +/* To Avoid dependency between IL Driver and Frameworks/base */ +/** Defining the constant kMetadataBufferTypeEglStreamSource here rather than + * <media/stagefright/MetadataBufferType.h> + * kMetadataBufferTypeEglSource is used to indicate that + * the source of the metadata buffer is EGL Stream Buffer. + */ +#define kMetadataBufferTypeEglStreamSource 0x7F000000 + +/* OMX extension index to inform the component about the horizontal video 563 + stride alignment for RAW video frames */ +/**< reference: NVX_INDEX_CONFIG_VIDEOSTRIDEALIGN + * Use NVX_CONFIG_VIDEO_STRIDEALIGN + */ + +#define NVX_INDEX_CONFIG_VIDEOSTRIDEALIGN "OMX.Nvidia.index.config.videostridealign" +typedef struct NVX_CONFIG_VIDEO_STRIDEALIGN +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + + OMX_U32 nAlign; /**< Horizontal stride alignment in bytes (power of 2) for + width per video plane */ +} NVX_CONFIG_VIDEO_STRIDEALIGN; + +/* OMX extension index about info per video plane */ +/**< reference: NVX_INDEX_CONFIG_VIDEOPLANESINFO + * Use NVX_CONFIG_VIDEOPLANESINFO + */ + +#define NVX_INDEX_CONFIG_VIDEOPLANESINFO "OMX.Nvidia.index.config.videoplanesinfo" +typedef struct NVX_CONFIG_VIDEOPLANESINFO +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + + OMX_U32 nAlign[3][2]; /**< Horizontal & vertical stride alignment in bytes (power of 2) + per video plane */ +} NVX_CONFIG_VIDEOPLANESINFO; + +/* OMX extension index about skipping non ref frames */ +/**< reference: NVX_INDEX_SKIP_NONREF_FRAMES + * Use NVX_CONFIG_SKIP_NONREF_FRAMES + */ + +#define NVX_INDEX_SKIP_NONREF_FRAMES "OMX.Nvidia.index.config.nonrefframes" +typedef struct NVX_CONFIG_SKIP_NONREF_FRAMES +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + + OMX_BOOL bSkipNonRefFrames; +} NVX_CONFIG_SKIP_NONREF_FRAMES; +#endif + + +/** @} */ + +/* File EOF */ diff --git a/omx/openmax/NVOMX_ParserExtensions.h b/omx/openmax/NVOMX_ParserExtensions.h new file mode 100644 index 0000000..0131e77 --- /dev/null +++ b/omx/openmax/NVOMX_ParserExtensions.h @@ -0,0 +1,534 @@ +/* Copyright (c) 2009-2013 NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file + * <b>NVIDIA Tegra: OpenMAX Container Extension Interface</b> + * + */ + +#ifndef NVOMX_ParserExtensions_h_ +#define NVOMX_ParserExtensions_h_ + +/** + * @defgroup nv_omx_il_parser_reader Container Demux + * + * This is the NVIDIA OpenMAX container demux class extension interface. + * + * These extensions include demuxer control and query of meta-data, stream type, + * cache size, duration, file name and more. + * + * See also \link nv_omx_il_tracklist Container Tracklist Extensions\endlink + * + * @ingroup nvomx_container_extension + * @{ + */ + +/* MUST ADD NEW TYPES TO END OF ENUM */ +typedef enum +{ + NvxStreamType_NONE = 0, + NvxStreamType_MPEG4, + NvxStreamType_H264, + NvxStreamType_H263, + NvxStreamType_WMV, + NvxStreamType_JPG, + NvxStreamType_MP3, + NvxStreamType_WAV, + NvxStreamType_AAC, + NvxStreamType_AACSBR, + NvxStreamType_BSAC, + NvxStreamType_WMA, + NvxStreamType_WMAPro, + NvxStreamType_WMALossless, + NvxStreamType_AMRWB, + NvxStreamType_AMRNB, + NvxStreamType_VORBIS, + NvxStreamType_MPEG2V, + NvxStreamType_AC3, + NvxStreamType_WMV7, + NvxStreamType_WMV8, + NvxStreamType_WMAVoice, + NvxStreamType_MP2, + NvxStreamType_ADPCM, + NvxStreamType_MS_MPG4, + NvxStreamType_QCELP, + NvxStreamType_EVRC, + NvxStreamType_H264Ext, + NvxStreamType_VP6, + NvxStreamType_MPEG4Ext, + NvxStreamType_MJPEG, + NvxStreamType_Theora, + NvxStreamType_H264_Secure, + NvxStreamType_WMV_Secure, + NvxStreamType_MAX = 0x7FFFFFFF +} ENvxStreamType; + +typedef enum +{ + NvxMetadata_Artist, + NvxMetadata_Album, + NvxMetadata_Genre, + NvxMetadata_Title, + NvxMetadata_Year, + NvxMetadata_TrackNum, + NvMMetadata_Encoded, + NvxMetadata_Comment, + NvxMetadata_Composer, + NvxMetadata_Publisher, + NvxMetadata_OriginalArtist, + NvxMetadata_AlbumArtist, + NvxMetadata_Copyright, + NvxMetadata_Url, + NvxMetadata_BPM, + NvxMetadata_CoverArt, + NvxMetadata_CoverArtURL, + NvxMetadata_ThumbnailSeektime, + NvxMetadata_RtcpAppData, + NvxMetadata_RTCPSdesCname, + NvxMetadata_RTCPSdesName, + NvxMetadata_RTCPSdesEmail, + NvxMetadata_RTCPSdesPhone, + NvxMetadata_RTCPSdesLoc, + NvxMetadata_RTCPSdesTool, + NvxMetadata_RTCPSdesNote, + NvxMetadata_RTCPSdesPriv, + NvxMetadata_SeekNotPossible, + NvxMetadata_MAX = 0x7FFFFFFF +} ENvxMetadataType; + +/** Temporary file path parameter for writer components that write files. + * See ::NVX_PARAM_FILENAME for details. + * @note This is implemented only for 3GP writer. + */ +#define NVX_INDEX_PARAM_TEMPFILEPATH "OMX.Nvidia.index.param.tempfilename" +/** Holds filename for components that read/write files. */ +typedef struct NVX_PARAM_TEMPFILEPATH { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_STRING pTempPath; /**< Temporary file path as supported by stdio implementation */ +} NVX_PARAM_TEMPFILEPATH; + + +/** Filename parameter for source, demux, and sink components that read/write files. + * See ::NVX_PARAM_FILENAME for details. + */ +#define NVX_INDEX_PARAM_FILENAME "OMX.Nvidia.index.param.filename" +/** Holds filename for components that read/write files. */ +typedef struct NVX_PARAM_FILENAME { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_STRING pFilename; /**< Name of file as supported by stdio implementation */ +} NVX_PARAM_FILENAME; + +/** Duration parameter for source, demux and sink components that read/write files. + * See ::NVX_PARAM_DURATION for details. + */ +#define NVX_INDEX_PARAM_DURATION "OMX.Nvidia.index.param.duration" +/** Holds duration for components that read/write files. */ +typedef struct NVX_PARAM_DURATION { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_TICKS nDuration; /**< Duration in microsecs */ +} NVX_PARAM_DURATION; + +/** Stream type parameter for source, demux and sink components that read/write files. + * See ::NVX_PARAM_STREAMTYPE for details. + */ +#define NVX_INDEX_PARAM_STREAMTYPE "OMX.Nvidia.index.param.streamtype" +/** Holds stream type for components that read/write files. */ +typedef struct NVX_PARAM_STREAMTYPE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPort; /**< Port that this struct applies to */ + ENvxStreamType eStreamType; /**< Stream type */ +} NVX_PARAM_STREAMTYPE; +/** Stream Count parameter for finding the no of streams in the file for reader. + * See ::NVX_PARAM_STREAMCOUNTfor details. + */ +#define NVX_INDEX_PARAM_STREAMCOUNT "OMX.Nvidia.index.param.streamcount" +/** Holds stream type for components that read/write files. */ +typedef struct NVX_PARAM_STREAMCOUNT{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 StreamCount; /**< no of streams count */ +} NVX_PARAM_STREAMCOUNT; + +/** Audio stream parameters for source, demux and sink components that read/write files. + * See ::NVX_PARAM_AUDIOPARAMS for details. + */ +#define NVX_INDEX_PARAM_AUDIOPARAMS "OMX.Nvidia.index.param.audioparams" +/** Holds audio stream info for components that read/write files. */ +typedef struct NVX_PARAM_AUDIOPARAMS { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPort; /**< Port that this struct applies to */ + OMX_U32 nSampleRate; /**< Sample rate in HZ */ + OMX_U32 nBitRate; /**< Bits rate in bits per second */ + OMX_U32 nChannels; /**< Number of channels (mono = 1, stereo = 2, etc) */ + OMX_U32 nBitsPerSample; /**< Bits per sample */ +} NVX_PARAM_AUDIOPARAMS; + +/** Metadata config for demux components that read files with meta data. + * If specified metadata not found, returns empty string or + * OMX_ErrorInsufficientResources if sValueStr is too small. + * + * See ::NVX_CONFIG_QUERYMETADATA + */ +#define NVX_INDEX_CONFIG_QUERYMETADATA "OMX.Nvidia.index.config.querymetadata" +/** Holds meta data info for demux components. */ +typedef struct NVX_CONFIG_QUERYMETADATA { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + ENvxMetadataType eType; /**< Meta data type */ + OMX_STRING sValueStr; /**< String to hold results */ + OMX_U32 nValueLen; /**< Length of results string */ + OMX_METADATACHARSETTYPE eCharSet; /**< Character set to use */ +} NVX_CONFIG_QUERYMETADATA; +/** Video Header parameter for getting the video header from parser. + * See ::NVX_PARAM_VIDEOHEADER for details. + */ +#define NVX_INDEX_CONFIG_HEADER "OMX.Nvidia.index.param.header" +/** Holds stream type for components that read/write files. */ +typedef struct NVX_CONFIG_HEADER{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port number the structure applies to */ + OMX_STRING nBuffer; /**< the buffer which holds header info */ + OMX_U32 nBufferlen; /**>Buffer length */ +} NVX_CONFIG_HEADER; + +/** Audio Header parameter for getting the audio header from parser. + * See ::NVX_CONFIG_AUDIOHEADER for details. + */ +#define NVX_INDEX_CONFIG_AUDIOHEADER "OMX.Nvidia.index.param.audioheader" +/** Holds stream type for components that read/write files. */ +typedef struct NVX_CONFIG_AUDIOHEADER{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_STRING nBuffer; /**< the buffer which holds header info */ + OMX_U32 nBufferlen; /**>Buffer length */ +} NVX_CONFIG_AUDIOHEADER; +/** WMA Header parameter for getting the audio header from parser. + * See ::NVX_CONFIG_WMAHEADER for details. + */ +#define NVX_INDEX_CONFIG_WMAHEADER "OMX.Nvidia.index.param.wmaheader" +/** Holds stream type for components that read/write files. */ +typedef struct NVX_CONFIG_WMAHEADER{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_STRING nBuffer; /**< the buffer which holds header info */ + OMX_U32 nBufferlen; /**>Buffer length */ +} NVX_CONFIG_WMAHEADER; +#define NVX_INDEX_CONFIG_MP3TSENABLE "OMX.Nvidia.index.config.mp3tsenable" +/** Holds a MP3TSEnable handle. */ +typedef struct NVX_CONFIG_MP3TSENABLE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 bMp3Enable; /**< Enable/Disable flag*/ +} NVX_CONFIG_MP3TSENABLE; + +/** File cache size config for demux components that read files. + * See ::NVX_CONFIG_FILECACHESIZE + */ +#define NVX_INDEX_CONFIG_FILECACHESIZE "OMX.Nvidia.index.config.filecachesize" +/** Holds cache size configuration. */ +typedef struct NVX_CONFIG_FILECACHESIZE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nFileCacheSize; /**< in MB, 0 = none, 1 = max */ +} NVX_CONFIG_FILECACHESIZE; +/** File cache size config for demux components that read files. + * See ::NVX_CONFIG_FILECACHESIZE + */ +#define NVX_INDEX_CONFIG_DISABLEBUFFCONFIG "OMX.Nvidia.index.config.disablebuffconfig" +/** Holds cache size configuration. */ +typedef struct NVX_CONFIG_DISABLEBUFFCONFIG { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_BOOL bDisableBuffConfig; /**< , 0 = enable, 1 = disable */ +} NVX_CONFIG_DISABLEBUFFCONFIG; + +/** File cache info config for demux components that read files. + * See ::NVX_CONFIG_FILECACHEINFO + */ +#define NVX_INDEX_CONFIG_FILECACHEINFO "OMX.Nvidia.index.config.filecacheinfo" +/** Holds file cache information. */ +typedef struct NVX_CONFIG_FILECACHEINFO { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U64 nDataBegin; /**< Data Begin */ + OMX_U64 nDataFirst; /**< Data First */ + OMX_U64 nDataCur; /**< Data Current */ + OMX_U64 nDataLast; /**< Data Last */ + OMX_U64 nDataEnd; /**< Data End */ +} NVX_CONFIG_FILECACHEINFO; + +/** User agent parameters required for streaming playback. + */ +#define NVX_INDEX_PARAM_USERAGENT "OMX.Nvidia.index.param.useragent" +/** Holds user agent info for streaming. */ +typedef struct NVX_PARAM_USERAGENT { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_STRING pUserAgentStr; /**< User agent info */ +} NVX_PARAM_USERAGENT; + +/** User agent profile parameters required for streaming playback. + */ +#define NVX_INDEX_PARAM_USERAGENT_PROFILE "OMX.Nvidia.index.param.useragentprofile" +/** Holds user agent profile info for streaming. */ +typedef struct NVX_PARAM_USERAGENTPROF { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_STRING pUserAgentProfStr; /**< User agent profile info */ +} NVX_PARAM_USERAGENTPROF; + +/* Charset define to extend OMX_METADATACHARSETTYPE for a U32 type */ +#define NVOMX_MetadataCharsetU32 0x10000000 +#define NVOMX_MetadataFormatJPEG 0x10000001 +#define NVOMX_MetadataFormatPNG 0x10000002 +#define NVOMX_MetadataFormatBMP 0x10000003 +#define NVOMX_MetadataFormatUnknown 0x10000004 +#define NVOMX_MetadataFormatGIF 0x10000005 +#define NVOMX_MetadataCharsetU64 0x10000006 + +/** @} */ + +/** + * @defgroup nv_omx_il_parser_dtv DTV Source + * + * This is the NVIDIA OpenMAX DTV source class extension interface. + * + * These extensions include recording and pause mode, source selection, channel + * info and control and more. + * + * @ingroup nvomx_container_extension + * @{ + */ + +typedef enum +{ + NvxRecordingMode_Enable = 1, + NvxRecordingMode_EnableExclusive, + NvxRecordingMode_Disable, + NvxRecordingMode_Force32 = 0x7FFFFFFF +} ENvxRecordingMode; + +typedef enum +{ + NvxSource_AutoDetect = 1, + NvxSource_File, + NvxSource_Force32 = 0x7FFFFFFF +} ENvxSource; + +/** Recording mode parameter for DTV components. + * See ::NVX_PARAM_RECORDINGMODE + */ +#define NVX_INDEX_PARAM_RECORDINGMODE "OMX.Nvidia.index.param.recordingmode" +/** Holds DTV recording mode. */ +typedef struct NVX_PARAM_RECORDINGMODE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + ENvxRecordingMode RecordingMode; /**< Recording mode */ +} NVX_PARAM_RECORDINGMODE; + +/** Source parameter for DTV components. + * See ::NVX_PARAM_SOURCE + */ +#define NVX_INDEX_PARAM_SOURCE "OMX.Nvidia.index.param.source" +/** Holds DTV source type. */ +typedef struct NVX_PARAM_SOURCE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + ENvxSource Source; /**< Source type */ +} NVX_PARAM_SOURCE; + +/** Channel ID parameter for DTV components. + * See ::NVX_PARAM_CHANNELID + */ +#define NVX_INDEX_PARAM_CHANNELID "OMX.Nvidia.index.param.channelid" +/** Holds DTV channel ID. */ +typedef struct NVX_PARAM_CHANNELID +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 ChannelID; /**< Channel ID */ +} NVX_PARAM_CHANNELID; + + +/** Pause config for DTV components. + * See ::NVX_CONFIG_PAUSEPLAYBACK + */ +#define NVX_INDEX_CONFIG_PAUSEPLAYBACK "OMX.Nvidia.index.config.pauseplayback" +/** Holds data to enable DTV pause. */ +typedef struct NVX_CONFIG_PAUSEPLAYBACK +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_BOOL bPausePlayback; /**< Pause if TRUE */ +} NVX_CONFIG_PAUSEPLAYBACK; + +/** Holds DTV program ID. */ +typedef struct ENvxDTVProgRec +{ + OMX_U32 ProgID; +} ENvxDTVProg; + +/** Holds a DTV program list. */ +typedef struct ENvxDTVProgProgsListRec +{ + OMX_U32 NumProgs; + ENvxDTVProg *pProgs; +} ENvxDTVProgProgsList; + +/** Program list config for DTV components. + * See ::NVX_CONFIG_PROGRAMS_LIST + */ +#define NVX_INDEX_CONFIG_PROGRAMS_LIST "OMX.Nvidia.index.config.programslist" +/** Holds a DTV program list. */ +typedef struct NVX_CONFIG_PROGRAMS_LIST +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + ENvxDTVProgProgsList ProgsList; /**< Program list */ +} NVX_CONFIG_PROGRAMS_LIST; + +/** Current program config for DTV components. + * See ::NVX_CONFIG_CURRENT_PROGRAM + */ +#define NVX_INDEX_CONFIG_CURRENT_PROGRAM "OMX.Nvidia.index.config.currentprogram" +/** Holds a DTV current program ID. */ +typedef struct NVX_CONFIG_CURRENT_PROGRAM +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 ProgID; /**< Current program */ +} NVX_CONFIG_CURRENT_PROGRAM; + +/** @} */ + +/** + * @defgroup nv_omx_il_parser_writer Container Mux + * + * This is the NVIDIA OpenMAX container mux class extension interface. + * + * These extensions include muxer control and query of stream type, cache size, + * duration, file name and more. + * + * @ingroup nvomx_container_extension + * @{ + */ + +/** Maximum number of frames to write to file parameter. + * See ::OMX_PARAM_U32TYPE + */ +#define NVX_INDEX_PARAM_MAXFRAMES "OMX.Nvidia.index.param.maxframes" + +/** Muxer buffer config parameter. + * @deprecated This parameter is deprecated. + */ +#define NVX_INDEX_PARAM_OTHER_3GPMUX_BUFFERCONFIG "OMX.Nvidia.index.param.other.3gpmux.bufferconfig" +/** @deprecated This structure is deprecated. */ +typedef struct NVX_PARAM_OTHER_3GPMUX_BUFFERCONFIG +{ + OMX_U32 nSize; /**< Size of the structure in bytes. */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information. */ + OMX_U32 nPortIndex; /**< Port to which this struct applies. */ + OMX_BOOL bUseCache; /**< @deprecated This field is deprecated. */ + OMX_U32 nBufferSize; /**< @deprecated This field is deprecated. */ + OMX_U32 nPageSize; /**< @deprecated This field is deprecated. */ +} NVX_PARAM_OTHER_3GPMUX_BUFFERCONFIG; + +/** Current number of audio and video frames config. + * See ::NVX_CONFIG_3GPMUXGETAVRECFRAMES + */ +#define NVX_INDEX_CONFIG_3GPMUXGETAVRECFRAMES "OMX.Nvidia.index.config.3gpmuxgetavrecframes" +/** Holds a number of audio and video frames. */ +typedef struct NVX_CONFIG_3GPMUXGETAVRECFRAMES +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 nAudioFrames; /**< Number of audio frames muxed */ + OMX_U32 nVideoFrames; /**< Number of video frames muxed */ +}NVX_CONFIG_3GPMUXGETAVRECFRAMES; + +/** Split filename config. + * See ::NVX_CONFIG_SPLITFILENAME + */ +#define NVX_INDEX_CONFIG_SPLITFILENAME "OMX.Nvidia.index.config.splitfilename" +/** Holds split filenames. */ +typedef struct NVX_CONFIG_SPLITFILENAME +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_STRING pFilename; /**< Name of file as supported by stdio implementation */ +}NVX_CONFIG_SPLITFILENAME; + +/** Output format parameter for writer. + * See ::NVX_PARAM_OUTPUTFORMAT for details. + */ +#define NVX_INDEX_PARAM_OUTPUTFORMAT "OMX.Nvidia.index.param.outputformat" +#define MAX_EXT_LEN 8 +/** Holds filename for components that read/write files. */ +typedef struct NVX_PARAM_OUTPUTFORMAT { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_STRING OutputFormat; +} NVX_PARAM_OUTPUTFORMAT; + +/** File size parameters for writer components that write files. + * See ::NVX_PARAM_WRITERFILESIZE + */ +#define NVX_INDEX_PARAM_WRITERFILESIZE "OMX.Nvidia.index.param.writerfilesize" +/** Holds file size configuration. */ +typedef struct NVX_PARAM_WRITERFILESIZE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U64 nFileSize; /**< Maximum file size to write */ +} NVX_PARAM_WRITERFILESIZE; + + +/* FIXME: Remove when parser code is reworked. Just added to fix a build + * break. + */ + +/** Video Header parameter for getting the video header from parser. + * See ::NVX_PARAM_VIDEOHEADER for details. + */ +#define NVX_INDEX_CONFIG_VIDEOHEADER "OMX.Nvidia.index.param.videoheader" +/** Holds stream type for components that read/write files. */ +typedef struct NVX_CONFIG_VIDEOHEADER{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_STRING nBuffer; /**< the buffer which holds header info */ + OMX_U32 nBufferlen; /**>Buffer length */ +} NVX_CONFIG_VIDEOHEADER; + +/** @} */ + + +#endif +/* File EOF */ diff --git a/omx/openmax/NVOMX_RendererExtensions.h b/omx/openmax/NVOMX_RendererExtensions.h new file mode 100644 index 0000000..1316d88 --- /dev/null +++ b/omx/openmax/NVOMX_RendererExtensions.h @@ -0,0 +1,427 @@ +/* Copyright (c) 2009 - 2013 NVIDIA Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file + * <b>NVIDIA Tegra: OpenMAX Renderer Extension Interface</b> + * + */ + +#ifndef NVOMX_RendererExtensions_h_ +#define NVOMX_RendererExtensions_h_ + +/** + * @defgroup nv_omx_il_video_renderer Video Renderer + * + * This is the NVIDIA OpenMAX video renderer class extensions interface. + * + * These extensions include aspect ratio control, single frame stepping, + * window and overlay control, frame capture, delivery statistics and more. + * + * @ingroup nvomx_renderer_extension + * @{ + */ + +// The actual color format for the secondary overlay is determined by the overlay +#define NVX_COLOR_FormatDefaultSecondaryOverlay (OMX_COLOR_Format24BitABGR6666 + 1) + +/** Config extension index to force video aspect ratio correction (letter-boxed). + * See ::NVX_CONFIG_KEEPASPECT + */ +#define NVX_INDEX_CONFIG_KEEPASPECT "OMX.Nvidia.index.config.keepaspect" +/** Holds data to force video aspect ratio correction. */ +typedef struct NVX_CONFIG_KEEPASPECT { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_BOOL bKeepAspect; /**< Boolean to enable aspect ratio correction */ +} NVX_CONFIG_KEEPASPECT; + +/** Config extension index to force video aspect ratio correction (letter-boxed) +with pixel aspect ratio supplied +* See ::NVX_CONFIG_FORCEASPECT +*/ +#define NVX_INDEX_CONFIG_FORCEASPECT "OMX.Nvidia.index.config.forceaspect" +/** Holds data to force video aspect ratio correction with pixel aspect params. */ +typedef struct NVX_CONFIG_FORCEASPECT { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nNumerator; /**< Numerator in pixel aspect ratio */ + OMX_U32 nDenominator; /**< Denominator in pixel aspect ratio */ +} NVX_CONFIG_FORCEASPECT; + +// Allow manual override on WinA to permit power optimizations from client side +typedef enum +{ + NvxWindow_A = 0, + NvxWindow_MAX = 0x7FFFFFFF +} ENvxWindowType; + +typedef enum +{ + NvxWindowAction_TurnOn = 0, + NvxWindowAction_TurnOff, + NvxWindowAction_MAX = 0x7FFFFFFF +} ENvxWindowDispActionType; + +/** Config extension index to disable/enable the primary display window and only show the video overlay. + * See ::NVX_CONFIG_WINDOWOVERRIDE + */ +#define NVX_INDEX_CONFIG_WINDOW_DISP_OVERRIDE "OMX.Nvidia.index.config.windisp" +/** Holds data to disable/enable the primary display window. */ +typedef struct NVX_CONFIG_WINDOWOVERRIDE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + ENvxWindowType eWindow; /**< Primary display window type */ + ENvxWindowDispActionType eAction; /**< Action */ +} NVX_CONFIG_WINDOWOVERRIDE; + +/** Config extension index to capture the uncompressed video frame data. + * See ::NVX_CONFIG_WINDOWOVERRIDE + */ +#define NVX_INDEX_CONFIG_CAPTURERAWFRAME "OMX.Nvidia.index.config.capturerawframe" +/** Holds data to capture the uncompressed video frame data. */ +typedef struct NVX_CONFIG_CAPTURERAWFRAME +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U8 *pBuffer; /**< Pointer to buffer to capture into */ + OMX_U32 nBufferSize; /**< Size of buffer */ +} NVX_CONFIG_CAPTURERAWFRAME; + +/** Config extension index to select tiled vs linear video data format. + * Tiled is a more efficent format, but less compatible with third-party components. + * + * See ::NVX_CONFIG_CUSTOMCOLORFORMAT + */ +#define NVX_INDEX_CONFIG_CUSTOMCOLORFORMAT "OMX.Nvidia.index.config.customcolorformat" +/** Holds data to select tiled versus linear video data format. */ +typedef struct NVX_CONFIG_CUSTOMCOLORFORMAT +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL bTiled; /**< Boolean to enable tiled video format */ +} NVX_CONFIG_CUSTOMCOLORFORMAT; + +/** Config extension index to allow single frame stepping. + * See ::NVX_CONFIG_SINGLE_FRAME + */ +#define NVX_INDEX_CONFIG_SINGLE_FRAME "OMX.Nvidia.index.config.singleframe" +/** Holds data to allow single frame stepping. */ +typedef struct NVX_CONFIG_SINGLE_FRAME +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_BOOL bEnableMode; /**< Boolean to enable single frame stepping mode */ +} NVX_CONFIG_SINGLE_FRAME; + +/** Config extension index to query the number of frames rendered. + * See ::NVX_CONFIG_NUMRENDEREDFRAMES + */ +#define NVX_INDEX_CONFIG_NUMRENDEREDFRAMES "OMX.Nvidia.index.config.numrenderedframes" +/** Holds data to query the number of frames rendered. */ +typedef struct NVX_CONFIG_NUMRENDEREDFRAMES +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 nFrames; /**< Number of rendered frames */ +} NVX_CONFIG_NUMRENDEREDFRAMES; + +/** Config extension index to allow the video renderer to handle differing size and format video + * frames on the fly. + * This will cause a power/performance penalty. + * + * See ::NVX_CONFIG_RENDERHINTMIXEDFRAMES + */ +#define NVX_INDEX_CONFIG_RENDERHINTMIXEDFRAMES "OMX.Nvidia.index.config.renderhintmixedframes" +/** Holds data to allow mixed format frame types. */ +typedef struct NVX_CONFIG_RENDERHINTMIXEDFRAMES +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL bMixedFrames; /**< Boolean to enable mixed frames support */ +} NVX_CONFIG_RENDERHINTMIXEDFRAMES; + +/** Config extension index to allow client to provide it's own overlay surface. + * See ::NVX_CONFIG_EXTERNALOVERLAY + */ +#define NVX_INDEX_CONFIG_EXTERNALOVERLAY "OMX.Nvidia.index.config.externaloverlay" +/** Holds data to allow the client to provide its own overlay surface. */ +typedef struct NVX_CONFIG_EXTERNALOVERLAY +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U64 oOverlayPtr; /**< Pointer to application overlay surface */ +} NVX_CONFIG_EXTERNALOVERLAY; + +/** Config extension index to allow client to provide it's own A/V sync function. + */ +#define NVX_INDEX_CONFIG_EXTERNALAVSYNC "OMX.Nvidia.index.config.externalavsync" +/** A/V sync function for the callback routine. */ +typedef void (* NVX_AVSYNC_CALLBACK) ( + OMX_PTR pAppData, /**< Application data (context) */ + OMX_TICKS nTimeStamp, /**< Timestamp of the frame */ + OMX_U32 nFlags, /**< Flags of the frame */ + OMX_S32 xScale, /**< Current playback speed */ + OMX_BOOL *pDropFrame); /**< Frame to be dropped (modified by the callback function) */ +/** Holds data to allow the client to provide its own A/V sync callback function. */ +typedef struct NVX_CONFIG_EXTERNALAVSYNC { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_PTR pAppData; /**< Application data (context) for the callback */ + NVX_AVSYNC_CALLBACK AVSyncCallBack; /**< Callback routine address */ +} NVX_CONFIG_EXTERNALAVSYNC; + +/** Config extension index to request il to allocate rm surface instead of os memory. + * See ::NVX_CONFIG_ALLOCATERMSURF + */ +#define NVX_INDEX_CONFIG_ALLOCATERMSURF "OMX.Nvidia.index.config.rmsurf" +/** Holds data to allow il to allocate rm surface for ilclient. */ +typedef struct NVX_CONFIG_ALLOCATERMSURF +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL bRmSurf; +} NVX_CONFIG_ALLOCATERMSURF; + +/** Config extension index to enable smart dimmer functionality if video is played in full screen. + * See ::NVX_CONFIG_SMARTDIMMER + */ +#define NVX_INDEX_CONFIG_SMARTDIMMER "OMX.Nvidia.index.config.smartdimmer" +/** Holds data to enable/disable smart dimmer. */ +typedef struct NVX_CONFIG_SMARTDIMMER { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_BOOL bSmartDimmerEnable; /**< Boolean to enable aspect ratio correction */ +} NVX_CONFIG_SMARTDIMMER; + +/** Config extension index to allow client to specify use of virtual desktop. + * See ::NVX_CONFIG_VIRTUALDESKTOP + */ +#define NVX_INDEX_CONFIG_VIRTUALDESKTOP "OMX.Nvidia.index.config.virtualdesktop" +/** Holds data to allow the client to provide a virtual desktop number. */ +typedef struct NVX_CONFIG_VIRTUALDESKTOP +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nDesktopNumber; /**< Virtual Desktop number */ +} NVX_CONFIG_VIRTUALDESKTOP; + +/** Config extension index to allow the video renderer to always enable display vsync wait. + * This is to prevent tearing when there is no actual timestamp on video frames like camera preview. + * + * See ::NVX_CONFIG_RENDERHINTCAMERAPREVIEW + */ +#define NVX_INDEX_CONFIG_RENDERHINTCAMERAPREVIEW "OMX.Nvidia.index.config.renderhintcamerapreview" +/** Holds data to allow camera preview mode. */ +typedef struct NVX_CONFIG_RENDERHINTCAMERAPREVIEW +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL bCameraPreviewMode; /**< Boolean to enable camera preview support */ +} NVX_CONFIG_RENDERHINTCAMERAPREVIEW; + +/** Config extension index to allow client to provide it's own overlay surface. + * See ::NVX_CONFIG_EXTERNALOVERLAY + */ +#define NVX_INDEX_CONFIG_ANDROIDWINDOW "OMX.Nvidia.index.config.androidwindow" + +/** Holds data to allow the client to provide its own overlay surface. */ +typedef struct NVX_CONFIG_ANDROIDWINDOW +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_PTR oAndroidWindowPtr; /**< Pointer to ANW */ +} NVX_CONFIG_ANDROIDWINDOW; + +/** Config extension index to allow client to provide its own overlay surface + * for camera preview. See ::NVX_CONFIG_EXTERNALOVERLAY + */ +#define NVX_INDEX_CONFIG_CAMERAPREVIEW "OMX.Nvidia.index.config.camerapreview" + +/** Holds data to allow the client to provide its own overlay surface. */ +typedef struct NVX_CONFIG_CAMERAPREVIEW +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_PTR oAndroidCameraPreviewPtr; /**< Pointer to a camera-preview interface */ +} NVX_CONFIG_CAMERAPREVIEW; + +/** Config extension index to allow client to specify the overlay surface + * index. + * See ::NVX_CONFIG_OVERLAYINDEX + */ +#define NVX_INDEX_CONFIG_OVERLAYINDEX "OMX.Nvidia.index.config.overlayindex" + +/** Holds data to allow client to specify the overlay surface index */ +typedef struct NVX_CONFIG_OVERLAYINDEX +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 index; +} NVX_CONFIG_OVERLAYINDEX; + +/** Config extension index to allow window mode on secondary displays + * See ::NVX_CONFIG_ALLOWSECONDARYWINDOW + */ +#define NVX_INDEX_CONFIG_ALLOWSECONDARYWINDOW "OMX.Nvidia.index.config.allowsecondarywindow" + +/** Holds data to allow window mode on secondary displays */ +typedef struct NVX_CONFIG_ALLOWSECONDARYWINDOW +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_BOOL bAllow; +} NVX_CONFIG_ALLOWSECONDARYWINDOW; + +/** @} */ + +/** + * @defgroup nv_omx_il_audio_renderer Audio Renderer + * + * This is the NVIDIA OpenMAX audio renderer class extensions interface. + * + * These extensions include HDMI and IS2 output control, graphic equalizer, + * dynamic range compression and automatic gain control, IIR filter setup and more. + * + * @ingroup nvomx_renderer_extension + * @{ + */ + +/** Number of bands for graphic equalizer */ +#define EQBANDS 5 +/** Number of channels for graphic equalizer */ +#define EQ_NO_CHANNEL 2 + +/** Number of parametric equalizer filter types */ +#define MIXER_NUM_PARA_EQ_FILTERS 4 +/** Band-pass parametric equalizer filter */ +#define MIXER_BANDPASS_IIR_FILTER 1 +/** High-pass parametric equalizer filter */ +#define MIXER_HIGHPASS_IIR_FILTER 2 +/** Low-pass parametric equalizer filter */ +#define MIXER_LOWPASS_IIR_FILTER 3 + +/** Defines the audio output types. */ +typedef enum NVX_AUDIO_OUTPUTTYPE { + NVX_AUDIO_OutputI2S = 0, + NVX_AUDIO_OutputHdmi, + NVX_AUDIO_OutputMusic, + NVX_AUDIO_OutputRingtone, + NVX_AUDIO_OutputSpdif, + NVX_AUDIO_OutputIEC, + NVX_AUDIO_Force32 = 0x7FFFFFFF +} NVX_AUDIO_OUTPUTTYPE; + +/** Config extension index to select audio output device. + * See ::NVX_CONFIG_AUDIOOUTPUT + */ +#define NVX_INDEX_CONFIG_AUDIO_OUTPUT "OMX.Nvidia.index.config.audio.output" +/** Holds data to select audio output device. */ +typedef struct NVX_CONFIG_AUDIOOUTPUT { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + NVX_AUDIO_OUTPUTTYPE eOutputType; /**< Audio output type */ +} NVX_CONFIG_AUDIOOUTPUT; + +/** Config extension index to disable timestamp event notifications. + * Disabling the events help lower power consumption. + * + * See ::NVX_CONFIG_DISABLETSUPDATES + */ +#define NVX_INDEX_CONFIG_DISABLETIMESTAMPUPDATES "OMX.Nvidia.index.config.disabletimestampupdates" +/** Holds data to disable timestamp event notifications. */ +typedef struct NVX_CONFIG_DISABLETSUPDATES { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_BOOL bDisableTSUpdates; /**< Boolean to disable timestamp event notification */ +} NVX_CONFIG_DISABLETSUPDATES; + +/** Config extension index to setup the graphic equalizer. + * See ::NVX_CONFIG_AUDIO_GRAPHICEQ + */ +#define NVX_INDEX_CONFIG_AUDIO_GRAPHICEQ "OMX.Nvidia.index.config.audio.graphiceq" +/** Holds data to setup the graphic equalizer. */ +typedef struct NVX_CONFIG_AUDIO_GRAPHICEQ +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 bEnable; /**< Boolean to enable the EQ */ + OMX_S32 dBGain[EQ_NO_CHANNEL][EQBANDS]; /**< Gain in dB per channel and frequency band */ +}NVX_CONFIG_AUDIO_GRAPHICEQ; + +/** Config extension index to setup dynamic range compression (DRC) and automatic gain control (AGC). + * See ::NVX_CONFIG_AUDIO_DRCPROPERTY + */ +#define NVX_INDEX_CONFIG_AUDIO_DRCPROPERTY "OMX.Nvidia.index.config.audio.drcproperty" +/** Holds data to setup dynamic range compression. */ +typedef struct NVX_CONFIG_AUDIO_DRCPROPERTY +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_S32 EnableDrc; /**< Boolean to enable DRC */ + OMX_S32 ClippingTh; /**< Clipping threshold in dB (UpperCompTh <= ClipTh <= 0dB) */ + OMX_S32 LowerCompTh; /**< Lower compression threshold in dB (NoiseGateTh <= LowerCompTh <= UpperCompTh) */ + OMX_S32 UpperCompTh; /**< Upper compression threshold in dB (LowerCompTh <= UpperCompTh <= ClipTh) */ + OMX_S32 NoiseGateTh; /**< Noise gate threshold in dB (-90dB <= NoiseGateTh <= LowerCompTh) */ +}NVX_CONFIG_AUDIO_DRCPROPERTY; + +/** Config extension index to setup the parametric equalizer filter. + * See ::NVX_CONFIG_AUDIO_PARAEQFILTER + */ +#define NVX_INDEX_CONFIG_AUDIO_PARAEQFILTER "OMX.Nvidia.index.config.audio.paraeqfilter" +/** Holds data to setup the parametric equalizer filter. */ +typedef struct NVX_CONFIG_AUDIO_PARAEQFILTER +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_U32 bEnable; /**< Boolean to enable parametric equalizer */ + OMX_U32 bUpdate; /**< Boolean indicates new filter parameters when already enabled */ + OMX_U32 FilterType[MIXER_NUM_PARA_EQ_FILTERS]; /**< MIXER_LOWPASS_IIR_FILTER, MIXER_BANDPASS_IIR_FILTER or MIXER_HIGHPASS_IIR_FILTER */ + OMX_S32 F0[MIXER_NUM_PARA_EQ_FILTERS]; /**< Frequency array in Hz (Range 0 - Fs/2) */ + OMX_S32 BndWdth[MIXER_NUM_PARA_EQ_FILTERS]; /**< Bandwidth array in Hz (Range 0 - Fs/2) */ + OMX_S32 dBGain[MIXER_NUM_PARA_EQ_FILTERS]; /**< Decibel gain array in dB (Limit +/- 12.0 dB) */ +}NVX_CONFIG_AUDIO_PARAEQFILTER; + +/** Config extension index to query audio session id from audio renderer + * Use OMX_PARAM_U32TYPE in GetConfig() + */ +#define NVX_INDEX_CONFIG_AUDIO_SESSION_ID "OMX.Nvidia.index.config.audiosessionid" + +/** @} */ +#endif + +/* File EOF */ diff --git a/omx/openmax/NVOMX_TrackList.h b/omx/openmax/NVOMX_TrackList.h new file mode 100644 index 0000000..b8e5a3e --- /dev/null +++ b/omx/openmax/NVOMX_TrackList.h @@ -0,0 +1,192 @@ +/* Copyright (c) 2008 NVIDIA Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file + * <b>NVIDIA Tegra: OpenMAX Container Tracklist Extension Interface</b> + * + */ + +#ifndef NVOMX_TrackList_h +#define NVOMX_TrackList_h + +/*************************************************************** + **** THIS INTERFACE IS DEPRECATED AND NO LONGER SUPPORTED **** + ***************************************************************/ + +/** + * @defgroup nv_omx_il_tracklist Tracklist + * + * This is the NVIDIA OpenMAX container demux class tracklist interface extension. + * + * It defines the container extension interface to play multiple files with one graph + * as well as support for gapless audio playback. + * + * @ingroup nvomx_container_extension + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include <OMX_Core.h> + +/** + * If NvxTrack_AutoAdvance is set, the next track will automatically be + * played + */ +typedef enum +{ + NvxTrack_NoFlags = 0x00000000, + NvxTrack_AutoAdvance = 0x00000001, + + NvxTrack_Force32 = 0x7FFFFFFF +} NvxTrackFlags; + +/** + * Filetypes to override the automatic detection. + */ +typedef enum +{ + NvxType_Default = 0, // Generally, use this. + NvxType_Asf, // asf, wma, wmv + NvxType_3gp, // mov, 3gp, m4a, m4v + NvxType_Avi, + NvxType_Mp3, + NvxType_Ogg, + NvxType_Ogm, + NvxType_Wav, + NvxType_Mkv, // mkv + NvxType_Force32 = 0x7FFFFFFF +} NvxFileType; +/** + * Holds information about a single track. + * + * pClientPrivate may be set to anything the IL client desires + * + * pPath _must_ be in UTF-8. + */ +typedef struct NvxTrackInfoRec +{ + NvxTrackFlags eTrackFlag; + void *pClientPrivate; + OMX_U32 uSize; + OMX_U8 *pPath; + NvxFileType eType; +} NvxTrackInfo; + +typedef OMX_HANDLETYPE NvxTrackList; + +/** + * Get/Set a tracklist handle. + * + * Get the handle from the parser component, and set it on all other components + * in the chain (ie, audio decoder, audio renderer). + */ +#define NVX_INDEX_CONFIG_TRACKLIST "OMX.Nvidia.index.config.tracklist" +/** Holds a tracklist handle. */ +typedef struct NVX_CONFIG_TRACKLIST +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + NvxTrackList hTrackList; /**< Tracklist handle */ +} NVX_CONFIG_TRACKLIST; + +/** + * Add/Get a track. + * + * Add a track to the specified position (uIndex) with SetConfig. + * Get info on a track at the specified position (uIndex) with GetConfig. + * + * Only valid on the parser component. + */ +#define NVX_INDEX_CONFIG_TRACKLIST_TRACK "OMX.Nvidia.index.config.tracklist.track" +/** Holds tracklist information. */ +typedef struct NVX_CONFIG_TRACKLIST_TRACK +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 uIndex; /**< Index of track */ + NvxTrackInfo *pTrackInfo; /**< Track information */ +} NVX_CONFIG_TRACKLIST_TRACK; + +/** + * Delete tracks from a tracklist. + * + * Use -1 for nIndex to delete all tracks from the tracklist. + * + * Only valid on the parser component. + */ +#define NVX_INDEX_CONFIG_TRACKLIST_DELETE "OMX.Nvidia.index.config.tracklist.delete" +/** Holds a tracklist index. */ +typedef struct NVX_CONFIG_TRACKLIST_DELETE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_S32 nIndex; /**< Index of track to delete */ +} NVX_CONFIG_TRACKLIST_DELETE; + +/** + * Query the size of the tracklist. + * + * Only valid as a GetConfig on the parser component. + */ +#define NVX_INDEX_CONFIG_TRACKLIST_SIZE "OMX.Nvidia.index.config.tracklist.size" +/** Holds a tracklist size. */ +typedef struct NVX_CONFIG_TRACKLIST_SIZE +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 uTracklistSize; /**< Number of tracks in the tracklist */ +} NVX_CONFIG_TRACKLIST_SIZE; + +/** + * Get/Set the current track. + * + * pTrackInfo will be filled on GetConfig, and unused on SetConfig. + * + * Only valid on the parser component. + */ +#define NVX_INDEX_CONFIG_TRACKLIST_CURRENT "OMX.Nvidia.index.config.tracklist.current" +/** Holds tracklist information. */ +typedef struct NVX_CONFIG_TRACKLIST_CURRENT +{ + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< NVX extensions specification version information */ + OMX_U32 uIndex; /**< Index of track to query info from */ + NvxTrackInfo *pTrackInfo; /**< Track information */ +} NVX_CONFIG_TRACKLIST_CURRENT; + +/** + * This event will be sent when a track is finished playing + */ +#define NVX_EventTrackFinished 0x7A000001 + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/** @} */ +#endif + +/* File EOF */ + diff --git a/omx/openmax/OMX_Component.h b/omx/openmax/OMX_Component.h index d595640..4005699 100644 --- a/omx/openmax/OMX_Component.h +++ b/omx/openmax/OMX_Component.h @@ -391,7 +391,7 @@ typedef struct OMX_COMPONENTTYPE */ OMX_ERRORTYPE (*GetExtensionIndex)( OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_STRING cParameterName, + OMX_IN OMX_CSTRING cParameterName, OMX_OUT OMX_INDEXTYPE* pIndexType); @@ -571,6 +571,52 @@ typedef struct OMX_COMPONENTTYPE } OMX_COMPONENTTYPE; +typedef enum OMX_MEDIACONTAINER_FORMATTYPE { + OMX_FORMAT_RAW = 0, + OMX_FORMAT_MP4, + OMX_FORMAT_3GP, + OMX_FORMAT_3G2, + OMX_FORMAT_AMC, + OMX_FORMAT_SKM, + OMX_FORMAT_K3G, + OMX_FORMAT_VOB, + OMX_FORMAT_AVI, + OMX_FORMAT_ASF, + OMX_FORMAT_RM, + OMX_FORMAT_MPEG_ES, + OMX_FORMAT_DIVX, + OMX_FORMAT_MPEG_TS, + OMX_FORMAT_QT, + OMX_FORMAT_M4A, + OMX_FORMAT_MP3, + OMX_FORMAT_WAVE, + OMX_FORMAT_XMF, + OMX_FORMAT_AMR, + OMX_FORMAT_AAC, + OMX_FORMAT_EVRC, + OMX_FORMAT_QCP, + OMX_FORMAT_SMF, + OMX_FORMAT_OGG, + OMX_FORMAT_BMP, + OMX_FORMAT_JPG, + OMX_FORMAT_JPG2000, + OMX_FORMAT_MKV, + OMX_FORMAT_FLV, + OMX_FORMAT_M4V, + OMX_FORMAT_F4V, + OMX_FORMAT_WEBM, + OMX_FORMAT_WEBP, + OMX_FORMATKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_FORMATVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_FORMATMax= 0x7FFFFFFF +} OMX_MEDIACONTAINER_FORMATTYPE; + +typedef struct OMX_MEDIACONTAINER_INFOTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_MEDIACONTAINER_FORMATTYPE eFmtType; +} OMX_MEDIACONTAINER_INFOTYPE; + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/omx/openmax/OMX_Index.h b/omx/openmax/OMX_Index.h index 44d4ea7..199c56b 100644 --- a/omx/openmax/OMX_Index.h +++ b/omx/openmax/OMX_Index.h @@ -60,146 +60,147 @@ extern "C" { typedef enum OMX_INDEXTYPE { OMX_IndexComponentStartUnused = 0x01000000, - OMX_IndexParamPriorityMgmt, /**< reference: OMX_PRIORITYMGMTTYPE */ - OMX_IndexParamAudioInit, /**< reference: OMX_PORT_PARAM_TYPE */ - OMX_IndexParamImageInit, /**< reference: OMX_PORT_PARAM_TYPE */ - OMX_IndexParamVideoInit, /**< reference: OMX_PORT_PARAM_TYPE */ - OMX_IndexParamOtherInit, /**< reference: OMX_PORT_PARAM_TYPE */ - OMX_IndexParamNumAvailableStreams, /**< reference: OMX_PARAM_U32TYPE */ - OMX_IndexParamActiveStream, /**< reference: OMX_PARAM_U32TYPE */ - OMX_IndexParamSuspensionPolicy, /**< reference: OMX_PARAM_SUSPENSIONPOLICYTYPE */ - OMX_IndexParamComponentSuspended, /**< reference: OMX_PARAM_SUSPENSIONTYPE */ - OMX_IndexConfigCapturing, /**< reference: OMX_CONFIG_BOOLEANTYPE */ - OMX_IndexConfigCaptureMode, /**< reference: OMX_CONFIG_CAPTUREMODETYPE */ - OMX_IndexAutoPauseAfterCapture, /**< reference: OMX_CONFIG_BOOLEANTYPE */ - OMX_IndexParamContentURI, /**< reference: OMX_PARAM_CONTENTURITYPE */ - OMX_IndexParamCustomContentPipe, /**< reference: OMX_PARAM_CONTENTPIPETYPE */ + OMX_IndexParamPriorityMgmt, /**< reference: OMX_PRIORITYMGMTTYPE */ + OMX_IndexParamAudioInit, /**< reference: OMX_PORT_PARAM_TYPE */ + OMX_IndexParamImageInit, /**< reference: OMX_PORT_PARAM_TYPE */ + OMX_IndexParamVideoInit, /**< reference: OMX_PORT_PARAM_TYPE */ + OMX_IndexParamOtherInit, /**< reference: OMX_PORT_PARAM_TYPE */ + OMX_IndexParamNumAvailableStreams, /**< reference: OMX_PARAM_U32TYPE */ + OMX_IndexParamActiveStream, /**< reference: OMX_PARAM_U32TYPE */ + OMX_IndexParamSuspensionPolicy, /**< reference: OMX_PARAM_SUSPENSIONPOLICYTYPE */ + OMX_IndexParamComponentSuspended, /**< reference: OMX_PARAM_SUSPENSIONTYPE */ + OMX_IndexConfigCapturing, /**< reference: OMX_CONFIG_BOOLEANTYPE */ + OMX_IndexConfigCaptureMode, /**< reference: OMX_CONFIG_CAPTUREMODETYPE */ + OMX_IndexAutoPauseAfterCapture, /**< reference: OMX_CONFIG_BOOLEANTYPE */ + OMX_IndexParamContentURI, /**< reference: OMX_PARAM_CONTENTURITYPE */ + OMX_IndexParamCustomContentPipe, /**< reference: OMX_PARAM_CONTENTPIPETYPE */ OMX_IndexParamDisableResourceConcealment, /**< reference: OMX_RESOURCECONCEALMENTTYPE */ - OMX_IndexConfigMetadataItemCount, /**< reference: OMX_CONFIG_METADATAITEMCOUNTTYPE */ - OMX_IndexConfigContainerNodeCount, /**< reference: OMX_CONFIG_CONTAINERNODECOUNTTYPE */ - OMX_IndexConfigMetadataItem, /**< reference: OMX_CONFIG_METADATAITEMTYPE */ - OMX_IndexConfigCounterNodeID, /**< reference: OMX_CONFIG_CONTAINERNODEIDTYPE */ - OMX_IndexParamMetadataFilterType, /**< reference: OMX_PARAM_METADATAFILTERTYPE */ - OMX_IndexParamMetadataKeyFilter, /**< reference: OMX_PARAM_METADATAFILTERTYPE */ - OMX_IndexConfigPriorityMgmt, /**< reference: OMX_PRIORITYMGMTTYPE */ - OMX_IndexParamStandardComponentRole, /**< reference: OMX_PARAM_COMPONENTROLETYPE */ + OMX_IndexConfigMetadataItemCount, /**< reference: OMX_CONFIG_METADATAITEMCOUNTTYPE */ + OMX_IndexConfigContainerNodeCount, /**< reference: OMX_CONFIG_CONTAINERNODECOUNTTYPE */ + OMX_IndexConfigMetadataItem, /**< reference: OMX_CONFIG_METADATAITEMTYPE */ + OMX_IndexConfigCounterNodeID, /**< reference: OMX_CONFIG_CONTAINERNODEIDTYPE */ + OMX_IndexParamMetadataFilterType, /** < reference: OMX_PARAM_METADATAFILTERTYPE */ + OMX_IndexParamMetadataKeyFilter, /**< reference: OMX_PARAM_METADATAFILTERTYPE */ + OMX_IndexConfigPriorityMgmt, /**< reference: OMX_PRIORITYMGMTTYPE */ + OMX_IndexParamStandardComponentRole, /**< reference: OMX_PARAM_COMPONENTROLETYPE */ OMX_IndexPortStartUnused = 0x02000000, - OMX_IndexParamPortDefinition, /**< reference: OMX_PARAM_PORTDEFINITIONTYPE */ - OMX_IndexParamCompBufferSupplier, /**< reference: OMX_PARAM_BUFFERSUPPLIERTYPE */ + OMX_IndexParamPortDefinition, /**< reference: OMX_PARAM_PORTDEFINITIONTYPE */ + OMX_IndexParamCompBufferSupplier, /**< reference: OMX_PARAM_BUFFERSUPPLIERTYPE */ OMX_IndexReservedStartUnused = 0x03000000, /* Audio parameters and configurations */ OMX_IndexAudioStartUnused = 0x04000000, - OMX_IndexParamAudioPortFormat, /**< reference: OMX_AUDIO_PARAM_PORTFORMATTYPE */ - OMX_IndexParamAudioPcm, /**< reference: OMX_AUDIO_PARAM_PCMMODETYPE */ - OMX_IndexParamAudioAac, /**< reference: OMX_AUDIO_PARAM_AACPROFILETYPE */ - OMX_IndexParamAudioRa, /**< reference: OMX_AUDIO_PARAM_RATYPE */ - OMX_IndexParamAudioMp3, /**< reference: OMX_AUDIO_PARAM_MP3TYPE */ - OMX_IndexParamAudioAdpcm, /**< reference: OMX_AUDIO_PARAM_ADPCMTYPE */ - OMX_IndexParamAudioG723, /**< reference: OMX_AUDIO_PARAM_G723TYPE */ - OMX_IndexParamAudioG729, /**< reference: OMX_AUDIO_PARAM_G729TYPE */ - OMX_IndexParamAudioAmr, /**< reference: OMX_AUDIO_PARAM_AMRTYPE */ - OMX_IndexParamAudioWma, /**< reference: OMX_AUDIO_PARAM_WMATYPE */ - OMX_IndexParamAudioSbc, /**< reference: OMX_AUDIO_PARAM_SBCTYPE */ - OMX_IndexParamAudioMidi, /**< reference: OMX_AUDIO_PARAM_MIDITYPE */ + OMX_IndexParamAudioPortFormat, /**< reference: OMX_AUDIO_PARAM_PORTFORMATTYPE */ + OMX_IndexParamAudioPcm, /**< reference: OMX_AUDIO_PARAM_PCMMODETYPE */ + OMX_IndexParamAudioAac, /**< reference: OMX_AUDIO_PARAM_AACPROFILETYPE */ + OMX_IndexParamAudioRa, /**< reference: OMX_AUDIO_PARAM_RATYPE */ + OMX_IndexParamAudioMp3, /**< reference: OMX_AUDIO_PARAM_MP3TYPE */ + OMX_IndexParamAudioAdpcm, /**< reference: OMX_AUDIO_PARAM_ADPCMTYPE */ + OMX_IndexParamAudioG723, /**< reference: OMX_AUDIO_PARAM_G723TYPE */ + OMX_IndexParamAudioG729, /**< reference: OMX_AUDIO_PARAM_G729TYPE */ + OMX_IndexParamAudioAmr, /**< reference: OMX_AUDIO_PARAM_AMRTYPE */ + OMX_IndexParamAudioWma, /**< reference: OMX_AUDIO_PARAM_WMATYPE */ + OMX_IndexParamAudioSbc, /**< reference: OMX_AUDIO_PARAM_SBCTYPE */ + OMX_IndexParamAudioMidi, /**< reference: OMX_AUDIO_PARAM_MIDITYPE */ OMX_IndexParamAudioGsm_FR, /**< reference: OMX_AUDIO_PARAM_GSMFRTYPE */ - OMX_IndexParamAudioMidiLoadUserSound, /**< reference: OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE */ - OMX_IndexParamAudioG726, /**< reference: OMX_AUDIO_PARAM_G726TYPE */ - OMX_IndexParamAudioGsm_EFR, /**< reference: OMX_AUDIO_PARAM_GSMEFRTYPE */ - OMX_IndexParamAudioGsm_HR, /**< reference: OMX_AUDIO_PARAM_GSMHRTYPE */ - OMX_IndexParamAudioPdc_FR, /**< reference: OMX_AUDIO_PARAM_PDCFRTYPE */ - OMX_IndexParamAudioPdc_EFR, /**< reference: OMX_AUDIO_PARAM_PDCEFRTYPE */ - OMX_IndexParamAudioPdc_HR, /**< reference: OMX_AUDIO_PARAM_PDCHRTYPE */ - OMX_IndexParamAudioTdma_FR, /**< reference: OMX_AUDIO_PARAM_TDMAFRTYPE */ - OMX_IndexParamAudioTdma_EFR, /**< reference: OMX_AUDIO_PARAM_TDMAEFRTYPE */ - OMX_IndexParamAudioQcelp8, /**< reference: OMX_AUDIO_PARAM_QCELP8TYPE */ - OMX_IndexParamAudioQcelp13, /**< reference: OMX_AUDIO_PARAM_QCELP13TYPE */ - OMX_IndexParamAudioEvrc, /**< reference: OMX_AUDIO_PARAM_EVRCTYPE */ - OMX_IndexParamAudioSmv, /**< reference: OMX_AUDIO_PARAM_SMVTYPE */ - OMX_IndexParamAudioVorbis, /**< reference: OMX_AUDIO_PARAM_VORBISTYPE */ + OMX_IndexParamAudioMidiLoadUserSound, /**< reference: OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE */ + OMX_IndexParamAudioG726, /**< reference: OMX_AUDIO_PARAM_G726TYPE */ + OMX_IndexParamAudioGsm_EFR, /**< reference: OMX_AUDIO_PARAM_GSMEFRTYPE */ + OMX_IndexParamAudioGsm_HR, /**< reference: OMX_AUDIO_PARAM_GSMHRTYPE */ + OMX_IndexParamAudioPdc_FR, /**< reference: OMX_AUDIO_PARAM_PDCFRTYPE */ + OMX_IndexParamAudioPdc_EFR, /**< reference: OMX_AUDIO_PARAM_PDCEFRTYPE */ + OMX_IndexParamAudioPdc_HR, /**< reference: OMX_AUDIO_PARAM_PDCHRTYPE */ + OMX_IndexParamAudioTdma_FR, /**< reference: OMX_AUDIO_PARAM_TDMAFRTYPE */ + OMX_IndexParamAudioTdma_EFR, /**< reference: OMX_AUDIO_PARAM_TDMAEFRTYPE */ + OMX_IndexParamAudioQcelp8, /**< reference: OMX_AUDIO_PARAM_QCELP8TYPE */ + OMX_IndexParamAudioQcelp13, /**< reference: OMX_AUDIO_PARAM_QCELP13TYPE */ + OMX_IndexParamAudioEvrc, /**< reference: OMX_AUDIO_PARAM_EVRCTYPE */ + OMX_IndexParamAudioSmv, /**< reference: OMX_AUDIO_PARAM_SMVTYPE */ + OMX_IndexParamAudioVorbis, /**< reference: OMX_AUDIO_PARAM_VORBISTYPE */ OMX_IndexConfigAudioMidiImmediateEvent, /**< reference: OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE */ - OMX_IndexConfigAudioMidiControl, /**< reference: OMX_AUDIO_CONFIG_MIDICONTROLTYPE */ + OMX_IndexConfigAudioMidiControl, /**< reference: OMX_AUDIO_CONFIG_MIDICONTROLTYPE */ OMX_IndexConfigAudioMidiSoundBankProgram, /**< reference: OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE */ - OMX_IndexConfigAudioMidiStatus, /**< reference: OMX_AUDIO_CONFIG_MIDISTATUSTYPE */ - OMX_IndexConfigAudioMidiMetaEvent, /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE */ - OMX_IndexConfigAudioMidiMetaEventData, /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE */ - OMX_IndexConfigAudioVolume, /**< reference: OMX_AUDIO_CONFIG_VOLUMETYPE */ - OMX_IndexConfigAudioBalance, /**< reference: OMX_AUDIO_CONFIG_BALANCETYPE */ - OMX_IndexConfigAudioChannelMute, /**< reference: OMX_AUDIO_CONFIG_CHANNELMUTETYPE */ - OMX_IndexConfigAudioMute, /**< reference: OMX_AUDIO_CONFIG_MUTETYPE */ - OMX_IndexConfigAudioLoudness, /**< reference: OMX_AUDIO_CONFIG_LOUDNESSTYPE */ - OMX_IndexConfigAudioEchoCancelation, /**< reference: OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE */ - OMX_IndexConfigAudioNoiseReduction, /**< reference: OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE */ - OMX_IndexConfigAudioBass, /**< reference: OMX_AUDIO_CONFIG_BASSTYPE */ - OMX_IndexConfigAudioTreble, /**< reference: OMX_AUDIO_CONFIG_TREBLETYPE */ - OMX_IndexConfigAudioStereoWidening, /**< reference: OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE */ - OMX_IndexConfigAudioChorus, /**< reference: OMX_AUDIO_CONFIG_CHORUSTYPE */ - OMX_IndexConfigAudioEqualizer, /**< reference: OMX_AUDIO_CONFIG_EQUALIZERTYPE */ - OMX_IndexConfigAudioReverberation, /**< reference: OMX_AUDIO_CONFIG_REVERBERATIONTYPE */ - OMX_IndexConfigAudioChannelVolume, /**< reference: OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE */ + OMX_IndexConfigAudioMidiStatus, /**< reference: OMX_AUDIO_CONFIG_MIDISTATUSTYPE */ + OMX_IndexConfigAudioMidiMetaEvent, /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE */ + OMX_IndexConfigAudioMidiMetaEventData, /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE */ + OMX_IndexConfigAudioVolume, /**< reference: OMX_AUDIO_CONFIG_VOLUMETYPE */ + OMX_IndexConfigAudioBalance, /**< reference: OMX_AUDIO_CONFIG_BALANCETYPE */ + OMX_IndexConfigAudioChannelMute, /**< reference: OMX_AUDIO_CONFIG_CHANNELMUTETYPE */ + OMX_IndexConfigAudioMute, /**< reference: OMX_AUDIO_CONFIG_MUTETYPE */ + OMX_IndexConfigAudioLoudness, /**< reference: OMX_AUDIO_CONFIG_LOUDNESSTYPE */ + OMX_IndexConfigAudioEchoCancelation, /**< reference: OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE */ + OMX_IndexConfigAudioNoiseReduction, /**< reference: OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE */ + OMX_IndexConfigAudioBass, /**< reference: OMX_AUDIO_CONFIG_BASSTYPE */ + OMX_IndexConfigAudioTreble, /**< reference: OMX_AUDIO_CONFIG_TREBLETYPE */ + OMX_IndexConfigAudioStereoWidening, /**< reference: OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE */ + OMX_IndexConfigAudioChorus, /**< reference: OMX_AUDIO_CONFIG_CHORUSTYPE */ + OMX_IndexConfigAudioEqualizer, /**< reference: OMX_AUDIO_CONFIG_EQUALIZERTYPE */ + OMX_IndexConfigAudioReverberation, /**< reference: OMX_AUDIO_CONFIG_REVERBERATIONTYPE */ + OMX_IndexConfigAudioChannelVolume, /**< reference: OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE */ /* Image specific parameters and configurations */ OMX_IndexImageStartUnused = 0x05000000, - OMX_IndexParamImagePortFormat, /**< reference: OMX_IMAGE_PARAM_PORTFORMATTYPE */ + OMX_IndexParamImagePortFormat, /**< reference: OMX_IMAGE_PARAM_PORTFORMATTYPE */ OMX_IndexParamFlashControl, /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */ OMX_IndexConfigFocusControl, /**< reference: OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE */ OMX_IndexParamQFactor, /**< reference: OMX_IMAGE_PARAM_QFACTORTYPE */ OMX_IndexParamQuantizationTable, /**< reference: OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE */ OMX_IndexParamHuffmanTable, /**< reference: OMX_IMAGE_PARAM_HUFFMANTTABLETYPE */ OMX_IndexConfigFlashControl, /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */ + OMX_IndexConfigCILThreshold, /**< reference: OMX_PARAM_U32TYPE */ /* Video specific parameters and configurations */ OMX_IndexVideoStartUnused = 0x06000000, - OMX_IndexParamVideoPortFormat, /**< reference: OMX_VIDEO_PARAM_PORTFORMATTYPE */ + OMX_IndexParamVideoPortFormat, /**< reference: OMX_VIDEO_PARAM_PORTFORMATTYPE */ OMX_IndexParamVideoQuantization, /**< reference: OMX_VIDEO_PARAM_QUANTIZATIONTYPE */ - OMX_IndexParamVideoFastUpdate, /**< reference: OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE */ - OMX_IndexParamVideoBitrate, /**< reference: OMX_VIDEO_PARAM_BITRATETYPE */ - OMX_IndexParamVideoMotionVector, /**< reference: OMX_VIDEO_PARAM_MOTIONVECTORTYPE */ - OMX_IndexParamVideoIntraRefresh, /**< reference: OMX_VIDEO_PARAM_INTRAREFRESHTYPE */ - OMX_IndexParamVideoErrorCorrection, /**< reference: OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE */ - OMX_IndexParamVideoVBSMC, /**< reference: OMX_VIDEO_PARAM_VBSMCTYPE */ - OMX_IndexParamVideoMpeg2, /**< reference: OMX_VIDEO_PARAM_MPEG2TYPE */ + OMX_IndexParamVideoFastUpdate, /**< reference: OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE */ + OMX_IndexParamVideoBitrate, /**< reference: OMX_VIDEO_PARAM_BITRATETYPE */ + OMX_IndexParamVideoMotionVector, /**< reference: OMX_VIDEO_PARAM_MOTIONVECTORTYPE */ + OMX_IndexParamVideoIntraRefresh, /**< reference: OMX_VIDEO_PARAM_INTRAREFRESHTYPE */ + OMX_IndexParamVideoErrorCorrection, /**< reference: OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE */ + OMX_IndexParamVideoVBSMC, /**< reference:OMX_VIDEO_PARAM_VBSMCTYPE */ + OMX_IndexParamVideoMpeg2, /**< reference:OMX_VIDEO_PARAM_MPEG2TYPE */ OMX_IndexParamVideoMpeg4, /**< reference: OMX_VIDEO_PARAM_MPEG4TYPE */ - OMX_IndexParamVideoWmv, /**< reference: OMX_VIDEO_PARAM_WMVTYPE */ - OMX_IndexParamVideoRv, /**< reference: OMX_VIDEO_PARAM_RVTYPE */ - OMX_IndexParamVideoAvc, /**< reference: OMX_VIDEO_PARAM_AVCTYPE */ - OMX_IndexParamVideoH263, /**< reference: OMX_VIDEO_PARAM_H263TYPE */ + OMX_IndexParamVideoWmv, /**< reference:OMX_VIDEO_PARAM_WMVTYPE */ + OMX_IndexParamVideoRv, /**< reference:OMX_VIDEO_PARAM_RVTYPE */ + OMX_IndexParamVideoAvc, /**< reference:OMX_VIDEO_PARAM_AVCTYPE */ + OMX_IndexParamVideoH263, /**< reference:OMX_VIDEO_PARAM_H263TYPE */ OMX_IndexParamVideoProfileLevelQuerySupported, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */ OMX_IndexParamVideoProfileLevelCurrent, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */ - OMX_IndexConfigVideoBitrate, /**< reference: OMX_VIDEO_CONFIG_BITRATETYPE */ + OMX_IndexConfigVideoBitrate, /**< reference: OMX_VIDEO_CONFIG_BITRATETYPE */ OMX_IndexConfigVideoFramerate, /**< reference: OMX_CONFIG_FRAMERATETYPE */ - OMX_IndexConfigVideoIntraVOPRefresh, /**< reference: OMX_CONFIG_INTRAREFRESHVOPTYPE */ - OMX_IndexConfigVideoIntraMBRefresh, /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */ - OMX_IndexConfigVideoMBErrorReporting, /**< reference: OMX_CONFIG_MBERRORREPORTINGTYPE */ + OMX_IndexConfigVideoIntraVOPRefresh, /**< reference: OMX_CONFIG_INTRAREFRESHVOPTYPE */ + OMX_IndexConfigVideoIntraMBRefresh, /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */ + OMX_IndexConfigVideoMBErrorReporting, /**< reference: OMX_CONFIG_MBERRORREPORTINGTYPE */ OMX_IndexParamVideoMacroblocksPerFrame, /**< reference: OMX_PARAM_MACROBLOCKSTYPE */ OMX_IndexConfigVideoMacroBlockErrorMap, /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */ - OMX_IndexParamVideoSliceFMO, /**< reference: OMX_VIDEO_PARAM_AVCSLICEFMO */ + OMX_IndexParamVideoSliceFMO, /**< reference: OMX_VIDEO_PARAM_AVCSLICEFMO */ OMX_IndexConfigVideoAVCIntraPeriod, /**< reference: OMX_VIDEO_CONFIG_AVCINTRAPERIOD */ OMX_IndexConfigVideoNalSize, /**< reference: OMX_VIDEO_CONFIG_NALSIZE */ /* Image & Video common Configurations */ OMX_IndexCommonStartUnused = 0x07000000, - OMX_IndexParamCommonDeblocking, /**< reference: OMX_PARAM_DEBLOCKINGTYPE */ - OMX_IndexParamCommonSensorMode, /**< reference: OMX_PARAM_SENSORMODETYPE */ + OMX_IndexParamCommonDeblocking, /**< reference: OMX_PARAM_DEBLOCKINGTYPE */ + OMX_IndexParamCommonSensorMode, /**< reference: OMX_PARAM_SENSORMODETYPE */ OMX_IndexParamCommonInterleave, /**< reference: OMX_PARAM_INTERLEAVETYPE */ - OMX_IndexConfigCommonColorFormatConversion, /**< reference: OMX_CONFIG_COLORCONVERSIONTYPE */ - OMX_IndexConfigCommonScale, /**< reference: OMX_CONFIG_SCALEFACTORTYPE */ - OMX_IndexConfigCommonImageFilter, /**< reference: OMX_CONFIG_IMAGEFILTERTYPE */ - OMX_IndexConfigCommonColorEnhancement, /**< reference: OMX_CONFIG_COLORENHANCEMENTTYPE */ - OMX_IndexConfigCommonColorKey, /**< reference: OMX_CONFIG_COLORKEYTYPE */ - OMX_IndexConfigCommonColorBlend, /**< reference: OMX_CONFIG_COLORBLENDTYPE */ - OMX_IndexConfigCommonFrameStabilisation,/**< reference: OMX_CONFIG_FRAMESTABTYPE */ - OMX_IndexConfigCommonRotate, /**< reference: OMX_CONFIG_ROTATIONTYPE */ - OMX_IndexConfigCommonMirror, /**< reference: OMX_CONFIG_MIRRORTYPE */ - OMX_IndexConfigCommonOutputPosition, /**< reference: OMX_CONFIG_POINTTYPE */ - OMX_IndexConfigCommonInputCrop, /**< reference: OMX_CONFIG_RECTTYPE */ - OMX_IndexConfigCommonOutputCrop, /**< reference: OMX_CONFIG_RECTTYPE */ - OMX_IndexConfigCommonDigitalZoom, /**< reference: OMX_CONFIG_SCALEFACTORTYPE */ - OMX_IndexConfigCommonOpticalZoom, /**< reference: OMX_CONFIG_SCALEFACTORTYPE*/ - OMX_IndexConfigCommonWhiteBalance, /**< reference: OMX_CONFIG_WHITEBALCONTROLTYPE */ - OMX_IndexConfigCommonExposure, /**< reference: OMX_CONFIG_EXPOSURECONTROLTYPE */ + OMX_IndexConfigCommonColorFormatConversion, /**< reference: OMX_CONFIG_COLORCONVERSIONTYPE */ + OMX_IndexConfigCommonScale, /**< reference: OMX_CONFIG_SCALEFACTORTYPE */ + OMX_IndexConfigCommonImageFilter, /**< reference: OMX_CONFIG_IMAGEFILTERTYPE */ + OMX_IndexConfigCommonColorEnhancement, /**< reference: OMX_CONFIG_COLORENHANCEMENTTYPE */ + OMX_IndexConfigCommonColorKey, /**< reference: OMX_CONFIG_COLORKEYTYPE */ + OMX_IndexConfigCommonColorBlend, /**< reference: OMX_CONFIG_COLORBLENDTYPE */ + OMX_IndexConfigCommonFrameStabilisation, /**< reference: OMX_CONFIG_FRAMESTABTYPE */ + OMX_IndexConfigCommonRotate, /**< reference: OMX_CONFIG_ROTATIONTYPE */ + OMX_IndexConfigCommonMirror, /**< reference: OMX_CONFIG_MIRRORTYPE */ + OMX_IndexConfigCommonOutputPosition, /**< reference: OMX_CONFIG_POINTTYPE */ + OMX_IndexConfigCommonInputCrop, /**< reference: OMX_CONFIG_RECTTYPE */ + OMX_IndexConfigCommonOutputCrop, /**< reference: OMX_CONFIG_RECTTYPE */ + OMX_IndexConfigCommonDigitalZoom, /**< reference: OMX_CONFIG_SCALEFACTORTYPE */ + OMX_IndexConfigCommonOpticalZoom, /**< reference: OMX_CONFIG_SCALEFACTORTYPE*/ + OMX_IndexConfigCommonWhiteBalance, /**< reference: OMX_CONFIG_WHITEBALCONTROLTYPE */ + OMX_IndexConfigCommonExposure, /**< reference: OMX_CONFIG_EXPOSURECONTROLTYPE */ OMX_IndexConfigCommonContrast, /**< reference: OMX_CONFIG_CONTRASTTYPE */ OMX_IndexConfigCommonBrightness, /**< reference: OMX_CONFIG_BRIGHTNESSTYPE */ OMX_IndexConfigCommonBacklight, /**< reference: OMX_CONFIG_BACKLIGHTTYPE */ @@ -209,34 +210,41 @@ typedef enum OMX_INDEXTYPE { OMX_IndexConfigCommonExclusionRect, /**< reference: OMX_CONFIG_RECTTYPE */ OMX_IndexConfigCommonDithering, /**< reference: OMX_CONFIG_DITHERTYPE */ OMX_IndexConfigCommonPlaneBlend, /**< reference: OMX_CONFIG_PLANEBLENDTYPE */ - OMX_IndexConfigCommonExposureValue, /**< reference: OMX_CONFIG_EXPOSUREVALUETYPE */ - OMX_IndexConfigCommonOutputSize, /**< reference: OMX_FRAMESIZETYPE */ - OMX_IndexParamCommonExtraQuantData, /**< reference: OMX_OTHER_EXTRADATATYPE */ + OMX_IndexConfigCommonExposureValue, /**< reference: OMX_CONFIG_EXPOSUREVALUETYPE */ + OMX_IndexConfigCommonOutputSize, /**< reference: OMX_FRAMESIZETYPE */ + OMX_IndexParamCommonExtraQuantData, /**< reference: OMX_OTHER_EXTRADATATYPE */ OMX_IndexConfigCommonFocusRegion, /**< reference: OMX_CONFIG_FOCUSREGIONTYPE */ OMX_IndexConfigCommonFocusStatus, /**< reference: OMX_PARAM_FOCUSSTATUSTYPE */ OMX_IndexConfigCommonTransitionEffect, /**< reference: OMX_CONFIG_TRANSITIONEFFECTTYPE */ /* Reserved Configuration range */ OMX_IndexOtherStartUnused = 0x08000000, - OMX_IndexParamOtherPortFormat, /**< reference: OMX_OTHER_PARAM_PORTFORMATTYPE */ - OMX_IndexConfigOtherPower, /**< reference: OMX_OTHER_CONFIG_POWERTYPE */ - OMX_IndexConfigOtherStats, /**< reference: OMX_OTHER_CONFIG_STATSTYPE */ + OMX_IndexParamOtherPortFormat, /**< reference: OMX_OTHER_PARAM_PORTFORMATTYPE */ + OMX_IndexConfigOtherPower, /**< reference: OMX_OTHER_CONFIG_POWERTYPE */ + OMX_IndexConfigOtherStats, /**< reference: OMX_OTHER_CONFIG_STATSTYPE */ /* Reserved Time range */ OMX_IndexTimeStartUnused = 0x09000000, - OMX_IndexConfigTimeScale, /**< reference: OMX_TIME_CONFIG_SCALETYPE */ - OMX_IndexConfigTimeClockState, /**< reference: OMX_TIME_CONFIG_CLOCKSTATETYPE */ - OMX_IndexConfigTimeActiveRefClock, /**< reference: OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE */ - OMX_IndexConfigTimeCurrentMediaTime, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */ - OMX_IndexConfigTimeCurrentWallTime, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */ + OMX_IndexConfigTimeScale, /**< reference: OMX_TIME_CONFIG_SCALETYPE */ + OMX_IndexConfigTimeClockState, /**< reference: OMX_TIME_CONFIG_CLOCKSTATETYPE */ + OMX_IndexConfigTimeActiveRefClock, /**< reference: OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE */ + OMX_IndexConfigTimeCurrentMediaTime, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only)*/ + OMX_IndexConfigTimeCurrentWallTime, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only)*/ OMX_IndexConfigTimeCurrentAudioReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */ OMX_IndexConfigTimeCurrentVideoReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */ - OMX_IndexConfigTimeMediaTimeRequest, /**< reference: OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE (write only) */ - OMX_IndexConfigTimeClientStartTime, /**<reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */ - OMX_IndexConfigTimePosition, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE */ - OMX_IndexConfigTimeSeekMode, /**< reference: OMX_TIME_CONFIG_SEEKMODETYPE */ + OMX_IndexConfigTimeMediaTimeRequest, /**< reference: OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE (write only) */ + OMX_IndexConfigTimeClientStartTime, /**<reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */ + OMX_IndexConfigTimePosition, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE */ + OMX_IndexConfigTimeSeekMode, /**< reference: OMX_TIME_CONFIG_SEEKMODETYPE */ + /* Common or Domain Independent Time range */ + OMX_IndexCommonIndependentStartUnused = 0x0A000000, + OMX_IndexConfigCommitMode, /**< reference: OMX_CONFIG_COMMITMODETYPE */ + OMX_IndexConfigCommit, /**< reference: OMX_CONFIG_COMMITTYPE */ + OMX_IndexConfigCallbackRequest, /**< reference: OMX_CONFIG_CALLBACKREQUESTTYPE */ + OMX_IndexParamMediaContainer, /**< reference: OMX_MEDIACONTAINER_INFOTYPE */ + OMX_IndexParamReadOnlyBuffers, /**< reference: OMX_CONFIG_PORTBOOLEANTYPE */ OMX_IndexKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ /* Vendor specific area */ diff --git a/omx/openmax/OMX_Types.h b/omx/openmax/OMX_Types.h index 8698358..adfc975 100644 --- a/omx/openmax/OMX_Types.h +++ b/omx/openmax/OMX_Types.h @@ -42,26 +42,26 @@ extern "C" { # ifdef __OMX_EXPORTS # define OMX_API __declspec(dllexport) # else -# ifdef _WIN32 -# define OMX_API __declspec(dllexport) -# else -# define OMX_API __declspec(dllimport) -# endif +#ifdef _WIN32 +# define OMX_API __declspec(dllexport) +# else +# define OMX_API __declspec(dllimport) # endif -#else +#endif +# else # ifdef _WIN32 -# ifdef __OMX_EXPORTS -# define OMX_API __declspec(dllexport) -# else -# define OMX_API __declspec(dllimport) -# endif +# ifdef __OMX_EXPORTS +# define OMX_API __declspec(dllexport) # else -# ifdef __OMX_EXPORTS -# define OMX_API -# else -# define OMX_API extern -# endif +# define OMX_API __declspec(dllimport) # endif +#else +# ifdef __OMX_EXPORTS +# define OMX_API +# else +# define OMX_API extern +# endif +#endif #endif #ifndef OMX_APIENTRY @@ -201,10 +201,17 @@ typedef void* OMX_PTR; /** The OMX_STRING type is intended to be used to pass "C" type strings between the application and the core and component. The OMX_STRING type is a 32 bit pointer to a zero terminated string. The pointer is word aligned and - the string is byte aligned. + the string is byte aligned. */ typedef char* OMX_STRING; +/** The OMX_CSTRING type is intended to be used to pass const "C" type strings + between the application and the core and component. The OMX_STRING type + is a 32 bit pointer to a zero terminated string. The pointer is word + aligned and the string is byte aligned. + */ +typedef const char* OMX_CSTRING; + /** The OMX_BYTE type is intended to be used to pass arrays of bytes such as buffers between the application and the component and core. The OMX_BYTE type is a 32 bit pointer to a zero terminated string. The pointer is word diff --git a/omx/openmax/OMX_Video.h b/omx/openmax/OMX_Video.h index 163e450..dd4aeb1 100644 --- a/omx/openmax/OMX_Video.h +++ b/omx/openmax/OMX_Video.h @@ -497,7 +497,7 @@ typedef struct OMX_VIDEO_PARAM_H263TYPE { OMX_U32 nPFrames; OMX_U32 nBFrames; OMX_VIDEO_H263PROFILETYPE eProfile; - OMX_VIDEO_H263LEVELTYPE eLevel; + OMX_VIDEO_H263LEVELTYPE eLevel; OMX_BOOL bPLUSPTYPEAllowed; OMX_U32 nAllowedPictureTypes; OMX_BOOL bForceRoundingTypeToZero; @@ -557,7 +557,7 @@ typedef struct OMX_VIDEO_PARAM_MPEG2TYPE { OMX_U32 nPFrames; OMX_U32 nBFrames; OMX_VIDEO_MPEG2PROFILETYPE eProfile; - OMX_VIDEO_MPEG2LEVELTYPE eLevel; + OMX_VIDEO_MPEG2LEVELTYPE eLevel; } OMX_VIDEO_PARAM_MPEG2TYPE; @@ -597,7 +597,7 @@ typedef enum OMX_VIDEO_MPEG4PROFILETYPE { OMX_VIDEO_MPEG4ProfileCoreScalable = 0x800, OMX_VIDEO_MPEG4ProfileAdvancedCoding = 0x1000, OMX_VIDEO_MPEG4ProfileAdvancedCore = 0x2000, - OMX_VIDEO_MPEG4ProfileAdvancedScalable = 0x4000, + OMX_VIDEO_MPEG4ProfileAdvancedScalable = 0x4000, OMX_VIDEO_MPEG4ProfileAdvancedSimple = 0x8000, OMX_VIDEO_MPEG4ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ OMX_VIDEO_MPEG4ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ @@ -737,9 +737,9 @@ typedef enum OMX_VIDEO_RVFORMATTYPE { * bEnableTemporalInterpolation : Turn on/off temporal interpolation * bEnableLatencyMode : When enabled, the decoder does not display a decoded * frame until it has detected that no enhancement layer - * frames or dependent B frames will be coming. This - * detection usually occurs when a subsequent non-B - * frame is encountered + * frames or dependent B frames will be coming. This + * detection usually occurs when a subsequent non-B + * frame is encountered */ typedef struct OMX_VIDEO_PARAM_RVTYPE { OMX_U32 nSize; @@ -883,25 +883,25 @@ typedef struct OMX_VIDEO_PARAM_AVCTYPE { OMX_U32 nBFrames; OMX_BOOL bUseHadamard; OMX_U32 nRefFrames; - OMX_U32 nRefIdx10ActiveMinus1; - OMX_U32 nRefIdx11ActiveMinus1; + OMX_U32 nRefIdx10ActiveMinus1; + OMX_U32 nRefIdx11ActiveMinus1; OMX_BOOL bEnableUEP; OMX_BOOL bEnableFMO; OMX_BOOL bEnableASO; OMX_BOOL bEnableRS; OMX_VIDEO_AVCPROFILETYPE eProfile; - OMX_VIDEO_AVCLEVELTYPE eLevel; + OMX_VIDEO_AVCLEVELTYPE eLevel; OMX_U32 nAllowedPictureTypes; - OMX_BOOL bFrameMBsOnly; + OMX_BOOL bFrameMBsOnly; OMX_BOOL bMBAFF; OMX_BOOL bEntropyCodingCABAC; OMX_BOOL bWeightedPPrediction; OMX_U32 nWeightedBipredicitonMode; OMX_BOOL bconstIpred ; OMX_BOOL bDirect8x8Inference; - OMX_BOOL bDirectSpatialTemporal; - OMX_U32 nCabacInitIdc; - OMX_VIDEO_AVCLOOPFILTERTYPE eLoopFilterMode; + OMX_BOOL bDirectSpatialTemporal; + OMX_U32 nCabacInitIdc; + OMX_VIDEO_AVCLOOPFILTERTYPE eLoopFilterMode; } OMX_VIDEO_PARAM_AVCTYPE; typedef struct OMX_VIDEO_PARAM_PROFILELEVELTYPE { |