AC_SUBST(GLIB_PREFIX)
AC_SUBST(GST_PREFIX)
- AS_HELP_STRING([--with-omx-target],[Use this OpenMAX IL target (generic, bellagio, rpi, tizonia, zynqultrascaleplus)]),
- [ac_cv_omx_target="$withval"], [ac_cv_omx_target="none"])
+ dnl *** EGL ***
+ PKG_CHECK_MODULES([EGL], [egl], [
+ AC_DEFINE(HAVE_EGL, 1, [Have egl])
+ HAVE_EGL=yes
+ ], [HAVE_EGL=no])
+ AM_CONDITIONAL(HAVE_EGL, test "x$HAVE_EGL" = "xyes")
+
+ dnl *** GLESv2 ***
+ PKG_CHECK_MODULES([GLES2], [glesv2], [
+ AC_DEFINE(HAVE_EGL, 1, [Have glesv2])
+ HAVE_GLES2=yes
+ ], [HAVE_GLES2=no])
+ AM_CONDITIONAL(HAVE_GLES2, test "x$HAVE_GLES2" = "xyes")
+
+ dnl *** X11 ***
+ PKG_CHECK_MODULES([X11], [x11], [
+ AC_DEFINE(HAVE_X11, 1, [Have x11])
+ HAVE_X11=yes
+ ], [HAVE_X11=no])
+ AM_CONDITIONAL(HAVE_X11, test "x$HAVE_X11" = "xyes")
+
+ dnl Check for -Bsymbolic-functions linker flag used to avoid
+ dnl intra-library PLT jumps, if available.
+ AC_ARG_ENABLE(Bsymbolic,
+ [AS_HELP_STRING([--disable-Bsymbolic],[avoid linking with -Bsymbolic])],,
+ [SAVED_LDFLAGS="${LDFLAGS}" SAVED_LIBS="${LIBS}"
+ AC_MSG_CHECKING([for -Bsymbolic-functions linker flag])
+ LDFLAGS=-Wl,-Bsymbolic-functions
+ LIBS=
+ AC_TRY_LINK([], [return 0],
+ AC_MSG_RESULT(yes)
+ enable_Bsymbolic=yes,
+ AC_MSG_RESULT(no)
+ enable_Bsymbolic=no)
+ LDFLAGS="${SAVED_LDFLAGS}" LIBS="${SAVED_LIBS}"])
+
+ AC_ARG_WITH([omx-target],
- AC_ERROR([invalid OpenMAX IL target, you must specify one of --with-omx-target={generic,rpi,bellagio,tizonia,zynqultrascaleplus}])
++ AS_HELP_STRING([--with-omx-target],[Use this OpenMAX IL target (generic, bellagio, rpi, tizonia, zynqultrascaleplus, exynos, exynos64)]),
++ [ac_cv_omx_target="$withval"], [ac_cv_omx_target="generic"])
+
+ ac_cv_omx_target_struct_packing="none"
+ AC_MSG_NOTICE([Using $ac_cv_omx_target as OpenMAX IL target])
+ case "${ac_cv_omx_target}" in
+ generic)
+ AC_DEFINE(USE_OMX_TARGET_GENERIC, 1, [Use generic OpenMAX IL target])
+ ;;
+ rpi)
+ AC_DEFINE(USE_OMX_TARGET_RPI, 1, [Use RPi OpenMAX IL target])
+ AC_DEFINE(OMX_SKIP64BIT, 1, [Required by the RPi implementation])
+ ac_cv_omx_target_struct_packing=4
+ ;;
+ bellagio)
+ AC_DEFINE(USE_OMX_TARGET_BELLAGIO, 1, [Use Bellagio OpenMAX IL target])
+ ;;
+ zynqultrascaleplus)
+ AC_DEFINE(USE_OMX_TARGET_ZYNQ_USCALE_PLUS, 1, [Use Zynq UltraScale+ OpenMAX IL target])
+ ;;
+ tizonia)
+ AC_DEFINE(USE_OMX_TARGET_TIZONIA, 1, [Use Tizonia OpenMAX IL target])
+ ;;
++ exynos)
++ AC_DEFINE(USE_OMX_TARGET_EXYNOS, 1, [Use Exynos OpenMAX IL target])
++ ;;
++ exynos64)
++ AC_DEFINE(USE_OMX_TARGET_EXYNOS64, 1, [Use Exynos64 OpenMAX IL target])
++ ;;
+ none|*)
++ AC_ERROR([invalid OpenMAX IL target, you must specify one of --with-omx-target={generic,rpi,bellagio,tizonia,zynqultrascaleplus,exynos,exynos64}])
+ ;;
+ esac
+ AM_CONDITIONAL(USE_OMX_TARGET_GENERIC, test "x$ac_cv_omx_target" = "xgeneric")
+ AM_CONDITIONAL(USE_OMX_TARGET_BELLAGIO, test "x$ac_cv_omx_target" = "xbellagio")
+ AM_CONDITIONAL(USE_OMX_TARGET_TIZONIA, test "x$ac_cv_omx_target" = "xtizonia")
+ AM_CONDITIONAL(USE_OMX_TARGET_RPI, test "x$ac_cv_omx_target" = "xrpi")
+ AM_CONDITIONAL(USE_OMX_TARGET_ZYNQ_USCALE_PLUS, test "x$ac_cv_omx_target" = "xzynqultrascaleplus")
+
+ AC_ARG_WITH([omx-struct-packing],
+ AS_HELP_STRING([--with-omx-struct-packing],[Force OpenMAX struct packing, (default is none)]),
+ [ac_cv_omx_struct_packing="$withval"], [ac_cv_omx_struct_packing="none"])
+
+ if test x"$ac_cv_omx_struct_packing" != x"none"; then
+ AC_MSG_NOTICE([Using $ac_cv_omx_struct_packing as OpenMAX struct packing])
+ AC_DEFINE_UNQUOTED(GST_OMX_STRUCT_PACKING, $ac_cv_omx_struct_packing, [The struct packing used for OpenMAX structures])
+ elif test x"$ac_cv_omx_target_struct_packing" != x"none"; then
+ AC_MSG_NOTICE([Using $ac_cv_omx_target_struct_packing as OpenMAX struct packing])
+ AC_DEFINE_UNQUOTED(GST_OMX_STRUCT_PACKING, $ac_cv_omx_target_struct_packing, [The struct packing used for OpenMAX structures])
+ fi
+
+ dnl settings for tizonia target
+ if test "x$ac_cv_omx_target" = "xtizonia"; then
+ PKG_CHECK_MODULES([TIZONIA], [tizilheaders])
+ CPPFLAGS="$CPPFLAGS $TIZONIA_CFLAGS"
+ TIZONIA_LIBDIR="`$PKG_CONFIG --variable=libdir tizilheaders`"
+ AC_SUBST(TIZONIA_LIBDIR)
+ fi
+
+ if test "x$ac_cv_omx_target" = "xrpi"; then
+ PKG_CHECK_MODULES([BRCMEGL], [brcmegl])
+ fi
+
AC_ARG_WITH([omx-header-path],
AS_HELP_STRING([--with-omx-header-path],[path of external OpenMAX IL header files]),
[omx_header_path="$withval"], [omx_header_path="none"])
"
fi
- dnl check for supporting vp8
- AC_MSG_CHECKING([for supporting vp8])
- AC_ARG_ENABLE(vp8, AC_HELP_STRING([--enable-vp8], [OpenMAX IL has VP8 support]),
+ if test "x$HAVE_INDEX_EXT" = "xyes"; then
+ AC_DEFINE(HAVE_INDEX_EXT, 1, [OpenMAX IL has OMX_IndexExt.h header])
+ fi
+
+ if test "x$HAVE_COMPONENT_EXT" = "xyes"; then
+ AC_DEFINE(HAVE_COMPONENT_EXT, 1, [OpenMAX IL has OMX_ComponentExt.h header])
+ fi
+
+ if test "x$HAVE_CORE_EXT" = "xyes"; then
+ AC_DEFINE(HAVE_CORE_EXT, 1, [OpenMAX IL has OMX_CoreExt.h header])
+ fi
+
+ if test "x$HAVE_AUDIO_EXT" = "xyes"; then
+ AC_DEFINE(HAVE_AUDIO_EXT, 1, [OpenMAX IL has OMX_AudioExt.h header])
+ fi
+
+ if test "x$HAVE_IV_COMMON_EXT" = "xyes"; then
+ AC_DEFINE(HAVE_IV_COMMON_EXT, 1, [OpenMAX IL has OMX_IVCommonExt.h header])
+ fi
+
+ if test "x$HAVE_IMAGE_EXT" = "xyes"; then
+ AC_DEFINE(HAVE_IMAGE_EXT, 1, [OpenMAX IL has OMX_ImageExt.h header])
+ fi
+
+ if test "x$HAVE_OTHER_EXT" = "xyes"; then
+ AC_DEFINE(HAVE_OTHER_EXT, 1, [OpenMAX IL has OMX_OtherExt.h header])
+ fi
+
+ AC_CHECK_DECLS([OMX_VIDEO_CodingVP8],
[
- case "${enableval}" in
- yes) HAVE_VP8=yes ;;
- no) HAVE_VP8=no ;;
- *) AC_MSG_ERROR(bad value ${enableval} for --enable-vp8) ;;
- esac
- ],
- [HAVE_VP8=no])
+ AC_DEFINE(HAVE_VP8, 1, [OpenMAX IL has VP8 support])
+ HAVE_VP8=yes
+ ], [
+ HAVE_VP8=no
+ ], [[$VIDEO_HEADERS]])
AM_CONDITIONAL(HAVE_VP8, test "x$HAVE_VP8" = "xyes")
- AC_MSG_RESULT([$HAVE_VP8])
- if test "x$HAVE_VP8" = "xyes"; then
- AC_DEFINE(HAVE_VP8, 1, [OpenMAX IL has VP8 support])
- fi
- dnl check for supporting theora
- AC_MSG_CHECKING([for supporting theora])
- AC_ARG_ENABLE(theora, AC_HELP_STRING([--enable-theora], [OpenMAX IL has Theora support]),
+dnl check for supporting vp9
+AC_MSG_CHECKING([for supporting vp9])
+AC_ARG_ENABLE(vp9, AC_HELP_STRING([--enable-vp9], [OpenMAX IL has VP9 support]),
+ [
+ case "${enableval}" in
+ yes) HAVE_VP9=yes ;;
+ no) HAVE_VP9=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-vp9) ;;
+ esac
+ ],
+ [HAVE_VP9=no])
+AM_CONDITIONAL(HAVE_VP9, test "x$HAVE_VP9" = "xyes")
+AC_MSG_RESULT([$HAVE_VP9])
+if test "x$HAVE_VP9" = "xyes"; then
+ AC_DEFINE(HAVE_VP9, 1, [OpenMAX IL has VP9 support])
+fi
+
+ AC_CHECK_DECLS([OMX_VIDEO_CodingTheora],
[
- case "${enableval}" in
- yes) HAVE_THEORA=yes ;;
- no) HAVE_THEORA=no ;;
- *) AC_MSG_ERROR(bad value ${enableval} for --enable-theora) ;;
- esac
- ],
- [HAVE_THEORA=no])
+ AC_DEFINE(HAVE_THEORA, 1, [OpenMAX IL has Theora support])
+ HAVE_THEORA=yes
+ ], [
+ HAVE_THEORA=no
+ ], [[$VIDEO_HEADERS]])
AM_CONDITIONAL(HAVE_THEORA, test "x$HAVE_THEORA" = "xyes")
- AC_MSG_RESULT([$HAVE_THEORA])
- if test "x$HAVE_THEORA" = "xyes"; then
- AC_DEFINE(HAVE_THEORA, 1, [OpenMAX IL has Theora support])
- fi
- dnl check for supporting hevc
- AC_MSG_CHECKING([for supporting hevc])
- AC_ARG_ENABLE(hevc, AC_HELP_STRING([--enable-hevc], [OpenMAX IL has HEVC support]),
+ AC_CHECK_DECLS([OMX_VIDEO_CodingHEVC],
[
- case "${enableval}" in
- yes) HAVE_HEVC=yes ;;
- no) HAVE_HEVC=no ;;
- *) AC_MSG_ERROR(bad value ${enableval} for --enable-hevc) ;;
- esac
- ],
- [HAVE_HEVC=no])
+ AC_DEFINE(HAVE_HEVC, 1, [OpenMAX IL has HEVC support])
+ HAVE_HEVC=yes
+ ], [
+ HAVE_HEVC=no
+ ], [[$VIDEO_HEADERS]])
AM_CONDITIONAL(HAVE_HEVC, test "x$HAVE_HEVC" = "xyes")
- AC_MSG_RESULT([$HAVE_HEVC])
- if test "x$HAVE_HEVC" = "xyes"; then
- AC_DEFINE(HAVE_HEVC, 1, [OpenMAX IL has HEVC support])
- fi
-
- dnl Check for -Bsymbolic-functions linker flag used to avoid
- dnl intra-library PLT jumps, if available.
- AC_ARG_ENABLE(Bsymbolic,
- [AC_HELP_STRING([--disable-Bsymbolic],
- [avoid linking with -Bsymbolic])],,
- [SAVED_LDFLAGS="${LDFLAGS}"
- AC_MSG_CHECKING([for -Bsymbolic-functions linker flag])
- LDFLAGS=-Wl,-Bsymbolic-functions
- AC_TRY_LINK([], [int main (void) { return 0; }],
- AC_MSG_RESULT(yes)
- enable_Bsymbolic=yes,
- AC_MSG_RESULT(no)
- enable_Bsymbolic=no)
- LDFLAGS="${SAVED_LDFLAGS}"])
-
- AC_ARG_WITH([omx-target],
- AS_HELP_STRING([--with-omx-target],[Use this OpenMAX IL target (generic, bellagio, rpi, exynos, exynos64)]),
- [ac_cv_omx_target="$withval"], [ac_cv_omx_target="generic"])
-
- ac_cv_omx_target_struct_packing="none"
- AC_MSG_NOTICE([Using $ac_cv_omx_target as OpenMAX IL target])
- case "${ac_cv_omx_target}" in
- generic)
- AC_DEFINE(USE_OMX_TARGET_GENERIC, 1, [Use generic OpenMAX IL target])
- ;;
- rpi)
- AC_DEFINE(USE_OMX_TARGET_RPI, 1, [Use RPi OpenMAX IL target])
- ac_cv_omx_target_struct_packing=4
- ;;
- bellagio)
- AC_DEFINE(USE_OMX_TARGET_BELLAGIO, 1, [Use Bellagio OpenMAX IL target])
- ;;
- exynos)
- AC_DEFINE(USE_OMX_TARGET_EXYNOS, 1, [Use Exynos OpenMAX IL target])
- ;;
- exynos64)
- AC_DEFINE(USE_OMX_TARGET_EXYNOS64, 1, [Use Exynos64 OpenMAX IL target])
- ;;
- *)
- AC_ERROR([invalid OpenMAX IL target])
- ;;
- esac
- AM_CONDITIONAL(USE_OMX_TARGET_GENERIC, test "x$ac_cv_omx_target" = "xgeneric")
- AM_CONDITIONAL(USE_OMX_TARGET_BELLAGIO, test "x$ac_cv_omx_target" = "xbellagio")
- AM_CONDITIONAL(USE_OMX_TARGET_RPI, test "x$ac_cv_omx_target" = "xrpi")
- AM_CONDITIONAL(USE_OMX_TARGET_EXYNOS, test "x$ac_cv_omx_target" = "xexynos")
- AM_CONDITIONAL(USE_OMX_TARGET_EXYNOS64, test "x$ac_cv_omx_target" = "xexynos64")
-
- AC_ARG_WITH([omx-struct-packing],
- AS_HELP_STRING([--with-omx-struct-packing],[Force OpenMAX struct packing, (default is none)]),
- [ac_cv_omx_struct_packing="$withval"], [ac_cv_omx_struct_packing="none"])
- if test x"$ac_cv_omx_struct_packing" != x"none"; then
- AC_MSG_NOTICE([Using $ac_cv_omx_struct_packing as OpenMAX struct packing])
- AC_DEFINE_UNQUOTED(GST_OMX_STRUCT_PACKING, $ac_cv_omx_struct_packing, [The struct packing used for OpenMAX structures])
- elif test x"$ac_cv_omx_target_struct_packing" != x"none"; then
- AC_MSG_NOTICE([Using $ac_cv_omx_target_struct_packing as OpenMAX struct packing])
- AC_DEFINE_UNQUOTED(GST_OMX_STRUCT_PACKING, $ac_cv_omx_target_struct_packing, [The struct packing used for OpenMAX structures])
+ if test "x$ac_cv_omx_target" = "xzynqultrascaleplus"; then
+ AC_CHECK_HEADER([OMX_Allegro.h], [], [AC_ERROR([Need Allegro OMX headers to build for Zynq UltraScale+. Use --with-omx-header-path= argument to specify the path of those headers.])], [AC_INCLUDES_DEFAULT])
fi
dnl *** set variables based on configure arguments ***
GST_PLUGIN_LDFLAGS="-module -avoid-version -export-symbols-regex '^[_]*gst_plugin_.*' $GST_ALL_LDFLAGS"
AC_SUBST(GST_PLUGIN_LDFLAGS)
+ AS_AC_EXPAND(GST_OMX_CONFIG_DIR, ${sysconfdir}/xdg)
+ AC_DEFINE_UNQUOTED(GST_OMX_CONFIG_DIR, "$GST_OMX_CONFIG_DIR", [gst-omx configuration directory])
+
dnl *** output files ***
+
+dnl drm buffer
+
+PKG_CHECK_MODULES(TBM, libtbm)
+AC_SUBST(TBM_CFLAGS)
+AC_SUBST(TBM_LIBS)
+
+PKG_CHECK_MODULES(MM_COMMON, mm-common)
+AC_SUBST(MM_COMMON_CFLAGS)
+AC_SUBST(MM_COMMON_LIBS)
+
AC_CONFIG_FILES(
Makefile
omx/Makefile
gstomxh263dec.c \
gstomxwmvdec.c \
$(VP8_C_FILES) \
+ $(VP9_C_FILES) \
$(THEORA_C_FILES) \
- $(HEVC_C_FILES) \
+ $(H265_C_FILES) \
gstomxmpeg4videoenc.c \
gstomxh264enc.c \
gstomxh263enc.c \
gstomxh263dec.h \
gstomxwmvdec.h \
$(VP8_H_FILES) \
+ $(VP9_H_FILES) \
$(THEORA_H_FILES) \
- $(HEVC_H_FILES) \
+ $(H265_H_FILES) \
gstomxmpeg4videoenc.h \
gstomxh264enc.h \
gstomxh263enc.h \
#include "gstomxmjpegdec.h"
#include "gstomxmpeg2videodec.h"
#include "gstomxmpeg4videodec.h"
+#include "gstomxh265dec.h"
#include "gstomxh264dec.h"
#include "gstomxh263dec.h"
+ #include "gstomxh265dec.h"
#include "gstomxvp8dec.h"
+#include "gstomxvp9dec.h"
#include "gstomxtheoradec.h"
#include "gstomxwmvdec.h"
#include "gstomxmpeg4videoenc.h"
+#include "gstomxh265enc.h"
#include "gstomxh264enc.h"
#include "gstomxh263enc.h"
+ #include "gstomxh265enc.h"
#include "gstomxaacdec.h"
#include "gstomxmp3dec.h"
+ #include "gstomxmp3enc.h"
#include "gstomxaacenc.h"
#include "gstomxamrdec.h"
#include "gstomxanalogaudiosink.h"
return gst_omx_error_to_string (gst_omx_component_get_last_error (comp));
}
+#ifdef TIZEN_FEATURE_OMX
+OMX_ERRORTYPE
+gst_omx_component_get_extension_index (GstOMXComponent * comp, OMX_STRING name,
+ gpointer index)
+{
+ OMX_ERRORTYPE err;
+
+ g_return_val_if_fail (comp != NULL, OMX_ErrorUndefined);
+
+ GST_DEBUG_OBJECT (comp->parent, "Getting %s parameter index for %s",
+ comp->name, name);
+ err = OMX_GetExtensionIndex (comp->handle, name, index);
+ GST_DEBUG_OBJECT (comp->parent, "Got %s parameter at name %s: %s "
+ "(0x%08x)", comp->name, name, gst_omx_error_to_string (err), err);
+
+ return err;
+}
+#endif
+
+ #ifndef GST_DISABLE_GST_DEBUG
+ static const gchar *
+ omx_index_type_to_str (OMX_INDEXTYPE index)
+ {
+ switch (index) {
+ case OMX_IndexComponentStartUnused:
+ return "OMX_IndexComponentStartUnused";
+ case OMX_IndexParamPriorityMgmt:
+ return "OMX_IndexParamPriorityMgmt";
+ case OMX_IndexParamAudioInit:
+ return "OMX_IndexParamAudioInit";
+ case OMX_IndexParamImageInit:
+ return "OMX_IndexParamImageInit";
+ case OMX_IndexParamVideoInit:
+ return "OMX_IndexParamVideoInit";
+ case OMX_IndexParamOtherInit:
+ return "OMX_IndexParamOtherInit";
+ case OMX_IndexParamNumAvailableStreams:
+ return "OMX_IndexParamNumAvailableStreams";
+ case OMX_IndexParamActiveStream:
+ return "OMX_IndexParamActiveStream";
+ case OMX_IndexParamSuspensionPolicy:
+ return "OMX_IndexParamSuspensionPolicy";
+ case OMX_IndexParamComponentSuspended:
+ return "OMX_IndexParamComponentSuspended";
+ case OMX_IndexConfigCapturing:
+ return "OMX_IndexConfigCapturing";
+ case OMX_IndexConfigCaptureMode:
+ return "OMX_IndexConfigCaptureMode";
+ case OMX_IndexAutoPauseAfterCapture:
+ return "OMX_IndexAutoPauseAfterCapture";
+ case OMX_IndexParamContentURI:
+ return "OMX_IndexParamContentURI";
+ case OMX_IndexParamDisableResourceConcealment:
+ return "OMX_IndexParamDisableResourceConcealment";
+ case OMX_IndexConfigMetadataItemCount:
+ return "OMX_IndexConfigMetadataItemCount";
+ case OMX_IndexConfigContainerNodeCount:
+ return "OMX_IndexConfigContainerNodeCount";
+ case OMX_IndexConfigMetadataItem:
+ return "OMX_IndexConfigMetadataItem";
+ case OMX_IndexConfigCounterNodeID:
+ return "OMX_IndexConfigCounterNodeID";
+ case OMX_IndexParamMetadataFilterType:
+ return "OMX_IndexParamMetadataFilterType";
+ case OMX_IndexParamMetadataKeyFilter:
+ return "OMX_IndexParamMetadataKeyFilter";
+ case OMX_IndexConfigPriorityMgmt:
+ return "OMX_IndexConfigPriorityMgmt";
+ case OMX_IndexParamStandardComponentRole:
+ return "OMX_IndexParamStandardComponentRole";
+ case OMX_IndexPortStartUnused:
+ return "OMX_IndexPortStartUnused";
+ case OMX_IndexParamPortDefinition:
+ return "OMX_IndexParamPortDefinition";
+ case OMX_IndexParamCompBufferSupplier:
+ return "OMX_IndexParamCompBufferSupplier";
+ case OMX_IndexReservedStartUnused:
+ return "OMX_IndexReservedStartUnused";
+ case OMX_IndexAudioStartUnused:
+ return "OMX_IndexAudioStartUnused";
+ case OMX_IndexParamAudioPortFormat:
+ return "OMX_IndexParamAudioPortFormat";
+ case OMX_IndexParamAudioPcm:
+ return "OMX_IndexParamAudioPcm";
+ case OMX_IndexParamAudioAac:
+ return "OMX_IndexParamAudioAac";
+ case OMX_IndexParamAudioRa:
+ return "OMX_IndexParamAudioRa";
+ case OMX_IndexParamAudioMp3:
+ return "OMX_IndexParamAudioMp3";
+ case OMX_IndexParamAudioAdpcm:
+ return "OMX_IndexParamAudioAdpcm";
+ case OMX_IndexParamAudioG723:
+ return "OMX_IndexParamAudioG723";
+ case OMX_IndexParamAudioG729:
+ return "OMX_IndexParamAudioG729";
+ case OMX_IndexParamAudioAmr:
+ return "OMX_IndexParamAudioAmr";
+ case OMX_IndexParamAudioWma:
+ return "OMX_IndexParamAudioWma";
+ case OMX_IndexParamAudioSbc:
+ return "OMX_IndexParamAudioSbc";
+ case OMX_IndexParamAudioMidi:
+ return "OMX_IndexParamAudioMidi";
+ case OMX_IndexParamAudioGsm_FR:
+ return "OMX_IndexParamAudioGsm_FR";
+ case OMX_IndexParamAudioMidiLoadUserSound:
+ return "OMX_IndexParamAudioMidiLoadUserSound";
+ case OMX_IndexParamAudioG726:
+ return "OMX_IndexParamAudioG726";
+ case OMX_IndexParamAudioGsm_EFR:
+ return "OMX_IndexParamAudioGsm_EFR";
+ case OMX_IndexParamAudioGsm_HR:
+ return "OMX_IndexParamAudioGsm_HR";
+ case OMX_IndexParamAudioPdc_FR:
+ return "OMX_IndexParamAudioPdc_FR";
+ case OMX_IndexParamAudioPdc_EFR:
+ return "OMX_IndexParamAudioPdc_EFR";
+ case OMX_IndexParamAudioPdc_HR:
+ return "OMX_IndexParamAudioPdc_HR";
+ case OMX_IndexParamAudioTdma_FR:
+ return "OMX_IndexParamAudioTdma_FR";
+ case OMX_IndexParamAudioTdma_EFR:
+ return "OMX_IndexParamAudioTdma_EFR";
+ case OMX_IndexParamAudioQcelp8:
+ return "OMX_IndexParamAudioQcelp8";
+ case OMX_IndexParamAudioQcelp13:
+ return "OMX_IndexParamAudioQcelp13";
+ case OMX_IndexParamAudioEvrc:
+ return "OMX_IndexParamAudioEvrc";
+ case OMX_IndexParamAudioSmv:
+ return "OMX_IndexParamAudioSmv";
+ case OMX_IndexParamAudioVorbis:
+ return "OMX_IndexParamAudioVorbis";
+ case OMX_IndexConfigAudioMidiImmediateEvent:
+ return "OMX_IndexConfigAudioMidiImmediateEvent";
+ case OMX_IndexConfigAudioMidiControl:
+ return "OMX_IndexConfigAudioMidiControl";
+ case OMX_IndexConfigAudioMidiSoundBankProgram:
+ return "OMX_IndexConfigAudioMidiSoundBankProgram";
+ case OMX_IndexConfigAudioMidiStatus:
+ return "OMX_IndexConfigAudioMidiStatus";
+ case OMX_IndexConfigAudioMidiMetaEvent:
+ return "OMX_IndexConfigAudioMidiMetaEvent";
+ case OMX_IndexConfigAudioMidiMetaEventData:
+ return "OMX_IndexConfigAudioMidiMetaEventData";
+ case OMX_IndexConfigAudioVolume:
+ return "OMX_IndexConfigAudioVolume";
+ case OMX_IndexConfigAudioBalance:
+ return "OMX_IndexConfigAudioBalance";
+ case OMX_IndexConfigAudioChannelMute:
+ return "OMX_IndexConfigAudioChannelMute";
+ case OMX_IndexConfigAudioMute:
+ return "OMX_IndexConfigAudioMute";
+ case OMX_IndexConfigAudioLoudness:
+ return "OMX_IndexConfigAudioLoudness";
+ case OMX_IndexConfigAudioEchoCancelation:
+ return "OMX_IndexConfigAudioEchoCancelation";
+ case OMX_IndexConfigAudioNoiseReduction:
+ return "OMX_IndexConfigAudioNoiseReduction";
+ case OMX_IndexConfigAudioBass:
+ return "OMX_IndexConfigAudioBass";
+ case OMX_IndexConfigAudioTreble:
+ return "OMX_IndexConfigAudioTreble";
+ case OMX_IndexConfigAudioStereoWidening:
+ return "OMX_IndexConfigAudioStereoWidening";
+ case OMX_IndexConfigAudioChorus:
+ return "OMX_IndexConfigAudioChorus";
+ case OMX_IndexConfigAudioEqualizer:
+ return "OMX_IndexConfigAudioEqualizer";
+ case OMX_IndexConfigAudioReverberation:
+ return "OMX_IndexConfigAudioReverberation";
+ case OMX_IndexConfigAudioChannelVolume:
+ return "OMX_IndexConfigAudioChannelVolume";
+ case OMX_IndexImageStartUnused:
+ return "OMX_IndexImageStartUnused";
+ case OMX_IndexParamImagePortFormat:
+ return "OMX_IndexParamImagePortFormat";
+ case OMX_IndexParamFlashControl:
+ return "OMX_IndexParamFlashControl";
+ case OMX_IndexConfigFocusControl:
+ return "OMX_IndexConfigFocusControl";
+ case OMX_IndexParamQFactor:
+ return "OMX_IndexParamQFactor";
+ case OMX_IndexParamQuantizationTable:
+ return "OMX_IndexParamQuantizationTable";
+ case OMX_IndexParamHuffmanTable:
+ return "OMX_IndexParamHuffmanTable";
+ case OMX_IndexConfigFlashControl:
+ return "OMX_IndexConfigFlashControl";
+ case OMX_IndexVideoStartUnused:
+ return "OMX_IndexVideoStartUnused";
+ case OMX_IndexParamVideoPortFormat:
+ return "OMX_IndexParamVideoPortFormat";
+ case OMX_IndexParamVideoQuantization:
+ return "OMX_IndexParamVideoQuantization";
+ case OMX_IndexParamVideoFastUpdate:
+ return "OMX_IndexParamVideoFastUpdate";
+ case OMX_IndexParamVideoBitrate:
+ return "OMX_IndexParamVideoBitrate";
+ case OMX_IndexParamVideoMotionVector:
+ return "OMX_IndexParamVideoMotionVector";
+ case OMX_IndexParamVideoIntraRefresh:
+ return "OMX_IndexParamVideoIntraRefresh";
+ case OMX_IndexParamVideoErrorCorrection:
+ return "OMX_IndexParamVideoErrorCorrection";
+ case OMX_IndexParamVideoVBSMC:
+ return "OMX_IndexParamVideoVBSMC";
+ case OMX_IndexParamVideoMpeg2:
+ return "OMX_IndexParamVideoMpeg2";
+ case OMX_IndexParamVideoMpeg4:
+ return "OMX_IndexParamVideoMpeg4";
+ case OMX_IndexParamVideoWmv:
+ return "OMX_IndexParamVideoWmv";
+ case OMX_IndexParamVideoRv:
+ return "OMX_IndexParamVideoRv";
+ case OMX_IndexParamVideoAvc:
+ return "OMX_IndexParamVideoAvc";
+ case OMX_IndexParamVideoH263:
+ return "OMX_IndexParamVideoH263";
+ case OMX_IndexParamVideoProfileLevelQuerySupported:
+ return "OMX_IndexParamVideoProfileLevelQuerySupported";
+ case OMX_IndexParamVideoProfileLevelCurrent:
+ return "OMX_IndexParamVideoProfileLevelCurrent";
+ case OMX_IndexConfigVideoBitrate:
+ return "OMX_IndexConfigVideoBitrate";
+ case OMX_IndexConfigVideoFramerate:
+ return "OMX_IndexConfigVideoFramerate";
+ case OMX_IndexConfigVideoIntraVOPRefresh:
+ return "OMX_IndexConfigVideoIntraVOPRefresh";
+ case OMX_IndexConfigVideoIntraMBRefresh:
+ return "OMX_IndexConfigVideoIntraMBRefresh";
+ case OMX_IndexConfigVideoMBErrorReporting:
+ return "OMX_IndexConfigVideoMBErrorReporting";
+ case OMX_IndexParamVideoMacroblocksPerFrame:
+ return "OMX_IndexParamVideoMacroblocksPerFrame";
+ case OMX_IndexConfigVideoMacroBlockErrorMap:
+ return "OMX_IndexConfigVideoMacroBlockErrorMap";
+ case OMX_IndexParamVideoSliceFMO:
+ return "OMX_IndexParamVideoSliceFMO";
+ case OMX_IndexConfigVideoAVCIntraPeriod:
+ return "OMX_IndexConfigVideoAVCIntraPeriod";
+ case OMX_IndexConfigVideoNalSize:
+ return "OMX_IndexConfigVideoNalSize";
+ case OMX_IndexCommonStartUnused:
+ return "OMX_IndexCommonStartUnused";
+ case OMX_IndexParamCommonDeblocking:
+ return "OMX_IndexParamCommonDeblocking";
+ case OMX_IndexParamCommonSensorMode:
+ return "OMX_IndexParamCommonSensorMode";
+ case OMX_IndexParamCommonInterleave:
+ return "OMX_IndexParamCommonInterleave";
+ case OMX_IndexConfigCommonColorFormatConversion:
+ return "OMX_IndexConfigCommonColorFormatConversion";
+ case OMX_IndexConfigCommonScale:
+ return "OMX_IndexConfigCommonScale";
+ case OMX_IndexConfigCommonImageFilter:
+ return "OMX_IndexConfigCommonImageFilter";
+ case OMX_IndexConfigCommonColorEnhancement:
+ return "OMX_IndexConfigCommonColorEnhancement";
+ case OMX_IndexConfigCommonColorKey:
+ return "OMX_IndexConfigCommonColorKey";
+ case OMX_IndexConfigCommonColorBlend:
+ return "OMX_IndexConfigCommonColorBlend";
+ case OMX_IndexConfigCommonFrameStabilisation:
+ return "OMX_IndexConfigCommonFrameStabilisation";
+ case OMX_IndexConfigCommonRotate:
+ return "OMX_IndexConfigCommonRotate";
+ case OMX_IndexConfigCommonMirror:
+ return "OMX_IndexConfigCommonMirror";
+ case OMX_IndexConfigCommonOutputPosition:
+ return "OMX_IndexConfigCommonOutputPosition";
+ case OMX_IndexConfigCommonInputCrop:
+ return "OMX_IndexConfigCommonInputCrop";
+ case OMX_IndexConfigCommonOutputCrop:
+ return "OMX_IndexConfigCommonOutputCrop";
+ case OMX_IndexConfigCommonDigitalZoom:
+ return "OMX_IndexConfigCommonDigitalZoom";
+ case OMX_IndexConfigCommonOpticalZoom:
+ return "OMX_IndexConfigCommonOpticalZoom";
+ case OMX_IndexConfigCommonWhiteBalance:
+ return "OMX_IndexConfigCommonWhiteBalance";
+ case OMX_IndexConfigCommonExposure:
+ return "OMX_IndexConfigCommonExposure";
+ case OMX_IndexConfigCommonContrast:
+ return "OMX_IndexConfigCommonContrast";
+ case OMX_IndexConfigCommonBrightness:
+ return "OMX_IndexConfigCommonBrightness";
+ case OMX_IndexConfigCommonBacklight:
+ return "OMX_IndexConfigCommonBacklight";
+ case OMX_IndexConfigCommonGamma:
+ return "OMX_IndexConfigCommonGamma";
+ case OMX_IndexConfigCommonSaturation:
+ return "OMX_IndexConfigCommonSaturation";
+ case OMX_IndexConfigCommonLightness:
+ return "OMX_IndexConfigCommonLightness";
+ case OMX_IndexConfigCommonExclusionRect:
+ return "OMX_IndexConfigCommonExclusionRect";
+ case OMX_IndexConfigCommonDithering:
+ return "OMX_IndexConfigCommonDithering";
+ case OMX_IndexConfigCommonPlaneBlend:
+ return "OMX_IndexConfigCommonPlaneBlend";
+ case OMX_IndexConfigCommonExposureValue:
+ return "OMX_IndexConfigCommonExposureValue";
+ case OMX_IndexConfigCommonOutputSize:
+ return "OMX_IndexConfigCommonOutputSize";
+ case OMX_IndexParamCommonExtraQuantData:
+ return "OMX_IndexParamCommonExtraQuantData";
+ case OMX_IndexConfigCommonTransitionEffect:
+ return "OMX_IndexConfigCommonTransitionEffect";
+ case OMX_IndexOtherStartUnused:
+ return "OMX_IndexOtherStartUnused";
+ case OMX_IndexParamOtherPortFormat:
+ return "OMX_IndexParamOtherPortFormat";
+ case OMX_IndexConfigOtherPower:
+ return "OMX_IndexConfigOtherPower";
+ case OMX_IndexConfigOtherStats:
+ return "OMX_IndexConfigOtherStats";
+ case OMX_IndexTimeStartUnused:
+ return "OMX_IndexTimeStartUnused";
+ case OMX_IndexConfigTimeScale:
+ return "OMX_IndexConfigTimeScale";
+ case OMX_IndexConfigTimeClockState:
+ return "OMX_IndexConfigTimeClockState";
+ case OMX_IndexConfigTimeCurrentMediaTime:
+ return "OMX_IndexConfigTimeCurrentMediaTime";
+ case OMX_IndexConfigTimeCurrentWallTime:
+ return "OMX_IndexConfigTimeCurrentWallTime";
+ case OMX_IndexConfigTimeMediaTimeRequest:
+ return "OMX_IndexConfigTimeMediaTimeRequest";
+ case OMX_IndexConfigTimeClientStartTime:
+ return "OMX_IndexConfigTimeClientStartTime";
+ case OMX_IndexConfigTimePosition:
+ return "OMX_IndexConfigTimePosition";
+ case OMX_IndexConfigTimeSeekMode:
+ return "OMX_IndexConfigTimeSeekMode";
+ case OMX_IndexKhronosExtensions:
+ return "OMX_IndexKhronosExtensions";
+ case OMX_IndexVendorStartUnused:
+ return "OMX_IndexVendorStartUnused";
+ case OMX_IndexMax:
+ return "OMX_IndexMax";
+ default:
+ break;
+ }
+
+ #if OMX_VERSION_MINOR == 1
+ switch (index) {
+ case OMX_IndexParamCustomContentPipe:
+ return "OMX_IndexParamCustomContentPipe";
+ case OMX_IndexConfigCommonFocusRegion:
+ return "OMX_IndexConfigCommonFocusRegion";
+ case OMX_IndexConfigCommonFocusStatus:
+ return "OMX_IndexConfigCommonFocusStatus";
+ case OMX_IndexConfigTimeActiveRefClock:
+ return "OMX_IndexConfigTimeActiveRefClock";
+ case OMX_IndexConfigTimeCurrentAudioReference:
+ return "OMX_IndexConfigTimeCurrentAudioReference";
+ case OMX_IndexConfigTimeCurrentVideoReference:
+ return "OMX_IndexConfigTimeCurrentVideoReference";
+ default:
+ break;
+ }
+ #endif
+
+ #ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
+ switch ((OMX_ALG_INDEXTYPE) index) {
+ case OMX_ALG_IndexVendorComponentStartUnused:
+ return "OMX_ALG_IndexVendorComponentStartUnused";
+ case OMX_ALG_IndexParamReportedLatency:
+ return "OMX_ALG_IndexParamReportedLatency";
+ case OMX_ALG_IndexParamPreallocation:
+ return "OMX_ALG_IndexParamPreallocation";
+ case OMX_ALG_IndexVendorPortStartUnused:
+ return "OMX_ALG_IndexVendorPortStartUnused";
+ case OMX_ALG_IndexPortParamBufferMode:
+ return "OMX_ALG_IndexPortParamBufferMode";
+ case OMX_ALG_IndexParamVendorVideoStartUnused:
+ return "OMX_ALG_IndexParamVendorVideoStartUnused";
+ case OMX_ALG_IndexParamVideoHevc:
+ return "OMX_ALG_IndexParamVideoHevc";
+ case OMX_ALG_IndexParamVideoVp9:
+ return "OMX_ALG_IndexParamVideoVp9";
+ case OMX_ALG_IndexParamVideoGopControl:
+ return "OMX_ALG_IndexParamVideoGopControl";
+ case OMX_ALG_IndexParamVideoSlices:
+ return "OMX_ALG_IndexParamVideoSlices";
+ case OMX_ALG_IndexParamVideoSceneChangeResilience:
+ return "OMX_ALG_IndexParamVideoSceneChangeResilience";
+ case OMX_ALG_IndexParamVideoPrefetchBuffer:
+ return "OMX_ALG_IndexParamVideoPrefetchBuffer";
+ case OMX_ALG_IndexParamVideoCodedPictureBuffer:
+ return "OMX_ALG_IndexParamVideoCodedPictureBuffer";
+ case OMX_ALG_IndexParamVideoQuantizationControl:
+ return "OMX_ALG_IndexParamVideoQuantizationControl";
+ case OMX_ALG_IndexParamVideoQuantizationExtension:
+ return "OMX_ALG_IndexParamVideoQuantizationExtension";
+ case OMX_ALG_IndexParamVideoScalingList:
+ return "OMX_ALG_IndexParamVideoScalingList";
+ case OMX_ALG_IndexParamVideoDecodedPictureBuffer:
+ return "OMX_ALG_IndexParamVideoDecodedPictureBuffer";
+ case OMX_ALG_IndexParamVideoInternalEntropyBuffers:
+ return "OMX_ALG_IndexParamVideoInternalEntropyBuffers";
+ case OMX_ALG_IndexParamVideoLowBandwidth:
+ return "OMX_ALG_IndexParamVideoLowBandwidth";
+ case OMX_ALG_IndexParamVideoAspectRatio:
+ return "OMX_ALG_IndexParamVideoAspectRatio";
+ case OMX_ALG_IndexParamVideoSubframe:
+ return "OMX_ALG_IndexParamVideoSubframe";
+ case OMX_ALG_IndexParamVideoInstantaneousDecodingRefresh:
+ return "OMX_ALG_IndexParamVideoInstantaneousDecodingRefresh";
+ case OMX_ALG_IndexParamVideoMaxBitrate:
+ return "OMX_ALG_IndexParamVideoMaxBitrate";
+ case OMX_ALG_IndexParamVideoFillerData:
+ return "OMX_ALG_IndexParamVideoFillerData";
+ case OMX_ALG_IndexParamVideoBufferMode:
+ return "OMX_ALG_IndexParamVideoBufferMode";
+ case OMX_ALG_IndexParamVideoInterlaceFormatCurrent:
+ return "OMX_ALG_IndexParamVideoInterlaceFormatCurrent";
+ case OMX_ALG_IndexParamVideoLongTerm:
+ return "OMX_ALG_IndexParamVideoLongTerm";
+ case OMX_ALG_IndexParamVideoLookAhead:
+ return "OMX_ALG_IndexParamVideoLookAhead";
+ case OMX_ALG_IndexConfigVendorVideoStartUnused:
+ return "OMX_ALG_IndexConfigVendorVideoStartUnused";
+ case OMX_ALG_IndexConfigVideoInsertInstantaneousDecodingRefresh:
+ return "OMX_ALG_IndexConfigVideoInsertInstantaneousDecodingRefresh";
+ case OMX_ALG_IndexConfigVideoGroupOfPictures:
+ return "OMX_ALG_IndexConfigVideoGroupOfPictures";
+ case OMX_ALG_IndexConfigVideoRegionOfInterest:
+ return "OMX_ALG_IndexConfigVideoRegionOfInterest";
+ case OMX_ALG_IndexConfigVideoNotifySceneChange:
+ return "OMX_ALG_IndexConfigVideoNotifySceneChange";
+ case OMX_ALG_IndexConfigVideoInsertLongTerm:
+ return "OMX_ALG_IndexConfigVideoInsertLongTerm";
+ case OMX_ALG_IndexConfigVideoUseLongTerm:
+ return "OMX_ALG_IndexConfigVideoUseLongTerm";
+ case OMX_ALG_IndexVendorCommonStartUnused:
+ return "OMX_ALG_IndexVendorCommonStartUnused";
+ case OMX_ALG_IndexParamCommonSequencePictureModeCurrent:
+ return "OMX_ALG_IndexParamCommonSequencePictureModeCurrent";
+ case OMX_ALG_IndexParamCommonSequencePictureModeQuerySupported:
+ return "OMX_ALG_IndexParamCommonSequencePictureModeQuerySupported";
+ case OMX_ALG_IndexParamVideoTwoPass:
+ return "OMX_ALG_IndexParamVideoTwoPass";
+ case OMX_ALG_IndexParamVideoColorPrimaries:
+ return "OMX_ALG_IndexParamVideoColorPrimaries";
+ case OMX_ALG_IndexParamVideoSkipFrame:
+ return "OMX_ALG_IndexParamVideoSkipFrame";
+ case OMX_ALG_IndexConfigVideoNotifyResolutionChange:
+ return "OMX_ALG_IndexConfigVideoNotifyResolutionChange";
+ case OMX_ALG_IndexConfigVideoInsertPrefixSEI:
+ return "OMX_ALG_IndexConfigVideoInsertPrefixSEI";
+ case OMX_ALG_IndexConfigVideoInsertSuffixSEI:
+ return "OMX_ALG_IndexConfigVideoInsertSuffixSEI";
+ case OMX_ALG_IndexConfigVideoQuantizationParameterTable:
+ return "OMX_ALG_IndexConfigVideoQuantizationParameterTable";
+ case OMX_ALG_IndexMaxEnum:
+ return "OMX_ALG_IndexMaxEnum";
+ }
+ #endif
+
+ #ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
+ /* Not part of the enum in OMX_IndexAlg.h */
+ if (index == OMX_ALG_IndexParamVideoInterlaceFormatSupported)
+ return "OMX_ALG_IndexParamVideoInterlaceFormatSupported";
+ #endif
+
+ return NULL;
+ }
+ #endif /* GST_DISABLE_GST_DEBUG */
+
+ static void
+ log_omx_api_trace_call (GstOMXComponent * comp, const gchar * function,
+ OMX_INDEXTYPE index, GstDebugLevel level)
+ {
+ #ifndef GST_DISABLE_GST_DEBUG
+ GstStructure *s;
+ const gchar *index_name;
+
+ /* Don't bother creating useless structs if not needed */
+ if (gst_debug_category_get_threshold (OMX_API_TRACE) < level)
+ return;
+
+ index_name = omx_index_type_to_str (index);
+ if (!index_name) {
+ GST_CAT_WARNING_OBJECT (OMX_API_TRACE, comp->parent,
+ "unknown call of %s with index 0x%08x", function, index);
+ return;
+ }
+
+ s = gst_structure_new (function, "index", G_TYPE_STRING, index_name, NULL);
+ GST_CAT_LEVEL_LOG (OMX_API_TRACE, level, comp->parent, "%" GST_PTR_FORMAT, s);
+ gst_structure_free (s);
+ #endif /* GST_DISABLE_GST_DEBUG */
+ }
+
/* comp->lock must be unlocked while calling this */
OMX_ERRORTYPE
gst_omx_component_get_parameter (GstOMXComponent * comp, OMX_INDEXTYPE index,
}
/* Check if the port is flushing */
+#ifdef TIZEN_FEATURE_OMX
+ if (port->flushing || port->flush_start) {
+ if (!g_queue_is_empty (&port->pending_buffers)) {
+ GST_DEBUG_OBJECT (comp->parent, "%s port %u has pending buffers",
+ comp->name, port->index);
+ _buf = g_queue_pop_head (&port->pending_buffers);
+
+ ret = GST_OMX_ACQUIRE_BUFFER_OK;
+ goto done;
+ }
+#else
if (port->flushing) {
- GST_DEBUG_OBJECT (comp->parent, "Component %s port %d is %s",
- comp->name, port->index, (port->flushing ? "flushing" : "flush_start"));
+#endif
+ GST_DEBUG_OBJECT (comp->parent, "Component %s port %d is flushing",
+ comp->name, port->index);
ret = GST_OMX_ACQUIRE_BUFFER_FLUSHING;
goto done;
}
if (g_queue_is_empty (&port->pending_buffers)) {
GST_DEBUG_OBJECT (comp->parent, "Queue of %s port %u is empty",
comp->name, port->index);
- gst_omx_component_wait_message (comp, 33 * GST_MSECOND);
+
+ if (wait == GST_OMX_WAIT) {
+#ifdef TIZEN_FEATURE_OMX
++ gst_omx_component_wait_message (comp, 33 * GST_MSECOND);
++#else
+ gst_omx_component_wait_message (comp,
+ timeout == -2 ? GST_CLOCK_TIME_NONE : timeout);
+#endif
- /* And now check everything again and maybe get a buffer */
- goto retry;
+ /* And now check everything again and maybe get a buffer */
+ goto retry;
+ } else {
+ ret = GST_OMX_ACQUIRE_BUFFER_NO_AVAILABLE;
+ goto done;
+ }
}
GST_DEBUG_OBJECT (comp->parent, "%s port %u has pending buffers",
buf->used = TRUE;
if (port->port_def.eDir == OMX_DirInput) {
+ log_omx_api_trace_buffer (comp, "EmptyThisBuffer", buf);
++#ifdef TIZEN_FEATURE_OMX
+ GST_LOG_OBJECT (comp->parent, "Calling OMX_EmptyThisBuffer. NalType : [(%p)0x%02x, 0x%02x], nFilledLen : %lu",
+ buf, buf->omx_buf->pBuffer[4], buf->omx_buf->pBuffer[10], buf->omx_buf->nFilledLen);
++#endif
err = OMX_EmptyThisBuffer (comp->handle, buf->omx_buf);
} else {
+ log_omx_api_trace_buffer (comp, "FillThisBuffer", buf);
++#ifdef TIZEN_FEATURE_OMX
+ GST_LOG_OBJECT (comp->parent, "Calling OMX_FillThisBuffer. pBuffer : [%p]", buf->omx_buf->pBuffer);
++#endif
err = OMX_FillThisBuffer (comp->handle, buf->omx_buf);
}
- GST_DEBUG_OBJECT (comp->parent, "Released buffer %p to %s port %u: %s "
+ DEBUG_IF_OK (comp->parent, err, "Released buffer %p to %s port %u: %s "
"(0x%08x)", buf, comp->name, port->index, gst_omx_error_to_string (err),
err);
g_assert (buf->omx_buf->pAppPrivate == buf);
/* In the beginning all buffers are not owned by the component */
++#ifdef TIZEN_FEATURE_OMX
+ GST_DEBUG_OBJECT (comp->parent, "Pushing pending_buffers, port:[%d], Buffer:[%p]",
+ port->index, buf);
++#endif
g_queue_push_tail (&port->pending_buffers, buf);
-
if (buffers || images)
l = l->next;
}
return err;
}
+#ifdef TIZEN_FEATURE_OMX
+/* NOTE: Uses comp->lock and comp->messages_lock */
+OMX_ERRORTYPE
+gst_omx_port_tbm_allocate_dec_buffers (GstOMXPort * port)
+{
+ gint i = 0;
+ gint num = 0;
+ GList *buffers = NULL;
+ tbm_surface_h buffer[MAX_INPUT_BUFFER];
+ GstOMXComponent *comp;
+ OMX_ERRORTYPE err = OMX_ErrorNone;
+ OMX_CONFIG_RECTTYPE rect;
+
+ g_return_val_if_fail (port != NULL, OMX_ErrorUndefined);
+
+ comp = port->comp;
+
+ GST_OMX_INIT_STRUCT (&rect);
+ rect.nPortIndex = port->index;
+
+ err =
+ gst_omx_component_get_config (comp, OMX_IndexConfigCommonOutputCrop,
+ &rect);
+ if (err != OMX_ErrorNone) {
+ rect.nLeft = 0;
+ rect.nTop = 0;
+ rect.nWidth = port->port_def.format.video.nFrameWidth;
+ rect.nHeight = port->port_def.format.video.nFrameHeight;
+ }
+
+ g_mutex_lock (&port->comp->lock);
+
+ /* deallocate previous allocated buffers... */
+ if (port->buffers)
+ gst_omx_port_deallocate_buffers (port);
+
+ if (port->use_buffer) {
+ for (i = 0; i < port->port_def.nBufferCountActual; i++) {
+ buffer[i] = tbm_surface_internal_create_with_flags (rect.nWidth, rect.nHeight, TBM_FORMAT_NV12, TBM_BO_WC);
+ if (!buffer[i]) {
+ g_mutex_unlock (&port->comp->lock);
+ goto error;
+ }
+
+ buffers = g_list_append (buffers, (gpointer) buffer[i]);
+
+ GST_INFO_OBJECT (comp->parent,
+ "Allocating %d buffer surface : %p for %s port %u",
+ i, buffer[i], comp->name, (guint) port->index);
+ }
+ }
+
+ num = port->use_buffer ? g_list_length ((GList *) buffers) : -1;
+ err = gst_omx_port_allocate_buffers_unlocked (port, buffers, NULL, num);
+
+ g_list_free (buffers);
+ g_mutex_unlock (&port->comp->lock);
+
+ return err;
+
+error:
+ for (i = 0; i < port->port_def.nBufferCountActual; i++) {
+ if (buffer[i]) {
+ tbm_surface_internal_destroy (buffer[i]);
+ buffer[i] = NULL;
+ }
+ }
+ g_list_free (buffers);
+ return OMX_ErrorInsufficientResources;
+}
+
+/* NOTE: Uses comp->lock and comp->messages_lock */
+OMX_ERRORTYPE
+gst_omx_port_tbm_allocate_enc_buffers (GstOMXPort * port)
+{
+ OMX_ERRORTYPE err = OMX_ErrorNone;
+ gint i = 0;
+ gint num = 0;
+ GList *buffers = NULL;
+ tbm_surface_h buffer[MAX_INPUT_BUFFER];
+
+ g_return_val_if_fail (port != NULL, OMX_ErrorUndefined);
+
+ g_mutex_lock (&port->comp->lock);
+
+ /* deallocate previous allocated buffers... */
+ if (port->buffers)
+ gst_omx_port_deallocate_buffers (port);
+
+ if (port->use_buffer) {
+ for (i = 0; i < port->port_def.nBufferCountActual; i++) {
+
+ /* Since the input buffer is queued via OMX_EmptyThisBuffer(),
+ * a minimum amount of memory is sufficient.
+ */
+ buffer[i] = tbm_surface_internal_create_with_flags (128, 128, TBM_FORMAT_NV12, TBM_BO_WC);
+
+ if (!buffer[i]) {
+ g_mutex_unlock (&port->comp->lock);
+ goto error;
+ }
+
+ buffers = g_list_append (buffers, (gpointer) buffer[i]);
+ }
+ }
+
+ num = port->use_buffer ? g_list_length ((GList *) buffers) : -1;
+ err = gst_omx_port_allocate_buffers_unlocked (port, buffers, NULL, num);
+
+ g_list_free (buffers);
+ g_mutex_unlock (&port->comp->lock);
+
+ return err;
+
+error:
+ for (i = 0; i < port->port_def.nBufferCountActual; i++) {
+ if (buffer[i]) {
+ tbm_surface_internal_destroy (buffer[i]);
+ buffer[i] = NULL;
+ }
+ }
+ g_list_free (buffers);
+ return OMX_ErrorInsufficientResources;
+}
+#endif
++
/* NOTE: Uses comp->lock and comp->messages_lock */
OMX_ERRORTYPE
gst_omx_port_use_buffers (GstOMXPort * port, const GList * buffers)
/* Reset all flags, some implementations don't
* reset them themselves and the flags are not
- * valid anymore after the buffer was consumed
+ * valid anymore after the buffer was consumed.
+ * Also reset nFilledLen as FillThisBuffer() expects an empty buffer.
*/
- buf->omx_buf->nFlags = 0;
+ gst_omx_buffer_reset (buf);
+
+ log_omx_api_trace_buffer (comp, "FillThisBuffer", buf);
++#ifdef TIZEN_FEATURE_OMX
+ GST_DEBUG_OBJECT(comp->parent,"Calling OMX_FillThisBuffer. buffer[%p]. function:[%s]",buf->omx_buf,__func__);
++#endif
err = OMX_FillThisBuffer (comp->handle, buf->omx_buf);
if (err != OMX_ErrorNone) {
GError *err;
gchar *core_name, *component_name, *component_role;
gint in_port_index, out_port_index;
++#ifdef TIZEN_FEATURE_OMX
+ gint in_port_usebuffer, out_port_usebuffer;
++#endif
gchar *template_caps;
GstPadTemplate *templ;
GstCaps *caps;
#include <OMX_Core.h>
#include <OMX_Component.h>
- #include <gst/allocators/gstdmabuf.h>
+#ifdef TIZEN_FEATURE_OMX
+#include <unistd.h>
+#include <tbm_surface.h>
+#include <tbm_surface_internal.h>
+#include <gst/allocators/gsttizenmemory.h>
+#endif
+
#ifdef USE_OMX_TARGET_RPI
#include <OMX_Broadcom.h>
#endif
(st)->nVersion.s.nStep = OMX_VERSION_STEP; \
} G_STMT_END
+ #ifdef OMX_SKIP64BIT
+ #define GST_OMX_GET_TICKS(ticks) ((((guint64) (ticks).nHighPart) << 32) | ((ticks).nLowPart))
+ #define GST_OMX_SET_TICKS(ticks, i) G_STMT_START { \
+ ticks.nLowPart = ((guint64) (i)) & 0xffffffff; \
+ ticks.nHighPart = ((guint64) (i)) >> 32; \
+ } G_STMT_END
+ #else
+ #define GST_OMX_GET_TICKS(ticks) (ticks)
+ #define GST_OMX_SET_TICKS(ticks, i) G_STMT_START { \
+ ticks = i; \
+ } G_STMT_END
+ #endif
+
+#if defined(USE_OMX_TARGET_EXYNOS) || defined(USE_OMX_TARGET_EXYNOS64)
+#define OMX_INIT_PARAM(param) G_STMT_START { \
+ memset (&(param), 0, sizeof ((param))); \
+ (param).nSize = sizeof (param); \
+ (param).nVersion.s.nVersionMajor = 1; \
+ (param).nVersion.s.nVersionMinor = 1; \
+} G_STMT_END
+#endif
+
+ /* If set on an element property means "use the OMX default value".
+ * If set on a default_* variable means that the default values hasn't been
+ * retrieved from OMX yet. */
+ #define GST_OMX_PROP_OMX_DEFAULT G_MAXUINT32
+
+ /* OMX_StateInvalid does not exist in 1.2.0 spec. The initial state is now
+ * StateLoaded. Problem is that gst-omx still needs an initial state different
+ * than StateLoaded. Otherwise gst_omx_component_set_state(StateLoaded) will
+ * early return because it will think it is already in StateLoaded. Also note
+ * that there is no call to gst_omx_component_set_state(StateInvalid) so this
+ * also shows that StateInvalid is used as a helper in gst-omx.
+ */
+ #if OMX_VERSION_MINOR == 2
+ #define OMX_StateInvalid OMX_StateReserved_0x00000000
+ #endif
+
/* Different hacks that are required to work around
* bugs in different OpenMAX implementations
*/
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 */
+ GstOMXBufferAllocation allocation;
+ gboolean using_pool; /* TRUE if the buffers of this port are managed by a pool */
+#ifdef TIZEN_FEATURE_OMX
+ gboolean use_buffer;
+ gboolean flush_start;
+#endif
/* Increased whenever the settings of these port change.
* If settings_cookie != configured_settings_cookie
/* TRUE if this is an EGLImage */
gboolean eglimage;
+
+ /* Used in dynamic buffer mode to keep track of the mapped content while it's
+ * being processed by the OMX component. */
+ GstVideoFrame input_frame;
+ gboolean input_frame_mapped; /* TRUE if input_frame is valid */
+ GstMemory *input_mem;
+ GstBuffer *input_buffer;
+ gboolean input_buffer_mapped;
+ GstMapInfo map;
+#ifdef TIZEN_FEATURE_OMX
+ tbm_surface_h surface;
+#endif
};
struct _GstOMXClassData {
typedef struct _GstOMXMemoryAllocator GstOMXMemoryAllocator;
typedef struct _GstOMXMemoryAllocatorClass GstOMXMemoryAllocatorClass;
+ enum
+ {
+ SIG_ALLOCATE,
+ LAST_SIGNAL
+ };
+
+ static guint signals[LAST_SIGNAL] = { 0 };
+
struct _GstOMXMemory
{
++#ifdef TIZEN_FEATURE_OMX
+ GstTizenMemory mem;
++#else
+ GstMemory mem;
++#endif
GstOMXBuffer *buf;
};
meta = gst_buffer_get_video_meta (buf);
if (!meta) {
++#ifdef TIZEN_FEATURE_OMX
+ meta = gst_buffer_add_video_meta (buf, GST_VIDEO_FRAME_FLAG_NONE,
++#else
+ gst_buffer_add_video_meta (buf, GST_VIDEO_FRAME_FLAG_NONE,
++#endif
GST_VIDEO_INFO_FORMAT (&pool->video_info),
GST_VIDEO_INFO_WIDTH (&pool->video_info),
GST_VIDEO_INFO_HEIGHT (&pool->video_info));
const guint nslice = pool->port->port_def.format.video.nSliceHeight;
gsize offset[GST_VIDEO_MAX_PLANES] = { 0, };
gint stride[GST_VIDEO_MAX_PLANES] = { nstride, 0, };
-
+#ifdef TIZEN_FEATURE_OMX
- tbm_surface_h surface;
++ tbm_surface_h surface = NULL;
+ uint32_t _offset = 0;
+ uint32_t _stride = 0;
++#endif
+
+ if (pool->output_mode == GST_OMX_BUFFER_MODE_DMABUF) {
+ gint fd;
+ GstMapInfo map;
- surface = (tbm_surface_h) omx_buf->omx_buf->pBuffer;
+ fd = GPOINTER_TO_INT (omx_buf->omx_buf->pBuffer);
- mem = gst_tizen_allocator_alloc_surface (pool->allocator, &pool->video_info, surface, omx_buf, (GDestroyNotify) _destroy_tbm_surface);
+ mem =
+ gst_dmabuf_allocator_alloc (pool->allocator, fd,
+ omx_buf->omx_buf->nAllocLen);
+
+ if (!gst_caps_features_contains (gst_caps_get_features (pool->caps, 0),
+ GST_CAPS_FEATURE_MEMORY_DMABUF)) {
+ /* Check if the memory is actually mappable */
+ if (!gst_memory_map (mem, &map, GST_MAP_READWRITE)) {
+ GST_ERROR_OBJECT (pool,
+ "dmabuf memory is not mappable but caps does not have the 'memory:DMABuf' feature");
+ gst_memory_unref (mem);
+ return GST_FLOW_ERROR;
+ }
+
+ gst_memory_unmap (mem, &map);
+ }
++#ifdef TIZEN_FEATURE_OMX
++ } else {
++ surface = (tbm_surface_h) omx_buf->omx_buf->pBuffer;
++
++ mem = gst_tizen_allocator_alloc_surface (pool->allocator, &pool->video_info,
++ surface, omx_buf, (GDestroyNotify)_destroy_tbm_surface);
+#else
- mem = gst_omx_memory_allocator_alloc (pool->allocator, 0, omx_buf);
+ } else {
+ mem = gst_omx_memory_allocator_alloc (pool->allocator, 0, omx_buf);
+#endif
+ }
+
buf = gst_buffer_new ();
gst_buffer_append_memory (buf, mem);
g_ptr_array_add (pool->buffers, buf);
/* We always add the videometa. It's the job of the user
* to copy the buffer if pool->need_copy is TRUE
*/
- GstVideoMeta *meta;
-
- meta = gst_buffer_add_video_meta_full (buf, GST_VIDEO_FRAME_FLAG_NONE,
++#ifdef TIZEN_FEATURE_OMX
++ GstVideoMeta *meta = gst_buffer_add_video_meta_full (buf, GST_VIDEO_FRAME_FLAG_NONE,
++#else
+ gst_buffer_add_video_meta_full (buf, GST_VIDEO_FRAME_FLAG_NONE,
++#endif
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);
-
+#ifdef TIZEN_FEATURE_OMX
+ meta->map = gst_omx_video_memory_map;
+ meta->unmap = gst_omx_video_memory_unmap;
+#endif
}
}
/* If it's our own memory we have to set the sizes */
if (!pool->other_pool) {
- GstMemory *mem = gst_buffer_peek_memory (buf, 0);
- #ifdef TIZEN_FEATURE_OMX
+ GstMemory *mem = gst_buffer_peek_memory (*buffer, 0);
GstOMXBuffer *omx_buf;
- if (pool->output_mode == GST_OMX_BUFFER_MODE_TBM) {
- omx_buf =
- gst_mini_object_get_qdata (GST_MINI_OBJECT_CAST (buf),
- gst_omx_buffer_data_quark);
+ if (pool->output_mode == GST_OMX_BUFFER_MODE_DMABUF) {
+ omx_buf = gst_omx_buffer_get_omx_buf (buf);
++#ifdef TIZEN_FEATURE_OMX
++ } else if (pool->output_mode == GST_OMX_BUFFER_MODE_TBM) {
++ omx_buf = gst_omx_buffer_get_omx_buf (buf);
++#endif
} else {
g_assert (mem
- && g_strcmp0 (mem->allocator->mem_type, GST_OMX_MEMORY_TYPE) == 0);
+ && g_strcmp0 (mem->allocator->mem_type, GST_OMX_MEMORY_TYPE) == 0);
/* We already have a pointer to the GstOMXBuffer, no need to retrieve it
- from the qdata */
- omx_buf = ((GstTizenMemory *) mem)->user_data;
+ * from the qdata */
+ omx_buf = ((GstOMXMemory *) mem)->buf;
}
mem->size = omx_buf->omx_buf->nFilledLen;
pool->allocator =
g_object_new (gst_omx_memory_allocator_get_type (), NULL);
break;
++#ifdef TIZEN_FEATURE_OMX
+ case GST_OMX_BUFFER_MODE_TBM:
+ pool->allocator = gst_tizen_allocator_new ();
+ break;
++#endif
default:
g_assert_not_reached ();
}
typedef enum {
GST_OMX_BUFFER_MODE_SYSTEM_MEMORY,
GST_OMX_BUFFER_MODE_DMABUF,
- } GstOMXBufferMode;
++#ifdef TIZEN_FEATURE_OMX
+ GST_OMX_BUFFER_MODE_TBM
+#endif
+ } GstOMXBufferMode;
struct _GstOMXBufferPool
{
GType gst_omx_buffer_pool_get_type (void);
- #ifdef TIZEN_FEATURE_OMX
- GstBufferPool *gst_omx_buffer_pool_new (GstElement * element, GstOMXComponent * component, GstOMXPort * port,
- GstOMXBufferMode output_mode);
+ GstBufferPool *gst_omx_buffer_pool_new (GstElement * element, GstOMXComponent * component, GstOMXPort * port, GstOMXBufferMode output_mode);
- #else
- GstBufferPool *gst_omx_buffer_pool_new (GstElement * element, GstOMXComponent * component, GstOMXPort * port);
++#ifdef TIZEN_FEATURE_OMX
+gboolean gst_omx_video_memory_map (GstVideoMeta * meta, guint plane, GstMapInfo * info,
+ gpointer * data, gint * stride, GstMapFlags flags);
+
+gboolean gst_omx_video_memory_unmap (GstVideoMeta * meta, guint plane, GstMapInfo * info);
+#endif
+
G_END_DECLS
#endif /* __GST_OMX_BUFFER_POOL_H__ */
videodec_class->cdata.default_sink_template_caps = "video/x-h264, "
"alignment=(string) au, "
"stream-format=(string) byte-stream, "
- "width=(int) [1,MAX], " "height=(int) [1,MAX],"
+#ifdef TIZEN_FEATURE_OMX
++ "width=(int) [1,MAX], " "height=(int) [1,MAX],"
+ "framerate = (fraction) [0/1, MAX]";
+#else
- "parsed=(boolean) true ";
+ "width=(int) [1,MAX], " "height=(int) [1,MAX]";
+#endif
gst_element_class_set_static_metadata (element_class,
"OpenMAX H.264 Video Decoder",
#ifdef USE_OMX_TARGET_RPI
PROP_INLINESPSPPSHEADERS,
#endif
+#if defined(USE_OMX_TARGET_EXYNOS) || defined(USE_OMX_TARGET_EXYNOS64)
+ PROP_NUM_REF_FRAME,
+ PROP_NUM_B_FRAME,
+#endif
PROP_PERIODICITYOFIDRFRAMES,
- PROP_INTERVALOFCODINGINTRAFRAMES
+ PROP_PERIODICITYOFIDRFRAMES_COMPAT,
+ PROP_INTERVALOFCODINGINTRAFRAMES,
+ PROP_B_FRAMES,
+ PROP_ENTROPY_MODE,
+ PROP_CONSTRAINED_INTRA_PREDICTION,
+ PROP_LOOP_FILTER_MODE,
};
#ifdef USE_OMX_TARGET_RPI
#define GST_OMX_H264_VIDEO_ENC_INLINE_SPS_PPS_HEADERS_DEFAULT TRUE
#endif
+#if defined(USE_OMX_TARGET_EXYNOS) || defined(USE_OMX_TARGET_EXYNOS64)
+#define GST_OMX_VIDEO_ENC_NUM_REF_FRAME_DEFAULT (0x00000001)
+#define GST_OMX_VIDEO_ENC_NUM_REF_FRAME_MAX (0x00000002)
+#define GST_OMX_VIDEO_ENC_NUM_B_FRAME_DEFAULT (0x00000001)
+#define GST_OMX_VIDEO_ENC_NUM_B_FRAME_MAX (0x00000002)
+#endif
#define GST_OMX_H264_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT (0xffffffff)
#define GST_OMX_H264_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT (0xffffffff)
+ #define GST_OMX_H264_VIDEO_ENC_B_FRAMES_DEFAULT (0xffffffff)
+ #define GST_OMX_H264_VIDEO_ENC_ENTROPY_MODE_DEFAULT (0xffffffff)
+ #define GST_OMX_H264_VIDEO_ENC_CONSTRAINED_INTRA_PREDICTION_DEFAULT (FALSE)
+ #define GST_OMX_H264_VIDEO_ENC_LOOP_FILTER_MODE_DEFAULT (0xffffffff)
/* class initialization */
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
#endif
+#if defined(USE_OMX_TARGET_EXYNOS) || defined(USE_OMX_TARGET_EXYNOS64)
+ g_object_class_install_property (gobject_class, PROP_NUM_REF_FRAME,
+ g_param_spec_uint ("reference-frame", "set number of reference frame",
+ "The number of reference frame (0x00000001=component default)",
+ GST_OMX_VIDEO_ENC_NUM_REF_FRAME_DEFAULT, GST_OMX_VIDEO_ENC_NUM_REF_FRAME_MAX,
+ GST_OMX_VIDEO_ENC_NUM_REF_FRAME_DEFAULT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+ GST_PARAM_MUTABLE_READY));
+ g_object_class_install_property (gobject_class, PROP_NUM_B_FRAME,
+ g_param_spec_uint ("b-frame", "set number of b frame",
+ "The number of reference frame (0x00000001=component default)",
+ GST_OMX_VIDEO_ENC_NUM_B_FRAME_DEFAULT, GST_OMX_VIDEO_ENC_NUM_B_FRAME_MAX,
+ GST_OMX_VIDEO_ENC_NUM_B_FRAME_DEFAULT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+ GST_PARAM_MUTABLE_READY));
+#endif
g_object_class_install_property (gobject_class, PROP_PERIODICITYOFIDRFRAMES,
- g_param_spec_uint ("periodicty-idr", "Target Bitrate",
+ g_param_spec_uint ("periodicity-idr", "IDR periodicity",
"Periodicity of IDR frames (0xffffffff=component default)",
0, G_MAXUINT,
GST_OMX_H264_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT,
self->inline_sps_pps_headers = g_value_get_boolean (value);
break;
#endif
+#if defined(USE_OMX_TARGET_EXYNOS) || defined(USE_OMX_TARGET_EXYNOS64)
+ case PROP_NUM_REF_FRAME:
+ self->reference_frame = g_value_get_int (value);
+ break;
+ case PROP_NUM_B_FRAME:
+ self->b_frame = g_value_get_int (value);
+ break;
+#endif
case PROP_PERIODICITYOFIDRFRAMES:
+ case PROP_PERIODICITYOFIDRFRAMES_COMPAT:
self->periodicty_idr = g_value_get_uint (value);
break;
case PROP_INTERVALOFCODINGINTRAFRAMES:
g_value_set_boolean (value, self->inline_sps_pps_headers);
break;
#endif
+#if defined(USE_OMX_TARGET_EXYNOS) || defined(USE_OMX_TARGET_EXYNOS64)
+ case PROP_NUM_REF_FRAME:
+ g_value_set_uint (value, self->reference_frame);
+ break;
+ case PROP_NUM_B_FRAME:
+ g_value_set_uint (value, self->b_frame);
+ break;
+#endif
case PROP_PERIODICITYOFIDRFRAMES:
+ case PROP_PERIODICITYOFIDRFRAMES_COMPAT:
g_value_set_uint (value, self->periodicty_idr);
break;
case PROP_INTERVALOFCODINGINTRAFRAMES:
#ifdef USE_OMX_TARGET_RPI
OMX_CONFIG_PORTBOOLEANTYPE config_inline_header;
#endif
+#if defined(USE_OMX_TARGET_EXYNOS) || defined(USE_OMX_TARGET_EXYNOS64)
+ OMX_VIDEO_PARAM_AVCTYPE avc_param;
+#endif
OMX_ERRORTYPE err;
const gchar *profile_string, *level_string;
+ OMX_VIDEO_AVCPROFILETYPE profile = OMX_VIDEO_AVCProfileMax;
+ OMX_VIDEO_AVCLEVELTYPE level = OMX_VIDEO_AVCLevelMax;
#ifdef USE_OMX_TARGET_RPI
GST_OMX_INIT_STRUCT (&config_inline_header);
return FALSE;
}
#endif
+#if defined(USE_OMX_TARGET_EXYNOS) || defined(USE_OMX_TARGET_EXYNOS64)
+ GST_OMX_INIT_STRUCT (&avc_param);
+
+ err =
+ gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+ OMX_IndexParamVideoAvc, &avc_param);
+ if (err != OMX_ErrorNone) {
+ GST_ERROR_OBJECT (self,
+ "can't get OMX_IndexParamVideoAvc %s (0x%08x)",
+ gst_omx_error_to_string (err), err);
+ return FALSE;
+ }
+
+ GST_DEBUG_OBJECT (self, "default nRefFrames:%u, nBFrames:%u",
+ (guint) avc_param.nRefFrames,
+ (guint) avc_param.nBFrames);
+
+ avc_param.nRefFrames = self->reference_frame;
+ avc_param.nBFrames = self->b_frame;
+ err =
+ gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+ OMX_IndexParamVideoAvc, &avc_param);
+ if (err != OMX_ErrorNone) {
+ GST_ERROR_OBJECT (self,
+ "can't set OMX_IndexParamVideoAvc %s (0x%08x)",
+ gst_omx_error_to_string (err), err);
+ return FALSE;
+ }
+
+#endif
+ /* Configure GOP pattern */
if (self->periodicty_idr !=
GST_OMX_H264_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT
|| self->interval_intraframes !=
#ifdef USE_OMX_TARGET_RPI
gboolean inline_sps_pps_headers;
#endif
+#if defined(USE_OMX_TARGET_EXYNOS) || defined(USE_OMX_TARGET_EXYNOS64)
+ guint32 reference_frame;
+ guint32 b_frame;
+#endif
guint32 periodicty_idr;
guint32 interval_intraframes;
+ guint32 b_frames;
+ guint32 entropy_mode;
+ gboolean constrained_intra_prediction;
+ guint32 loop_filter_mode;
GList *headers;
};
format = GST_VIDEO_FORMAT_I420;
break;
case OMX_COLOR_FormatYUV420SemiPlanar:
+ case OMX_COLOR_FormatYUV420PackedSemiPlanar:
+#ifdef TIZEN_FEATURE_OMX
+ format = GST_VIDEO_FORMAT_SN12;
+#else
format = GST_VIDEO_FORMAT_NV12;
+#endif
break;
case OMX_COLOR_FormatYUV422SemiPlanar:
format = GST_VIDEO_FORMAT_NV16;
static OMX_ERRORTYPE gst_omx_video_dec_allocate_output_buffers (GstOMXVideoDec *
self);
- static OMX_ERRORTYPE gst_omx_video_dec_deallocate_output_buffers (GstOMXVideoDec
+ static gboolean gst_omx_video_dec_deallocate_output_buffers (GstOMXVideoDec
* self);
+#ifdef TIZEN_FEATURE_OMX
+static gboolean gst_omx_video_dec_acquire_request_flush_event (GstOMXVideoDec * self, GstEvent ** flush_request_event);
+static gboolean gst_omx_video_dec_handle_event (GstVideoDecoder * decoder, GstEvent *event);
+#endif
+
enum
{
- PROP_0
+ PROP_0,
+ PROP_INTERNAL_ENTROPY_BUFFERS,
};
+ #define GST_OMX_VIDEO_DEC_INTERNAL_ENTROPY_BUFFERS_DEFAULT (5)
+
/* class initialization */
#define DEBUG_INIT \
video_decoder_class->handle_frame =
GST_DEBUG_FUNCPTR (gst_omx_video_dec_handle_frame);
video_decoder_class->finish = GST_DEBUG_FUNCPTR (gst_omx_video_dec_finish);
+ video_decoder_class->drain = GST_DEBUG_FUNCPTR (gst_omx_video_dec_drain);
video_decoder_class->decide_allocation =
GST_DEBUG_FUNCPTR (gst_omx_video_dec_decide_allocation);
+ video_decoder_class->propose_allocation =
+ GST_DEBUG_FUNCPTR (gst_omx_video_dec_propose_allocation);
+#ifdef TIZEN_FEATURE_OMX
+ video_decoder_class->sink_event = GST_DEBUG_FUNCPTR (gst_omx_video_dec_handle_event);
+#endif
+
klass->cdata.type = GST_OMX_COMPONENT_TYPE_FILTER;
klass->cdata.default_src_template_caps =
- #if defined (USE_OMX_TARGET_RPI) && defined (HAVE_GST_GL)
+ #if defined (HAVE_GST_GL)
GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_GL_MEMORY,
"RGBA") "; "
#endif
ret = TRUE;
goto done;
}
- #endif //ENS:a
++#endif
/* Different strides */
+#ifndef TIZEN_FEATURE_OMX
if (gst_video_frame_map (&frame, vinfo, outbuf, GST_MAP_WRITE)) {
- const guint nstride = port_def->format.video.nStride;
- const guint nslice = port_def->format.video.nSliceHeight;
- guint src_stride[GST_VIDEO_MAX_PLANES] = { nstride, 0, };
- guint src_size[GST_VIDEO_MAX_PLANES] = { nstride * nslice, 0, };
- gint dst_width[GST_VIDEO_MAX_PLANES] = { 0, };
- gint dst_height[GST_VIDEO_MAX_PLANES] =
- { GST_VIDEO_INFO_HEIGHT (vinfo), 0, };
- const guint8 *src;
- guint p;
- #endif
-
- switch (GST_VIDEO_INFO_FORMAT (vinfo)) {
+ const guint nstride = port_def->format.video.nStride;
+ const guint nslice = port_def->format.video.nSliceHeight;
+ guint src_stride[GST_VIDEO_MAX_PLANES] = { nstride, 0, };
+ guint src_size[GST_VIDEO_MAX_PLANES] = { nstride * nslice, 0, };
+ gint dst_width[GST_VIDEO_MAX_PLANES] = { 0, };
+ gint dst_height[GST_VIDEO_MAX_PLANES] =
+ { GST_VIDEO_INFO_HEIGHT (vinfo), 0, };
+ const guint8 *src;
+ guint p;
++#endif
+
+ switch (GST_VIDEO_INFO_FORMAT (vinfo)) {
+#ifndef TIZEN_FEATURE_OMX
- case GST_VIDEO_FORMAT_ABGR:
- case GST_VIDEO_FORMAT_ARGB:
- dst_width[0] = GST_VIDEO_INFO_WIDTH (vinfo) * 4;
- break;
- case GST_VIDEO_FORMAT_RGB16:
- case GST_VIDEO_FORMAT_BGR16:
- case GST_VIDEO_FORMAT_YUY2:
- case GST_VIDEO_FORMAT_UYVY:
- case GST_VIDEO_FORMAT_YVYU:
- dst_width[0] = GST_VIDEO_INFO_WIDTH (vinfo) * 2;
- break;
- case GST_VIDEO_FORMAT_GRAY8:
- dst_width[0] = GST_VIDEO_INFO_WIDTH (vinfo);
- break;
- case GST_VIDEO_FORMAT_I420:
- dst_width[0] = GST_VIDEO_INFO_WIDTH (vinfo);
- src_stride[1] = nstride / 2;
- src_size[1] = (src_stride[1] * nslice) / 2;
- dst_width[1] = GST_VIDEO_INFO_WIDTH (vinfo) / 2;
- dst_height[1] = GST_VIDEO_INFO_HEIGHT (vinfo) / 2;
- src_stride[2] = nstride / 2;
- src_size[2] = (src_stride[1] * nslice) / 2;
- dst_width[2] = GST_VIDEO_INFO_WIDTH (vinfo) / 2;
- dst_height[2] = GST_VIDEO_INFO_HEIGHT (vinfo) / 2;
- break;
- case GST_VIDEO_FORMAT_NV12:
- dst_width[0] = GST_VIDEO_INFO_WIDTH (vinfo);
- src_stride[1] = nstride;
- src_size[1] = src_stride[1] * nslice / 2;
- dst_width[1] = GST_VIDEO_INFO_WIDTH (vinfo);
- dst_height[1] = GST_VIDEO_INFO_HEIGHT (vinfo) / 2;
- break;
- case GST_VIDEO_FORMAT_NV16:
- dst_width[0] = GST_VIDEO_INFO_WIDTH (vinfo);
- src_stride[1] = nstride;
- src_size[1] = src_stride[1] * nslice;
- dst_width[1] = GST_VIDEO_INFO_WIDTH (vinfo);
- dst_height[1] = GST_VIDEO_INFO_HEIGHT (vinfo);
- break;
+ case GST_VIDEO_FORMAT_ABGR:
+ case GST_VIDEO_FORMAT_ARGB:
+ dst_width[0] = GST_VIDEO_INFO_WIDTH (vinfo) * 4;
+ break;
+ case GST_VIDEO_FORMAT_RGB16:
+ case GST_VIDEO_FORMAT_BGR16:
+ case GST_VIDEO_FORMAT_YUY2:
+ case GST_VIDEO_FORMAT_UYVY:
+ case GST_VIDEO_FORMAT_YVYU:
+ dst_width[0] = GST_VIDEO_INFO_WIDTH (vinfo) * 2;
+ break;
+ case GST_VIDEO_FORMAT_GRAY8:
+ dst_width[0] = GST_VIDEO_INFO_WIDTH (vinfo);
+ break;
+ case GST_VIDEO_FORMAT_I420:
+ dst_width[0] = GST_VIDEO_INFO_WIDTH (vinfo);
+ src_stride[1] = nstride / 2;
+ src_size[1] = (src_stride[1] * nslice) / 2;
+ dst_width[1] = GST_VIDEO_INFO_WIDTH (vinfo) / 2;
+ dst_height[1] = GST_VIDEO_INFO_HEIGHT (vinfo) / 2;
+ src_stride[2] = nstride / 2;
+ src_size[2] = (src_stride[1] * nslice) / 2;
+ dst_width[2] = GST_VIDEO_INFO_WIDTH (vinfo) / 2;
+ dst_height[2] = GST_VIDEO_INFO_HEIGHT (vinfo) / 2;
+ break;
+ case GST_VIDEO_FORMAT_NV12:
+ dst_width[0] = GST_VIDEO_INFO_WIDTH (vinfo);
+ src_stride[1] = nstride;
+ src_size[1] = src_stride[1] * nslice / 2;
+ dst_width[1] = GST_VIDEO_INFO_WIDTH (vinfo);
+ dst_height[1] = GST_VIDEO_INFO_HEIGHT (vinfo) / 2;
+ break;
+ case GST_VIDEO_FORMAT_NV16:
+ dst_width[0] = GST_VIDEO_INFO_WIDTH (vinfo);
+ src_stride[1] = nstride;
+ src_size[1] = src_stride[1] * nslice;
+ dst_width[1] = GST_VIDEO_INFO_WIDTH (vinfo);
+ dst_height[1] = GST_VIDEO_INFO_HEIGHT (vinfo);
+ break;
+ case GST_VIDEO_FORMAT_NV12_10LE32:
+ /* Need ((width + 2) / 3) 32-bits words */
+ dst_width[0] = (GST_VIDEO_INFO_WIDTH (vinfo) + 2) / 3 * 4;
+ dst_width[1] = dst_width[0];
+ src_stride[1] = nstride;
+ src_size[1] = src_stride[1] * nslice / 2;
+ dst_height[1] = GST_VIDEO_INFO_HEIGHT (vinfo) / 2;
+ break;
+ case GST_VIDEO_FORMAT_NV16_10LE32:
+ /* Need ((width + 2) / 3) 32-bits words */
+ dst_width[0] = (GST_VIDEO_INFO_WIDTH (vinfo) + 2) / 3 * 4;
+ dst_width[1] = dst_width[0];
+ src_stride[1] = nstride;
+ src_size[1] = src_stride[1] * nslice;
+ dst_height[1] = GST_VIDEO_INFO_HEIGHT (vinfo);
+ break;
+#endif
+#ifdef TIZEN_FEATURE_OMX
- case GST_VIDEO_FORMAT_SN12:
- case GST_VIDEO_FORMAT_ST12:
- ret = TRUE;
- break;
++ case GST_VIDEO_FORMAT_SN12:
++ case GST_VIDEO_FORMAT_ST12:
++ ret = TRUE;
++ break;
+#endif
default:
g_assert_not_reached ();
break;
}
was_enabled = FALSE;
}
- err = gst_omx_port_tbm_allocate_dec_buffers (port);
+
+ if (!caps)
+ self->use_buffers = FALSE;
+
+ if (self->use_buffers) {
+ GList *images = NULL;
+ GList *frames = NULL;
+ GstVideoInfo v_info;
+ gint i;
+
+ if (!gst_video_info_from_caps (&v_info, caps)) {
+ GST_INFO_OBJECT (self,
+ "Failed to get video info from caps %" GST_PTR_FORMAT, caps);
+ err = OMX_ErrorUndefined;
+ self->use_buffers = FALSE;
+ }
+
+ GST_DEBUG_OBJECT (self, "Trying to use %d buffers", min);
+
+ for (i = 0; i < min && self->use_buffers; i++) {
+ GstBuffer *buffer = NULL;
+ GstVideoFrame *frame = NULL;
+
+ buffer =
+ gst_omx_try_importing_buffer (self, pool, port, &v_info, i, &frame);
+ if (!buffer) {
+ /* buffer does not match minimal requirement to try OMX_UseBuffer */
+ GST_DEBUG_OBJECT (self, "Failed to import %d-th buffer", i);
+ g_list_free (images);
+ g_list_free_full (frames, (GDestroyNotify) gst_video_frame_unmap);
+ g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
+ buffers = NULL;
+ images = NULL;
+ err = OMX_ErrorUndefined;
+ self->use_buffers = FALSE;
+ break;
+ } else {
+ /* if downstream pool is 1 n_mem then always try to use buffers
+ * and retry without using them if it fails */
+ buffers = g_list_append (buffers, buffer);
+ frames = g_list_append (frames, frame);
+ images =
+ g_list_append (images, GST_VIDEO_FRAME_PLANE_DATA (frame, 0));
+ }
+ }
+
+ /* buffers match minimal requirements then
+ * now try to actually use them */
+ if (images) {
+ err = gst_omx_port_use_buffers (port, images);
+ g_list_free (images);
+ g_list_free_full (frames, (GDestroyNotify) gst_video_frame_unmap);
+
+ if (err == OMX_ErrorNone) {
+ GST_DEBUG_OBJECT (self, "Using %d buffers", min);
+ } else {
+ GST_INFO_OBJECT (self,
+ "Failed to OMX_UseBuffer on port: %s (0x%08x)",
+ gst_omx_error_to_string (err), err);
+ g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
+ self->use_buffers = FALSE;
+ }
+ }
+ }
+
+ if (!self->use_buffers)
+#ifdef TIZEN_FEATURE_OMX
- err = gst_omx_port_allocate_buffers (port);
++ err = gst_omx_port_tbm_allocate_dec_buffers (port);
+#else
+ err = gst_omx_port_allocate_buffers (port);
+#endif
+
if (err != OMX_ErrorNone && min > port->port_def.nBufferCountMin) {
GST_ERROR_OBJECT (self,
"Failed to allocate required number of buffers %d, trying less and copying",
if (caps) {
config = gst_buffer_pool_get_config (self->out_port_pool);
+#ifndef TIZEN_FEATURE_OMX
if (add_videometa)
- /* FIXME : it doensn't get a list of options supported by pool */
- GST_DEBUG_OBJECT (self, "Check if the pool supports option %d", add_videometa);
-
- gst_buffer_pool_config_add_option (config,
- GST_BUFFER_POOL_OPTION_VIDEO_META);
+#endif
+ gst_buffer_pool_config_add_option (config,
+ GST_BUFFER_POOL_OPTION_VIDEO_META);
gst_buffer_pool_config_set_params (config, caps,
self->dec_out_port->port_def.nBufferSize, min, max);
GstVideoCodecFrame *frame;
GstFlowReturn flow_ret = GST_FLOW_OK;
GstOMXAcquireBufferReturn acq_return;
- GstClockTimeDiff deadline;
OMX_ERRORTYPE err;
+#ifdef TIZEN_FEATURE_OMX
+ GstMessage *msg = NULL;
+ GstEvent *flush_request_event = NULL;
+#endif
+
+#if defined (USE_OMX_TARGET_RPI) && defined (HAVE_GST_GL)
+ port = self->eglimage ? self->egl_out_port : self->dec_out_port;
+#else
+ port = self->dec_out_port;
+#endif
#if defined (USE_OMX_TARGET_RPI) && defined (HAVE_GST_GL)
port = self->eglimage ? self->egl_out_port : self->dec_out_port;
return (err == OMX_ErrorNone);
}
- static gboolean
- gst_omx_video_dec_set_format (GstVideoDecoder * decoder,
- GstVideoCodecState * state)
+ #ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
+ static void
+ gst_omx_video_dec_set_latency (GstOMXVideoDec * self)
{
- GstOMXVideoDec *self;
- GstOMXVideoDecClass *klass;
- GstVideoInfo *info = &state->info;
- gboolean is_format_change = FALSE;
- gboolean needs_disable = FALSE;
- OMX_PARAM_PORTDEFINITIONTYPE port_def;
+ GstClockTime latency;
+ OMX_ALG_PARAM_REPORTED_LATENCY param;
+ OMX_ERRORTYPE err;
- self = GST_OMX_VIDEO_DEC (decoder);
- klass = GST_OMX_VIDEO_DEC_GET_CLASS (decoder);
+ GST_OMX_INIT_STRUCT (¶m);
+ err =
+ gst_omx_component_get_parameter (self->dec,
+ (OMX_INDEXTYPE) OMX_ALG_IndexParamReportedLatency, ¶m);
- GST_DEBUG_OBJECT (self, "Setting new caps %" GST_PTR_FORMAT, state->caps);
+ if (err != OMX_ErrorNone) {
+ GST_WARNING_OBJECT (self, "Couldn't retrieve latency: %s (0x%08x)",
+ gst_omx_error_to_string (err), err);
+ return;
+ }
- gst_omx_port_get_port_definition (self->dec_in_port, &port_def);
+ GST_DEBUG_OBJECT (self, "retrieved latency of %d ms",
+ (guint32) param.nLatency);
- /* 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));
- is_format_change |= (self->codec_data != state->codec_data);
- if (klass->is_format_change)
- is_format_change |=
- klass->is_format_change (self, self->dec_in_port, state);
+ /* Convert to ns */
+ latency = param.nLatency * GST_MSECOND;
- needs_disable =
- gst_omx_component_get_state (self->dec,
- GST_CLOCK_TIME_NONE) != OMX_StateLoaded;
- /* If the component is not in Loaded state and a real format change happens
- * we have to disable the port and re-allocate all buffers. If no real
- * format change happened we can just exit here.
- */
- if (needs_disable && !is_format_change) {
- GST_DEBUG_OBJECT (self,
- "Already running and caps did not change the format");
- if (self->input_state)
- gst_video_codec_state_unref (self->input_state);
- self->input_state = gst_video_codec_state_ref (state);
- return TRUE;
- }
+ gst_video_decoder_set_latency (GST_VIDEO_DECODER (self), latency, latency);
+ }
+ #endif
+
+ static gboolean
+ gst_omx_video_dec_disable (GstOMXVideoDec * self)
+ {
+ GstOMXVideoDecClass *klass = GST_OMX_VIDEO_DEC_GET_CLASS (self);
- if (needs_disable && is_format_change) {
#if defined (USE_OMX_TARGET_RPI) && defined (HAVE_GST_GL)
- GstOMXPort *out_port =
- self->eglimage ? self->egl_out_port : self->dec_out_port;
+ GstOMXPort *out_port =
+ self->eglimage ? self->egl_out_port : self->dec_out_port;
#else
- GstOMXPort *out_port = self->dec_out_port;
+ GstOMXPort *out_port = self->dec_out_port;
#endif
- GST_DEBUG_OBJECT (self, "Need to disable and drain decoder");
+ GST_DEBUG_OBJECT (self, "Need to disable and drain decoder");
- gst_omx_video_dec_drain (self);
- gst_omx_video_dec_flush (decoder);
- gst_omx_port_set_flushing (out_port, 5 * GST_SECOND, TRUE);
+ gst_omx_video_dec_drain (GST_VIDEO_DECODER (self));
+ gst_omx_port_set_flushing (out_port, 5 * GST_SECOND, TRUE);
- if (klass->cdata.hacks & GST_OMX_HACK_NO_COMPONENT_RECONFIGURE) {
- GST_VIDEO_DECODER_STREAM_UNLOCK (self);
- gst_omx_video_dec_stop (GST_VIDEO_DECODER (self));
- gst_omx_video_dec_close (GST_VIDEO_DECODER (self));
- GST_VIDEO_DECODER_STREAM_LOCK (self);
+ if (klass->cdata.hacks & GST_OMX_HACK_NO_COMPONENT_RECONFIGURE) {
+ GST_VIDEO_DECODER_STREAM_UNLOCK (self);
+ gst_omx_video_dec_stop (GST_VIDEO_DECODER (self));
+ gst_omx_video_dec_close (GST_VIDEO_DECODER (self));
+ GST_VIDEO_DECODER_STREAM_LOCK (self);
- if (!gst_omx_video_dec_open (GST_VIDEO_DECODER (self)))
- return FALSE;
- needs_disable = FALSE;
- #ifdef TIZEN_FEATURE_OMX
- gst_omx_port_get_port_definition (self->dec_in_port, &port_def);
+ if (!gst_omx_video_dec_open (GST_VIDEO_DECODER (self)))
+ return FALSE;
+
+ self->disabled = FALSE;
+ } else {
+ #if defined (USE_OMX_TARGET_RPI) && defined (HAVE_GST_GL)
+ if (self->eglimage) {
+ 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_omx_port_set_flushing (self->egl_in_port, 5 * GST_SECOND, TRUE);
+ gst_omx_port_set_flushing (self->egl_out_port, 5 * GST_SECOND, TRUE);
+ }
#endif
- } else {
+
+ /* Disabling at the same time input port and output port is only
+ * required when a buffer is shared between the ports. This cannot
+ * be the case for a decoder because its input and output buffers
+ * are of different nature. So let's disable ports sequencially.
+ * Starting from IL 1.2.0, this point has been clarified.
+ * OMX_SendCommand will return an error if the IL client attempts to
+ * call it when there is already an on-going command being processed.
+ * The exception is for buffer sharing above and the event
+ * OMX_EventPortNeedsDisable will be sent to request disabling the
+ * other port at the same time. */
+ if (gst_omx_port_set_enabled (self->dec_in_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_deallocate_buffers (self->dec_in_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_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))
+ return FALSE;
+ if (gst_omx_port_wait_enabled (out_port, 1 * GST_SECOND) != OMX_ErrorNone)
+ return FALSE;
+
#if defined (USE_OMX_TARGET_RPI) && defined (HAVE_GST_GL)
- if (self->eglimage) {
- 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_omx_port_set_flushing (self->egl_in_port, 5 * GST_SECOND, TRUE);
- gst_omx_port_set_flushing (self->egl_out_port, 5 * GST_SECOND, TRUE);
+ if (self->eglimage) {
+ OMX_STATETYPE egl_state;
+
+ egl_state = gst_omx_component_get_state (self->egl_render, 0);
+ if (egl_state > OMX_StateLoaded || egl_state == OMX_StateInvalid) {
+
+ if (egl_state > OMX_StateIdle) {
+ gst_omx_component_set_state (self->egl_render, OMX_StateIdle);
+ gst_omx_component_set_state (self->dec, OMX_StateIdle);
+ egl_state = gst_omx_component_get_state (self->egl_render,
+ 5 * GST_SECOND);
+ gst_omx_component_get_state (self->dec, 1 * GST_SECOND);
+ }
+ gst_omx_component_set_state (self->egl_render, OMX_StateLoaded);
+ gst_omx_component_set_state (self->dec, OMX_StateLoaded);
+
+ gst_omx_close_tunnel (self->dec_out_port, self->egl_in_port);
+
+ if (egl_state > OMX_StateLoaded) {
+ gst_omx_component_get_state (self->egl_render, 5 * GST_SECOND);
+ }
+
+ gst_omx_component_set_state (self->dec, OMX_StateIdle);
+
+ gst_omx_component_set_state (self->dec, OMX_StateExecuting);
+ gst_omx_component_get_state (self->dec, GST_CLOCK_TIME_NONE);
}
+ self->eglimage = FALSE;
+ }
#endif
- if (gst_omx_port_set_enabled (self->dec_in_port, FALSE) != OMX_ErrorNone)
- return FALSE;
- if (gst_omx_port_wait_buffers_released (self->dec_in_port,
- 5 * GST_SECOND) != OMX_ErrorNone)
- return FALSE;
+ self->disabled = TRUE;
+ }
+ if (self->input_state)
+ gst_video_codec_state_unref (self->input_state);
+ self->input_state = NULL;
- if (gst_omx_port_deallocate_buffers (self->dec_in_port) != OMX_ErrorNone)
- return FALSE;
+ GST_DEBUG_OBJECT (self, "Decoder drained and disabled");
+ return TRUE;
+ }
- if (gst_omx_port_wait_enabled (self->dec_in_port,
- 1 * GST_SECOND) != OMX_ErrorNone)
+ static gboolean
+ gst_omx_video_dec_allocate_in_buffers (GstOMXVideoDec * self)
+ {
+ switch (self->input_allocation) {
+ case GST_OMX_BUFFER_ALLOCATION_ALLOCATE_BUFFER:
++#ifdef TIZEN_FEATURE_OMX
++ if (gst_omx_port_tbm_allocate_dec_buffers (self->dec_in_port) != OMX_ErrorNone)
+ return FALSE;
- #ifndef TIZEN_FEATURE_OMX
- if (gst_omx_port_set_enabled (out_port, FALSE) != OMX_ErrorNone)
++#else
+ if (gst_omx_port_allocate_buffers (self->dec_in_port) != OMX_ErrorNone)
return FALSE;
-
- if (gst_omx_port_wait_buffers_released (out_port,
- 1 * GST_SECOND) != OMX_ErrorNone)
++#endif
+ break;
+ case GST_OMX_BUFFER_ALLOCATION_USE_BUFFER_DYNAMIC:
+ if (gst_omx_port_use_dynamic_buffers (self->dec_in_port) != OMX_ErrorNone)
return FALSE;
+ break;
+ case GST_OMX_BUFFER_ALLOCATION_USE_BUFFER:
+ default:
+ /* Not supported */
+ g_return_val_if_reached (FALSE);
+ }
- if (gst_omx_video_dec_deallocate_output_buffers (self) != OMX_ErrorNone)
- return FALSE;
+ return TRUE;
+ }
- 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_GL)
- if (self->eglimage) {
- OMX_STATETYPE egl_state;
-
- egl_state = gst_omx_component_get_state (self->egl_render, 0);
- if (egl_state > OMX_StateLoaded || egl_state == OMX_StateInvalid) {
-
- if (egl_state > OMX_StateIdle) {
- gst_omx_component_set_state (self->egl_render, OMX_StateIdle);
- gst_omx_component_set_state (self->dec, OMX_StateIdle);
- egl_state = gst_omx_component_get_state (self->egl_render,
- 5 * GST_SECOND);
- gst_omx_component_get_state (self->dec, 1 * GST_SECOND);
- }
- gst_omx_component_set_state (self->egl_render, OMX_StateLoaded);
- gst_omx_component_set_state (self->dec, OMX_StateLoaded);
+ static gboolean
+ check_input_alignment (GstOMXVideoDec * self, GstMapInfo * map)
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *port_def = &self->dec_in_port->port_def;
- gst_omx_close_tunnel (self->dec_out_port, self->egl_in_port);
+ if (port_def->nBufferAlignment &&
+ (GPOINTER_TO_UINT (map->data) & (port_def->nBufferAlignment - 1)) != 0) {
+ GST_DEBUG_OBJECT (self,
+ "input buffer is not properly aligned (address: %p alignment: %u bytes), can't use dynamic allocation",
+ map->data, (guint32) port_def->nBufferAlignment);
+ return FALSE;
+ }
- if (egl_state > OMX_StateLoaded) {
- gst_omx_component_get_state (self->egl_render, 5 * GST_SECOND);
- }
+ return TRUE;
+ }
- gst_omx_component_set_state (self->dec, OMX_StateIdle);
+ /* Check if @inbuf's alignment matches the requirements to use the
+ * dynamic buffer mode. */
+ static gboolean
+ can_use_dynamic_buffer_mode (GstOMXVideoDec * self, GstBuffer * inbuf)
+ {
+ gboolean result = TRUE;
+ guint i;
- gst_omx_component_set_state (self->dec, OMX_StateExecuting);
- gst_omx_component_get_state (self->dec, GST_CLOCK_TIME_NONE);
- }
- self->eglimage = FALSE;
- }
- #endif
+ for (i = 0; i < gst_buffer_n_memory (inbuf) && result; i++) {
+ GstMemory *mem = gst_buffer_peek_memory (inbuf, i);
+ GstMapInfo map;
+
+ if (!gst_memory_map (mem, &map, GST_MAP_READ)) {
+ GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL),
+ ("failed to map input buffer"));
+ return FALSE;
}
- if (self->input_state)
- gst_video_codec_state_unref (self->input_state);
- self->input_state = NULL;
- GST_DEBUG_OBJECT (self, "Decoder drained and disabled");
+ result = check_input_alignment (self, &map);
+
+ gst_memory_unmap (mem, &map);
}
- 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);
+ return result;
+ }
- GST_DEBUG_OBJECT (self, "Setting inport port definition");
+ /* Choose the allocation mode for input buffers depending of what's supported by
+ * the component and the size/alignment of the input buffer. */
+ static GstOMXBufferAllocation
+ gst_omx_video_dec_pick_input_allocation_mode (GstOMXVideoDec * self,
+ GstBuffer * inbuf)
+ {
+ if (!gst_omx_is_dynamic_allocation_supported ())
+ return GST_OMX_BUFFER_ALLOCATION_ALLOCATE_BUFFER;
- if (gst_omx_port_update_port_definition (self->dec_in_port,
- &port_def) != OMX_ErrorNone)
- return FALSE;
+ if (can_use_dynamic_buffer_mode (self, inbuf)) {
+ GST_DEBUG_OBJECT (self,
+ "input buffer is properly aligned, use dynamic allocation");
+ return GST_OMX_BUFFER_ALLOCATION_USE_BUFFER_DYNAMIC;
+ }
- if (klass->set_format) {
- if (!klass->set_format (self, self->dec_in_port, state)) {
- GST_ERROR_OBJECT (self, "Subclass failed to set the new format");
+ GST_DEBUG_OBJECT (self, "let input buffer allocate its buffers");
+ return GST_OMX_BUFFER_ALLOCATION_ALLOCATE_BUFFER;
+ }
+
+ static gboolean
+ gst_omx_video_dec_ensure_nb_in_buffers (GstOMXVideoDec * self)
+ {
+ GstOMXVideoDecClass *klass = GST_OMX_VIDEO_DEC_GET_CLASS (self);
+
+ if ((klass->cdata.hacks & GST_OMX_HACK_ENSURE_BUFFER_COUNT_ACTUAL)) {
+ if (!gst_omx_port_ensure_buffer_count_actual (self->dec_in_port, 0))
return FALSE;
- }
}
- GST_DEBUG_OBJECT (self, "Updating outport port definition");
- if (gst_omx_port_update_port_definition (self->dec_out_port,
- NULL) != OMX_ErrorNone)
- return FALSE;
+ return TRUE;
+ }
- gst_buffer_replace (&self->codec_data, state->codec_data);
- self->input_state = gst_video_codec_state_ref (state);
+ static gboolean
+ gst_omx_video_dec_enable (GstOMXVideoDec * self, GstBuffer * input)
+ {
+ GstOMXVideoDecClass *klass = GST_OMX_VIDEO_DEC_GET_CLASS (self);
GST_DEBUG_OBJECT (self, "Enabling component");
- if (needs_disable) {
+ self->input_allocation = gst_omx_video_dec_pick_input_allocation_mode (self,
+ input);
+
+ if (self->disabled) {
+ if (!gst_omx_video_dec_ensure_nb_in_buffers (self))
+ return FALSE;
if (gst_omx_port_set_enabled (self->dec_in_port, TRUE) != OMX_ErrorNone)
return FALSE;
- #ifdef TIZEN_FEATURE_OMX
- if (gst_omx_port_tbm_allocate_dec_buffers (self->dec_in_port) != OMX_ErrorNone)
- return FALSE;
- #else
- if (gst_omx_port_allocate_buffers (self->dec_in_port) != OMX_ErrorNone)
+ if (!gst_omx_video_dec_allocate_in_buffers (self))
return FALSE;
- #endif
+
+#ifndef TIZEN_FEATURE_OMX
if ((klass->cdata.hacks & GST_OMX_HACK_NO_DISABLE_OUTPORT)) {
if (gst_omx_port_set_enabled (self->dec_out_port, TRUE) != OMX_ErrorNone)
return FALSE;
5 * GST_SECOND) != OMX_ErrorNone)
return FALSE;
}
+#endif
+
if (gst_omx_port_wait_enabled (self->dec_in_port,
5 * GST_SECOND) != OMX_ErrorNone)
return FALSE;
return FALSE;
/* Need to allocate buffers to reach Idle state */
- if (gst_omx_port_tbm_allocate_dec_buffers (self->dec_in_port) != OMX_ErrorNone)
- return FALSE;
+ if (!gst_omx_video_dec_allocate_in_buffers (self))
+ return FALSE;
+#ifdef TIZEN_FEATURE_OMX
- return FALSE;
+ if (gst_omx_port_tbm_allocate_dec_buffers (self->dec_out_port) != OMX_ErrorNone)
- if (gst_omx_port_allocate_buffers (self->dec_in_port) != OMX_ErrorNone)
- return FALSE;
+#else
if (gst_omx_port_allocate_buffers (self->dec_out_port) != OMX_ErrorNone)
- return FALSE;
+#endif
- }
+ return FALSE;
+ }
if (gst_omx_component_get_state (self->dec,
GST_CLOCK_TIME_NONE) != OMX_StateIdle)
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);
+#ifdef CODEC_DEC_INTPUT_DUMP
+ decoder_input_dump (buf, port->use_buffer);
+#endif
+
if (GST_CLOCK_TIME_IS_VALID (timestamp))
- buf->omx_buf->nTimeStamp =
- gst_util_uint64_scale (timestamp, OMX_TICKS_PER_SECOND, GST_SECOND);
+ GST_OMX_SET_TICKS (buf->omx_buf->nTimeStamp,
+ gst_util_uint64_scale (timestamp, OMX_TICKS_PER_SECOND,
+ GST_SECOND));
else
- buf->omx_buf->nTimeStamp = 0;
+ GST_OMX_SET_TICKS (buf->omx_buf->nTimeStamp, G_GUINT64_CONSTANT (0));
buf->omx_buf->nTickCount = 0;
self->started = TRUE;
}
/* 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_DEBUG_OBJECT (self, "nFilledLen %lu, %p", buf->omx_buf->nFilledLen, buf->omx_buf->pBuffer);
+ if (self->input_allocation == GST_OMX_BUFFER_ALLOCATION_USE_BUFFER_DYNAMIC) {
+ /* Transfer the buffer content per memory rather than mapping the full
+ * buffer to prevent copies. */
+ GstMemory *mem = gst_buffer_peek_memory (frame->input_buffer, memory_idx);
+
+ GST_LOG_OBJECT (self,
+ "Transferring %" G_GSIZE_FORMAT " bytes to the component",
+ gst_memory_get_sizes (mem, NULL, NULL));
- gst_buffer_extract (frame->input_buffer, offset,
- buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
- buf->omx_buf->nFilledLen);
+ if (!gst_omx_buffer_map_memory (buf, mem))
+ goto map_failed;
+
+ if (!check_input_alignment (self, &buf->map)) {
+ GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL),
+ ("input buffer now has wrong alignment/stride, can't use dynamic allocation any more"));
+ return FALSE;
+ }
+
+ memory_idx++;
+ if (memory_idx == gst_buffer_n_memory (frame->input_buffer))
+ done = TRUE;
+ } else {
+ /* 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_LOG_OBJECT (self,
+ "Copying %d bytes (frame offset %d) to the component",
+ (guint) buf->omx_buf->nFilledLen, offset);
+
+ gst_buffer_extract (frame->input_buffer, offset,
+ buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
+ buf->omx_buf->nFilledLen);
+
+ offset += buf->omx_buf->nFilledLen;
+ if (offset == size)
+ done = TRUE;
+ }
+#ifdef CODEC_DEC_INTPUT_DUMP
+ decoder_input_dump (buf, port->use_buffer);
+#endif
+
if (timestamp != GST_CLOCK_TIME_NONE) {
- buf->omx_buf->nTimeStamp =
- gst_util_uint64_scale (timestamp, OMX_TICKS_PER_SECOND, GST_SECOND);
+ GST_OMX_SET_TICKS (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;
+ GST_OMX_SET_TICKS (buf->omx_buf->nTimeStamp, G_GUINT64_CONSTANT (0));
}
- if (duration != GST_CLOCK_TIME_NONE && offset == 0) {
+ if (duration != GST_CLOCK_TIME_NONE && first_ouput_buffer) {
buf->omx_buf->nTickCount =
gst_util_uint64_scale (duration, OMX_TICKS_PER_SECOND, GST_SECOND);
self->last_upstream_ts += duration;
return TRUE;
}
+ static gboolean
+ gst_omx_video_dec_propose_allocation (GstVideoDecoder * bdec, GstQuery * query)
+ {
+ GstOMXVideoDec *self = GST_OMX_VIDEO_DEC (bdec);
+ guint size, num_buffers;
+
+ size = self->dec_in_port->port_def.nBufferSize;
+ num_buffers = self->dec_in_port->port_def.nBufferCountMin + 1;
+
+ GST_DEBUG_OBJECT (self,
+ "request at least %d buffers of size %d", num_buffers, size);
+ gst_query_add_allocation_pool (query, NULL, size, num_buffers, 0);
+
+ return
+ GST_VIDEO_DECODER_CLASS
+ (gst_omx_video_dec_parent_class)->propose_allocation (bdec, query);
+ }
++
+#ifdef TIZEN_FEATURE_OMX
+static gboolean
+gst_omx_video_dec_acquire_request_flush_event (GstOMXVideoDec * self, GstEvent ** flush_request_event)
+{
+ GstEvent *event;
+
+ GST_DEBUG_OBJECT (self, "flush buffer request");
+
+ if (self->out_port_pool) {
+ if (gst_buffer_pool_is_active(self->out_port_pool)) {
+ event = gst_event_new_custom(GST_EVENT_CUSTOM_DOWNSTREAM,
+ gst_structure_new_empty("tizen/flush-buffer"));
+
+ *flush_request_event = event;
+
+ GST_DEBUG_OBJECT (self, "flush buffer requested");
+ return TRUE;
+ } else {
+ GST_DEBUG_OBJECT (self, "the out port pool has not yet been activated");
+ return FALSE;
+ }
+ } else {
+ GST_DEBUG_OBJECT (self, "the output port has not yet been activated");
+ return FALSE;
+ }
+}
+
+static gboolean
+gst_omx_video_dec_handle_event (GstVideoDecoder * decoder,
+ GstEvent * event)
+{
+ GstOMXVideoDec *self;
+
+ self = GST_OMX_VIDEO_DEC (decoder);
+
+ GST_DEBUG_OBJECT (self, "event: %s", GST_EVENT_TYPE_NAME (event));
+
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_FLUSH_START:
+ {
+ gst_omx_port_flush_start (self->dec_in_port, TRUE);
+ gst_omx_port_flush_start (self->dec_out_port, TRUE);
+ break;
+ }
+ case GST_EVENT_FLUSH_STOP:
+ {
+ gst_omx_port_flush_start (self->dec_in_port, FALSE);
+ gst_omx_port_flush_start (self->dec_out_port, FALSE);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return GST_VIDEO_DECODER_CLASS (gst_omx_video_dec_parent_class)->sink_event (decoder, event);
+}
+#endif
#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 GST_OMX_VIDEO_ENC_QP_MODE_DEFAULT (0xffffffff)
+ #define GST_OMX_VIDEO_ENC_MIN_QP_DEFAULT (10)
+ #define GST_OMX_VIDEO_ENC_MAX_QP_DEFAULT (51)
+ #define GST_OMX_VIDEO_ENC_GOP_MODE_DEFAULT (OMX_ALG_GOP_MODE_DEFAULT)
+ #define GST_OMX_VIDEO_ENC_GDR_MODE_DEFAULT (OMX_ALG_GDR_OFF)
+ #define GST_OMX_VIDEO_ENC_INITIAL_DELAY_DEFAULT (1500)
+ #define GST_OMX_VIDEO_ENC_CPB_SIZE_DEFAULT (3000)
+ #define GST_OMX_VIDEO_ENC_SCALING_LIST_DEFAULT (OMX_ALG_SCL_DEFAULT)
+ #define GST_OMX_VIDEO_ENC_LOW_BANDWIDTH_DEFAULT (FALSE)
+ #define GST_OMX_VIDEO_ENC_MAX_BITRATE_DEFAULT (0xffffffff)
+ #define GST_OMX_VIDEO_ENC_ASPECT_RATIO_DEFAULT (OMX_ALG_ASPECT_RATIO_AUTO)
+ #define GST_OMX_VIDEO_ENC_FILLER_DATA_DEFAULT (TRUE)
+ #define GST_OMX_VIDEO_ENC_NUM_SLICES_DEFAULT (0xffffffff)
+ #define GST_OMX_VIDEO_ENC_SLICE_SIZE_DEFAULT (0)
+ #define GST_OMX_VIDEO_ENC_DEPENDENT_SLICE_DEFAULT (FALSE)
+ #define GST_OMX_VIDEO_ENC_DEFAULT_ROI_QUALITY OMX_ALG_ROI_QUALITY_HIGH
+
/* class initialization */
-
- #define DEBUG_INIT \
+ #define do_init \
+ { \
GST_DEBUG_CATEGORY_INIT (gst_omx_video_enc_debug_category, "omxvideoenc", 0, \
- "debug category for gst-omx video encoder base class");
+ "debug category for gst-omx video encoder base class"); \
+ G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL); \
+ }
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstOMXVideoEnc, gst_omx_video_enc,
- GST_TYPE_VIDEO_ENCODER, DEBUG_INIT);
+ GST_TYPE_VIDEO_ENCODER, do_init);
static void
gst_omx_video_enc_class_init (GstOMXVideoEncClass * klass)
g_mutex_init (&self->drain_lock);
g_cond_init (&self->drain_cond);
+
+ #ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
+ self->alg_roi_quality_enum_class =
+ g_type_class_ref (GST_TYPE_OMX_VIDEO_ENC_ROI_QUALITY);
+ #endif
+ }
+
+ #ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
+
+ #define CHECK_ERR(setting) \
+ if (err == OMX_ErrorUnsupportedIndex || err == OMX_ErrorUnsupportedSetting) { \
+ GST_WARNING_OBJECT (self, \
+ "Setting " setting " parameters not supported by the component"); \
+ } else if (err != OMX_ErrorNone) { \
+ GST_ERROR_OBJECT (self, \
+ "Failed to set " setting " parameters: %s (0x%08x)", \
+ gst_omx_error_to_string (err), err); \
+ return FALSE; \
+ }
+
+ static gboolean
+ set_zynqultrascaleplus_props (GstOMXVideoEnc * self)
+ {
+ OMX_ERRORTYPE err;
+
+ if (self->qp_mode != GST_OMX_VIDEO_ENC_QP_MODE_DEFAULT) {
+ OMX_ALG_VIDEO_PARAM_QUANTIZATION_CONTROL quant;
+
+ GST_OMX_INIT_STRUCT (&quant);
+ quant.nPortIndex = self->enc_out_port->index;
+ quant.eQpControlMode = self->qp_mode;
+
+ GST_DEBUG_OBJECT (self, "setting QP mode to %d", self->qp_mode);
+
+ err =
+ gst_omx_component_set_parameter (self->enc,
+ (OMX_INDEXTYPE) OMX_ALG_IndexParamVideoQuantizationControl, &quant);
+ CHECK_ERR ("quantization");
+ }
+
+ {
+ OMX_ALG_VIDEO_PARAM_QUANTIZATION_EXTENSION qp_values;
+
+ GST_OMX_INIT_STRUCT (&qp_values);
+ qp_values.nPortIndex = self->enc_out_port->index;
+ qp_values.nQpMin = self->min_qp;
+ qp_values.nQpMax = self->max_qp;
+
+ GST_DEBUG_OBJECT (self, "setting min QP as %d and max QP as %d",
+ self->min_qp, self->max_qp);
+
+ err =
+ gst_omx_component_set_parameter (self->enc,
+ (OMX_INDEXTYPE) OMX_ALG_IndexParamVideoQuantizationExtension,
+ &qp_values);
+ CHECK_ERR ("min-qp and max-qp");
+ }
+
+ {
+ OMX_ALG_VIDEO_PARAM_GOP_CONTROL gop_mode;
+
+ if (self->gdr_mode != OMX_ALG_GDR_OFF &&
+ self->gop_mode != OMX_ALG_GOP_MODE_LOW_DELAY_P) {
+ GST_ERROR_OBJECT (self,
+ "gdr-mode mode only can be set if gop-mode=low-delay-p");
+ return FALSE;
+ }
+
+ GST_OMX_INIT_STRUCT (&gop_mode);
+ gop_mode.nPortIndex = self->enc_out_port->index;
+ gop_mode.eGopControlMode = self->gop_mode;
+ gop_mode.eGdrMode = self->gdr_mode;
+
+ GST_DEBUG_OBJECT (self, "setting GOP mode to %d and GDR mode to %d",
+ self->gop_mode, self->gdr_mode);
+
+ err =
+ gst_omx_component_set_parameter (self->enc,
+ (OMX_INDEXTYPE) OMX_ALG_IndexParamVideoGopControl, &gop_mode);
+ CHECK_ERR ("GOP & GDR");
+ }
+
+ if (self->control_rate != OMX_Video_ControlRateDisable) {
+ if (self->cpb_size < self->initial_delay) {
+ GST_ERROR_OBJECT (self,
+ "cpb-size (%d) cannot be smaller than initial-delay (%d)",
+ self->cpb_size, self->initial_delay);
+ g_critical ("cpb-size (%d) cannot be smaller than initial-delay (%d)",
+ self->cpb_size, self->initial_delay);
+ } else {
+ OMX_ALG_VIDEO_PARAM_CODED_PICTURE_BUFFER cpb;
+
+ GST_OMX_INIT_STRUCT (&cpb);
+ cpb.nPortIndex = self->enc_out_port->index;
+ cpb.nCodedPictureBufferSize = self->cpb_size;
+ cpb.nInitialRemovalDelay = self->initial_delay;
+
+ GST_DEBUG_OBJECT (self, "setting cpb size to %d and initial delay to %d",
+ self->cpb_size, self->initial_delay);
+
+ err =
+ gst_omx_component_set_parameter (self->enc,
+ (OMX_INDEXTYPE) OMX_ALG_IndexParamVideoCodedPictureBuffer, &cpb);
+ CHECK_ERR ("cpb size & initial delay");
+ }
+ }
+
+ {
+ OMX_ALG_VIDEO_PARAM_SCALING_LIST scaling_list;
+
+ GST_OMX_INIT_STRUCT (&scaling_list);
+ scaling_list.nPortIndex = self->enc_out_port->index;
+ scaling_list.eScalingListMode = self->scaling_list;
+
+ GST_DEBUG_OBJECT (self, "setting scaling list mode as %d",
+ self->scaling_list);
+
+ err =
+ gst_omx_component_set_parameter (self->enc,
+ (OMX_INDEXTYPE) OMX_ALG_IndexParamVideoScalingList, &scaling_list);
+ CHECK_ERR ("scaling-list");
+ }
+
+ {
+ OMX_ALG_VIDEO_PARAM_LOW_BANDWIDTH low_bw;
+
+ GST_OMX_INIT_STRUCT (&low_bw);
+ low_bw.nPortIndex = self->enc_out_port->index;
+ low_bw.bEnableLowBandwidth = self->low_bandwidth;
+
+ GST_DEBUG_OBJECT (self, "%s low bandwith moded",
+ self->low_bandwidth ? "Enable" : "Disable");
+
+ err =
+ gst_omx_component_set_parameter (self->enc,
+ (OMX_INDEXTYPE) OMX_ALG_IndexParamVideoLowBandwidth, &low_bw);
+ CHECK_ERR ("low-bandwidth");
+ }
+
+ if (self->max_bitrate != GST_OMX_VIDEO_ENC_MAX_BITRATE_DEFAULT) {
+ OMX_ALG_VIDEO_PARAM_MAX_BITRATE max_bitrate;
+
+ GST_OMX_INIT_STRUCT (&max_bitrate);
+ max_bitrate.nPortIndex = self->enc_out_port->index;
+ /* nMaxBitrate is in kbps while max-bitrate is in bps */
+ max_bitrate.nMaxBitrate = self->max_bitrate / 1000;
+
+ GST_DEBUG_OBJECT (self, "setting max bitrate to %d", self->max_bitrate);
+
+ err =
+ gst_omx_component_set_parameter (self->enc,
+ (OMX_INDEXTYPE) OMX_ALG_IndexParamVideoMaxBitrate, &max_bitrate);
+ CHECK_ERR ("max-bitrate");
+ }
+
+ {
+ OMX_ALG_VIDEO_PARAM_ASPECT_RATIO aspect_ratio;
+
+ GST_OMX_INIT_STRUCT (&aspect_ratio);
+ aspect_ratio.nPortIndex = self->enc_out_port->index;
+ aspect_ratio.eAspectRatio = self->aspect_ratio;
+
+ GST_DEBUG_OBJECT (self, "setting aspect ratio to %d", self->aspect_ratio);
+
+ err =
+ gst_omx_component_set_parameter (self->enc,
+ (OMX_INDEXTYPE) OMX_ALG_IndexParamVideoAspectRatio, &aspect_ratio);
+ CHECK_ERR ("aspect-ratio");
+ }
+
+ {
+ OMX_ALG_VIDEO_PARAM_FILLER_DATA filler_data;
+
+ GST_OMX_INIT_STRUCT (&filler_data);
+ filler_data.nPortIndex = self->enc_out_port->index;
+ filler_data.bDisableFillerData = !(self->filler_data);
+
+ GST_DEBUG_OBJECT (self, "%s filler data",
+ self->filler_data ? "Enable" : "Disable");
+
+ err =
+ gst_omx_component_set_parameter (self->enc,
+ (OMX_INDEXTYPE) OMX_ALG_IndexParamVideoFillerData, &filler_data);
+ CHECK_ERR ("filler-data");
+ }
+
+ if (self->num_slices != GST_OMX_VIDEO_ENC_NUM_SLICES_DEFAULT ||
+ self->slice_size != GST_OMX_VIDEO_ENC_SLICE_SIZE_DEFAULT) {
+ OMX_ALG_VIDEO_PARAM_SLICES slices;
+
+ GST_OMX_INIT_STRUCT (&slices);
+ slices.nPortIndex = self->enc_out_port->index;
+
+ err = gst_omx_component_get_parameter (self->enc,
+ (OMX_INDEXTYPE) OMX_ALG_IndexParamVideoSlices, &slices);
+ if (err != OMX_ErrorNone) {
+ GST_WARNING_OBJECT (self, "Error getting slice parameters: %s (0x%08x)",
+ gst_omx_error_to_string (err), err);
+ return FALSE;
+ }
+
+ if (self->num_slices != GST_OMX_VIDEO_ENC_NUM_SLICES_DEFAULT) {
+ slices.nNumSlices = self->num_slices;
+ GST_DEBUG_OBJECT (self,
+ "setting number of slices to %d (dependent slices: %d)",
+ self->num_slices, self->dependent_slice);
+ }
+
+ if (self->slice_size != GST_OMX_VIDEO_ENC_SLICE_SIZE_DEFAULT) {
+ slices.nSlicesSize = self->slice_size;
+ GST_DEBUG_OBJECT (self, "setting slice size to %d (dependent slices: %d)",
+ self->slice_size, self->dependent_slice);
+ }
+
+ slices.bDependentSlices = self->dependent_slice;
+
+ err =
+ gst_omx_component_set_parameter (self->enc,
+ (OMX_INDEXTYPE) OMX_ALG_IndexParamVideoSlices, &slices);
+ CHECK_ERR ("slices");
+ }
+
+ return TRUE;
+ }
+ #endif
+
+ static gboolean
+ gst_omx_video_enc_set_bitrate (GstOMXVideoEnc * self)
+ {
+ OMX_ERRORTYPE err;
+ OMX_VIDEO_PARAM_BITRATETYPE bitrate_param;
+ gboolean result = TRUE;
+
+ GST_OBJECT_LOCK (self);
+
+ GST_OMX_INIT_STRUCT (&bitrate_param);
+ bitrate_param.nPortIndex = self->enc_out_port->index;
+
+ err = gst_omx_component_get_parameter (self->enc,
+ OMX_IndexParamVideoBitrate, &bitrate_param);
+
+ 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->default_target_bitrate == GST_OMX_PROP_OMX_DEFAULT)
+ /* Save the actual OMX default so we can restore it if needed */
+ self->default_target_bitrate = bitrate_param.nTargetBitrate;
+
+ if (self->control_rate != 0xffffffff)
+ bitrate_param.eControlRate = self->control_rate;
+ if (self->target_bitrate != 0xffffffff)
+ bitrate_param.nTargetBitrate = self->target_bitrate;
+ else
+ bitrate_param.nTargetBitrate = self->default_target_bitrate;
+
+ 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);
+ result = FALSE;
+ }
+ } else {
+ GST_ERROR_OBJECT (self, "Failed to get bitrate parameters: %s (0x%08x)",
+ gst_omx_error_to_string (err), err);
+ }
+
+ GST_OBJECT_UNLOCK (self);
+ return result;
}
+#ifdef CODEC_ENC_INPUT_DUMP
+
+static inline void
+gst_omx_video_enc_input_dump (GstBuffer *inbuf)
+{
+ char *temp = (char *)inbuf->data[0];
+ int i = 0;
+ char filename[100]={0};
+ FILE *fp = NULL;
+
+ GST_WARNING ("codec enc input dump start. w = %d, h = %d", inbuf->width[0], inbuf->height[0]);
+
+ sprintf(filename, "/tmp/enc_input_dump_%d_%d.yuv", inbuf->width[0], inbuf->height[0]);
+ fp = fopen(filename, "ab");
+
+ for (i = 0; i < inbuf->height[0]; i++) {
+ fwrite(temp, inbuf->width[0], 1, fp);
+ temp += inbuf->stride_width[0];
+ }
+
+ temp = (char*)inbuf->data[1];
+
+ for(i = 0; i < inbuf->height[1] ; i++) {
+ fwrite(temp, inbuf->width[1], 1, fp);
+ temp += inbuf->stride_width[1];
+ }
+ GST_WARNING ("codec encoder input dumped!!");
+ fclose(fp);
+}
+#endif
+
static gboolean
gst_omx_video_enc_open (GstVideoEncoder * encoder)
{
}
}
}
- #ifdef TIZEN_FEATURE_OMX
- self->enc_in_port->use_buffer = klass->cdata.in_port_usebuffer;
- self->enc_out_port->use_buffer = klass->cdata.out_port_usebuffer;
+ #ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
+ if (!set_zynqultrascaleplus_props (self))
+ return FALSE;
+ #endif
+
+ return TRUE;
+ }
+
+ static gboolean
+ gst_omx_video_enc_deallocate_in_buffers (GstOMXVideoEnc * self)
+ {
+ /* Pool will take care of deallocating buffers when deactivated upstream */
+ if (!self->in_pool_used
+ && gst_omx_port_deallocate_buffers (self->enc_in_port) != OMX_ErrorNone)
+ return FALSE;
- #endif
+ /* get extension index and set platform specific buffer enable */
+#if defined(USE_OMX_TARGET_EXYNOS) || defined(USE_OMX_TARGET_EXYNOS64)
+ {
+ OMX_ERRORTYPE err;
+ OMX_INDEXTYPE index = OMX_IndexComponentStartUnused;
+ EnableGemBuffersParams gem_param;
+
+ err = gst_omx_component_get_extension_index (self->enc, (OMX_STRING) EXYNOS_INDEX_PARAM_STORE_METADATA_BUFFER, &index);
+ if (err != OMX_ErrorNone) {
+ GST_WARNING_OBJECT (self, "Failed to get extension index : %s (0x%08x)",
+ gst_omx_error_to_string (err), err);
+ }
+
+ OMX_INIT_PARAM (gem_param);
+ gem_param.enable = OMX_TRUE;
+ gem_param.nPortIndex = 0;
+
+
+ err = gst_omx_component_set_parameter (self->enc, index, &gem_param);
+ if (err != OMX_ErrorNone) {
+ GST_ERROR_OBJECT (self, "Failed to set platform specific buffer: %s (0x%08x)",
+ gst_omx_error_to_string (err), err);
+ }
+
+ }
+#endif
return TRUE;
}
self->input_state);
state->codec_data = codec_data;
gst_video_codec_state_unref (state);
+#ifdef TIZEN_FEATURE_OMX
+ /*Modification : codec data already set_caps, so unref frame whenever negotiate ok or not*/
+ if (!gst_video_encoder_negotiate (GST_VIDEO_ENCODER (self)))
+ flow_ret = GST_FLOW_NOT_NEGOTIATED;
+ else
+ flow_ret = GST_FLOW_OK;
+ gst_video_codec_frame_unref (frame);
+#else
if (!gst_video_encoder_negotiate (GST_VIDEO_ENCODER (self))) {
gst_video_codec_frame_unref (frame);
+ GST_ERROR_OBJECT (self,
+ "Downstream element refused to negotiate codec_data in the caps");
return GST_FLOW_NOT_NEGOTIATED;
}
flow_ret = GST_FLOW_OK;
GST_ERROR_OBJECT (self, "Width or height do not match");
goto done;
}
+
+ if (self->enc_in_port->allocation ==
+ GST_OMX_BUFFER_ALLOCATION_USE_BUFFER_DYNAMIC) {
+ if (gst_buffer_n_memory (inbuf) > 1) {
+ GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL),
+ ("input buffer now has more than one memory, can't use dynamic allocation any more"));
+ return FALSE;
+ }
+
+ if (!self->input_dmabuf) {
+ /* Map and keep a ref on the buffer while it's being processed
+ * by the OMX component. */
+ if (!gst_omx_buffer_map_frame (outbuf, inbuf, info)) {
+ GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL),
+ ("failed to map input buffer"));
+ return FALSE;
+ }
+
+ if (!check_input_alignment (self, &outbuf->input_frame.map[0])) {
+ GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL),
+ ("input buffer now has wrong alignment/stride, can't use dynamic allocation any more"));
+ return FALSE;
+ }
+
+ GST_LOG_OBJECT (self, "Transfer buffer of %" G_GSIZE_FORMAT " bytes",
+ gst_buffer_get_size (inbuf));
+ } else {
+ /* dmabuf input */
+ if (!gst_omx_buffer_import_fd (outbuf, inbuf)) {
+ GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL),
+ ("failed to import dmabuf"));
+ return FALSE;
+ }
+
+ GST_LOG_OBJECT (self, "Import dmabuf of %" G_GSIZE_FORMAT " bytes",
+ gst_buffer_get_size (inbuf));
+ }
+
+ ret = TRUE;
+ goto done;
+ }
+
+#ifndef TIZEN_FEATURE_OMX
/* Same strides and everything */
if (gst_buffer_get_size (inbuf) ==
outbuf->omx_buf->nAllocLen - outbuf->omx_buf->nOffset) {
ret = TRUE;
goto done;
}
+#endif
+
/* Different strides */
+ GST_LOG_OBJECT (self, "Mismatched strides - copying line-by-line");
switch (info->finfo->format) {
case GST_VIDEO_FORMAT_I420:{