diff --git a/config/Makefile.am b/config/Makefile.am
index 008e823..4566ece 100644
--- a/config/Makefile.am
+++ b/config/Makefile.am
@@ -1 +1 @@
-SUBDIRS = bellagio rpi tizonia zynqultrascaleplus
+SUBDIRS = bellagio rpi tizonia zynqultrascaleplus rcar
diff --git a/config/meson.build b/config/meson.build
index 1068c6d..d12d9fd 100644
--- a/config/meson.build
+++ b/config/meson.build
@@ -6,6 +6,8 @@ elif omx_target == 'zynqultrascaleplus'
   sub = 'zynqultrascaleplus'
 elif omx_target == 'tizonia'
   sub = 'tizonia'
+elif omx_target == 'rcar'
+  sub = 'rcar'
 else
   # No config file defined for the 'generic' target
   sub = ''
diff --git a/config/rcar/Makefile.am b/config/rcar/Makefile.am
new file mode 100644
index 0000000..9d79c24
--- /dev/null
+++ b/config/rcar/Makefile.am
@@ -0,0 +1,6 @@
+EXTRA_DIST = gstomx.conf
+
+if USE_OMX_TARGET_RCAR
+configdir = $(sysconfdir)/xdg
+config_DATA = gstomx.conf
+endif
diff --git a/config/rcar/meson.build b/config/rcar/meson.build
new file mode 100644
index 0000000..dc99c08
--- /dev/null
+++ b/config/rcar/meson.build
@@ -0,0 +1 @@
+install_data (['gstomx.conf'], install_dir : omx_conf_dir)
diff --git a/configure.ac b/configure.ac
index c2710a8..755316f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -200,7 +200,7 @@ AC_ARG_ENABLE(Bsymbolic,
                LDFLAGS="${SAVED_LDFLAGS}" LIBS="${SAVED_LIBS}"])
 
 AC_ARG_WITH([omx-target],
-        AS_HELP_STRING([--with-omx-target],[Use this OpenMAX IL target (generic, bellagio, rpi, tizonia, zynqultrascaleplus)]),
+        AS_HELP_STRING([--with-omx-target],[Use this OpenMAX IL target (generic, bellagio, rpi, tizonia, zynqultrascaleplus, rcar)]),
         [ac_cv_omx_target="$withval"], [ac_cv_omx_target="none"])
 
 ac_cv_omx_target_struct_packing="none"
@@ -223,8 +223,11 @@ case "${ac_cv_omx_target}" in
   tizonia)
     AC_DEFINE(USE_OMX_TARGET_TIZONIA, 1, [Use Tizonia OpenMAX IL target])
     ;;
+  rcar)
+    AC_DEFINE(USE_OMX_TARGET_RCAR, 1, [Use RCar OpenMAX IL target])
+    ;;
   none|*)
-    AC_ERROR([invalid OpenMAX IL target, you must specify one of --with-omx-target={generic,rpi,bellagio,tizonia,zynqultrascaleplus}])
+    AC_ERROR([invalid OpenMAX IL target, you must specify one of --with-omx-target={generic,rpi,bellagio,tizonia,zynqultrascaleplus,rcar}])
     ;;
 esac
 AM_CONDITIONAL(USE_OMX_TARGET_GENERIC, test "x$ac_cv_omx_target" = "xgeneric")
@@ -232,6 +235,7 @@ 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")
+AM_CONDITIONAL(USE_OMX_TARGET_RCAR, test "x$ac_cv_omx_target" = "xrcar")
 
 AC_ARG_WITH([omx-struct-packing],
         AS_HELP_STRING([--with-omx-struct-packing],[Force OpenMAX struct packing, (default is none)]),
@@ -281,7 +285,11 @@ HAVE_IV_COMMON_EXT=no
 HAVE_IMAGE_EXT=no
 HAVE_OTHER_EXT=no
 if test "x$HAVE_EXTERNAL_OMX" = "xyes"; then
-    AC_CHECK_HEADER([OMX_VideoExt.h], [HAVE_VIDEO_EXT=yes], [HAVE_VIDEO_EXT=no], [AC_INCLUDES_DEFAULT])
+    AC_CHECK_HEADERS([OMX_Video.h OMX_VideoExt.h], [HAVE_VIDEO_EXT=yes], [HAVE_VIDEO_EXT=no],
+    [[#ifdef HAVE_OMX_VIDEO_H
+    #include <OMX_Video.h>
+    #endif
+    ]])
     AC_CHECK_HEADER([OMX_IndexExt.h], [HAVE_INDEX_EXT=yes], [HAVE_INDEX_EXT=no], [AC_INCLUDES_DEFAULT])
     AC_CHECK_HEADER([OMX_ComponentExt.h], [HAVE_COMPONENT_EXT=yes], [HAVE_COMPONENT_EXT=no], [AC_INCLUDES_DEFAULT])
     AC_CHECK_HEADER([OMX_CoreExt.h], [HAVE_CORE_EXT=yes], [HAVE_CORE_EXT=no], [AC_INCLUDES_DEFAULT])
@@ -358,6 +366,74 @@ 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 check for dmabuf support
+AC_ARG_ENABLE([dmabuf],
+             [AS_HELP_STRING([--disable-dmabuf],
+                             [Disable dmabuf even if you have mmngrbuf library])],
+             [],
+             [enable_dmabuf=yes]
+             )
+
+if test "x${enable_dmabuf}" = "xyes"; then
+  dnl check mmngrbuf library to use dmabuf exporter
+  AC_CHECK_LIB([mmngrbuf], [mmngr_export_start_in_user],
+             [have_mmngrbuf=yes
+              GST_LIBS="$GST_LIBS -lmmngrbuf"
+              AC_DEFINE(HAVE_MMNGRBUF, 1, [Define if you have mmngrbuf library])
+             ])
+  dnl check OMXR_Extension_vdcmn.h
+  AC_CHECK_HEADER([OMXR_Extension_vdcmn.h],
+             [have_exvdcmn=yes],
+             [],
+             [AC_INCLUDES_DEFAULT])
+ if test "x${have_mmngrbuf}" = "xyes" -a "x${have_exvdcmn}" = "xyes"; then
+   AC_DEFINE(USE_RCAR_DMABUF, 1, [Define if you have OMXR_Extension_vdcmn.h header and mmngrbuf])
+ fi
+fi
+
+dnl check OMXR_Extension_vp8e.h
+AC_CHECK_HEADER([OMXR_Extension_vp8e.h],
+           [AC_DEFINE(HAVE_VP8ENC_EXT, 1, [Define if you have OMXR_Extension_vp8e.h header])],
+           [],
+           [AC_INCLUDES_DEFAULT])
+
+dnl check OMXR_Extension_vp9d.h
+AC_CHECK_HEADER([OMXR_Extension_vp9d.h],
+           [AC_DEFINE(HAVE_VP9DEC_EXT, 1, [Define if you have OMXR_Extension_vp9d.h header])],
+           [],
+           [AC_INCLUDES_DEFAULT])
+
+dnl check OMXR_Extension_aapd.h
+AC_CHECK_HEADER([OMXR_Extension_aapd.h],
+           [AC_DEFINE(HAVE_AACDEC_EXT, 1, [Define if you have OMXR_Extension_aapd.h header])],
+           [],
+           [AC_INCLUDES_DEFAULT])
+
+dnl check OMXR_Extension_audio.h
+AC_CHECK_HEADER([OMXR_Extension_audio.h],
+           [AC_DEFINE(HAVE_AUDIOR_EXT, 1, [Define if you have OMXR_Extension_audio.h header])],
+           [],
+           [AC_INCLUDES_DEFAULT])
+
+dnl check OMXR_Extension_vecmn.h
+AC_CHECK_HEADER([OMXR_Extension_vecmn.h],
+           [AC_DEFINE(HAVE_VIDEOENC_EXT, 1, [Define if you have OMXR_Extension_vecmn.h header])],
+           [],
+           [AC_INCLUDES_DEFAULT])
+
+dnl check OMXR_Extension_video.h
+AC_CHECK_HEADER([OMXR_Extension_video.h],
+           [AC_DEFINE(HAVE_VIDEOR_EXT, 1, [Define if you have OMXR_Extension_video.h he
+der])],
+           [],
+           [AC_INCLUDES_DEFAULT])
+
+dnl check OMXR_Extension_h265d.h
+AC_CHECK_HEADER([OMXR_Extension_h265d.h],
+           [AC_DEFINE(HAVE_H265DEC_EXT, 1, [Define if you have OMXR_Extension_h265d.h header])],
+           [],
+           [AC_INCLUDES_DEFAULT])
+
 dnl *** set variables based on configure arguments ***
 
 dnl set license and copyright notice
@@ -466,6 +542,7 @@ config/rpi/Makefile
 config/tizonia/gstomx.conf
 config/tizonia/Makefile
 config/zynqultrascaleplus/Makefile
+config/rcar/Makefile
 examples/Makefile
 examples/egl/Makefile
 m4/Makefile
diff --git a/meson.build b/meson.build
index 69c8e2a..c48c19a 100644
--- a/meson.build
+++ b/meson.build
@@ -212,6 +212,67 @@ elif omx_target == 'tizonia'
   cdata.set('TIZONIA_LIBDIR', tizil_dep.get_pkgconfig_variable('libdir'))
   tizil_includedir = tizil_dep.get_pkgconfig_variable('includedir')
   gst_omx_args += ['-I' + tizil_includedir + '/tizonia']
+elif omx_target == 'rcar'
+  cdata.set('USE_OMX_TARGET_RCAR', 1)
+
+  # check mmngrbuf library and function to use dmabuf exporter
+  lib_mmngrbuf = cc.find_library('mmngrbuf', required : false)
+  have_mmngrbuf = cc.has_function('mmngr_export_start_in_user', dependencies : lib_mmngrbuf)
+  if have_mmngrbuf
+    cdata.set('HAVE_MMNGRBUF', 1)
+  endif
+
+  if get_option('dmabuf_support')
+    # check OMXR_Extension_vdcmn.h
+    have_exvdcmn = cc.has_header(
+        'OMXR_Extension_vdcmn.h',
+        args : gst_omx_args)
+    if have_mmngrbuf and have_exvdcmn
+      cdata.set ('USE_RCAR_DMABUF', 1)
+    endif
+  endif
+
+  # check OMXR_Extension_vp8e.h
+  if cc.has_header (
+    'OMXR_Extension_vp8e.h',
+    args : gst_omx_args)
+    cdata.set ('HAVE_VP8ENC_EXT', 1)
+  endif
+
+  # check OMXR_Extension_aapd.h
+  if cc.has_header (
+      'OMXR_Extension_aapd.h',
+      args : gst_omx_args)
+    cdata.set ('HAVE_AACDEC_EXT', 1)
+  endif
+
+  # check OMXR_Extension_audio.h
+  if cc.has_header (
+      'OMXR_Extension_audio.h',
+      args : gst_omx_args)
+    cdata.set ('HAVE_AUDIOR_EXT', 1)
+  endif
+
+  # check OMXR_Extension_vecmn.h
+  if cc.has_header (
+      'OMXR_Extension_vecmn.h',
+      args : gst_omx_args)
+    cdata.set ('HAVE_VIDEOENC_EXT', 1)
+  endif
+
+  # check OMXR_Extension_video.h
+  if cc.has_header (
+      'OMXR_Extension_video.h',
+      args : gst_omx_args)
+    cdata.set ('HAVE_VIDEOR_EXT', 1)
+  endif
+
+  # check OMXR_Extension_h265d.h
+  if cc.has_header (
+      'OMXR_Extension_h265d.h',
+      args : gst_omx_args)
+    cdata.set ('HAVE_H265DEC_EXT', 1)
+  endif
 else
   error ('Unsupported omx target specified. Use the -Dtarget option')
 endif
@@ -224,6 +285,7 @@ if cc.has_header (
     args : gst_omx_args,
     include_directories : [omx_inc])
   extra_video_headers += '''
+#include <OMX_Video.h>
 #include <OMX_VideoExt.h>'''
   cdata.set ('HAVE_VIDEO_EXT', 1)
 endif
diff --git a/meson_options.txt b/meson_options.txt
index 75985ce..0afb142 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,7 +1,7 @@
 option('header_path', type : 'string', value : '',
     description : 'An extra include directory to find the OpenMax headers')
 option('target', type : 'combo',
-    choices : ['none', 'generic', 'rpi', 'bellagio', 'tizonia', 'zynqultrascaleplus'], value : 'none',
+    choices : ['none', 'generic', 'rpi', 'bellagio', 'tizonia', 'zynqultrascaleplus', 'rcar'], value : 'none',
     description : 'The OMX platform to target')
 option('struct_packing', type : 'combo',
     choices : ['0', '1', '2', '4', '8'], value : '0',
@@ -11,3 +11,6 @@ option('struct_packing', type : 'combo',
 option('examples', type : 'feature', value : 'auto', yield : true)
 option('tests', type : 'feature', value : 'auto', yield : true)
 option('tools', type : 'feature', value : 'auto', yield : true)
+
+#R-Car custom options
+option('dmabuf_support', type: 'boolean', value: true)
diff --git a/omx/Makefile.am b/omx/Makefile.am
index 3019040..0440bc7 100644
--- a/omx/Makefile.am
+++ b/omx/Makefile.am
@@ -1,8 +1,8 @@
 plugin_LTLIBRARIES = libgstomx.la
 
 if HAVE_VP8
-VP8_C_FILES=gstomxvp8dec.c
-VP8_H_FILES=gstomxvp8dec.h
+VP8_C_FILES=gstomxvp8dec.c gstomxvp8enc.c
+VP8_H_FILES=gstomxvp8dec.h gstomxvp8enc.h
 endif
 
 if HAVE_THEORA
@@ -19,6 +19,11 @@ H265_H_FILES = \
 	gstomxh265dec.h \
 	gstomxh265enc.h \
 	gstomxh265utils.h
+else
+if USE_OMX_TARGET_RCAR
+H265_C_FILES = gstomxh265dec.c
+H265_H_FILES = gstomxh265dec.h
+endif
 endif
 
 libgstomx_la_SOURCES = \
@@ -36,6 +41,7 @@ libgstomx_la_SOURCES = \
 	gstomxh264utils.c \
 	gstomxh263dec.c \
 	gstomxwmvdec.c \
+	gstomxvp9dec.c \
 	$(VP8_C_FILES) \
 	$(THEORA_C_FILES) \
 	$(H265_C_FILES) \
@@ -45,6 +51,7 @@ libgstomx_la_SOURCES = \
 	gstomxaacdec.c \
 	gstomxmp3dec.c \
 	gstomxmp3enc.c \
+	gstomxwmadec.c \
 	gstomxaacenc.c \
 	gstomxamrdec.c \
 	gstomxaudiosink.c \
@@ -66,6 +73,7 @@ noinst_HEADERS = \
 	gstomxh264utils.h \
 	gstomxh263dec.h \
 	gstomxwmvdec.h \
+	gstomxvp9dec.h \
 	$(VP8_H_FILES) \
 	$(THEORA_H_FILES) \
 	$(H265_H_FILES) \
@@ -75,6 +83,7 @@ noinst_HEADERS = \
 	gstomxaacdec.h \
 	gstomxmp3dec.h \
 	gstomxmp3enc.h \
+	gstomxwmadec.h \
 	gstomxaacenc.h \
 	gstomxamrdec.h \
 	gstomxaudiosink.h \
@@ -100,6 +109,7 @@ libgstomx_la_LIBADD = \
 	-lgstaudio-@GST_API_VERSION@ \
 	-lgstpbutils-@GST_API_VERSION@ \
 	-lgstvideo-@GST_API_VERSION@ \
+        -lgstallocators-@GST_API_VERSION@ \
 	$(GST_BASE_LIBS) \
 	$(GST_LIBS) \
 	$(GST_ALLOCATORS_LIBS) \
diff --git a/omx/gstomx.c b/omx/gstomx.c
index 038ce32..4e82fac 100644
--- a/omx/gstomx.c
+++ b/omx/gstomx.c
@@ -3,6 +3,7 @@
  *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
  * Copyright (C) 2013, Collabora Ltd.
  *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ * Copyright (C) 2017,2020-2021 Renesas Electronics Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -36,15 +37,18 @@
 #include "gstomxh263dec.h"
 #include "gstomxh265dec.h"
 #include "gstomxvp8dec.h"
+#include "gstomxvp9dec.h"
 #include "gstomxtheoradec.h"
 #include "gstomxwmvdec.h"
 #include "gstomxmpeg4videoenc.h"
 #include "gstomxh264enc.h"
+#include "gstomxvp8enc.h"
 #include "gstomxh263enc.h"
 #include "gstomxh265enc.h"
 #include "gstomxaacdec.h"
 #include "gstomxmp3dec.h"
 #include "gstomxmp3enc.h"
+#include "gstomxwmadec.h"
 #include "gstomxaacenc.h"
 #include "gstomxamrdec.h"
 #include "gstomxanalogaudiosink.h"
@@ -388,6 +392,9 @@ gst_omx_component_handle_messages (GstOMXComponent * comp)
         GstOMXBuffer *buf = msg->content.buffer_done.buffer->pAppPrivate;
         GstOMXPort *port;
 
+        if (!buf)
+          break;
+
         port = buf->port;
 
         buf->used = FALSE;
@@ -3418,14 +3425,17 @@ static const GGetTypeFunction types[] = {
   gst_omx_aac_dec_get_type, gst_omx_mp3_enc_get_type,
   gst_omx_amr_dec_get_type
 #ifdef HAVE_VP8
-      , gst_omx_vp8_dec_get_type
+      , gst_omx_vp8_dec_get_type, gst_omx_vp8_enc_get_type
 #endif
 #ifdef HAVE_THEORA
       , gst_omx_theora_dec_get_type
 #endif
 #ifdef HAVE_HEVC
       , gst_omx_h265_enc_get_type, gst_omx_h265_dec_get_type
+#elif USE_OMX_TARGET_RCAR
+      , gst_omx_h265_dec_get_type, gst_omx_vp9_dec_get_type
 #endif
+  , gst_omx_wma_dec_get_type
 };
 
 struct TypeOffest
@@ -3722,6 +3732,16 @@ gst_omx_parse_hacks (gchar ** hacks)
       hacks_flags |= GST_OMX_HACK_PASS_COLOR_FORMAT_TO_DECODER;
     else if (g_str_equal (*hacks, "ensure-buffer-count-actual"))
       hacks_flags |= GST_OMX_HACK_ENSURE_BUFFER_COUNT_ACTUAL;
+    else if (g_str_equal (*hacks, "use-copy-mode-as-default"))
+      hacks_flags |= GST_OMX_HACK_USE_COPY_MODE_AS_DEFAULT;
+    else if (g_str_equal (*hacks, "use-no-copy-mode-as-default"))
+      hacks_flags |= GST_OMX_HACK_USE_NO_COPY_MODE_AS_DEFAULT;
+    else if (g_str_equal (*hacks, "default-pix-aspect-ratio"))
+      hacks_flags |= GST_OMX_HACK_DEFAULT_PIXEL_ASPECT_RATIO;
+    else if (g_str_equal (*hacks, "skip-handle-codec-data"))
+      hacks_flags |= GST_OMX_HACK_SKIP_HANDLE_CODEC_DATA;
+    else if (g_str_equal (*hacks, "renesas-encmc-stride-align"))
+      hacks_flags |= GST_OMX_HACK_RENESAS_ENCMC_STRIDE_ALIGN;
     else
       GST_WARNING ("Unknown hack: %s", *hacks);
     hacks++;
diff --git a/omx/gstomx.h b/omx/gstomx.h
index 4b61343..0115114 100644
--- a/omx/gstomx.h
+++ b/omx/gstomx.h
@@ -3,6 +3,7 @@
  *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
  * Copyright (C) 2013, Collabora Ltd.
  *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ * Copyright (C) 2017,2020-2021 Renesas Electronics Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -59,6 +60,7 @@
 #endif
 
 #ifdef HAVE_VIDEO_EXT
+#include <OMX_Video.h>
 #include <OMX_VideoExt.h>
 #endif
 
@@ -207,6 +209,31 @@ G_BEGIN_DECLS
  */
 #define GST_OMX_HACK_ENSURE_BUFFER_COUNT_ACTUAL          G_GUINT64_CONSTANT (0x0000000000002000)
 
+/* omx videodecoder support 3 modes (copy, no-copy(use buffer of Bufferpool), dmabuf) to choose.
+ * Default is dmabuf mode. This hack will choose copy mode is default mode
+ */
+#define GST_OMX_HACK_USE_COPY_MODE_AS_DEFAULT                         G_GUINT64_CONSTANT (0x0000000000004000)
+
+/* omx videodecoder support 3 modes (copy, no-copy(use buffer of Bufferpool), dmabuf) to choose.
+ * Default is dmabuf mode. This hack will choose no-copy mode is default mode
+ */
+#define GST_OMX_HACK_USE_NO_COPY_MODE_AS_DEFAULT                      G_GUINT64_CONSTANT (0x0000000000008000)
+
+/* Support default pixel aspect ratio is 1:1.
+ */
+#define GST_OMX_HACK_DEFAULT_PIXEL_ASPECT_RATIO                       G_GUINT64_CONSTANT (0x0000000000010000)
+/* Align Stride for 32 in case support for NV12 format (Semi-planar)
+ * Align Stride for 64 in case support for I420 format (Planar).
+ * This alignment support for Renesas Video Encoder MC that have restriction
+ * of nStride in OMX.
+ */
+#define GST_OMX_HACK_RENESAS_ENCMC_STRIDE_ALIGN                       G_GUINT64_CONSTANT (0x0000000000020000)
+
+/* If the component does not handle for codec data. Skip this handling
+ * Happens with Renesas OMX WMADEC
+ */
+#define GST_OMX_HACK_SKIP_HANDLE_CODEC_DATA                           G_GUINT64_CONSTANT (0x0000000000040000)
+
 typedef struct _GstOMXCore GstOMXCore;
 typedef struct _GstOMXPort GstOMXPort;
 typedef enum _GstOMXPortDirection GstOMXPortDirection;
diff --git a/omx/gstomxaacdec.c b/omx/gstomxaacdec.c
index 9606b7f..f928597 100644
--- a/omx/gstomxaacdec.c
+++ b/omx/gstomxaacdec.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2014, Sebastian Dröge <sebastian@centricular.com>
+ * Copyright (C) 2017,2020 Renesas Electronics Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -24,6 +25,9 @@
 #include <gst/gst.h>
 
 #include "gstomxaacdec.h"
+#if defined (USE_OMX_TARGET_RCAR) && defined (HAVE_AACDEC_EXT)
+#include "OMXR_Extension_aapd.h"
+#endif
 
 GST_DEBUG_CATEGORY_STATIC (gst_omx_aac_dec_debug_category);
 #define GST_CAT_DEFAULT gst_omx_aac_dec_debug_category
@@ -37,6 +41,16 @@ static gint gst_omx_aac_dec_get_samples_per_frame (GstOMXAudioDec * dec,
     GstOMXPort * port);
 static gboolean gst_omx_aac_dec_get_channel_positions (GstOMXAudioDec * dec,
     GstOMXPort * port, GstAudioChannelPosition position[OMX_AUDIO_MAXCHANNELS]);
+static void gst_omx_aac_dec_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_omx_aac_dec_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+
+enum
+{
+  PROP_0,
+  PROP_DOWN_MIX
+};
 
 /* class initialization */
 
@@ -53,6 +67,10 @@ gst_omx_aac_dec_class_init (GstOMXAACDecClass * klass)
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
   GstOMXAudioDecClass *audiodec_class = GST_OMX_AUDIO_DEC_CLASS (klass);
 
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->set_property = gst_omx_aac_dec_set_property;
+  gobject_class->get_property = gst_omx_aac_dec_get_property;
+
   audiodec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_aac_dec_set_format);
   audiodec_class->is_format_change =
       GST_DEBUG_FUNCPTR (gst_omx_aac_dec_is_format_change);
@@ -73,6 +91,13 @@ gst_omx_aac_dec_class_init (GstOMXAACDecClass * klass)
       "Decode AAC audio streams",
       "Sebastian Dröge <sebastian@centricular.com>");
 
+  g_object_class_install_property (gobject_class, PROP_DOWN_MIX,
+      g_param_spec_boolean ("down-mix", "Down Mix",
+          "Whether or not use down mix function.\n\
+                      down-mix=true: output channel is 2 always.\n\
+                      down-mix=false: output channel is 1, 2 or 6\n\
+                      This option is available for omxaacdec only", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   gst_omx_set_default_role (&audiodec_class->cdata, "audio_decoder.aac");
 }
 
@@ -81,6 +106,7 @@ gst_omx_aac_dec_init (GstOMXAACDec * self)
 {
   /* FIXME: Other values exist too! */
   self->spf = 1024;
+  self->down_mix = TRUE;
 }
 
 static gboolean
@@ -161,6 +187,31 @@ gst_omx_aac_dec_set_format (GstOMXAudioDec * dec, GstOMXPort * port,
         gst_omx_error_to_string (err), err);
     return FALSE;
   }
+#if defined (USE_OMX_TARGET_RCAR) && defined (HAVE_AACDEC_EXT)
+  {
+    /* Setting down-mix mode */
+    GstOMXAudioDecClass *klass;
+    klass = GST_OMX_AUDIO_DEC_GET_CLASS (dec);
+    if (g_strcmp0 (klass->cdata.component_name,
+            "OMX.RENESAS.AUDIO.DECODER.AAC") == 0) {
+      OMXR_MC_AUDIO_PARAM_AACDOWNMIXTYPE downmix_par;
+      GST_OMX_INIT_STRUCT (&downmix_par);
+      downmix_par.nPortIndex = dec->dec_out_port->index;
+      if (self->down_mix != FALSE)
+        downmix_par.bDownmix = TRUE;
+      else
+        downmix_par.bDownmix = FALSE;
+
+      gst_omx_component_set_parameter
+          (dec->dec, OMXR_MC_IndexParamAacDownMix, &downmix_par);
+    } else {
+      GST_WARNING_OBJECT (self, "down-mix is not effective on omxaaclcdec");
+    }
+  }
+#else
+  GST_WARNING_OBJECT (self,
+      "down-mix option is invalid now due to MC does not support");
+#endif
 
   return TRUE;
 }
@@ -232,6 +283,41 @@ gst_omx_aac_dec_is_format_change (GstOMXAudioDec * dec, GstOMXPort * port,
 static gint
 gst_omx_aac_dec_get_samples_per_frame (GstOMXAudioDec * dec, GstOMXPort * port)
 {
+  /* Handle for aacplus */
+  OMX_AUDIO_PARAM_AACPROFILETYPE aac_param;
+  OMX_AUDIO_PARAM_PCMMODETYPE pcm_param;
+  OMX_ERRORTYPE err;
+  /* aacplus has output sampling rate = 2 * input sampling rate
+   * check input sampling rate and output sampling rate to detect
+   * aacplus stream */
+  GST_OMX_INIT_STRUCT (&aac_param);
+  aac_param.nPortIndex = dec->dec_in_port->index;
+  err =
+      gst_omx_component_get_parameter (dec->dec, OMX_IndexParamAudioAac,
+      &aac_param);
+  if (err != OMX_ErrorNone) {
+    GST_ERROR_OBJECT (dec, "Failed to get AAC parameters: %s (0x%08x)\
+    Can not detect input is aacplus or not", gst_omx_error_to_string (err), err);
+    goto done;
+  }
+  GST_OMX_INIT_STRUCT (&pcm_param);
+  pcm_param.nPortIndex = dec->dec_out_port->index;
+  err =
+      gst_omx_component_get_parameter (dec->dec, OMX_IndexParamAudioPcm,
+      &pcm_param);
+  if (err != OMX_ErrorNone) {
+    GST_ERROR_OBJECT (dec, "Failed to get PCM parameters: %s (0x%08x)\
+    Can not detect input is aacplus or not", gst_omx_error_to_string (err), err);
+    goto done;
+  }
+  if (pcm_param.nSamplingRate == (2 * aac_param.nSampleRate))
+    GST_OMX_AAC_DEC (dec)->spf = 2048;
+  else
+    GST_OMX_AAC_DEC (dec)->spf = 1024;
+
+  GST_DEBUG_OBJECT (dec, "Decoding with spf=%d", GST_OMX_AAC_DEC (dec)->spf);
+
+done:
   return GST_OMX_AAC_DEC (dec)->spf;
 }
 
@@ -294,3 +380,35 @@ gst_omx_aac_dec_get_channel_positions (GstOMXAudioDec * dec,
 
   return TRUE;
 }
+
+static void
+gst_omx_aac_dec_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstOMXAACDec *self = GST_OMX_AAC_DEC (object);
+
+  switch (prop_id) {
+    case PROP_DOWN_MIX:
+      self->down_mix = g_value_get_boolean (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_omx_aac_dec_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  GstOMXAACDec *self = GST_OMX_AAC_DEC (object);
+
+  switch (prop_id) {
+    case PROP_DOWN_MIX:
+      g_value_set_boolean (value, self->down_mix);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
diff --git a/omx/gstomxaacdec.h b/omx/gstomxaacdec.h
index 891589b..98413c7 100644
--- a/omx/gstomxaacdec.h
+++ b/omx/gstomxaacdec.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2014, Sebastian Dröge <sebastian@centricular.com>
+ * Copyright (C) 2017,2020 Renesas Electronics Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -45,6 +46,9 @@ struct _GstOMXAACDec
 {
   GstOMXAudioDec parent;
   gint spf;
+  /* Set FALSE if do not use down mix. Down mix will be set TRUE as default
+   * With down_mix=TRUE, output channel is always 2 (stereo)*/
+  gboolean down_mix;
 };
 
 struct _GstOMXAACDecClass
diff --git a/omx/gstomxaudiodec.c b/omx/gstomxaudiodec.c
index 8275b72..70de829 100644
--- a/omx/gstomxaudiodec.c
+++ b/omx/gstomxaudiodec.c
@@ -4,6 +4,7 @@
  * Copyright (C) 2013, Collabora Ltd.
  *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
  * Copyright (C) 2014, Sebastian Dröge <sebastian@centricular.com>
+ * Copyright (C) 2017,2020 Renesas Electronics Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -50,6 +51,8 @@ static gboolean gst_omx_audio_dec_set_format (GstAudioDecoder * decoder,
 static void gst_omx_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard);
 static GstFlowReturn gst_omx_audio_dec_handle_frame (GstAudioDecoder * decoder,
     GstBuffer * buffer);
+static GstCaps *gst_omx_audio_dec_getcaps (GstAudioDecoder * dec,
+    GstCaps * filter);
 static GstFlowReturn gst_omx_audio_dec_drain (GstOMXAudioDec * self);
 
 enum
@@ -88,6 +91,7 @@ gst_omx_audio_dec_class_init (GstOMXAudioDecClass * klass)
       GST_DEBUG_FUNCPTR (gst_omx_audio_dec_set_format);
   audio_decoder_class->handle_frame =
       GST_DEBUG_FUNCPTR (gst_omx_audio_dec_handle_frame);
+  audio_decoder_class->getcaps = GST_DEBUG_FUNCPTR (gst_omx_audio_dec_getcaps);
 
   klass->cdata.type = GST_OMX_COMPONENT_TYPE_FILTER;
   klass->cdata.default_src_template_caps =
@@ -406,6 +410,16 @@ gst_omx_audio_dec_loop (GstOMXAudioDec * self)
         && omx_position[0] == GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER)
       omx_position[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
 
+#ifdef USE_OMX_TARGET_RCAR
+    /* Workaround for handle audio stream have dual channel */
+    if (pcm_param.nChannels == 2
+        && omx_position[0] == GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER
+        && omx_position[1] == GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER) {
+      omx_position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
+      omx_position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
+    }
+#endif
+
     if (omx_position[0] == GST_AUDIO_CHANNEL_POSITION_NONE
         && klass->get_channel_positions) {
       GST_WARNING_OBJECT (self,
@@ -748,6 +762,7 @@ gst_omx_audio_dec_start (GstAudioDecoder * decoder)
   self = GST_OMX_AUDIO_DEC (decoder);
 
   self->last_upstream_ts = 0;
+  self->eos = FALSE;
   self->downstream_flow_ret = GST_FLOW_OK;
 
   return TRUE;
@@ -772,6 +787,7 @@ gst_omx_audio_dec_stop (GstAudioDecoder * decoder)
 
   self->downstream_flow_ret = GST_FLOW_FLUSHING;
   self->started = FALSE;
+  self->eos = FALSE;
 
   g_mutex_lock (&self->drain_lock);
   self->draining = FALSE;
@@ -890,16 +906,19 @@ gst_omx_audio_dec_set_format (GstAudioDecoder * decoder, GstCaps * caps)
           NULL) != OMX_ErrorNone)
     return FALSE;
 
-  /* Get codec data from caps */
-  gst_buffer_replace (&self->codec_data, NULL);
-  s = gst_caps_get_structure (caps, 0);
-  codec_data = gst_structure_get_value (s, "codec_data");
-  if (codec_data) {
-    /* Vorbis and some other codecs have multiple buffers in
-     * the stream-header field */
-    self->codec_data = gst_value_get_buffer (codec_data);
-    if (self->codec_data)
-      gst_buffer_ref (self->codec_data);
+  /* Skip to get codec data from cap if use "skip-handle-codec-data" hack */
+  if (!(klass->cdata.hacks & GST_OMX_HACK_SKIP_HANDLE_CODEC_DATA)) {
+    /* Get codec data from caps */
+    gst_buffer_replace (&self->codec_data, NULL);
+    s = gst_caps_get_structure (caps, 0);
+    codec_data = gst_structure_get_value (s, "codec_data");
+    if (codec_data) {
+      /* Vorbis and some other codecs have multiple buffers in
+       * the stream-header field */
+      self->codec_data = gst_value_get_buffer (codec_data);
+      if (self->codec_data)
+        gst_buffer_ref (self->codec_data);
+    }
   }
 
   GST_DEBUG_OBJECT (self, "Enabling component");
@@ -1035,6 +1054,7 @@ gst_omx_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard)
   self->last_upstream_ts = 0;
   self->downstream_flow_ret = GST_FLOW_OK;
   self->started = FALSE;
+  self->eos = FALSE;
   GST_DEBUG_OBJECT (self, "Flush finished");
 }
 
@@ -1059,7 +1079,7 @@ gst_omx_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf)
     return self->downstream_flow_ret;
   }
 
-  if (!self->started) {
+  if (!self->started && !self->eos) {
     GST_DEBUG_OBJECT (self, "Starting task");
     gst_pad_start_task (GST_AUDIO_DECODER_SRC_PAD (self),
         (GstTaskFunction) gst_omx_audio_dec_loop, decoder, NULL);
@@ -1322,6 +1342,21 @@ release_error:
   }
 }
 
+static GstCaps *
+gst_omx_audio_dec_getcaps (GstAudioDecoder * dec, GstCaps * filter)
+{
+  GstCaps *templ_caps;
+  GstCaps *fcaps;
+  templ_caps = gst_pad_get_pad_template_caps (dec->sinkpad);
+  if (filter) {
+    fcaps = gst_caps_intersect (templ_caps, filter);
+    gst_caps_unref (templ_caps);
+    templ_caps = fcaps;
+  }
+
+  return templ_caps;
+}
+
 static GstFlowReturn
 gst_omx_audio_dec_drain (GstOMXAudioDec * self)
 {
@@ -1392,6 +1427,7 @@ gst_omx_audio_dec_drain (GstOMXAudioDec * self)
     g_cond_wait (&self->drain_cond, &self->drain_lock);
     GST_DEBUG_OBJECT (self, "Drained component");
   }
+  self->eos = TRUE;
 
   g_mutex_unlock (&self->drain_lock);
   GST_AUDIO_DECODER_STREAM_LOCK (self);
diff --git a/omx/gstomxaudiodec.h b/omx/gstomxaudiodec.h
index 0f4adc6..9d7e25f 100644
--- a/omx/gstomxaudiodec.h
+++ b/omx/gstomxaudiodec.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2014, Sebastian Dröge <sebastian@centricular.com>
+ * Copyright (C) 2017,2020 Renesas Electronics Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -75,6 +76,8 @@ struct _GstOMXAudioDec
   GCond drain_cond;
   /* TRUE if EOS buffers shouldn't be forwarded */
   gboolean draining;
+  /* TRUE if upstream is EOS */
+  gboolean eos;
 
   GstAdapter *output_adapter;
 
diff --git a/omx/gstomxbufferpool.c b/omx/gstomxbufferpool.c
index c662c42..bc0f0af 100644
--- a/omx/gstomxbufferpool.c
+++ b/omx/gstomxbufferpool.c
@@ -3,6 +3,7 @@
  *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
  * Copyright (C) 2013, Collabora Ltd.
  *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ * Copyright (C) 2019-2020, Renesas Electronics Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -25,8 +26,13 @@
 #endif
 
 #include "gstomxbufferpool.h"
-
+#include "gstomxvideodec.h"
 #include <gst/allocators/gstdmabuf.h>
+#ifdef USE_RCAR_DMABUF
+#include "mmngr_buf_user_public.h"
+#include "OMXR_Extension_vdcmn.h"
+#endif
+#include <unistd.h>             /* getpagesize() */
 
 GST_DEBUG_CATEGORY_STATIC (gst_omx_buffer_pool_debug_category);
 #define GST_CAT_DEFAULT gst_omx_buffer_pool_debug_category
@@ -396,6 +402,88 @@ wrong_video_caps:
   }
 }
 
+#if defined USE_RCAR_DMABUF
+static gboolean
+gst_omx_buffer_pool_export_dmabuf (GstOMXBufferPool * pool,
+    guint phys_addr, gint size, gint * id_export, gint * dmabuf_fd)
+{
+  gint res;
+
+  res =
+      mmngr_export_start_in_user_ext (id_export,
+      (gsize) size, phys_addr, dmabuf_fd, NULL);
+  if (res != R_MM_OK) {
+    GST_ERROR_OBJECT (pool,
+        "mmngr_export_start_in_user failed (phys_addr:0x%08x)", phys_addr);
+    return FALSE;
+  }
+  GST_DEBUG_OBJECT (pool,
+      "Export dmabuf:%d id_export:%d (phys_addr:0x%08x)", *dmabuf_fd,
+      *id_export, phys_addr);
+
+  return TRUE;
+}
+
+static GstMemory *
+gst_omx_buffer_pool_create_dmabuf_memory (gint num_plane,
+    GstOMXBufferPool * self, GstOMXBuffer * omx_buf, gint stride, gint slice)
+{
+  gint dmabuf_fd;
+  gint plane_size;
+  gint plane_size_ext;
+  gint dmabuf_id;
+  gint page_offset;
+  gint page_size;
+  guint phys_addr;
+  guint offset = 0;
+  GstMemory *mem;
+  OMXR_MC_VIDEO_DECODERESULTTYPE *decode_res;
+
+  page_size = getpagesize ();
+
+  if (num_plane) {
+    if (num_plane == 1)
+      offset = stride * slice;
+    else
+      offset = stride * slice + stride / 2 * slice / 2;
+
+    if (GST_VIDEO_INFO_FORMAT (&self->video_info) == GST_VIDEO_FORMAT_I420)
+      stride = stride / 2;
+    slice = slice / 2;
+  }
+
+  decode_res =
+      (OMXR_MC_VIDEO_DECODERESULTTYPE *) omx_buf->omx_buf->pOutputPortPrivate;
+
+  phys_addr = (guintptr) decode_res->pvPhysImageAddressY + offset;
+  /* Calculate offset between physical address and page boundary */
+  page_offset = phys_addr & (page_size - 1);
+
+  plane_size = stride * slice;
+
+  /* When downstream plugins do mapping from dmabuf fd it requires
+   * mapping from boundary page and size align for page size so
+   * memory for plane must increase to handle for this case */
+  plane_size_ext = GST_ROUND_UP_N (plane_size + page_offset, page_size);
+
+  if (!gst_omx_buffer_pool_export_dmabuf (self,
+          GST_ROUND_DOWN_N (phys_addr, page_size),
+          plane_size_ext, &dmabuf_id, &dmabuf_fd)) {
+    GST_ERROR_OBJECT (self, "dmabuf exporting failed");
+    return NULL;
+  }
+
+  g_array_append_val (self->id_array, dmabuf_id);
+  /* Set offset's information */
+  mem = gst_dmabuf_allocator_alloc (self->allocator, dmabuf_fd, plane_size_ext);
+  mem->offset = page_offset;
+  /* Only allow to access plane size */
+  mem->size = plane_size;
+
+  return mem;
+}
+#endif
+
 static GstFlowReturn
 gst_omx_buffer_pool_alloc_buffer (GstBufferPool * bpool,
     GstBuffer ** buffer, GstBufferPoolAcquireParams * params)
@@ -404,12 +492,16 @@ gst_omx_buffer_pool_alloc_buffer (GstBufferPool * bpool,
   GstBuffer *buf;
   GstOMXBuffer *omx_buf;
 
+  g_return_val_if_fail (pool->port->buffers->len > pool->current_buffer_index,
+      GST_FLOW_ERROR);
   omx_buf = g_ptr_array_index (pool->port->buffers, pool->current_buffer_index);
   g_return_val_if_fail (omx_buf != NULL, GST_FLOW_ERROR);
 
   if (pool->other_pool) {
     guint i, n;
 
+    g_return_val_if_fail (pool->buffers->len > pool->current_buffer_index,
+        GST_FLOW_ERROR);
     buf = g_ptr_array_index (pool->buffers, pool->current_buffer_index);
     g_assert (pool->other_pool == buf->pool);
     gst_object_replace ((GstObject **) & buf->pool, NULL);
@@ -446,34 +538,55 @@ gst_omx_buffer_pool_alloc_buffer (GstBufferPool * bpool,
     gsize offset[GST_VIDEO_MAX_PLANES] = { 0, };
     gint stride[GST_VIDEO_MAX_PLANES] = { nstride, 0, };
 
+    buf = gst_buffer_new ();
+
     if (pool->output_mode == GST_OMX_BUFFER_MODE_DMABUF) {
-      gint fd;
       GstMapInfo map;
+      gint n_planes;
+      gint i;
 
-      fd = GPOINTER_TO_INT (omx_buf->omx_buf->pBuffer);
-
-      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);
+#ifndef USE_OMX_TARGET_RCAR
+      n_planes = 1;
+#else
+      n_planes = GST_VIDEO_INFO_N_PLANES (&pool->video_info);
+#endif
+      for (i = 0; i < n_planes; i++) {
+#ifndef USE_RCAR_DMABUF
+        gint fd;
+
+        fd = GPOINTER_TO_INT (omx_buf->omx_buf->pBuffer);
+
+        mem =
+            gst_dmabuf_allocator_alloc (pool->allocator, fd,
+            omx_buf->omx_buf->nAllocLen);
+#else
+        mem = gst_omx_buffer_pool_create_dmabuf_memory (i, pool,
+            omx_buf, nstride, nslice);
+#endif
+        if (!mem) {
+          GST_ERROR_OBJECT (pool, "Can not create dmabuf");
+          gst_buffer_unref (buf);
           return GST_FLOW_ERROR;
         }
-
-        gst_memory_unmap (mem, &map);
+        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);
+            gst_buffer_unref (buf);
+            return GST_FLOW_ERROR;
+          }
+          gst_memory_unmap (mem, &map);
+        }
+        gst_buffer_append_memory (buf, mem);
       }
     } else {
       mem = gst_omx_memory_allocator_alloc (pool->allocator, 0, omx_buf);
+      gst_buffer_append_memory (buf, mem);
     }
 
-    buf = gst_buffer_new ();
-    gst_buffer_append_memory (buf, mem);
     g_ptr_array_add (pool->buffers, buf);
 
     switch (GST_VIDEO_INFO_FORMAT (&pool->video_info)) {
@@ -595,10 +708,15 @@ gst_omx_buffer_pool_acquire_buffer (GstBufferPool * bpool,
   GstFlowReturn ret;
   GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
 
+  if (GST_BUFFER_POOL_IS_FLUSHING (bpool))
+    goto flushing;
+
   if (pool->port->port_def.eDir == OMX_DirOutput) {
     GstBuffer *buf;
 
     g_return_val_if_fail (pool->current_buffer_index != -1, GST_FLOW_ERROR);
+    g_return_val_if_fail (pool->buffers->len > pool->current_buffer_index,
+        GST_FLOW_ERROR);
 
     buf = g_ptr_array_index (pool->buffers, pool->current_buffer_index);
     g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);
@@ -606,7 +724,8 @@ gst_omx_buffer_pool_acquire_buffer (GstBufferPool * bpool,
     ret = GST_FLOW_OK;
 
     /* If it's our own memory we have to set the sizes */
-    if (!pool->other_pool) {
+    if ((!pool->other_pool) &&
+        ((GST_OMX_VIDEO_DEC (pool->element)->dmabuf) == FALSE)) {
       GstMemory *mem = gst_buffer_peek_memory (*buffer, 0);
       GstOMXBuffer *omx_buf;
 
@@ -645,6 +764,12 @@ gst_omx_buffer_pool_acquire_buffer (GstBufferPool * bpool,
   }
 
   return ret;
+
+flushing:
+  {
+    GST_DEBUG_OBJECT (pool, "we are flushing");
+    return GST_FLOW_FLUSHING;
+  }
 }
 
 static void
@@ -678,6 +803,22 @@ gst_omx_buffer_pool_finalize (GObject * object)
 {
   GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (object);
 
+#ifdef USE_RCAR_DMABUF
+  gint i;
+  gint dmabuf_id;
+
+  for (i = 0; i < pool->id_array->len; i++) {
+    dmabuf_id = g_array_index (pool->id_array, gint, i);
+    if (dmabuf_id >= 0) {
+      GST_DEBUG_OBJECT (pool, "mmngr_export_end_in_user (%d)", dmabuf_id);
+      mmngr_export_end_in_user_ext (dmabuf_id);
+    } else {
+      GST_WARNING_OBJECT (pool, "Invalid dmabuf_id");
+    }
+  }
+  g_array_free (pool->id_array, TRUE);
+#endif
+
   if (pool->element)
     gst_object_unref (pool->element);
   pool->element = NULL;
@@ -728,6 +869,9 @@ static void
 gst_omx_buffer_pool_init (GstOMXBufferPool * pool)
 {
   pool->buffers = g_ptr_array_new ();
+#ifdef USE_RCAR_DMABUF
+  pool->id_array = g_array_new (FALSE, FALSE, sizeof (gint));
+#endif
 }
 
 GstBufferPool *
diff --git a/omx/gstomxbufferpool.h b/omx/gstomxbufferpool.h
index a09c825..edeba0d 100644
--- a/omx/gstomxbufferpool.h
+++ b/omx/gstomxbufferpool.h
@@ -1,6 +1,7 @@
 /*
  * Copyright 2014 Advanced Micro Devices, Inc.
  *   Author: Christian König <christian.koenig@amd.com>
+ * Copyright (C) 2019-2020, Renesas Electronics Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -84,6 +85,11 @@ struct _GstOMXBufferPool
 
   /* The type of buffers produced by the decoder */
   GstOMXBufferMode output_mode;
+
+#ifdef USE_RCAR_DMABUF
+  /* Array use to contain dma_id. It is used in export_end dmabuf area */
+  GArray *id_array;
+#endif
 };
 
 struct _GstOMXBufferPoolClass
diff --git a/omx/gstomxh264enc.c b/omx/gstomxh264enc.c
index f75fff0..30cda67 100644
--- a/omx/gstomxh264enc.c
+++ b/omx/gstomxh264enc.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
  *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
+ * Copyright (C) 2017,2020 Renesas Electronics Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,6 +32,9 @@
 #include <OMX_Broadcom.h>
 #include <OMX_Index.h>
 #endif
+#if defined (USE_OMX_TARGET_RCAR) && defined (HAVE_VIDEOENC_EXT)
+#include "OMXR_Extension_vecmn.h"
+#endif
 
 GST_DEBUG_CATEGORY_STATIC (gst_omx_h264_enc_debug_category);
 #define GST_CAT_DEFAULT gst_omx_h264_enc_debug_category
@@ -62,6 +66,11 @@ enum
   PROP_ENTROPY_MODE,
   PROP_CONSTRAINED_INTRA_PREDICTION,
   PROP_LOOP_FILTER_MODE,
+  PROP_REF_FRAMES,
+#ifdef USE_OMX_TARGET_RCAR
+  PROP_SEND_EOS,
+  PROP_USE_INCAPS_HEADER
+#endif
 };
 
 #ifdef USE_OMX_TARGET_RPI
@@ -73,7 +82,17 @@ enum
 #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)
-
+#ifndef USE_OMX_TARGET_RCAR
+#define GST_OMX_H264_VIDEO_ENC_REF_FRAMES_DEFAULT 0
+#define GST_OMX_H264_VIDEO_ENC_REF_FRAMES_MIN 0
+#define GST_OMX_H264_VIDEO_ENC_REF_FRAMES_MAX 16
+#else
+#define GST_OMX_H264_VIDEO_ENC_REF_FRAMES_DEFAULT (0xffffffff)
+#define GST_OMX_H264_VIDEO_ENC_REF_FRAMES_MIN 0
+#define GST_OMX_H264_VIDEO_ENC_REF_FRAMES_MAX G_MAXUINT
+#define GST_OMX_H264_VIDEO_ENC_SEND_EOS_DEFAULT      FALSE
+#define GST_OMX_H264_VIDEO_ENC_USE_INCAPS_HEADER_DEFAULT      FALSE
+#endif
 
 /* class initialization */
 
@@ -210,6 +229,33 @@ gst_omx_h264_enc_class_init (GstOMXH264EncClass * klass)
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
           GST_PARAM_MUTABLE_READY));
 
+  g_object_class_install_property (gobject_class, PROP_REF_FRAMES,
+      g_param_spec_uint ("ref-frames", "Reference frames",
+          "Number of reference frames used for inter-motion search (0=component default)",
+          GST_OMX_H264_VIDEO_ENC_REF_FRAMES_MIN,
+          GST_OMX_H264_VIDEO_ENC_REF_FRAMES_MAX,
+          GST_OMX_H264_VIDEO_ENC_REF_FRAMES_DEFAULT,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+          GST_PARAM_MUTABLE_READY));
+#ifdef USE_OMX_TARGET_RCAR
+  g_object_class_install_property (gobject_class, PROP_SEND_EOS,
+      g_param_spec_boolean ("send-eos",
+          "Send EOS/EOF data to downstream",
+          "Send EOS/EOF data to downstream",
+          GST_OMX_H264_VIDEO_ENC_SEND_EOS_DEFAULT,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+          GST_PARAM_MUTABLE_READY));
+
+  g_object_class_install_property (gobject_class, PROP_USE_INCAPS_HEADER,
+      g_param_spec_boolean ("use-incaps-header",
+          "Caps codec header",
+          "Send codec header via caps"
+          "(deprecated, not necessary now and can leads to performance deterioration)",
+          GST_OMX_H264_VIDEO_ENC_USE_INCAPS_HEADER_DEFAULT,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+          GST_PARAM_MUTABLE_READY | G_PARAM_DEPRECATED));
+#endif
+
   basevideoenc_class->flush = gst_omx_h264_enc_flush;
   basevideoenc_class->stop = gst_omx_h264_enc_stop;
 
@@ -247,7 +293,10 @@ gst_omx_h264_enc_set_property (GObject * object, guint prop_id,
       self->interval_intraframes = g_value_get_uint (value);
       break;
     case PROP_B_FRAMES:
-      self->b_frames = g_value_get_uint (value);
+      if (!GST_OMX_VIDEO_ENC (object)->no_copy)
+        self->b_frames = g_value_get_uint (value);
+      else
+        GST_WARNING_OBJECT (self, "no-copy mode does not support for b-frame");
       break;
     case PROP_ENTROPY_MODE:
       self->entropy_mode = g_value_get_enum (value);
@@ -258,6 +307,19 @@ gst_omx_h264_enc_set_property (GObject * object, guint prop_id,
     case PROP_LOOP_FILTER_MODE:
       self->loop_filter_mode = g_value_get_enum (value);
       break;
+    case PROP_REF_FRAMES:
+      self->ref_frames = g_value_get_uint (value);
+      break;
+#ifdef USE_OMX_TARGET_RCAR
+    case PROP_SEND_EOS:
+      self->send_eos = g_value_get_boolean (value);
+      break;
+    case PROP_USE_INCAPS_HEADER:
+      GST_WARNING_OBJECT (self,
+          "The option \"use_incaps_header\" is deprecated");
+      self->use_incaps_header = g_value_get_boolean (value);
+      break;
+#endif
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -295,6 +357,17 @@ gst_omx_h264_enc_get_property (GObject * object, guint prop_id, GValue * value,
     case PROP_LOOP_FILTER_MODE:
       g_value_set_enum (value, self->loop_filter_mode);
       break;
+    case PROP_REF_FRAMES:
+      g_value_set_uint (value, self->ref_frames);
+      break;
+#ifdef USE_OMX_TARGET_RCAR
+    case PROP_SEND_EOS:
+      g_value_set_boolean (value, self->send_eos);
+      break;
+    case PROP_USE_INCAPS_HEADER:
+      g_value_set_boolean (value, self->use_incaps_header);
+      break;
+#endif
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -317,6 +390,11 @@ gst_omx_h264_enc_init (GstOMXH264Enc * self)
   self->constrained_intra_prediction =
       GST_OMX_H264_VIDEO_ENC_CONSTRAINED_INTRA_PREDICTION_DEFAULT;
   self->loop_filter_mode = GST_OMX_H264_VIDEO_ENC_LOOP_FILTER_MODE_DEFAULT;
+  self->ref_frames = GST_OMX_H264_VIDEO_ENC_REF_FRAMES_DEFAULT;
+#ifdef USE_OMX_TARGET_RCAR
+  self->send_eos = GST_OMX_H264_VIDEO_ENC_SEND_EOS_DEFAULT;
+  self->use_incaps_header = GST_OMX_H264_VIDEO_ENC_USE_INCAPS_HEADER_DEFAULT;
+#endif
 }
 
 static gboolean
@@ -449,6 +527,9 @@ update_param_avc (GstOMXH264Enc * self,
     param.nBFrames = self->b_frames;
   }
 
+  if (self->ref_frames != GST_OMX_H264_VIDEO_ENC_REF_FRAMES_DEFAULT)
+    param.nRefFrames = self->ref_frames;
+
   if (self->entropy_mode != GST_OMX_H264_VIDEO_ENC_ENTROPY_MODE_DEFAULT) {
     param.bEntropyCodingCABAC = self->entropy_mode;
   }
@@ -486,9 +567,18 @@ set_avc_intra_period (GstOMXH264Enc * self)
   GST_OMX_INIT_STRUCT (&config_avcintraperiod);
   config_avcintraperiod.nPortIndex =
       GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
+
+#ifdef USE_OMX_TARGET_RCAR
+  /* Renesas OMX support Get/Set Config for this Index. */
+  err =
+      gst_omx_component_get_config (GST_OMX_VIDEO_ENC (self)->enc,
+      OMX_IndexConfigVideoAVCIntraPeriod, &config_avcintraperiod);
+#else
   err =
       gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
       OMX_IndexConfigVideoAVCIntraPeriod, &config_avcintraperiod);
+#endif
+
   if (err == OMX_ErrorUnsupportedIndex) {
     GST_WARNING_OBJECT (self,
         "OMX_IndexConfigVideoAVCIntraPeriod  not supported by component");
@@ -518,10 +608,17 @@ set_avc_intra_period (GstOMXH264Enc * self)
     if (self->b_frames == GST_OMX_H264_VIDEO_ENC_B_FRAMES_DEFAULT)
       config_avcintraperiod.nPFrames = self->interval_intraframes;
   }
-
+#ifdef USE_OMX_TARGET_RCAR
+  /* Renesas OMX support Get/Set Config for this Index. */
+  err =
+      gst_omx_component_set_config (GST_OMX_VIDEO_ENC (self)->enc,
+      OMX_IndexConfigVideoAVCIntraPeriod, &config_avcintraperiod);
+#else
   err =
       gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc,
       OMX_IndexConfigVideoAVCIntraPeriod, &config_avcintraperiod);
+#endif
+
   if (err != OMX_ErrorNone) {
     GST_ERROR_OBJECT (self,
         "can't set OMX_IndexConfigVideoAVCIntraPeriod %s (0x%08x)",
@@ -665,6 +762,18 @@ gst_omx_h264_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port,
       profile = gst_omx_h264_utils_get_profile_from_str (profile_string);
       if (profile == OMX_VIDEO_AVCProfileMax)
         goto unsupported_profile;
+#if defined (USE_OMX_TARGET_RCAR) && defined (HAVE_VIDEOENC_EXT)
+      if (profile == OMX_VIDEO_AVCProfileBaseline) {
+        guint32 scan_type = GST_OMX_VIDEO_ENC (self)->scan_type;
+
+        if (scan_type == OMXR_MC_VIDEO_MemAllocFieldTff ||
+            scan_type == OMXR_MC_VIDEO_MemAllocFieldBff) {
+          GST_ERROR_OBJECT (self,
+              "Baseline profile doesn't support interlace encoding");
+          return FALSE;
+        }
+      }
+#endif
     }
     level_string = gst_structure_get_string (s, "level");
     if (level_string) {
@@ -700,6 +809,72 @@ unsupported_level:
   return FALSE;
 }
 
+#ifdef USE_OMX_TARGET_RCAR
+static gboolean
+keep_level_caps (GstOMXVideoEnc * enc, const gchar ** level)
+{
+  GstOMXH264Enc *self = GST_OMX_H264_ENC (enc);
+  GstCaps *peercaps = gst_pad_peer_query_caps (GST_VIDEO_ENCODER_SRC_PAD (enc),
+      gst_pad_get_pad_template_caps (GST_VIDEO_ENCODER_SRC_PAD (enc)));
+  GstStructure *s = gst_caps_get_structure (peercaps, 0);
+  const gchar *level_string = gst_structure_get_string (s, "level");
+
+  if (level_string && (!g_str_equal (level_string, *level))) {
+    /* FIXME: Currently, level=1 is auto judgment mode */
+    if (g_str_equal (level_string, "1")) {
+      GST_WARNING_OBJECT (self,
+          "level: %s changed to appropriate level: %s. Video bitstream will have level %s",
+          level_string, *level, *level);
+      *level = level_string;
+    } else {
+      GST_ERROR_OBJECT (self,
+          "Incorrect level: expect level %s actual level %s",
+          level_string, *level);
+      gst_caps_unref (peercaps);
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+static void
+inform_port_parameters (GstOMXH264Enc * self)
+{
+  OMX_VIDEO_CONFIG_AVCINTRAPERIOD config_avcintraperiod;
+  OMX_VIDEO_PARAM_AVCTYPE param_avc;
+  OMX_ERRORTYPE err;
+
+  GST_OMX_INIT_STRUCT (&config_avcintraperiod);
+  config_avcintraperiod.nPortIndex =
+      GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
+  err =
+      gst_omx_component_get_config (GST_OMX_VIDEO_ENC (self)->enc,
+      OMX_IndexConfigVideoAVCIntraPeriod, &config_avcintraperiod);
+  if (err != OMX_ErrorNone)
+    GST_ERROR_OBJECT (self,
+        "Can't get OMX_IndexConfigVideoAVCIntraPeriod %s (0x%08x)",
+        gst_omx_error_to_string (err), err);
+
+  GST_OMX_INIT_STRUCT (&param_avc);
+  param_avc.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
+  err =
+      gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+      OMX_IndexParamVideoAvc, &param_avc);
+  if (err != OMX_ErrorNone)
+    GST_ERROR_OBJECT (self,
+        "Can't get OMX_IndexParamVideoAvc %s (0x%08x)",
+        gst_omx_error_to_string (err), err);
+
+  GST_INFO_OBJECT (self,
+      "OMX judgement: Video will be encoded with nIDRPeriod = %u"
+      " nPFrames = %u BFrames = %u nRefFrames = %u",
+      (guint) config_avcintraperiod.nIDRPeriod,
+      (guint) param_avc.nPFrames, (guint) param_avc.nBFrames,
+      (guint) param_avc.nRefFrames);
+}
+#endif
+
 static GstCaps *
 gst_omx_h264_enc_get_caps (GstOMXVideoEnc * enc, GstOMXPort * port,
     GstVideoCodecState * state)
@@ -709,6 +884,9 @@ gst_omx_h264_enc_get_caps (GstOMXVideoEnc * enc, GstOMXPort * port,
   OMX_ERRORTYPE err;
   OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
   const gchar *profile, *level;
+#ifdef USE_OMX_TARGET_RCAR
+  GstCaps *peercaps = NULL;
+#endif
 
   GST_OMX_INIT_STRUCT (&param);
   param.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
@@ -799,8 +977,21 @@ gst_omx_h264_enc_get_caps (GstOMXVideoEnc * enc, GstOMXPort * port,
         gst_caps_unref (caps);
         return NULL;
     }
+#ifdef USE_OMX_TARGET_RCAR
+    peercaps = gst_pad_peer_query_caps (GST_VIDEO_ENCODER_SRC_PAD (enc),
+        gst_pad_get_pad_template_caps (GST_VIDEO_ENCODER_SRC_PAD (enc)));
+
+    if (peercaps && !keep_level_caps (enc, &level))
+      return NULL;
+
+    inform_port_parameters (self);
+#endif
     gst_caps_set_simple (caps,
         "profile", G_TYPE_STRING, profile, "level", G_TYPE_STRING, level, NULL);
+#ifdef USE_OMX_TARGET_RCAR
+    if (peercaps)
+      gst_caps_unref (peercaps);
+#endif
   }
 
   return caps;
@@ -812,6 +1003,14 @@ gst_omx_h264_enc_handle_output_frame (GstOMXVideoEnc * enc, GstOMXPort * port,
 {
   GstOMXH264Enc *self = GST_OMX_H264_ENC (enc);
 
+#ifdef USE_OMX_TARGET_RCAR
+  if (self->use_incaps_header)
+    return
+        GST_OMX_VIDEO_ENC_CLASS
+        (gst_omx_h264_enc_parent_class)->handle_output_frame (enc, port, buf,
+        frame);
+#endif
+
   if (buf->omx_buf->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
     /* The codec data is SPS/PPS with a startcode => bytestream stream format
      * For bytestream stream format the SPS/PPS is only in-stream and not
@@ -840,7 +1039,8 @@ gst_omx_h264_enc_handle_output_frame (GstOMXVideoEnc * enc, GstOMXPort * port,
       return GST_FLOW_OK;
     }
   } else if (self->headers) {
-    gst_video_encoder_set_headers (GST_VIDEO_ENCODER (self), self->headers);
+    /* When alignment=au, headers should be sent with data frame */
+    enc->headers = self->headers;
     self->headers = NULL;
   }
 
diff --git a/omx/gstomxh264enc.h b/omx/gstomxh264enc.h
index c8db9aa..06de296 100644
--- a/omx/gstomxh264enc.h
+++ b/omx/gstomxh264enc.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
  *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
+ * Copyright (C) 2017-2018,2020 Renesas Electronics Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -55,6 +56,11 @@ struct _GstOMXH264Enc
   guint32 entropy_mode;
   gboolean constrained_intra_prediction;
   guint32 loop_filter_mode;
+  guint32 ref_frames;
+#ifdef USE_OMX_TARGET_RCAR
+  gboolean send_eos;
+  gboolean use_incaps_header;
+#endif
 
   GList *headers;
 };
diff --git a/omx/gstomxh265dec.c b/omx/gstomxh265dec.c
index e10c0c1..307a6e5 100644
--- a/omx/gstomxh265dec.c
+++ b/omx/gstomxh265dec.c
@@ -2,6 +2,7 @@
  * Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
  * Copyright (C) 2017 Xilinx, Inc.
  *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
+ * Copyright (C) 2017,2020 Renesas Electronics Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -26,7 +27,12 @@
 #include <gst/gst.h>
 
 #include "gstomxh265dec.h"
+#ifndef USE_OMX_TARGET_RCAR
 #include "gstomxh265utils.h"
+#endif
+#ifdef HAVE_H265DEC_EXT
+#include "OMXR_Extension_h265d.h"
+#endif
 
 GST_DEBUG_CATEGORY_STATIC (gst_omx_h265_dec_debug_category);
 #define GST_CAT_DEFAULT gst_omx_h265_dec_debug_category
@@ -62,6 +68,9 @@ gst_omx_h265_dec_class_init (GstOMXH265DecClass * klass)
   videodec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_h265_dec_set_format);
 
   videodec_class->cdata.default_sink_template_caps = "video/x-h265, "
+#ifdef USE_OMX_TARGET_RCAR
+      "parsed=(boolean) true, "
+#endif
       "alignment=(string) au, "
       "stream-format=(string) byte-stream, "
       "width=(int) [1,MAX], " "height=(int) [1,MAX]";
@@ -84,6 +93,7 @@ static gboolean
 gst_omx_h265_dec_is_format_change (GstOMXVideoDec * dec,
     GstOMXPort * port, GstVideoCodecState * state)
 {
+#ifndef USE_OMX_TARGET_RCAR
   GstCaps *old_caps = NULL;
   GstCaps *new_caps = state->caps;
   GstStructure *old_structure, *new_structure;
@@ -112,10 +122,12 @@ gst_omx_h265_dec_is_format_change (GstOMXVideoDec * dec,
       || g_strcmp0 (old_tier, new_tier)) {
     return TRUE;
   }
+#endif
 
   return FALSE;
 }
 
+#ifndef USE_OMX_TARGET_RCAR
 static gboolean
 set_profile_and_level (GstOMXH265Dec * self, GstVideoCodecState * state)
 {
@@ -176,16 +188,20 @@ unsupported_level:
   GST_ERROR_OBJECT (self, "Unsupported level %s", level_string);
   return FALSE;
 }
+#endif
 
 static gboolean
 gst_omx_h265_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port,
     GstVideoCodecState * state)
 {
+#ifndef USE_OMX_TARGET_RCAR
   GstOMXVideoDecClass *klass = GST_OMX_VIDEO_DEC_GET_CLASS (dec);
+#endif
   OMX_PARAM_PORTDEFINITIONTYPE port_def;
   OMX_ERRORTYPE err;
 
   gst_omx_port_get_port_definition (port, &port_def);
+#ifndef USE_OMX_TARGET_RCAR
   port_def.format.video.eCompressionFormat =
       (OMX_VIDEO_CODINGTYPE) OMX_VIDEO_CodingHEVC;
   err = gst_omx_port_update_port_definition (port, &port_def);
@@ -197,5 +213,15 @@ gst_omx_h265_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port,
       return FALSE;
   }
 
+  return TRUE;
+#endif
+
+#ifdef HAVE_H265DEC_EXT
+  port_def.format.video.eCompressionFormat = OMXR_MC_VIDEO_CodingHEVC;
+#endif
+  err = gst_omx_port_update_port_definition (port, &port_def);
+  if (err != OMX_ErrorNone)
+    return FALSE;
+
   return TRUE;
 }
diff --git a/omx/gstomxh265dec.h b/omx/gstomxh265dec.h
index f0f1016..b2ed833 100644
--- a/omx/gstomxh265dec.h
+++ b/omx/gstomxh265dec.h
@@ -2,6 +2,7 @@
  * Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
  * Copyright (C) 2017 Xilinx, Inc.
  *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
+ * Copyright (C) 2017,2020 Renesas Electronics Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
diff --git a/omx/gstomxmp3dec.c b/omx/gstomxmp3dec.c
index aa22e80..0e3bb90 100644
--- a/omx/gstomxmp3dec.c
+++ b/omx/gstomxmp3dec.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2014, Sebastian Dröge <sebastian@centricular.com>
+ * Copyright (C) 2017,2020 Renesas Electronics Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -128,7 +129,12 @@ gst_omx_mp3_dec_set_format (GstOMXAudioDec * dec, GstOMXPort * port,
     return FALSE;
   }
 
-  self->spf = (mpegaudioversion == 1 ? 1152 : 576);
+  if (layer == 1)
+    self->spf = 384;
+  else if (layer == 2)
+    self->spf = 1152;
+  else
+    self->spf = (mpegaudioversion == 1 ? 1152 : 576);
 
   mp3_param.nChannels = channels;
   mp3_param.nBitRate = 0;       /* unknown */
diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c
index abe6e30..ec3a1c3 100644
--- a/omx/gstomxvideodec.c
+++ b/omx/gstomxvideodec.c
@@ -3,6 +3,7 @@
  *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
  * Copyright (C) 2013, Collabora Ltd.
  *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ * Copyright (C) 2019-2021, Renesas Electronics Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -51,6 +52,11 @@
 #include "gstomxbufferpool.h"
 #include "gstomxvideo.h"
 #include "gstomxvideodec.h"
+#include "gstomxvp9dec.h"
+#ifdef HAVE_VIDEODEC_EXT
+#include "OMXR_Extension_vdcmn.h"
+#endif
+#include "gstomxwmvdec.h"
 
 GST_DEBUG_CATEGORY_STATIC (gst_omx_video_dec_debug_category);
 #define GST_CAT_DEFAULT gst_omx_video_dec_debug_category
@@ -84,10 +90,17 @@ static OMX_ERRORTYPE gst_omx_video_dec_allocate_output_buffers (GstOMXVideoDec *
 static gboolean gst_omx_video_dec_deallocate_output_buffers (GstOMXVideoDec
     * self);
 
+static gboolean get_crop_info (GstOMXVideoDec * self, crop_info * c_info);
+
 enum
 {
   PROP_0,
   PROP_INTERNAL_ENTROPY_BUFFERS,
+  PROP_USE_DMABUF,
+  PROP_NO_COPY,
+  PROP_NO_REORDER,
+  PROP_LOSSY_COMPRESS,
+  PROP_ENABLE_CROP
 };
 
 #define GST_OMX_VIDEO_DEC_INTERNAL_ENTROPY_BUFFERS_DEFAULT (5)
@@ -106,9 +119,7 @@ static void
 gst_omx_video_dec_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)
 {
-#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
   GstOMXVideoDec *self = GST_OMX_VIDEO_DEC (object);
-#endif
 
   switch (prop_id) {
 #ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
@@ -116,6 +127,24 @@ gst_omx_video_dec_set_property (GObject * object, guint prop_id,
       self->internal_entropy_buffers = g_value_get_uint (value);
       break;
 #endif
+    case PROP_NO_COPY:
+      self->no_copy = g_value_get_boolean (value);
+      self->use_dmabuf = FALSE;
+      self->has_set_property = TRUE;
+      break;
+    case PROP_USE_DMABUF:
+      self->use_dmabuf = g_value_get_boolean (value);
+      self->has_set_property = TRUE;
+      break;
+    case PROP_NO_REORDER:
+      self->no_reorder = g_value_get_boolean (value);
+      break;
+    case PROP_LOSSY_COMPRESS:
+      self->lossy_compress = g_value_get_boolean (value);
+      break;
+    case PROP_ENABLE_CROP:
+      self->enable_crop = g_value_get_boolean (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -126,9 +155,7 @@ static void
 gst_omx_video_dec_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec)
 {
-#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
   GstOMXVideoDec *self = GST_OMX_VIDEO_DEC (object);
-#endif
 
   switch (prop_id) {
 #ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
@@ -136,6 +163,21 @@ gst_omx_video_dec_get_property (GObject * object, guint prop_id,
       g_value_set_uint (value, self->internal_entropy_buffers);
       break;
 #endif
+    case PROP_USE_DMABUF:
+      g_value_set_boolean (value, self->use_dmabuf);
+      break;
+    case PROP_NO_COPY:
+      g_value_set_boolean (value, self->no_copy);
+      break;
+    case PROP_NO_REORDER:
+      g_value_set_boolean (value, self->no_reorder);
+      break;
+    case PROP_LOSSY_COMPRESS:
+      g_value_set_boolean (value, self->lossy_compress);
+      break;
+    case PROP_ENABLE_CROP:
+      g_value_set_boolean (value, self->enable_crop);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -163,6 +205,34 @@ gst_omx_video_dec_class_init (GstOMXVideoDecClass * klass)
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
           GST_PARAM_MUTABLE_READY));
 #endif
+  g_object_class_install_property (gobject_class, PROP_USE_DMABUF,
+      g_param_spec_boolean ("use-dmabuf", "Use dmabuffer ",
+          "Whether or not to transfer decoded data using dmabuf",
+          TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+          GST_PARAM_MUTABLE_READY));
+  g_object_class_install_property (gobject_class, PROP_NO_COPY,
+      g_param_spec_boolean ("no-copy", "No copy",
+          "Whether or not to transfer decoded data without copy",
+          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+          GST_PARAM_MUTABLE_READY));
+
+  g_object_class_install_property (gobject_class, PROP_NO_REORDER,
+      g_param_spec_boolean ("no-reorder", "Output picture reordering",
+          "Whether or not to let output picture data in decoding order",
+          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+          GST_PARAM_MUTABLE_READY));
+  g_object_class_install_property (gobject_class, PROP_LOSSY_COMPRESS,
+      g_param_spec_boolean ("lossy-compress",
+          "Use lossy image compression function",
+          "Whether or not to use lossy image compression function",
+          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+          GST_PARAM_MUTABLE_READY));
+  g_object_class_install_property (gobject_class, PROP_ENABLE_CROP,
+      g_param_spec_boolean ("enable-crop",
+          "Enable cropping video as value of left_offset and top_offset",
+          "Whether or not to enable cropping if there is cropping information on SPS",
+          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+          GST_PARAM_MUTABLE_READY));
 
   element_class->change_state =
       GST_DEBUG_FUNCPTR (gst_omx_video_dec_change_state);
@@ -201,6 +271,13 @@ gst_omx_video_dec_init (GstOMXVideoDec * self)
   self->internal_entropy_buffers =
       GST_OMX_VIDEO_DEC_INTERNAL_ENTROPY_BUFFERS_DEFAULT;
 #endif
+#ifdef USE_RCAR_DMABUF
+  self->use_dmabuf = TRUE;
+#endif
+  self->no_reorder = FALSE;
+  self->lossy_compress = FALSE;
+  self->has_set_property = FALSE;
+  self->enable_crop = FALSE;
 
   gst_video_decoder_set_packetized (GST_VIDEO_DECODER (self), TRUE);
   gst_video_decoder_set_use_default_pad_acceptcaps (GST_VIDEO_DECODER_CAST
@@ -303,6 +380,9 @@ gst_omx_video_dec_open (GstVideoDecoder * decoder)
 #ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
   GST_DEBUG_OBJECT (self, "Configure decoder output to export dmabuf");
   self->dmabuf = gst_omx_port_set_dmabuf (self->dec_out_port, TRUE);
+#elif defined USE_RCAR_DMABUF
+  if (self->use_dmabuf)
+    self->dmabuf = TRUE;
 #endif
 
   if (!self->dec_in_port || !self->dec_out_port)
@@ -362,6 +442,25 @@ gst_omx_video_dec_open (GstVideoDecoder * decoder)
     return FALSE;
 #endif
 
+  /* Use hacks to choose default mode, normally default mode is dmabuf */
+  if (!((klass->cdata.hacks & GST_OMX_HACK_USE_COPY_MODE_AS_DEFAULT) &&
+          (klass->cdata.hacks & GST_OMX_HACK_USE_NO_COPY_MODE_AS_DEFAULT)) &&
+      (!self->has_set_property)) {
+    if (klass->cdata.hacks & GST_OMX_HACK_USE_COPY_MODE_AS_DEFAULT) {
+      GST_DEBUG_OBJECT (self, "Use copy mode as default");
+      self->no_copy = FALSE;
+      self->use_dmabuf = FALSE;
+    }
+    if (klass->cdata.hacks & GST_OMX_HACK_USE_NO_COPY_MODE_AS_DEFAULT) {
+      GST_DEBUG_OBJECT (self, "Use no-copy mode as default");
+      self->no_copy = TRUE;
+      self->use_dmabuf = FALSE;
+    }
+  } else {
+    GST_DEBUG_OBJECT (self,
+        "Disable hacks due to option(s) from user or incorrect setting for hacks");
+  }
+
   return TRUE;
 }
 
@@ -537,32 +636,29 @@ gst_omx_video_dec_fill_buffer (GstOMXVideoDec * self,
   OMX_PARAM_PORTDEFINITIONTYPE *port_def = &self->dec_out_port->port_def;
   gboolean ret = FALSE;
   GstVideoFrame frame;
+  crop_info cinfo = { 0, };
 
-  if (vinfo->width != port_def->format.video.nFrameWidth ||
-      vinfo->height != port_def->format.video.nFrameHeight) {
-    GST_ERROR_OBJECT (self, "Resolution do not match: port=%ux%u vinfo=%dx%d",
+  if (self->enable_crop) {
+    if (!get_crop_info (self, &cinfo))
+      goto done;
+  }
+
+  if (vinfo->width + cinfo.crop_left != port_def->format.video.nFrameWidth ||
+      vinfo->height + cinfo.crop_top != port_def->format.video.nFrameHeight) {
+    GST_ERROR_OBJECT (self, "Resolution do not match: port=%ux%u vinfo =%dx%d,"
+        "crop left=%d, crop top=%d",
         (guint) port_def->format.video.nFrameWidth,
         (guint) port_def->format.video.nFrameHeight,
-        vinfo->width, vinfo->height);
+        vinfo->width, vinfo->height, cinfo.crop_left, cinfo.crop_top);
     goto done;
   }
 
-  /* Same strides and everything */
-  if (gst_buffer_get_size (outbuf) == inbuf->omx_buf->nFilledLen) {
-    GstMapInfo map = GST_MAP_INFO_INIT;
-
-    if (!gst_buffer_map (outbuf, &map, GST_MAP_WRITE)) {
-      GST_ERROR_OBJECT (self, "Failed to map output buffer");
-      goto done;
-    }
-
-    memcpy (map.data,
-        inbuf->omx_buf->pBuffer + inbuf->omx_buf->nOffset,
-        inbuf->omx_buf->nFilledLen);
-    gst_buffer_unmap (outbuf, &map);
-    ret = TRUE;
-    goto done;
-  }
+  /* Try using gst_video_frame_map() before use gst_buffer_map() because
+   * gst_buffer_map() could return the different pointer in buffers
+   * received from downstream if downstream propose unwritable memory
+   * or multiple seperated blocks, gst_buffer_map() can create a new allocation.
+   * It is safety to use gst_video_frame_map() for all cases instead.
+   */
 
   /* Different strides */
   if (gst_video_frame_map (&frame, vinfo, outbuf, GST_MAP_WRITE)) {
@@ -642,9 +738,16 @@ gst_omx_video_dec_fill_buffer (GstOMXVideoDec * self,
       const guint8 *data;
       guint8 *dst;
       guint h;
+      gint crop_offset;
+      const GstVideoFormatInfo *finfo = vinfo->finfo;
+
+      crop_offset = (src_stride[p] *
+          GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (finfo, p, cinfo.crop_top))
+          + (GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (finfo, p, cinfo.crop_left) *
+          GST_VIDEO_FORMAT_INFO_PSTRIDE (finfo, p));
 
       dst = GST_VIDEO_FRAME_PLANE_DATA (&frame, p);
-      data = src;
+      data = src + crop_offset;
       for (h = 0; h < dst_height[p]; h++) {
         memcpy (dst, data, dst_width[p]);
         dst += GST_VIDEO_FRAME_PLANE_STRIDE (&frame, p);
@@ -656,8 +759,25 @@ gst_omx_video_dec_fill_buffer (GstOMXVideoDec * self,
     gst_video_frame_unmap (&frame);
     ret = TRUE;
   } else {
-    GST_ERROR_OBJECT (self, "Can't map output buffer to frame");
-    goto done;
+    GST_DEBUG_OBJECT (self,
+        "Can't map output buffer to frame, try with gst_buffer_map");
+    /* Try using gst_buffer_map() if gst_video_frame_map() fail */
+    /* Same strides and everything */
+    if (gst_buffer_get_size (outbuf) == inbuf->omx_buf->nFilledLen) {
+      GstMapInfo map = GST_MAP_INFO_INIT;
+
+      if (!gst_buffer_map (outbuf, &map, GST_MAP_WRITE)) {
+        GST_ERROR_OBJECT (self, "Failed to map output buffer");
+        goto done;
+      }
+
+      memcpy (map.data,
+          inbuf->omx_buf->pBuffer + inbuf->omx_buf->nOffset,
+          inbuf->omx_buf->nFilledLen);
+      gst_buffer_unmap (outbuf, &map);
+      ret = TRUE;
+      goto done;
+    }
   }
 
 done:
@@ -821,8 +941,10 @@ gst_omx_video_dec_allocate_output_buffers (GstOMXVideoDec * self)
     goto done;
   }
 #endif
+  if (!self->no_copy && !self->dmabuf)
+    caps = NULL;
 
-  if (caps)
+  if (caps || self->no_copy || self->use_dmabuf)
     self->out_port_pool =
         gst_omx_buffer_pool_new (GST_ELEMENT_CAST (self), self->dec, port,
         self->dmabuf ? GST_OMX_BUFFER_MODE_DMABUF :
@@ -1148,7 +1270,7 @@ gst_omx_video_dec_allocate_output_buffers (GstOMXVideoDec * self)
 
   err = OMX_ErrorNone;
 
-  if (caps) {
+  if (caps || self->no_copy || self->use_dmabuf) {
     config = gst_buffer_pool_get_config (self->out_port_pool);
 
     if (add_videometa)
@@ -1170,6 +1292,8 @@ gst_omx_video_dec_allocate_output_buffers (GstOMXVideoDec * self)
       GST_INFO_OBJECT (self, "Failed to activate internal pool");
       gst_object_unref (self->out_port_pool);
       self->out_port_pool = NULL;
+    } else if (!self->use_buffers) {
+      gst_buffer_pool_set_active (pool, FALSE);
     }
   } else if (self->out_port_pool) {
     gst_object_unref (self->out_port_pool);
@@ -1228,6 +1352,7 @@ gst_omx_video_dec_reconfigure_output_port (GstOMXVideoDec * self)
   GstVideoCodecState *state;
   OMX_PARAM_PORTDEFINITIONTYPE port_def;
   GstVideoFormat format;
+  GstOMXVideoDecClass *klass = GST_OMX_VIDEO_DEC_GET_CLASS (self);
 
   /* At this point the decoder output port is disabled */
 
@@ -1460,6 +1585,12 @@ gst_omx_video_dec_reconfigure_output_port (GstOMXVideoDec * self)
       format, port_def.format.video.nFrameWidth,
       port_def.format.video.nFrameHeight, self->input_state);
 
+  if (klass->cdata.hacks & GST_OMX_HACK_DEFAULT_PIXEL_ASPECT_RATIO) {
+    /* Set pixel-aspect-ratio is 1/1. It means that always keep
+     * original image when display   */
+    state->info.par_d = state->info.par_n;
+  }
+
   if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
     gst_video_codec_state_unref (state);
     GST_ERROR_OBJECT (self, "Failed to negotiate");
@@ -1574,6 +1705,94 @@ copy_frame (const GstVideoInfo * info, GstBuffer * outbuf)
   return tmpbuf;
 }
 
+static gboolean
+get_crop_info (GstOMXVideoDec * self, crop_info * c_info)
+{
+  GstOMXPort *port;
+  OMX_CONFIG_RECTTYPE crop;
+  OMX_ERRORTYPE err;
+
+  port = self->dec_out_port;
+  GST_OMX_INIT_STRUCT (&crop);
+  crop.nPortIndex = port->index;
+
+  err = gst_omx_component_get_config (self->dec,
+      OMX_IndexConfigCommonOutputCrop, &crop);
+
+  if (err != OMX_ErrorNone)
+    return FALSE;
+
+  c_info->crop_left = crop.nLeft;
+  c_info->crop_top = crop.nTop;
+
+  return TRUE;
+}
+
+static void
+update_buffer_meta (GstOMXVideoDec * self, GstBuffer * buffer,
+    const crop_info * cinfo, GstVideoMeta * vmeta)
+{
+  GstVideoCodecState *state =
+      gst_video_decoder_get_output_state (GST_VIDEO_DECODER (self));
+  GstVideoInfo *vinfo = &state->info;
+  gint i;
+
+  if ((GST_VIDEO_INFO_WIDTH (vinfo) == vmeta->width) &&
+      (GST_VIDEO_INFO_HEIGHT (vinfo) == vmeta->height))
+    return;
+
+  GST_DEBUG_OBJECT (self, "update buffer meta");
+
+  for (i = 0; i < GST_VIDEO_INFO_N_PLANES (vinfo); i++) {
+    const GstVideoFormatInfo *finfo = vinfo->finfo;
+    vmeta->offset[i] += (vmeta->stride[i] *
+        GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (finfo, i, cinfo->crop_top))
+        + (GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (finfo, i, cinfo->crop_left) *
+        GST_VIDEO_FORMAT_INFO_PSTRIDE (finfo, i));
+  }
+
+  vmeta->width -= cinfo->crop_left;
+  vmeta->height -= cinfo->crop_top;
+}
+
+static gboolean
+update_output_state (GstOMXVideoDec * self, const crop_info * cinfo)
+{
+  GstVideoCodecState *state;
+  gint state_width, state_height;
+  GstOMXPort *port;
+  OMX_PARAM_PORTDEFINITIONTYPE port_def;
+  guint cropped_width, cropped_height;
+
+  state = gst_video_decoder_get_output_state (GST_VIDEO_DECODER (self));
+  state_width = GST_VIDEO_INFO_WIDTH (&state->info);
+  state_height = GST_VIDEO_INFO_HEIGHT (&state->info);
+
+  port = self->dec_out_port;
+  gst_omx_port_get_port_definition (port, &port_def);
+
+  cropped_width = port_def.format.video.nFrameWidth - cinfo->crop_left;
+  cropped_height = port_def.format.video.nFrameHeight - cinfo->crop_top;
+
+  if (state_width != cropped_width || state_height != cropped_height) {
+    gst_video_decoder_set_output_state (GST_VIDEO_DECODER (self),
+        gst_omx_video_get_format_from_omx (port_def.format.video.eColorFormat),
+        cropped_width, cropped_height, state);
+    if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
+      GST_ERROR_OBJECT (self, "Negotiation failed");
+      return FALSE;
+    }
+
+    if (self->out_port_pool) {
+      GstBufferPool *pool =
+          gst_video_decoder_get_buffer_pool (GST_VIDEO_DECODER (self));
+      gst_buffer_pool_set_active (pool, FALSE);
+    }
+  }
+
+  return TRUE;
+}
+
 static void
 gst_omx_video_dec_pause_loop (GstOMXVideoDec * self, GstFlowReturn flow_ret)
 {
@@ -1597,6 +1816,8 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self)
   GstFlowReturn flow_ret = GST_FLOW_OK;
   GstOMXAcquireBufferReturn acq_return;
   OMX_ERRORTYPE err;
+  GstOMXVideoDecClass *klass = GST_OMX_VIDEO_DEC_GET_CLASS (self);
+  crop_info cinfo = { 0 };
 
 #if defined (USE_OMX_TARGET_RPI) && defined (HAVE_GST_GL)
   port = self->eglimage ? self->egl_out_port : self->dec_out_port;
@@ -1678,6 +1899,11 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self)
           port_def.format.video.nFrameHeight, self->input_state);
 
       /* Take framerate and pixel-aspect-ratio from sinkpad caps */
+      if (klass->cdata.hacks & GST_OMX_HACK_DEFAULT_PIXEL_ASPECT_RATIO) {
+        /* Set pixel-aspect-ratio is 1/1. It means that always keep
+         * original image when display   */
+        state->info.par_d = state->info.par_n;
+      }
 
       if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
         if (buf)
@@ -1723,8 +1949,21 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self)
    * stream, corrupted input data...
    * In any cases, not likely to be seen again. so drop it before they pile up
    * and use all the memory. */
-  gst_omx_video_dec_clean_older_frames (self, buf,
-      gst_video_decoder_get_frames (GST_VIDEO_DECODER (self)));
+  if (self->no_reorder == FALSE)
+    /* Do not clean in no_reorder mode, as in that mode the output frames
+     * are not in display order */
+    gst_omx_video_dec_clean_older_frames (self, buf,
+        gst_video_decoder_get_frames (GST_VIDEO_DECODER (self)));
+
+  if (self->enable_crop) {
+    if (!get_crop_info (self, &cinfo))
+      goto component_error;
+
+    if (cinfo.crop_left || cinfo.crop_top) {
+      if (!update_output_state (self, &cinfo))
+        goto caps_failed;
+    }
+  }
 
   if (!frame && (buf->omx_buf->nFilledLen > 0 || buf->eglimage)) {
     GstBuffer *outbuf = NULL;
@@ -1763,6 +2002,14 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self)
             copy_frame (&GST_OMX_BUFFER_POOL (self->out_port_pool)->video_info,
             outbuf);
 
+      if (self->enable_crop && (cinfo.crop_top || cinfo.crop_left)) {
+        GstVideoMeta *vmeta;
+
+        vmeta = gst_buffer_get_video_meta (outbuf);
+        if (vmeta)
+          update_buffer_meta (self, outbuf, &cinfo, vmeta);
+      }
+
       buf = NULL;
     } else {
       outbuf =
@@ -1807,8 +2054,15 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self)
             copy_frame (&GST_OMX_BUFFER_POOL (self->out_port_pool)->video_info,
             outbuf);
 
-      frame->output_buffer = outbuf;
+      if (self->enable_crop && (cinfo.crop_top || cinfo.crop_left)) {
+        GstVideoMeta *vmeta;
+
+        vmeta = gst_buffer_get_video_meta (outbuf);
+        if (vmeta)
+          update_buffer_meta (self, outbuf, &cinfo, vmeta);
+      }
 
+      frame->output_buffer = outbuf;
       flow_ret =
           gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame);
       frame = NULL;
@@ -2453,6 +2707,11 @@ gst_omx_video_dec_enable (GstOMXVideoDec * self, GstBuffer * input)
   gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, FALSE);
   gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, FALSE);
 
+  /* Populate (FillThisBuffer) all output buffers to the component so
+   * that gst_omx_video_dec_loop() can detect RECONFIGURE in initial loop */
+  if (gst_omx_port_populate (self->dec_out_port) != OMX_ErrorNone)
+    return FALSE;
+
   if (gst_omx_component_get_last_error (self->dec) != OMX_ErrorNone) {
     GST_ERROR_OBJECT (self, "Component in error state: %s (0x%08x)",
         gst_omx_component_get_last_error_string (self->dec),
@@ -2628,8 +2887,70 @@ gst_omx_video_dec_set_format (GstVideoDecoder * decoder,
       return FALSE;
     }
   }
+#ifdef HAVE_VIDEODEC_EXT
+  if (!needs_disable) {
+    /* Setting reorder mode (output port only) */
+    OMXR_MC_VIDEO_PARAM_REORDERTYPE sReorder;
+    GST_OMX_INIT_STRUCT (&sReorder);
+    sReorder.nPortIndex = self->dec_out_port->index;    /* default */
+
+    if (self->no_reorder != FALSE)
+      sReorder.bReorder = OMX_FALSE;
+    else
+      sReorder.bReorder = OMX_TRUE;
+
+    gst_omx_component_set_parameter (self->dec, OMXR_MC_IndexParamVideoReorder,
+        &sReorder);
+  }
+
+  if (!needs_disable) {
+    /* Setting lossy compression mode (output port) */
+    OMXR_MC_VIDEO_PARAM_LOSSY_COMPRESSIONTYPE sLossy;
+    GST_OMX_INIT_STRUCT (&sLossy);
+    sLossy.nPortIndex = self->dec_out_port->index;
+
+    if (self->lossy_compress == TRUE)
+      sLossy.bEnable = OMX_TRUE;
+    else
+      sLossy.bEnable = OMX_FALSE;
+
+    gst_omx_component_set_parameter (self->dec,
+        OMXR_MC_IndexParamVideoLossyCompression, &sLossy);
+  }
+#else
+  if (self->no_reorder != FALSE)
+    GST_ERROR_OBJECT (self,
+        "no-reorder mode is invalid now due to MC does not support");
+
+  if (self->lossy_compress == TRUE)
+    GST_ERROR_OBJECT (self,
+        "lossy-compress mode is invalid now due to MC does not support");
+#endif
 
   GST_DEBUG_OBJECT (self, "Updating ports definition");
+#ifdef USE_OMX_TARGET_RCAR
+  if (!needs_disable) {
+    OMX_PARAM_PORTDEFINITIONTYPE out_port_def;
+
+    /* Initialize default output allocation align for page size
+     * Choose 192x192 for VP9 Decoder and 128x128 for other Decoders
+     * because they are close to minimum setting 192 (VP9) and 80 (others)*/
+    gst_omx_port_get_port_definition (self->dec_out_port, &out_port_def);
+    if (GST_IS_OMX_VP9_DEC (self)) {
+      out_port_def.format.video.nStride = 192;
+      out_port_def.format.video.nSliceHeight = 192;
+    } else {
+      out_port_def.format.video.nStride = 128;
+      out_port_def.format.video.nSliceHeight = 128;
+    }
+
+    if (gst_omx_port_update_port_definition (self->dec_out_port,
+            &out_port_def) != OMX_ErrorNone)
+      return FALSE;
+  }
+  /* To make source code flexible, accept getting port_def param again */
+#endif
+
   if (gst_omx_port_update_port_definition (self->dec_out_port,
           NULL) != OMX_ErrorNone)
     return FALSE;
@@ -2740,6 +3061,7 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder,
 {
   GstOMXAcquireBufferReturn acq_ret = GST_OMX_ACQUIRE_BUFFER_ERROR;
   GstOMXVideoDec *self;
+  GstOMXVideoDecClass *klass;
   GstOMXPort *port;
   GstOMXBuffer *buf;
   GstBuffer *codec_data = NULL;
@@ -2751,6 +3073,7 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder,
   guint memory_idx = 0;         /* only used in dynamic buffer mode */
 
   self = GST_OMX_VIDEO_DEC (decoder);
+  klass = GST_OMX_VIDEO_DEC_GET_CLASS (self);
 
   GST_DEBUG_OBJECT (self, "Handling frame");
 
@@ -2777,6 +3100,19 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder,
 
   timestamp = frame->pts;
   duration = frame->duration;
+
+  if (klass->prepare_frame) {
+    GstFlowReturn ret;
+
+    ret = klass->prepare_frame (self, frame);
+    if (ret != GST_FLOW_OK) {
+      GST_ERROR_OBJECT (self, "Preparing frame failed: %s",
+          gst_flow_get_name (ret));
+      gst_video_codec_frame_unref (frame);
+      return ret;
+    }
+  }
+
   port = self->dec_in_port;
 
   size = gst_buffer_get_size (frame->input_buffer);
@@ -2943,10 +3279,40 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder,
           "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);
+      if (GST_IS_OMX_WMV_DEC (self) && GST_OMX_WMV_DEC (self)->advanced_profile) {
+        guint8 *pd_sc;          //start code of picture data
+        GstMapInfo map;
+        gboolean right_struct = FALSE;
+        OMX_U32 omx_offset = buf->omx_buf->nOffset;
 
+        if (!gst_buffer_map (frame->input_buffer, &map, GST_MAP_READ)) {
+          GST_ERROR_OBJECT (self, "Failed to create a GstBuffer mapping");
+          goto map_failed;
+        }
+        if (map.data[0] == 0x00 && map.data[1] == 0x00 && map.data[2] == 0x01
+            && (map.data[3] == 0x0d || map.data[3] == 0x0e))
+          right_struct = TRUE;
+        gst_buffer_unmap (frame->input_buffer, &map);
+
+        if (!right_struct) {
+          pd_sc = (guint8 *) g_malloc (4);
+          pd_sc[0] = 0x00;
+          pd_sc[1] = 0x00;
+          pd_sc[2] = 0x01;
+          pd_sc[3] = 0x0d;
+
+          memcpy (buf->omx_buf->pBuffer + buf->omx_buf->nOffset, pd_sc, 4);
+          omx_offset += 4;
+
+          g_free (pd_sc);
+        }
+        gst_buffer_extract (frame->input_buffer, offset,
+            buf->omx_buf->pBuffer + omx_offset, buf->omx_buf->nFilledLen);
+      } else {
+        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;
@@ -3230,9 +3596,11 @@ gst_omx_video_dec_decide_allocation (GstVideoDecoder * bdec, GstQuery * query)
       GST_DEBUG_OBJECT (self, "Discard OMX pool from downstream");
       gst_query_remove_nth_allocation_pool (query, i);
     } else {
+#ifndef USE_OMX_TARGET_RCAR
       GST_DEBUG_OBJECT (self,
           "Try using downstream buffers with OMX_UseBuffer");
       self->use_buffers = TRUE;
+#endif
       i++;
     }
 
diff --git a/omx/gstomxvideodec.h b/omx/gstomxvideodec.h
index df441d9..06645ee 100644
--- a/omx/gstomxvideodec.h
+++ b/omx/gstomxvideodec.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
  *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
+ * Copyright (C) 2019-2020, Renesas Electronics Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -48,6 +49,13 @@ G_BEGIN_DECLS
 
 typedef struct _GstOMXVideoDec GstOMXVideoDec;
 typedef struct _GstOMXVideoDecClass GstOMXVideoDecClass;
+typedef struct _crop_info crop_info;
+
+struct _crop_info
+{
+  gint crop_left;
+  gint crop_top;
+};
 
 struct _GstOMXVideoDec
 {
@@ -100,6 +108,19 @@ struct _GstOMXVideoDec
 #ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
   guint32 internal_entropy_buffers;
 #endif
+
+  /* Set TRUE to use dmabuf to transfer decoded data */
+  gboolean use_dmabuf;
+  /* Set TRUE to send buffer of omxbufferpool to downstream */
+  gboolean no_copy;
+  /* Set TRUE to not using frame reorder */
+  gboolean no_reorder;
+  /* Set TRUE to use lossy image compression  */
+  gboolean lossy_compress;
+  /* TRUE when set_property() runs */
+  gboolean has_set_property;
+  /* Set TRUE to crop as info of conf_win_left_offset and conf_win_top_offset */
+  gboolean enable_crop;
 };
 
 struct _GstOMXVideoDecClass
@@ -110,6 +131,7 @@ struct _GstOMXVideoDecClass
 
   gboolean (*is_format_change) (GstOMXVideoDec * self, GstOMXPort * port, GstVideoCodecState * state);
   gboolean (*set_format)       (GstOMXVideoDec * self, GstOMXPort * port, GstVideoCodecState * state);
+  GstFlowReturn (*prepare_frame)   (GstOMXVideoDec * self, GstVideoCodecFrame *frame);
 };
 
 GType gst_omx_video_dec_get_type (void);
diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c
index dfc03c5..e19a29e 100644
--- a/omx/gstomxvideoenc.c
+++ b/omx/gstomxvideoenc.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
  *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
+ * Copyright (C) 2017,2020 Renesas Electronics Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -32,14 +33,29 @@
 #include "gstomxvideo.h"
 #include "gstomxvideoenc.h"
 
+#if defined (HAVE_MMNGRBUF) && defined (HAVE_VIDEOR_EXT)
+#include "mmngr_buf_user_public.h"
+#include "OMXR_Extension_video.h"
+#endif
+
 #ifdef USE_OMX_TARGET_RPI
 #include <OMX_Broadcom.h>
 #include <OMX_Index.h>
 #endif
+#if defined (USE_OMX_TARGET_RCAR)
+#include "gstomxh264enc.h"
+#endif
+#if defined (USE_OMX_TARGET_RCAR) && defined (HAVE_VIDEOENC_EXT)
+#include "OMXR_Extension_vecmn.h"
+#endif
 
 GST_DEBUG_CATEGORY_STATIC (gst_omx_video_enc_debug_category);
 #define GST_CAT_DEFAULT gst_omx_video_enc_debug_category
 
+#if defined (HAVE_MMNGRBUF) && defined (HAVE_VIDEOR_EXT)
+static gboolean gst_omx_video_enc_set_use_buffer (GstOMXVideoEnc * self);
+#endif
+
 #define GST_TYPE_OMX_VIDEO_ENC_CONTROL_RATE (gst_omx_video_enc_control_rate_get_type ())
 static GType
 gst_omx_video_enc_control_rate_get_type (void)
@@ -203,6 +219,30 @@ gst_omx_video_enc_roi_quality_type (void)
 }
 #endif
 
+#define GST_TYPE_OMX_VIDEO_ENC_SCAN_TYPE (gst_omx_video_enc_get_scantype ())
+static GType
+gst_omx_video_enc_get_scantype (void)
+{
+  static GType qtype = 0;
+
+  if (qtype == 0) {
+    static const GEnumValue values[] = {
+#if defined (USE_OMX_TARGET_RCAR) && defined (HAVE_VIDEOENC_EXT)
+      {OMXR_MC_VIDEO_MemAllocFrame, "Progressive", "progressive"},
+      {OMXR_MC_VIDEO_MemAllocFieldTff, "Interlaced Top Field First",
+          "interlaced-Tff"},
+      {OMXR_MC_VIDEO_MemAllocFieldBff, "Interlaced Bottom Field First",
+          "interlaced-Bff"},
+#endif
+      {0xffffffff, "Component Default", "default"},
+      {0, NULL, NULL},
+    };
+
+    qtype = g_enum_register_static ("GstOMXVideoEncScanType", values);
+  }
+  return qtype;
+}
+
 /* prototypes */
 static void gst_omx_video_enc_finalize (GObject * object);
 static void gst_omx_video_enc_set_property (GObject * object, guint prop_id,
@@ -261,6 +301,9 @@ enum
   PROP_SLICE_SIZE,
   PROP_DEPENDENT_SLICE,
   PROP_DEFAULT_ROI_QUALITY,
+  PROP_SCAN_TYPE,
+  PROP_NO_COPY,
+  PROP_USE_DMABUF
 };
 
 /* FIXME: Better defaults */
@@ -285,6 +328,7 @@ enum
 #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
+#define GST_OMX_VIDEO_ENC_SCAN_TYPE_DEFAULT (0xffffffff)
 
 /* class initialization */
 #define do_init \
@@ -345,6 +389,26 @@ gst_omx_video_enc_class_init (GstOMXVideoEncClass * klass)
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
           GST_PARAM_MUTABLE_READY));
 
+  g_object_class_install_property (gobject_class, PROP_SCAN_TYPE,
+      g_param_spec_enum ("scan-type", "Scan Type",
+          "Encode Scan Type method",
+          GST_TYPE_OMX_VIDEO_ENC_SCAN_TYPE,
+          GST_OMX_VIDEO_ENC_SCAN_TYPE_DEFAULT,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+          GST_PARAM_MUTABLE_READY));
+
+  g_object_class_install_property (gobject_class, PROP_NO_COPY,
+      g_param_spec_boolean ("no-copy", "Propose buffer to upstream",
+          "Whether or not to share input buffer (userptr) with upstream element",
+          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+          GST_PARAM_MUTABLE_READY));
+
+  g_object_class_install_property (gobject_class, PROP_USE_DMABUF,
+      g_param_spec_boolean ("use-dmabuf", "Use dmabuf method",
+          "Whether or not to use dmabuf method",
+          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+          GST_PARAM_MUTABLE_READY));
+
 #ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
   g_object_class_install_property (gobject_class, PROP_QP_MODE,
       g_param_spec_enum ("qp-mode", "QP mode",
@@ -505,6 +569,16 @@ gst_omx_video_enc_init (GstOMXVideoEnc * self)
   self->quant_i_frames = GST_OMX_VIDEO_ENC_QUANT_I_FRAMES_DEFAULT;
   self->quant_p_frames = GST_OMX_VIDEO_ENC_QUANT_P_FRAMES_DEFAULT;
   self->quant_b_frames = GST_OMX_VIDEO_ENC_QUANT_B_FRAMES_DEFAULT;
+  self->scan_type = GST_OMX_VIDEO_ENC_SCAN_TYPE_DEFAULT;
+  self->no_copy = FALSE;
+  self->import_dmabuf = FALSE;
+#if defined (HAVE_MMNGRBUF) && defined (HAVE_VIDEOR_EXT)
+  self->fd_table_array = g_array_new (FALSE, FALSE, sizeof (fd_table));
+  self->id_array = g_array_new (FALSE, FALSE, sizeof (gint));
+  self->extaddr_array =
+      g_array_new (FALSE, FALSE, sizeof (OMXR_MC_VIDEO_EXTEND_ADDRESSTYPE));
+#endif
+
 #ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
   self->qp_mode = GST_OMX_VIDEO_ENC_QP_MODE_DEFAULT;
   self->min_qp = GST_OMX_VIDEO_ENC_MIN_QP_DEFAULT;
@@ -523,6 +597,7 @@ gst_omx_video_enc_init (GstOMXVideoEnc * self)
   self->dependent_slice = GST_OMX_VIDEO_ENC_DEPENDENT_SLICE_DEFAULT;
   self->default_roi_quality = GST_OMX_VIDEO_ENC_DEFAULT_ROI_QUALITY;
 #endif
+  self->headers = NULL;
 
   self->default_target_bitrate = GST_OMX_PROP_OMX_DEFAULT;
 
@@ -915,6 +990,39 @@ gst_omx_video_enc_open (GstVideoEncoder * encoder)
 
       }
     }
+
+    if (self->scan_type != 0xffffffff) {
+#if defined (USE_OMX_TARGET_RCAR) && defined (HAVE_VIDEOENC_EXT)
+      OMXR_MC_VIDEO_PARAM_PICTURE_MEMORY_ALLOCTYPE alloctype_param;
+
+      GST_OMX_INIT_STRUCT (&alloctype_param);
+      alloctype_param.nPortIndex = self->enc_out_port->index;
+      GST_DEBUG_OBJECT (self, "Setting memory alloc type parameter");
+
+      err = gst_omx_component_get_parameter (self->enc,
+          OMXR_MC_IndexParamVideoPictureMemoryAlloc, &alloctype_param);
+      if (err != OMX_ErrorNone) {
+        GST_ERROR_OBJECT (self,
+            "Failed to get memory alloc type: %s (0x%08x)",
+            gst_omx_error_to_string (err), err);
+        return FALSE;
+      }
+
+      alloctype_param.eMemoryAlloc = self->scan_type;
+
+      err = gst_omx_component_set_parameter (self->enc,
+          OMXR_MC_IndexParamVideoPictureMemoryAlloc, &alloctype_param);
+      if (err != OMX_ErrorNone) {
+        GST_ERROR_OBJECT (self,
+            "Failed to set memory alloc type: %s (0x%08x)",
+            gst_omx_error_to_string (err), err);
+        return FALSE;
+      }
+#else
+      GST_ERROR_OBJECT (self,
+          "scan-type is invalid now due to MC does not support");
+#endif
+    }
   }
 #ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
   if (!set_zynqultrascaleplus_props (self))
@@ -987,6 +1095,12 @@ gst_omx_video_enc_finalize (GObject * object)
   g_mutex_clear (&self->drain_lock);
   g_cond_clear (&self->drain_cond);
 
+#if defined (HAVE_MMNGRBUF) && defined (HAVE_VIDEOR_EXT)
+  g_array_free (self->fd_table_array, TRUE);
+  g_array_free (self->id_array, TRUE);
+  g_array_free (self->extaddr_array, TRUE);
+#endif
+
 #ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
   g_clear_pointer (&self->alg_roi_quality_enum_class, g_type_class_unref);
 #endif
@@ -1033,6 +1147,15 @@ gst_omx_video_enc_set_property (GObject * object, guint prop_id,
     case PROP_QUANT_B_FRAMES:
       self->quant_b_frames = g_value_get_uint (value);
       break;
+    case PROP_SCAN_TYPE:
+      self->scan_type = g_value_get_enum (value);
+      break;
+    case PROP_NO_COPY:
+      self->no_copy = g_value_get_boolean (value);
+      break;
+    case PROP_USE_DMABUF:
+      self->import_dmabuf = g_value_get_boolean (value);
+      break;
 #ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
     case PROP_QP_MODE:
       self->qp_mode = g_value_get_enum (value);
@@ -1113,6 +1236,15 @@ gst_omx_video_enc_get_property (GObject * object, guint prop_id, GValue * value,
     case PROP_QUANT_B_FRAMES:
       g_value_set_uint (value, self->quant_b_frames);
       break;
+    case PROP_SCAN_TYPE:
+      g_value_set_enum (value, self->scan_type);
+      break;
+    case PROP_NO_COPY:
+      g_value_set_boolean (value, self->no_copy);
+      break;
+    case PROP_USE_DMABUF:
+      g_value_set_boolean (value, self->import_dmabuf);
+      break;
 #ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
     case PROP_QP_MODE:
       g_value_set_enum (value, self->qp_mode);
@@ -1333,17 +1465,47 @@ gst_omx_video_enc_handle_output_frame (GstOMXVideoEnc * self, GstOMXPort * port,
           "Downstream element refused to negotiate codec_data in the caps");
       return GST_FLOW_NOT_NEGOTIATED;
     }
+    gst_video_codec_frame_unref (frame);
     flow_ret = GST_FLOW_OK;
   } else if (buf->omx_buf->nFilledLen > 0) {
     GstBuffer *outbuf;
     GstMapInfo map = GST_MAP_INFO_INIT;
+    guint hdrs_size = 0;
 
     GST_DEBUG_OBJECT (self, "Handling output data");
 
-    outbuf = gst_buffer_new_and_alloc (buf->omx_buf->nFilledLen);
+    if (self->headers) {
+      /* When OMX send headers in separated buffers, merge these headers
+       * with data frame to created completed frame which satisfies with
+       * elements have alignment=au */
+      guint size = 0;
+      GList *tmp;
 
-    gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
-    memcpy (map.data,
+      for (tmp = self->headers; tmp; tmp = tmp->next) {
+        GstBuffer *tmpbuf = GST_BUFFER (tmp->data);
+        hdrs_size += gst_buffer_get_size (tmpbuf);
+      }
+      outbuf = gst_buffer_new_and_alloc (buf->omx_buf->nFilledLen + hdrs_size);
+      gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
+
+      for (tmp = self->headers; tmp; tmp = tmp->next) {
+        GstBuffer *tmpbuf = GST_BUFFER (tmp->data);
+        GstMapInfo info;
+
+        gst_buffer_map (tmpbuf, &info, GST_MAP_READ);
+        memcpy (map.data + size, info.data, gst_buffer_get_size (tmpbuf));
+        size += gst_buffer_get_size (tmpbuf);
+        gst_buffer_unmap (tmpbuf, &info);
+      }
+
+      g_list_free_full (self->headers, (GDestroyNotify) gst_buffer_unref);
+      self->headers = NULL;
+    } else {
+      outbuf = gst_buffer_new_and_alloc (buf->omx_buf->nFilledLen);
+      gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
+    }
+
+    memcpy (map.data + hdrs_size,
         buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
         buf->omx_buf->nFilledLen);
     gst_buffer_unmap (outbuf, &map);
@@ -1374,8 +1536,16 @@ gst_omx_video_enc_handle_output_frame (GstOMXVideoEnc * self, GstOMXPort * port,
       flow_ret =
           gst_video_encoder_finish_frame (GST_VIDEO_ENCODER (self), frame);
     } else {
-      GST_ERROR_OBJECT (self, "No corresponding frame found");
-      flow_ret = gst_pad_push (GST_VIDEO_ENCODER_SRC_PAD (self), outbuf);
+#ifdef USE_OMX_TARGET_RCAR
+      if (GST_IS_OMX_H264_ENC (self) && !GST_OMX_H264_ENC (self)->send_eos) {
+        GST_DEBUG_OBJECT (self, "Skip sending EOS/EOF data to downstream");
+        gst_buffer_unref (outbuf);
+      } else
+#endif
+      {
+        GST_ERROR_OBJECT (self, "No corresponding frame found");
+        flow_ret = gst_pad_push (GST_VIDEO_ENCODER_SRC_PAD (self), outbuf);
+      }
     }
   } else if (frame != NULL) {
     /* Just ignore empty buffers, don't drop a frame for that */
@@ -1701,6 +1871,14 @@ gst_omx_video_enc_stop (GstVideoEncoder * encoder)
 
   gst_omx_component_get_state (self->enc, 5 * GST_SECOND);
 
+#if defined (HAVE_MMNGRBUF) && defined (HAVE_VIDEOR_EXT)
+  for (gint i = 0; i < self->id_array->len; i++)
+    mmngr_import_end_in_user_ext (g_array_index (self->id_array, gint, i));
+  g_array_set_size (self->fd_table_array, 0);
+  g_array_set_size (self->id_array, 0);
+  g_array_set_size (self->extaddr_array, 0);
+#endif
+
   return TRUE;
 }
 
@@ -1803,40 +1981,30 @@ gst_omx_video_enc_disable (GstOMXVideoEnc * self)
 }
 
 static gboolean
-gst_omx_video_enc_configure_input_buffer (GstOMXVideoEnc * self,
-    GstBuffer * input)
+gst_omx_video_enc_update_input_port (GstOMXVideoEnc * self,
+    OMX_PARAM_PORTDEFINITIONTYPE port_def, guint stride, guint slice_height)
 {
   GstOMXVideoEncClass *klass = GST_OMX_VIDEO_ENC_GET_CLASS (self);
-  GstVideoInfo *info = &self->input_state->info;
-  OMX_PARAM_PORTDEFINITIONTYPE port_def;
-  GstVideoMeta *meta;
-  guint stride, slice_height;
-
-  gst_omx_port_get_port_definition (self->enc_in_port, &port_def);
 
-  meta = gst_buffer_get_video_meta (input);
-  if (meta) {
-    /* Use the stride and slice height of the first plane */
-    stride = meta->stride[0];
-    g_assert (stride != 0);
-    slice_height = (meta->offset[1] - meta->offset[0]) / stride;
-
-    GST_DEBUG_OBJECT (self,
-        "adjusting stride (%d) and slice-height (%d) using input buffer meta",
-        stride, slice_height);
-  } else {
-    GST_WARNING_OBJECT (self,
-        "input buffer doesn't provide video meta, can't adjust stride and slice height");
-
-    stride = info->stride[0];
-    slice_height = info->height;
-  }
-
-  if (port_def.nBufferAlignment)
+  if (port_def.nBufferAlignment) {
     port_def.format.video.nStride =
         GST_ROUND_UP_N (stride, port_def.nBufferAlignment);
-  else
-    port_def.format.video.nStride = GST_ROUND_UP_4 (stride);    /* safe (?) default */
+  } else {
+    if (klass->cdata.hacks & GST_OMX_HACK_RENESAS_ENCMC_STRIDE_ALIGN) {
+      switch (port_def.format.video.eColorFormat) {
+        case OMX_COLOR_FormatYUV420Planar:
+          port_def.format.video.nStride = GST_ROUND_UP_64 (stride);
+          break;
+        case OMX_COLOR_FormatYUV420SemiPlanar:
+          port_def.format.video.nStride = GST_ROUND_UP_32 (stride);
+          break;
+        default:
+          break;
+      }
+    } else {
+      port_def.format.video.nStride = GST_ROUND_UP_4 (stride);  /* safe (?) default */
+    }
+  }
 
   if (klass->cdata.hacks & GST_OMX_HACK_HEIGHT_MULTIPLE_16)
     port_def.format.video.nSliceHeight = GST_ROUND_UP_16 (slice_height);
@@ -1913,6 +2081,41 @@ gst_omx_video_enc_ensure_nb_in_buffers (GstOMXVideoEnc * self)
   return TRUE;
 }
 
+#ifndef USE_OMX_TARGET_RCAR
+static gboolean
+gst_omx_video_enc_configure_input_buffer (GstOMXVideoEnc * self,
+    GstBuffer * input)
+{
+  GstVideoInfo *info = &self->input_state->info;
+  OMX_PARAM_PORTDEFINITIONTYPE port_def;
+  GstVideoMeta *meta;
+  guint stride, slice_height;
+
+  gst_omx_port_get_port_definition (self->enc_in_port, &port_def);
+
+  meta = gst_buffer_get_video_meta (input);
+  if (meta) {
+    /* Use the stride and slice height of the first plane */
+    stride = meta->stride[0];
+    g_assert (stride != 0);
+    slice_height = (meta->offset[1] - meta->offset[0]) / stride;
+
+    GST_DEBUG_OBJECT (self,
+        "adjusting stride (%d) and slice-height (%d) using input buffer meta",
+        stride, slice_height);
+  } else {
+    GST_WARNING_OBJECT (self,
+        "input buffer doesn't provide video meta, can't adjust stride and slice height");
+
+    stride = info->stride[0];
+    slice_height = info->height;
+  }
+
+  return gst_omx_video_enc_update_input_port (self, port_def, stride,
+      slice_height);
+}
+#endif
+
 static gboolean
 gst_omx_video_enc_allocate_in_buffers (GstOMXVideoEnc * self)
 {
@@ -2024,9 +2227,19 @@ gst_omx_video_enc_set_to_idle (GstOMXVideoEnc * self)
   if (gst_omx_component_set_state (self->enc, OMX_StateIdle) != OMX_ErrorNone)
     return FALSE;
 
-  /* Need to allocate buffers to reach Idle state */
-  if (!gst_omx_video_enc_allocate_in_buffers (self))
+  if (self->import_dmabuf) {
+#if defined (HAVE_MMNGRBUF) && defined (HAVE_VIDEOR_EXT)
+    if (!gst_omx_video_enc_set_use_buffer (self))
+      return FALSE;
+#else
+    GST_ERROR_OBJECT (self, "We can't import dmabuf");
     return FALSE;
+#endif
+  } else {
+    /* Need to allocate buffers to reach Idle state */
+    if (!gst_omx_video_enc_allocate_in_buffers (self))
+      return FALSE;
+  }
 
   if (no_disable_outport) {
     if (gst_omx_port_allocate_buffers (self->enc_out_port) != OMX_ErrorNone)
@@ -2054,6 +2267,143 @@ buffer_is_from_input_pool (GstOMXVideoEnc * self, GstBuffer * buffer)
   return buf->port == self->enc_in_port;
 }
 
+#if defined (HAVE_MMNGRBUF) && defined (HAVE_VIDEOR_EXT)
+static gboolean
+update_input_port_color_format (GstOMXVideoEnc * self)
+{
+  OMX_PARAM_PORTDEFINITIONTYPE port_def;
+
+  gst_omx_port_get_port_definition (self->enc_in_port, &port_def);
+
+  switch (port_def.format.video.eColorFormat) {
+    case OMX_COLOR_FormatYUV420Planar:
+      port_def.format.video.eColorFormat =
+          OMX_COLOR_FormatYUV420PlanarMultiPlane;
+      break;
+    case OMX_COLOR_FormatYUV420SemiPlanar:
+      port_def.format.video.eColorFormat =
+          OMX_COLOR_FormatYUV420SemiPlanarMultiPlane;
+      break;
+    default:
+      GST_ERROR_OBJECT (self, "Unsupported dmabuf mode for this format");
+      return FALSE;
+  }
+
+  if (gst_omx_port_update_port_definition (self->enc_in_port,
+          &port_def) != OMX_ErrorNone)
+    return FALSE;
+
+  return TRUE;
+}
+
+static gboolean
+update_input_port_buffer_count (GstOMXVideoEnc * self, GstBuffer * input)
+{
+  GstStructure *config;
+  guint min, max;
+
+  config = gst_buffer_pool_get_config (input->pool);
+  if (!gst_buffer_pool_config_get_params (config, NULL, NULL, &min, &max)) {
+    gst_structure_free (config);
+    return FALSE;
+  }
+
+  if (min != max)
+    GST_WARNING_OBJECT (self,
+        "We can't handle dynamic changing of number of buffers");
+
+  if (!gst_omx_port_update_buffer_count_actual (self->enc_in_port, min))
+    return FALSE;
+
+  return TRUE;
+}
+
+static gboolean
+gst_omx_video_enc_set_use_buffer (GstOMXVideoEnc * self)
+{
+  OMX_PARAM_PORTDEFINITIONTYPE port_def;
+  OMXR_MC_VIDEO_EXTEND_ADDRESSTYPE ext_addr;
+  const GList *addr = NULL;
+  gint i;
+
+  memset (&ext_addr, 0, sizeof (OMXR_MC_VIDEO_EXTEND_ADDRESSTYPE));
+  ext_addr.nSize = sizeof (OMXR_MC_VIDEO_EXTEND_ADDRESSTYPE);
+  gst_omx_port_get_port_definition (self->enc_in_port, &port_def);
+
+  /* doing copy internally */
+  for (i = 0; i < port_def.nBufferCountActual; i++)
+    g_array_append_val (self->extaddr_array, ext_addr);
+
+  for (i = 0; i < port_def.nBufferCountActual; i++)
+    addr =
+        g_list_append ((GList *) addr,
+        (gpointer) & g_array_index (self->extaddr_array,
+            OMXR_MC_VIDEO_EXTEND_ADDRESSTYPE, i));
+
+  if (gst_omx_port_use_buffers (self->enc_in_port, addr) != OMX_ErrorNone) {
+    GST_ERROR_OBJECT (self,
+        ("Fail to allocate OMXBuffer by using OMX_UseBuffer"));
+    g_list_free ((GList *) addr);
+    return FALSE;
+  }
+  g_list_free ((GList *) addr);
+
+  return TRUE;
+}
+
+static gboolean
+mmngr_import_dmabuf (GstOMXVideoEnc * self, gint fd, gint * id,
+    guint * phys_addr)
+{
+  gsize size;
+  gint ret;
+
+  ret = mmngr_import_start_in_user_ext (id, &size, phys_addr, fd, NULL);
+  if (ret != R_MM_OK) {
+    GST_ERROR_OBJECT (self, "Fail to import dmabuf fd");
+    return FALSE;
+  }
+
+  GST_DEBUG_OBJECT (self, "Got physical address 0x%x at fd %d", *phys_addr, fd);
+
+  return TRUE;
+}
+
+static gboolean
+register_input_buffer (GstOMXVideoEnc * self,
+    OMXR_MC_VIDEO_EXTEND_ADDRESSTYPE * ext_addr, GstBuffer * input_buffer)
+{
+  guint n_mem;
+  gint i;
+  gint fd[GST_VIDEO_MAX_PLANES];
+  fd_table table;
+
+  n_mem = gst_buffer_n_memory (input_buffer);
+  for (i = 0; i < n_mem; i++) {
+    GstMemory *mem;
+    gint id[GST_VIDEO_MAX_PLANES];
+    guint phys_addr[GST_VIDEO_MAX_PLANES] = { 0, };
+
+    mem = gst_buffer_peek_memory (input_buffer, i);
+    fd[i] = gst_dmabuf_memory_get_fd (mem);
+
+    if (!mmngr_import_dmabuf (self, fd[i], &id[i], &phys_addr[i])) {
+      GST_ERROR_OBJECT (self, "Failed to mmngr_import_dmabuf");
+      return FALSE;
+    }
+
+    ext_addr->u32HwipAddr[i] = phys_addr[i] + mem->offset;
+    g_array_append_val (self->id_array, id[i]);
+  }
+
+  table.fd = fd[0];
+  table.ext_addr = ext_addr;
+  g_array_append_val (self->fd_table_array, table);
+
+  return TRUE;
+}
+#endif
+
 static gboolean
 gst_omx_video_enc_enable (GstOMXVideoEnc * self, GstBuffer * input)
 {
@@ -2067,15 +2417,17 @@ gst_omx_video_enc_enable (GstOMXVideoEnc * self, GstBuffer * input)
   }
 
   if (!self->in_pool_used) {
+#ifndef USE_OMX_TARGET_RCAR
     if (!gst_omx_video_enc_configure_input_buffer (self, input))
       return FALSE;
+#endif
 
     self->input_allocation = gst_omx_video_enc_pick_input_allocation_mode (self,
         input);
     self->input_dmabuf = FALSE;
 
-#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
     if (gst_is_dmabuf_memory (gst_buffer_peek_memory (input, 0))) {
+#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
       if (self->input_allocation ==
           GST_OMX_BUFFER_ALLOCATION_USE_BUFFER_DYNAMIC) {
         GST_DEBUG_OBJECT (self, "Configure encoder input to import dmabuf");
@@ -2087,8 +2439,19 @@ gst_omx_video_enc_enable (GstOMXVideoEnc * self, GstBuffer * input)
       }
 
       self->input_dmabuf = TRUE;
-    }
+#elif defined (HAVE_MMNGRBUF) && defined (HAVE_VIDEOR_EXT)
+      if (self->import_dmabuf) {
+        if (update_input_port_buffer_count (self, input) &&
+            update_input_port_color_format (self))
+          self->input_dmabuf = TRUE;
+        else
+          return FALSE;
+      }
 #endif
+    } else if (self->import_dmabuf) {
+      GST_ERROR_OBJECT (self, ("Input buffer is not dmabuf"));
+      return FALSE;
+    }
   }
 
   GST_DEBUG_OBJECT (self, "Enabling component");
@@ -2293,8 +2656,8 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder,
         gst_omx_video_calculate_framerate_q16 (info);
 
   GST_DEBUG_OBJECT (self, "Setting inport port definition");
-  if (gst_omx_port_update_port_definition (self->enc_in_port,
-          &port_def) != OMX_ErrorNone)
+  if (!gst_omx_video_enc_update_input_port (self, port_def, info->width,
+          info->height))
     return FALSE;
 
 #ifdef USE_OMX_TARGET_RPI
@@ -2455,7 +2818,6 @@ gst_omx_video_enc_semi_planar_manual_copy (GstOMXVideoEnc * self,
 
     if (dest + dest_stride * height >
         outbuf->omx_buf->pBuffer + outbuf->omx_buf->nAllocLen) {
-      gst_video_frame_unmap (&frame);
       GST_ERROR_OBJECT (self, "Invalid output buffer size");
       gst_video_frame_unmap (&frame);
       return FALSE;
@@ -2534,9 +2896,17 @@ gst_omx_video_enc_fill_buffer (GstOMXVideoEnc * self, GstBuffer * inbuf,
     goto done;
   }
 
+  if (!gst_video_frame_map (&frame, info, inbuf, GST_MAP_READ)) {
+    GST_ERROR_OBJECT (self, "Invalid input buffer size");
+    ret = FALSE;
+    goto done;
+  }
+
   /* Same strides and everything */
-  if (gst_buffer_get_size (inbuf) ==
-      outbuf->omx_buf->nAllocLen - outbuf->omx_buf->nOffset) {
+  if ((gst_buffer_get_size (inbuf) ==
+          outbuf->omx_buf->nAllocLen - outbuf->omx_buf->nOffset) &&
+      (GST_VIDEO_FRAME_COMP_STRIDE (&frame, 0) ==
+          port_def->format.video.nStride)) {
     outbuf->omx_buf->nFilledLen = gst_buffer_get_size (inbuf);
 
     GST_LOG_OBJECT (self, "Matched strides - direct copy %u bytes",
@@ -2546,7 +2916,7 @@ gst_omx_video_enc_fill_buffer (GstOMXVideoEnc * self, GstBuffer * inbuf,
         outbuf->omx_buf->pBuffer + outbuf->omx_buf->nOffset,
         outbuf->omx_buf->nFilledLen);
     ret = TRUE;
-    goto done;
+    goto unmap_frame;
   }
 
   /* Different strides */
@@ -2560,12 +2930,6 @@ gst_omx_video_enc_fill_buffer (GstOMXVideoEnc * self, GstBuffer * inbuf,
 
       outbuf->omx_buf->nFilledLen = 0;
 
-      if (!gst_video_frame_map (&frame, info, inbuf, GST_MAP_READ)) {
-        GST_ERROR_OBJECT (self, "Invalid input buffer size");
-        ret = FALSE;
-        goto done;
-      }
-
       for (i = 0; i < 3; i++) {
         if (i == 0) {
           dest_stride = port_def->format.video.nStride;
@@ -2594,10 +2958,9 @@ gst_omx_video_enc_fill_buffer (GstOMXVideoEnc * self, GstBuffer * inbuf,
 
         if (dest + dest_stride * height >
             outbuf->omx_buf->pBuffer + outbuf->omx_buf->nAllocLen) {
-          gst_video_frame_unmap (&frame);
           GST_ERROR_OBJECT (self, "Invalid output buffer size");
           ret = FALSE;
-          goto done;
+          goto unmap_frame;
         }
 
         for (j = 0; j < height; j++) {
@@ -2616,7 +2979,6 @@ gst_omx_video_enc_fill_buffer (GstOMXVideoEnc * self, GstBuffer * inbuf,
               (port_def->format.video.nSliceHeight / 2) *
               (port_def->format.video.nStride / 2);
       }
-      gst_video_frame_unmap (&frame);
       ret = TRUE;
       break;
     }
@@ -2630,10 +2992,14 @@ gst_omx_video_enc_fill_buffer (GstOMXVideoEnc * self, GstBuffer * inbuf,
       break;
     default:
       GST_ERROR_OBJECT (self, "Unsupported format");
-      goto done;
+      goto unmap_frame;
       break;
   }
 
+unmap_frame:
+
+  gst_video_frame_unmap (&frame);
+
 done:
 
   gst_video_codec_state_unref (state);
@@ -2717,6 +3083,9 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder,
   GstOMXBuffer *buf;
   OMX_ERRORTYPE err;
   GstClockTimeDiff deadline;
+#if defined (HAVE_MMNGRBUF) && defined (HAVE_VIDEOR_EXT)
+  fd_table *table = NULL;
+#endif
 
   self = GST_OMX_VIDEO_ENC (encoder);
 
@@ -2750,6 +3119,34 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder,
 
   port = self->enc_in_port;
 
+#if defined (HAVE_MMNGRBUF) && defined (HAVE_VIDEOR_EXT)
+  if (self->import_dmabuf) {
+    GstMemory *mem;
+    gint fd;
+    gint i;
+
+    mem = gst_buffer_peek_memory (frame->input_buffer, 0);
+    fd = gst_dmabuf_memory_get_fd (mem);
+
+    for (i = 0; i < self->fd_table_array->len; i++) {
+      table = &g_array_index (self->fd_table_array, fd_table, i);
+
+      if (fd == table->fd)
+        break;
+      table = NULL;
+    }
+
+    if (!table
+        && self->fd_table_array->len == port->port_def.nBufferCountActual) {
+      GST_ERROR_OBJECT (self,
+          "Buffer out of guarantee of OMX MC, received %d, guarantee %d",
+          self->fd_table_array->len + 1, port->port_def.nBufferCountActual);
+      gst_video_codec_frame_unref (frame);
+      return GST_FLOW_ERROR;
+    }
+  }
+#endif
+
   while (acq_ret != GST_OMX_ACQUIRE_BUFFER_OK) {
     GstClockTime timestamp, duration;
     gboolean fill_buffer = TRUE;
@@ -2900,6 +3297,31 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder,
     handle_roi_metadata (self, frame->input_buffer);
 #endif
 
+#if defined (HAVE_MMNGRBUF) && defined (HAVE_VIDEOR_EXT)
+    if (self->import_dmabuf) {
+      OMXR_MC_VIDEO_EXTEND_ADDRESSTYPE *ext_addr;
+
+      ext_addr = (OMXR_MC_VIDEO_EXTEND_ADDRESSTYPE *) buf->omx_buf->pBuffer;
+
+      if ((table && (ext_addr != table->ext_addr)) || (!table &&
+              ext_addr->u32HwipAddr[0])) {
+        g_queue_push_tail (&port->pending_buffers, buf);
+        acq_ret = GST_OMX_ACQUIRE_BUFFER_ERROR;
+        continue;
+      }
+
+      if (!table) {
+        if (!register_input_buffer (self, ext_addr, frame->input_buffer)) {
+          gst_video_codec_frame_unref (frame);
+          return GST_FLOW_ERROR;
+        }
+      }
+
+      buf->omx_buf->nFilledLen = port->port_def.nBufferSize;
+      fill_buffer = FALSE;
+    }
+#endif
+
     /* Copy the buffer content in chunks of size as requested
      * by the port */
     if (fill_buffer
@@ -3082,7 +3504,6 @@ gst_omx_video_enc_drain (GstOMXVideoEnc * self)
   return GST_FLOW_OK;
 }
 
-#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
 static gboolean
 pool_request_allocate_cb (GstBufferPool * pool, GstOMXVideoEnc * self)
 {
@@ -3109,7 +3530,8 @@ pool_request_allocate_cb (GstBufferPool * pool, GstOMXVideoEnc * self)
     return FALSE;
 
   self->input_allocation = GST_OMX_BUFFER_ALLOCATION_ALLOCATE_BUFFER;
-  self->input_dmabuf = TRUE;
+  if (!self->no_copy)
+    self->input_dmabuf = TRUE;
 
   /* gst_omx_port_acquire_buffer() will fail if the input port is stil flushing
    * which will prevent upstream from acquiring buffers. */
@@ -3126,7 +3548,8 @@ create_input_pool (GstOMXVideoEnc * self, GstCaps * caps, guint num_buffers)
 
   pool =
       gst_omx_buffer_pool_new (GST_ELEMENT_CAST (self), self->enc,
-      self->enc_in_port, GST_OMX_BUFFER_MODE_DMABUF);
+      self->enc_in_port, self->no_copy ? GST_OMX_BUFFER_MODE_SYSTEM_MEMORY :
+      GST_OMX_BUFFER_MODE_DMABUF);
 
   g_signal_connect_object (pool, "allocate",
       G_CALLBACK (pool_request_allocate_cb), self, 0);
@@ -3144,7 +3567,6 @@ create_input_pool (GstOMXVideoEnc * self, GstCaps * caps, guint num_buffers)
 
   return pool;
 }
-#endif
 
 static gboolean
 gst_omx_video_enc_propose_allocation (GstVideoEncoder * encoder,
@@ -3153,7 +3575,6 @@ gst_omx_video_enc_propose_allocation (GstVideoEncoder * encoder,
   GstOMXVideoEnc *self = GST_OMX_VIDEO_ENC (encoder);
   guint num_buffers;
   GstCaps *caps;
-  GstVideoInfo info;
   GstBufferPool *pool = NULL;
 
   gst_query_parse_allocation (query, &caps, NULL);
@@ -3163,27 +3584,21 @@ gst_omx_video_enc_propose_allocation (GstVideoEncoder * encoder,
     return FALSE;
   }
 
-  if (!gst_video_info_from_caps (&info, caps)) {
-    GST_WARNING_OBJECT (self, "Failed to parse caps %" GST_PTR_FORMAT, caps);
-    return FALSE;
-  }
-
   gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
 
   num_buffers = self->enc_in_port->port_def.nBufferCountMin + 1;
 
-#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
-  /* dmabuf export is currently only supported on Zynqultrascaleplus */
-  pool = create_input_pool (self, caps, num_buffers);
-  if (!pool) {
-    GST_WARNING_OBJECT (self, "Failed to create and configure pool");
-    return FALSE;
+  if (self->no_copy) {
+    pool = create_input_pool (self, caps, num_buffers);
+    if (!pool) {
+      GST_WARNING_OBJECT (self, "Failed to create and configure pool");
+      return FALSE;
+    }
   }
-#endif
 
   GST_DEBUG_OBJECT (self,
-      "request at least %d buffers of size %" G_GSIZE_FORMAT, num_buffers,
-      info.size);
+      "request at least %d buffers of size %u", num_buffers,
+      (guint) self->enc_in_port->port_def.nBufferSize);
   gst_query_add_allocation_pool (query, pool,
       self->enc_in_port->port_def.nBufferSize, num_buffers, 0);
 
diff --git a/omx/gstomxvideoenc.h b/omx/gstomxvideoenc.h
index c84e62a..0e33dee 100644
--- a/omx/gstomxvideoenc.h
+++ b/omx/gstomxvideoenc.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
  *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
+ * Copyright (C) 2017,2020 Renesas Electronics Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -27,6 +28,10 @@
 
 #include "gstomx.h"
 
+#if defined (HAVE_MMNGRBUF) && defined (HAVE_VIDEOR_EXT)
+#include "OMXR_Extension_video.h"
+#endif
+
 G_BEGIN_DECLS
 
 #define GST_TYPE_OMX_VIDEO_ENC \
@@ -45,6 +50,16 @@ G_BEGIN_DECLS
 typedef struct _GstOMXVideoEnc GstOMXVideoEnc;
 typedef struct _GstOMXVideoEncClass GstOMXVideoEncClass;
 
+#if defined (HAVE_MMNGRBUF) && defined (HAVE_VIDEOR_EXT)
+typedef struct fd_table fd_table;
+
+struct fd_table
+{
+  guint fd;
+  OMXR_MC_VIDEO_EXTEND_ADDRESSTYPE *ext_addr;
+};
+#endif
+
 struct _GstOMXVideoEnc
 {
   GstVideoEncoder parent;
@@ -60,6 +75,19 @@ struct _GstOMXVideoEnc
   gboolean started;
    /* TRUE if the ports where disabled after being activated the first time. */
   gboolean disabled;
+  /* TRUE to share buffers (userptr) to upstream */
+  gboolean no_copy;
+  /* TRUE to receive dmabuf fd from upstream */
+  gboolean import_dmabuf;
+
+#if defined (HAVE_MMNGRBUF) && defined (HAVE_VIDEOR_EXT)
+  /* Array contain table of top fd and physical address of GstBuffer */
+  GArray *fd_table_array;
+  /* Array contain extension address */
+  GArray *extaddr_array;
+  /* Array contain id when using mmngrbuf to import fd */
+  GArray *id_array;
+#endif
 
   GstClockTime last_upstream_ts;
 
@@ -75,6 +103,7 @@ struct _GstOMXVideoEnc
   guint32 quant_i_frames;
   guint32 quant_p_frames;
   guint32 quant_b_frames;
+  guint32 scan_type;
 #ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
   guint32 qp_mode;
   guint32 min_qp;
@@ -93,6 +122,7 @@ struct _GstOMXVideoEnc
   gboolean dependent_slice;
   gint default_roi_quality;
 #endif
+  GList *headers;
 
   guint32 default_target_bitrate;
 
diff --git a/omx/gstomxvp8enc.c b/omx/gstomxvp8enc.c
new file mode 100644
index 0000000..5e6de91
--- /dev/null
+++ b/omx/gstomxvp8enc.c
@@ -0,0 +1,440 @@
+/*
+ * Copyright (C) 2017,2020 Renesas Electronics Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+
+#include "gstomxvp8enc.h"
+#ifdef HAVE_VP8ENC_EXT
+#include "OMXR_Extension_vp8e.h"
+#endif
+
+GST_DEBUG_CATEGORY_STATIC (gst_omx_vp8_enc_debug_category);
+#define GST_CAT_DEFAULT gst_omx_vp8_enc_debug_category
+
+/* prototypes */
+static gboolean gst_omx_vp8_enc_set_format (GstOMXVideoEnc * enc,
+    GstOMXPort * port, GstVideoCodecState * state);
+static GstCaps *gst_omx_vp8_enc_get_caps (GstOMXVideoEnc * enc,
+    GstOMXPort * port, GstVideoCodecState * state);
+static GstFlowReturn gst_omx_vp8_enc_handle_output_frame (GstOMXVideoEnc *
+    self, GstOMXPort * port, GstOMXBuffer * buf, GstVideoCodecFrame * frame);
+static void gst_omx_vp8_enc_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_omx_vp8_enc_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+
+enum
+{
+  PROP_0,
+#ifdef HAVE_VP8ENC_EXT
+  PROP_INTERVALOFCODINGINTRAFRAMES,
+  PROP_SHARPNESS,
+#endif
+  PROP_DCTPARTITIONS
+};
+
+#ifdef HAVE_VP8ENC_EXT
+#define GST_OMX_VP8_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT (0xffffffff)
+#define GST_OMX_VP8_VIDEO_ENC_SHARPNESS_DEFAULT 0
+#endif
+#define GST_OMX_VP8_VIDEO_ENC_DCT_PARTITIONS_DEFAULT 0
+
+/* class initialization */
+
+#define DEBUG_INIT \
+  GST_DEBUG_CATEGORY_INIT (gst_omx_vp8_enc_debug_category, "omxvp8enc", 0, \
+      "debug category for gst-omx video encoder base class");
+
+#define parent_class gst_omx_vp8_enc_parent_class
+G_DEFINE_TYPE_WITH_CODE (GstOMXVP8Enc, gst_omx_vp8_enc,
+    GST_TYPE_OMX_VIDEO_ENC, DEBUG_INIT);
+
+static void
+gst_omx_vp8_enc_class_init (GstOMXVP8EncClass * klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+  GstOMXVideoEncClass *videoenc_class = GST_OMX_VIDEO_ENC_CLASS (klass);
+
+  videoenc_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_vp8_enc_set_format);
+  videoenc_class->get_caps = GST_DEBUG_FUNCPTR (gst_omx_vp8_enc_get_caps);
+
+  gobject_class->set_property = gst_omx_vp8_enc_set_property;
+  gobject_class->get_property = gst_omx_vp8_enc_get_property;
+#ifdef HAVE_VP8ENC_EXT
+  g_object_class_install_property (gobject_class,
+      PROP_INTERVALOFCODINGINTRAFRAMES,
+      g_param_spec_uint ("interval-intraframes",
+          "Interval of coding Intra frames",
+          "Interval of coding Intra frames (0xffffffff=component default)", 0,
+          G_MAXUINT,
+          GST_OMX_VP8_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+          GST_PARAM_MUTABLE_READY));
+
+  g_object_class_install_property (gobject_class, PROP_SHARPNESS,
+      g_param_spec_uint ("sharpness", "Control the blocking filter",
+          "Control the blocking filter", 0,
+          7, GST_OMX_VP8_VIDEO_ENC_SHARPNESS_DEFAULT,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+          GST_PARAM_MUTABLE_READY));
+#endif
+  g_object_class_install_property (gobject_class, PROP_DCTPARTITIONS,
+      g_param_spec_uint ("dct-partitions", "DCT residual data partition",
+          "DCT residual data partition", 0, 1,
+          GST_OMX_VP8_VIDEO_ENC_DCT_PARTITIONS_DEFAULT,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+          GST_PARAM_MUTABLE_READY));
+
+  videoenc_class->cdata.default_src_template_caps = "video/x-vp8, "
+      "width=(int) [ 80, 1920 ], " "height=(int) [ 80, 1080 ]";
+  videoenc_class->handle_output_frame =
+      GST_DEBUG_FUNCPTR (gst_omx_vp8_enc_handle_output_frame);
+
+  gst_element_class_set_static_metadata (element_class,
+      "OpenMAX VP8 Video Encoder",
+      "Codec/Encoder/Video",
+      "Encode VP8 video streams", "Renesas Electronics Corporation");
+
+  gst_omx_set_default_role (&videoenc_class->cdata, "video_encoder.vp8");
+}
+
+static void
+gst_omx_vp8_enc_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstOMXVP8Enc *self = GST_OMX_VP8_ENC (object);
+
+  switch (prop_id) {
+#ifdef HAVE_VP8ENC_EXT
+    case PROP_INTERVALOFCODINGINTRAFRAMES:
+      self->interval_intraframes = g_value_get_uint (value);
+      break;
+    case PROP_SHARPNESS:
+      self->sharpness = g_value_get_uint (value);
+      break;
+#endif
+    case PROP_DCTPARTITIONS:
+      self->dct_partitions = g_value_get_uint (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_omx_vp8_enc_get_property (GObject * object, guint prop_id, GValue * value,
+    GParamSpec * pspec)
+{
+  GstOMXVP8Enc *self = GST_OMX_VP8_ENC (object);
+
+  switch (prop_id) {
+#ifdef HAVE_VP8ENC_EXT
+    case PROP_INTERVALOFCODINGINTRAFRAMES:
+      g_value_set_uint (value, self->interval_intraframes);
+      break;
+    case PROP_SHARPNESS:
+      g_value_set_uint (value, self->sharpness);
+      break;
+#endif
+    case PROP_DCTPARTITIONS:
+      g_value_set_uint (value, self->dct_partitions);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_omx_vp8_enc_init (GstOMXVP8Enc * self)
+{
+#ifdef HAVE_VP8ENC_EXT
+  self->interval_intraframes =
+      GST_OMX_VP8_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT;
+  self->sharpness = GST_OMX_VP8_VIDEO_ENC_SHARPNESS_DEFAULT;
+#endif
+  self->dct_partitions = GST_OMX_VP8_VIDEO_ENC_DCT_PARTITIONS_DEFAULT;
+}
+
+static gboolean
+gst_omx_vp8_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port,
+    GstVideoCodecState * state)
+{
+  GstOMXVP8Enc *self = GST_OMX_VP8_ENC (enc);
+  GstCaps *peercaps;
+  OMX_PARAM_PORTDEFINITIONTYPE port_def;
+  OMX_VIDEO_PARAM_PROFILELEVELTYPE param_profilelevel;
+  OMX_VIDEO_PARAM_VP8TYPE param_type;
+  OMX_ERRORTYPE err;
+  const gchar *profile_string, *level_string;
+
+#ifdef HAVE_VP8ENC_EXT
+  if ((self->interval_intraframes !=
+          GST_OMX_VP8_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT) ||
+      (self->sharpness != GST_OMX_VP8_VIDEO_ENC_SHARPNESS_DEFAULT)) {
+
+    OMXR_MC_VIDEO_PARAM_VP8_MISCELLANEOUS param_miscellaneous;
+
+    GST_OMX_INIT_STRUCT (&param_miscellaneous);
+    param_miscellaneous.nPortIndex =
+        GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
+    err =
+        gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+        OMXR_MC_IndexParamVideoVP8Miscellaneous, &param_miscellaneous);
+
+    if (err != OMX_ErrorNone) {
+      GST_ERROR_OBJECT (self,
+          "can't get OMXR_MC_IndexParamVideoVP8Miscellaneous %s (0x%08x)",
+          gst_omx_error_to_string (err), err);
+      return FALSE;
+    }
+
+    GST_DEBUG_OBJECT (self, "default nPFrames:%u nSharpness:%u",
+        (guint) param_miscellaneous.nPFrames,
+        (guint) param_miscellaneous.nSharpness);
+
+    if (self->interval_intraframes !=
+        GST_OMX_VP8_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT)
+      param_miscellaneous.nPFrames = self->interval_intraframes;
+    if (self->sharpness != GST_OMX_VP8_VIDEO_ENC_SHARPNESS_DEFAULT)
+      param_miscellaneous.nSharpness = self->sharpness;
+
+    err =
+        gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+        OMXR_MC_IndexParamVideoVP8Miscellaneous, &param_miscellaneous);
+
+    if (err != OMX_ErrorNone) {
+      GST_ERROR_OBJECT (self,
+          "can't set OMXR_MC_IndexParamVideoVP8Miscellaneous %s (0x%08x)",
+          gst_omx_error_to_string (err), err);
+      return FALSE;
+    }
+
+    err =
+        gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+        OMXR_MC_IndexParamVideoVP8Miscellaneous, &param_miscellaneous);
+
+    if (err == OMX_ErrorNone)
+      GST_INFO_OBJECT (self, "updated nPFrames:%u nSharpness:%u",
+          (guint) param_miscellaneous.nPFrames,
+          (guint) param_miscellaneous.nSharpness);
+    else
+      GST_INFO_OBJECT (self,
+          "Can't get updated OMXR_MC_IndexParamVideoVP8Miscellaneous %s (0x%08x)",
+          gst_omx_error_to_string (err), err);
+  }
+#endif
+
+  if (self->dct_partitions != GST_OMX_VP8_VIDEO_ENC_DCT_PARTITIONS_DEFAULT) {
+
+    GST_OMX_INIT_STRUCT (&param_type);
+    param_type.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
+    err =
+        gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+        OMX_IndexParamVideoVp8, &param_type);
+
+    if (err != OMX_ErrorNone) {
+      GST_ERROR_OBJECT (self, "can't get OMX_IndexParamVideoVp8 %s (0x%08x)",
+          gst_omx_error_to_string (err), err);
+      return FALSE;
+    }
+
+    GST_DEBUG_OBJECT (self, "default nDCTPartitions:%u",
+        (guint) param_type.nDCTPartitions);
+
+    param_type.nDCTPartitions = self->dct_partitions;
+
+    err =
+        gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+        OMX_IndexParamVideoVp8, &param_type);
+
+    if (err != OMX_ErrorNone) {
+      GST_ERROR_OBJECT (self, "can't set OMX_IndexParamVideoVp8 %s (0x%08x)",
+          gst_omx_error_to_string (err), err);
+      return FALSE;
+    }
+
+    err =
+        gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+        OMX_IndexParamVideoVp8, &param_type);
+
+    if (err == OMX_ErrorNone)
+      GST_INFO_OBJECT (self, "updated nDCTPartitions:%u",
+          (guint) param_type.nDCTPartitions);
+    else
+      GST_INFO_OBJECT (self,
+          "Can't get updated OMX_IndexParamVideoVp8 %s (0x%08x)",
+          gst_omx_error_to_string (err), err);
+  }
+
+  gst_omx_port_get_port_definition (GST_OMX_VIDEO_ENC (self)->enc_out_port,
+      &port_def);
+  port_def.format.video.eCompressionFormat = OMX_VIDEO_CodingVP8;
+  err =
+      gst_omx_port_update_port_definition (GST_OMX_VIDEO_ENC
+      (self)->enc_out_port, &port_def);
+  if (err != OMX_ErrorNone)
+    return FALSE;
+
+  GST_OMX_INIT_STRUCT (&param_profilelevel);
+  param_profilelevel.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
+
+  err =
+      gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+      OMX_IndexParamVideoProfileLevelCurrent, &param_profilelevel);
+  if (err != OMX_ErrorNone) {
+    GST_WARNING_OBJECT (self,
+        "Setting profile/level not supported by component");
+    return TRUE;
+  }
+
+  peercaps = gst_pad_peer_query_caps (GST_VIDEO_ENCODER_SRC_PAD (enc),
+      gst_pad_get_pad_template_caps (GST_VIDEO_ENCODER_SRC_PAD (enc)));
+  if (peercaps) {
+    GstStructure *s;
+
+    if (gst_caps_is_empty (peercaps)) {
+      gst_caps_unref (peercaps);
+      GST_ERROR_OBJECT (self, "Empty caps");
+      return FALSE;
+    }
+
+    s = gst_caps_get_structure (peercaps, 0);
+    profile_string = gst_structure_get_string (s, "profile");
+    if (profile_string) {
+      if (g_str_equal (profile_string, "main")) {
+        param_profilelevel.eProfile = OMX_VIDEO_VP8ProfileMain;
+      } else {
+        goto unsupported_profile;
+      }
+    }
+    level_string = gst_structure_get_string (s, "level");
+    if (level_string) {
+      if (g_str_equal (level_string, "0")) {
+        param_profilelevel.eLevel = OMX_VIDEO_VP8Level_Version0;
+      } else if (g_str_equal (level_string, "1")) {
+        param_profilelevel.eLevel = OMX_VIDEO_VP8Level_Version1;
+      } else if (g_str_equal (level_string, "2")) {
+        param_profilelevel.eLevel = OMX_VIDEO_VP8Level_Version2;
+      } else if (g_str_equal (level_string, "3")) {
+        param_profilelevel.eLevel = OMX_VIDEO_VP8Level_Version3;
+      } else {
+        goto unsupported_level;
+      }
+    }
+    gst_caps_unref (peercaps);
+  }
+
+  err =
+      gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+      OMX_IndexParamVideoProfileLevelCurrent, &param_profilelevel);
+  if (err == OMX_ErrorUnsupportedIndex) {
+    GST_WARNING_OBJECT (self,
+        "Setting profile/level not supported by component");
+  } else if (err != OMX_ErrorNone) {
+    GST_ERROR_OBJECT (self,
+        "Error setting profile %u and level %u: %s (0x%08x)",
+        (guint) param_profilelevel.eProfile, (guint) param_profilelevel.eLevel,
+        gst_omx_error_to_string (err), err);
+    return FALSE;
+  }
+
+  return TRUE;
+
+unsupported_profile:
+  GST_ERROR_OBJECT (self, "Unsupported profile %s", profile_string);
+  gst_caps_unref (peercaps);
+  return FALSE;
+
+unsupported_level:
+  GST_ERROR_OBJECT (self, "Unsupported level %s", level_string);
+  gst_caps_unref (peercaps);
+  return FALSE;
+}
+
+static GstCaps *
+gst_omx_vp8_enc_get_caps (GstOMXVideoEnc * enc, GstOMXPort * port,
+    GstVideoCodecState * state)
+{
+  GstOMXVP8Enc *self = GST_OMX_VP8_ENC (enc);
+  GstCaps *caps;
+  OMX_ERRORTYPE err;
+  OMX_VIDEO_PARAM_PROFILELEVELTYPE param_profilelevel;
+  const gchar *profile, *level;
+
+  caps = gst_caps_new_simple ("video/x-vp8", NULL, NULL);
+
+  GST_OMX_INIT_STRUCT (&param_profilelevel);
+  param_profilelevel.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
+
+  err =
+      gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+      OMX_IndexParamVideoProfileLevelCurrent, &param_profilelevel);
+  if (err != OMX_ErrorNone && err != OMX_ErrorUnsupportedIndex)
+    return NULL;
+
+  if (err == OMX_ErrorNone) {
+    switch (param_profilelevel.eProfile) {
+      case OMX_VIDEO_VP8ProfileMain:
+        profile = "main";
+        break;
+      default:
+        g_assert_not_reached ();
+        return NULL;
+    }
+
+    switch (param_profilelevel.eLevel) {
+      case OMX_VIDEO_VP8Level_Version0:
+        level = "0";
+        break;
+      case OMX_VIDEO_VP8Level_Version1:
+        level = "1";
+        break;
+      case OMX_VIDEO_VP8Level_Version2:
+        level = "2";
+        break;
+      case OMX_VIDEO_VP8Level_Version3:
+        level = "3";
+        break;
+      default:
+        g_assert_not_reached ();
+        return NULL;
+    }
+    gst_caps_set_simple (caps,
+        "profile", G_TYPE_STRING, profile, "level", G_TYPE_STRING, level, NULL);
+  }
+
+  return caps;
+}
+
+static GstFlowReturn
+gst_omx_vp8_enc_handle_output_frame (GstOMXVideoEnc * enc, GstOMXPort * port,
+    GstOMXBuffer * buf, GstVideoCodecFrame * frame)
+{
+  return
+      GST_OMX_VIDEO_ENC_CLASS
+      (gst_omx_vp8_enc_parent_class)->handle_output_frame (enc, port, buf,
+      frame);
+}
diff --git a/omx/gstomxvp8enc.h b/omx/gstomxvp8enc.h
new file mode 100644
index 0000000..de30a18
--- /dev/null
+++ b/omx/gstomxvp8enc.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2017,2020 Renesas Electronics Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#ifndef __GST_OMX_VP8_ENC_H__
+#define __GST_OMX_VP8_ENC_H__
+
+#include <gst/gst.h>
+#include "gstomxvideoenc.h"
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_OMX_VP8_ENC \
+  (gst_omx_vp8_enc_get_type())
+#define GST_OMX_VP8_ENC(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_VP8_ENC,GstOMXVP8Enc))
+#define GST_OMX_VP8_ENC_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_VP8_ENC,GstOMXVP8EncClass))
+#define GST_OMX_VP8_ENC_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_VP8_ENC,GstOMXVP8EncClass))
+#define GST_IS_OMX_VP8_ENC(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_VP8_ENC))
+#define GST_IS_OMX_VP8_ENC_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_VP8_ENC))
+
+typedef struct _GstOMXVP8Enc GstOMXVP8Enc;
+typedef struct _GstOMXVP8EncClass GstOMXVP8EncClass;
+
+struct _GstOMXVP8Enc
+{
+  GstOMXVideoEnc parent;
+
+#ifdef HAVE_VP8ENC_EXT
+  guint32 interval_intraframes;
+  guint32 sharpness;
+#endif
+  guint32 dct_partitions;
+};
+
+struct _GstOMXVP8EncClass
+{
+  GstOMXVideoEncClass parent_class;
+};
+
+GType gst_omx_vp8_enc_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_OMX_VP8_ENC_H__ */
diff --git a/omx/gstomxvp9dec.c b/omx/gstomxvp9dec.c
new file mode 100644
index 0000000..db470aa
--- /dev/null
+++ b/omx/gstomxvp9dec.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2017-2018,2021 Renesas Electronics Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+
+#include "gstomxvp9dec.h"
+#ifdef HAVE_VP9DEC_EXT
+#include "OMXR_Extension_vp9d.h"
+#endif
+
+GST_DEBUG_CATEGORY_STATIC (gst_omx_vp9_dec_debug_category);
+#define GST_CAT_DEFAULT gst_omx_vp9_dec_debug_category
+
+/* prototypes */
+static gboolean gst_omx_vp9_dec_is_format_change (GstOMXVideoDec * dec,
+    GstOMXPort * port, GstVideoCodecState * state);
+static gboolean gst_omx_vp9_dec_set_format (GstOMXVideoDec * dec,
+    GstOMXPort * port, GstVideoCodecState * state);
+
+enum
+{
+  PROP_0
+};
+
+/* class initialization */
+
+#define DEBUG_INIT \
+  GST_DEBUG_CATEGORY_INIT (gst_omx_vp9_dec_debug_category, "omxvp9dec", 0, \
+      "debug category for gst-omx video decoder base class");
+
+G_DEFINE_TYPE_WITH_CODE (GstOMXVP9Dec, gst_omx_vp9_dec,
+    GST_TYPE_OMX_VIDEO_DEC, DEBUG_INIT);
+
+static void
+gst_omx_vp9_dec_class_init (GstOMXVP9DecClass * klass)
+{
+  GstOMXVideoDecClass *videodec_class = GST_OMX_VIDEO_DEC_CLASS (klass);
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+  videodec_class->is_format_change =
+      GST_DEBUG_FUNCPTR (gst_omx_vp9_dec_is_format_change);
+  videodec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_vp9_dec_set_format);
+
+  videodec_class->cdata.default_sink_template_caps = "video/x-vp9, "
+      "width=(int) [1,MAX], " "height=(int) [1,MAX]";
+
+  gst_element_class_set_static_metadata (element_class,
+      "OpenMAX VP9 Video Decoder",
+      "Codec/Decoder/Video",
+      "Decode VP9 video streams", "Renesas Electronics Corporation");
+
+  gst_omx_set_default_role (&videodec_class->cdata, "video_decoder.vp9");
+}
+
+static void
+gst_omx_vp9_dec_init (GstOMXVP9Dec * self)
+{
+}
+
+static gboolean
+gst_omx_vp9_dec_is_format_change (GstOMXVideoDec * dec,
+    GstOMXPort * port, GstVideoCodecState * state)
+{
+  return FALSE;
+}
+
+static gboolean
+gst_omx_vp9_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port,
+    GstVideoCodecState * state)
+{
+  gboolean ret;
+  OMX_PARAM_PORTDEFINITIONTYPE port_def;
+
+  gst_omx_port_get_port_definition (port, &port_def);
+#ifdef HAVE_VP9DEC_EXT
+  port_def.format.video.eCompressionFormat = OMXR_MC_VIDEO_CodingVP9;
+#endif
+  ret = gst_omx_port_update_port_definition (port, &port_def) == OMX_ErrorNone;
+
+  return ret;
+}
diff --git a/omx/gstomxvp9dec.h b/omx/gstomxvp9dec.h
new file mode 100644
index 0000000..957583b
--- /dev/null
+++ b/omx/gstomxvp9dec.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2017,2021 Renesas Electronics Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#ifndef __GST_OMX_VP9_DEC_H__
+#define __GST_OMX_VP9_DEC_H__
+
+#include <gst/gst.h>
+#include "gstomxvideodec.h"
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_OMX_VP9_DEC \
+  (gst_omx_vp9_dec_get_type())
+#define GST_OMX_VP9_DEC(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_VP9_DEC,GstOMXVP9Dec))
+#define GST_OMX_VP9_DEC_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_VP9_DEC,GstOMXVP9DecClass))
+#define GST_OMX_VP9_DEC_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_VP9_DEC,GstOMXVP9DecClass))
+#define GST_IS_OMX_VP9_DEC(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_VP9_DEC))
+#define GST_IS_OMX_VP9_DEC_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_VP9_DEC))
+
+typedef struct _GstOMXVP9Dec GstOMXVP9Dec;
+typedef struct _GstOMXVP9DecClass GstOMXVP9DecClass;
+
+struct _GstOMXVP9Dec
+{
+  GstOMXVideoDec parent;
+};
+
+struct _GstOMXVP9DecClass
+{
+  GstOMXVideoDecClass parent_class;
+};
+
+GType gst_omx_vp9_dec_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_OMX_VP9_DEC_H__ */
diff --git a/omx/gstomxwmadec.c b/omx/gstomxwmadec.c
new file mode 100644
index 0000000..915f2ef
--- /dev/null
+++ b/omx/gstomxwmadec.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2017,2020 Renesas Electronics Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+
+#include "gstomxwmadec.h"
+#ifdef HAVE_AUDIOR_EXT
+#include "OMXR_Extension_audio.h"
+#endif
+
+GST_DEBUG_CATEGORY_STATIC (gst_omx_wma_dec_debug_category);
+#define GST_CAT_DEFAULT gst_omx_wma_dec_debug_category
+
+/* prototypes */
+static gboolean gst_omx_wma_dec_set_format (GstOMXAudioDec * dec,
+    GstOMXPort * port, GstCaps * caps);
+static gboolean gst_omx_wma_dec_is_format_change (GstOMXAudioDec * dec,
+    GstOMXPort * port, GstCaps * caps);
+static gint gst_omx_wma_dec_get_samples_per_frame (GstOMXAudioDec * dec,
+    GstOMXPort * port);
+static gboolean gst_omx_wma_dec_get_channel_positions (GstOMXAudioDec * dec,
+    GstOMXPort * port, GstAudioChannelPosition position[OMX_AUDIO_MAXCHANNELS]);
+
+/* class initialization */
+
+#define DEBUG_INIT \
+  GST_DEBUG_CATEGORY_INIT (gst_omx_wma_dec_debug_category, "omxwmadec", 0, \
+      "debug category for gst-omx wma audio decoder");
+
+G_DEFINE_TYPE_WITH_CODE (GstOMXWMADec, gst_omx_wma_dec,
+    GST_TYPE_OMX_AUDIO_DEC, DEBUG_INIT);
+
+
+static void
+gst_omx_wma_dec_class_init (GstOMXWMADecClass * klass)
+{
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+  GstOMXAudioDecClass *audiodec_class = GST_OMX_AUDIO_DEC_CLASS (klass);
+
+  audiodec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_wma_dec_set_format);
+  audiodec_class->is_format_change =
+      GST_DEBUG_FUNCPTR (gst_omx_wma_dec_is_format_change);
+  audiodec_class->get_samples_per_frame =
+      GST_DEBUG_FUNCPTR (gst_omx_wma_dec_get_samples_per_frame);
+  audiodec_class->get_channel_positions =
+      GST_DEBUG_FUNCPTR (gst_omx_wma_dec_get_channel_positions);
+
+  audiodec_class->cdata.default_sink_template_caps = "audio/x-wma, "
+      "wmaversion=(int)[1,3],"
+      "rate=(int)[8000,48000], "
+      "channels=(int)[1,2], "
+      "block_align=(int)[0, 2147483647], " "bitrate=(int)[0, 2147483647]";
+
+  gst_element_class_set_static_metadata (element_class,
+      "OpenMAX WMA Audio Decoder",
+      "Codec/Decoder/Audio",
+      "Decode WMA audio streams", "Renesas Electronics Corporation");
+
+  gst_omx_set_default_role (&audiodec_class->cdata, "audio_decoder.wma");
+}
+
+static void
+gst_omx_wma_dec_init (GstOMXWMADec * self)
+{
+  self->spf = -1;
+}
+
+static gboolean
+gst_omx_wma_dec_set_format (GstOMXAudioDec * dec, GstOMXPort * port,
+    GstCaps * caps)
+{
+  GstOMXWMADec *self = GST_OMX_WMA_DEC (dec);
+  OMX_PARAM_PORTDEFINITIONTYPE port_def;
+  OMX_AUDIO_PARAM_WMATYPE wma_param;
+  OMX_ERRORTYPE err;
+  GstStructure *s;
+  gint wmaversion, block_align, bitrate, rate, channels;
+  const GValue *codec_data;
+  GstBuffer *buf;
+  GstMapInfo info;
+
+  gst_omx_port_get_port_definition (port, &port_def);
+  port_def.format.audio.eEncoding = OMX_AUDIO_CodingWMA;
+  err = gst_omx_port_update_port_definition (port, &port_def);
+
+  if (err != OMX_ErrorNone) {
+    GST_ERROR_OBJECT (self,
+        "Failed to set WMA format on component: %s (0x%08x)",
+        gst_omx_error_to_string (err), err);
+    return FALSE;
+  }
+
+  GST_OMX_INIT_STRUCT (&wma_param);
+  wma_param.nPortIndex = port->index;
+
+  err =
+      gst_omx_component_get_parameter (dec->dec, OMX_IndexParamAudioWma,
+      &wma_param);
+
+  if (err != OMX_ErrorNone) {
+    GST_ERROR_OBJECT (self,
+        "Failed to get WMA parameters from component: %s (0x%08x)",
+        gst_omx_error_to_string (err), err);
+    return FALSE;
+  }
+
+  s = gst_caps_get_structure (caps, 0);
+  if (!gst_structure_get_int (s, "wmaversion", &wmaversion) ||
+      !gst_structure_get_int (s, "rate", &rate) ||
+      !gst_structure_get_int (s, "channels", &channels) ||
+      !gst_structure_get_int (s, "block_align", &block_align) ||
+      !gst_structure_get_int (s, "bitrate", &bitrate)) {
+    GST_ERROR_OBJECT (self, "Incomplete caps");
+    return FALSE;
+  }
+
+  wma_param.nChannels = channels;
+  wma_param.nBitRate = bitrate;
+  /* wma_param.eFormat not supported */
+  /* wma_param.eProfile not supported */
+  wma_param.nSamplingRate = rate;
+  wma_param.nBlockAlign = block_align;
+
+  codec_data = gst_structure_get_value (s, "codec_data");
+  if (codec_data) {
+    buf = gst_value_get_buffer (codec_data);
+    gst_buffer_map (buf, &info, GST_MAP_READ);
+    if (info.size >= 10) {
+      guint *puint32data;
+      guint16 *puint16data;
+      guint16 wEncodeOptions;
+      guint32 dwSuperBlockAlign;
+
+      puint16data = (guint16 *) (info.data + 4);
+      wEncodeOptions = *puint16data;
+
+      puint32data = (guint *) (info.data + 6);
+      dwSuperBlockAlign = *puint32data;
+      wma_param.nEncodeOptions = wEncodeOptions;
+      wma_param.nSuperBlockAlign = dwSuperBlockAlign;
+    }
+    gst_buffer_unmap (buf, &info);
+  }
+
+  err =
+      gst_omx_component_set_parameter (dec->dec, OMX_IndexParamAudioWma,
+      &wma_param);
+  if (err != OMX_ErrorNone) {
+    GST_ERROR_OBJECT (self, "Error setting WMA parameters: %s (0x%08x)",
+        gst_omx_error_to_string (err), err);
+    return FALSE;
+  }
+#ifdef HAVE_AUDIOR_EXT
+  /* Set output pcm unit */
+  {
+    OMXR_MC_AUDIO_PARAM_OUTPUTUNITTYPE unit;
+    GST_OMX_INIT_STRUCT (&unit);
+    unit.nPortIndex = dec->dec_out_port->index;
+    unit.eUnit = OMXR_MC_AUDIO_UnitPayload;
+    err = gst_omx_component_set_parameter (dec->dec,
+        OMXR_MC_IndexParamAudioOutputUnit, &unit);
+
+    if (err != OMX_ErrorNone) {
+      GST_ERROR_OBJECT (self, "Error setting Unit parameters: %s (0x%08x)",
+          gst_omx_error_to_string (err), err);
+      return FALSE;
+    }
+  }
+#endif
+  return TRUE;
+}
+
+static gboolean
+gst_omx_wma_dec_is_format_change (GstOMXAudioDec * dec, GstOMXPort * port,
+    GstCaps * caps)
+{
+  GstOMXWMADec *self = GST_OMX_WMA_DEC (dec);
+  OMX_AUDIO_PARAM_WMATYPE wma_param;
+  OMX_ERRORTYPE err;
+  GstStructure *s;
+  gint wmaversion, block_align, bitrate, rate, channels;
+
+  GST_OMX_INIT_STRUCT (&wma_param);
+  wma_param.nPortIndex = port->index;
+
+  err =
+      gst_omx_component_get_parameter (dec->dec, OMX_IndexParamAudioWma,
+      &wma_param);
+  if (err != OMX_ErrorNone) {
+    GST_ERROR_OBJECT (self,
+        "Failed to get WMA parameters from component: %s (0x%08x)",
+        gst_omx_error_to_string (err), err);
+    return FALSE;
+  }
+
+  s = gst_caps_get_structure (caps, 0);
+
+  if (!gst_structure_get_int (s, "wmaversion", &wmaversion) ||
+      !gst_structure_get_int (s, "rate", &rate) ||
+      !gst_structure_get_int (s, "channels", &channels) ||
+      !gst_structure_get_int (s, "block_align", &block_align) ||
+      !gst_structure_get_int (s, "bitrate", &bitrate)) {
+    GST_ERROR_OBJECT (self, "Incomplete caps");
+    return FALSE;
+  }
+
+  if (wma_param.nChannels != channels)
+    return TRUE;
+
+  if (wma_param.nBitRate != bitrate)
+    return TRUE;
+
+  if (wma_param.nSamplingRate != rate)
+    return TRUE;
+
+  if (wma_param.nBlockAlign != block_align)
+    return TRUE;
+
+  return FALSE;
+}
+
+static gint
+gst_omx_wma_dec_get_samples_per_frame (GstOMXAudioDec * dec, GstOMXPort * port)
+{
+  return GST_OMX_WMA_DEC (dec)->spf;
+}
+
+static gboolean
+gst_omx_wma_dec_get_channel_positions (GstOMXAudioDec * dec,
+    GstOMXPort * port, GstAudioChannelPosition position[OMX_AUDIO_MAXCHANNELS])
+{
+  OMX_AUDIO_PARAM_PCMMODETYPE pcm_param;
+  OMX_ERRORTYPE err;
+
+  GST_OMX_INIT_STRUCT (&pcm_param);
+  pcm_param.nPortIndex = port->index;
+  err =
+      gst_omx_component_get_parameter (dec->dec, OMX_IndexParamAudioPcm,
+      &pcm_param);
+  if (err != OMX_ErrorNone) {
+    GST_ERROR_OBJECT (dec, "Failed to get PCM parameters: %s (0x%08x)",
+        gst_omx_error_to_string (err), err);
+    return FALSE;
+  }
+
+  switch (pcm_param.nChannels) {
+    case 1:
+      position[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
+      break;
+    case 2:
+      position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
+      position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
+      break;
+    default:
+      return FALSE;
+  }
+
+  return TRUE;
+}
diff --git a/omx/gstomxwmadec.h b/omx/gstomxwmadec.h
new file mode 100644
index 0000000..24ae5be
--- /dev/null
+++ b/omx/gstomxwmadec.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017,2020 Renesas Electronics Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#ifndef __GST_OMX_WMA_DEC_H__
+#define __GST_OMX_WMA_DEC_H__
+
+#include <gst/gst.h>
+#include "gstomxaudiodec.h"
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_OMX_WMA_DEC \
+  (gst_omx_wma_dec_get_type())
+#define GST_OMX_WMA_DEC(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_WMA_DEC,GstOMXWMADec))
+#define GST_OMX_WMA_DEC_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_WMA_DEC,GstOMXWMADecClass))
+#define GST_OMX_WMA_DEC_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_WMA_DEC,GstOMXWMADecClass))
+#define GST_IS_OMX_WMA_DEC(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_WMA_DEC))
+#define GST_IS_OMX_WMA_DEC_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_WMA_DEC))
+
+typedef struct _GstOMXWMADec GstOMXWMADec;
+typedef struct _GstOMXWMADecClass GstOMXWMADecClass;
+
+struct _GstOMXWMADec
+{
+  GstOMXAudioDec parent;
+  gint spf;
+};
+
+struct _GstOMXWMADecClass
+{
+  GstOMXAudioDecClass parent_class;
+};
+
+GType gst_omx_wma_dec_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_OMX_WMA_DEC_H__ */
diff --git a/omx/gstomxwmvdec.c b/omx/gstomxwmvdec.c
index 1475827..b47fbc6 100644
--- a/omx/gstomxwmvdec.c
+++ b/omx/gstomxwmvdec.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
  *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
+ * Copyright (C) 2017,2020 Renesas Electronics Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -29,11 +30,15 @@
 GST_DEBUG_CATEGORY_STATIC (gst_omx_wmv_dec_debug_category);
 #define GST_CAT_DEFAULT gst_omx_wmv_dec_debug_category
 
+#define SEQ_PARAM_BUF_SIZE 24
+
 /* prototypes */
 static gboolean gst_omx_wmv_dec_is_format_change (GstOMXVideoDec * dec,
     GstOMXPort * port, GstVideoCodecState * state);
 static gboolean gst_omx_wmv_dec_set_format (GstOMXVideoDec * dec,
     GstOMXPort * port, GstVideoCodecState * state);
+static GstFlowReturn gst_omx_wmv_dec_prepare_frame (GstOMXVideoDec * self,
+    GstVideoCodecFrame * frame);
 
 enum
 {
@@ -58,6 +63,8 @@ gst_omx_wmv_dec_class_init (GstOMXWMVDecClass * klass)
   videodec_class->is_format_change =
       GST_DEBUG_FUNCPTR (gst_omx_wmv_dec_is_format_change);
   videodec_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_wmv_dec_set_format);
+  videodec_class->prepare_frame =
+      GST_DEBUG_FUNCPTR (gst_omx_wmv_dec_prepare_frame);
 
   videodec_class->cdata.default_sink_template_caps = "video/x-wmv, "
       "width=(int) [1,MAX], " "height=(int) [1,MAX]";
@@ -96,3 +103,76 @@ gst_omx_wmv_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port,
 
   return ret;
 }
+
+static GstFlowReturn
+gst_omx_wmv_dec_prepare_frame (GstOMXVideoDec * dec, GstVideoCodecFrame * frame)
+{
+  GstFlowReturn ret = GST_FLOW_OK;
+  GstOMXWMVDec *self;
+  OMX_PARAM_PORTDEFINITIONTYPE port_def;
+  GstCaps *caps;
+  GstStructure *structure;
+  const gchar *fourcc;
+
+  self = GST_OMX_WMV_DEC (dec);
+
+  gst_omx_port_get_port_definition (dec->dec_in_port, &port_def);
+
+  caps = gst_pad_get_current_caps (GST_VIDEO_DECODER_SINK_PAD (dec));
+  structure = gst_caps_get_structure (caps, 0);
+  fourcc = gst_structure_get_string (structure, "format");
+
+  if (strncmp (fourcc, "WVC1", strlen ("WVC1")) == 0) {
+    GST_DEBUG_OBJECT (self, "Handling for VC-1 stream - Advanced profile");
+    self->advanced_profile = TRUE;
+  } else
+    self->advanced_profile = FALSE;
+  gst_caps_unref (caps);
+#ifdef USE_OMX_TARGET_RCAR
+  if (dec->codec_data) {
+    GstMapInfo info;
+    GstBuffer *codec_data;
+    guint32 *SeqHdrBuf;
+    guint8 *u8ptr;
+
+    if (!self->advanced_profile) {
+      /* Get Sequence Layer Data Structure send to MC before pushing frame
+       * in case Simple/Main profile
+       */
+      if (!gst_buffer_map (dec->codec_data, &info, GST_MAP_READ)) {
+        GST_ERROR_OBJECT (self, "Failed to create a gstbuffer mapping");
+        return GST_FLOW_ERROR;
+      }
+      SeqHdrBuf = (guint32 *) g_malloc (SEQ_PARAM_BUF_SIZE);
+      if (SeqHdrBuf == NULL) {
+        GST_ERROR_OBJECT (self, "Failed to g_malloc");
+        return GST_FLOW_ERROR;
+      }
+
+      /* create sequence header */
+      SeqHdrBuf[0] = 0xc5000000;
+      SeqHdrBuf[1] = 0x00000004;
+      u8ptr = (guint8 *) & SeqHdrBuf[2];
+      u8ptr[0] = info.data[0];
+      u8ptr[1] = info.data[1];
+      u8ptr[2] = info.data[2];
+      u8ptr[3] = info.data[3];
+      SeqHdrBuf[3] = port_def.format.video.nFrameHeight;
+      SeqHdrBuf[4] = port_def.format.video.nFrameWidth;
+      SeqHdrBuf[5] = 0x0000000c;
+
+      gst_buffer_unmap (dec->codec_data, &info);
+
+      codec_data = gst_buffer_new_wrapped (SeqHdrBuf, SEQ_PARAM_BUF_SIZE);
+
+      if (!gst_buffer_replace (&dec->codec_data, codec_data)) {
+        GST_ERROR_OBJECT (self, "Failed to replace analysed codec_data");
+        return GST_FLOW_ERROR;
+      }
+      gst_buffer_unref (codec_data);
+    }
+  }
+#endif
+
+  return ret;
+}
diff --git a/omx/gstomxwmvdec.h b/omx/gstomxwmvdec.h
index 9375dc5..3be2dc8 100644
--- a/omx/gstomxwmvdec.h
+++ b/omx/gstomxwmvdec.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
  *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
+ * Copyright (C) 2017,2020 Renesas Electronics Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -45,6 +46,7 @@ typedef struct _GstOMXWMVDecClass GstOMXWMVDecClass;
 struct _GstOMXWMVDec
 {
   GstOMXVideoDec parent;
+  gboolean advanced_profile;
 };
 
 struct _GstOMXWMVDecClass
diff --git a/omx/meson.build b/omx/meson.build
index b68cc55..2aff7a3 100644
--- a/omx/meson.build
+++ b/omx/meson.build
@@ -13,6 +13,7 @@ omx_sources = [
   'gstomxh264utils.c',
   'gstomxh263dec.c',
   'gstomxwmvdec.c',
+  'gstomxvp9dec.c',
   'gstomxmpeg4videoenc.c',
   'gstomxh264enc.c',
   'gstomxh263enc.c',
@@ -24,12 +25,14 @@ omx_sources = [
   'gstomxanalogaudiosink.c',
   'gstomxhdmiaudiosink.c',
   'gstomxmp3enc.c',
+  'gstomxwmadec.c',
 ]
 
 extra_c_args = []
 
 if have_omx_vp8
   omx_sources += 'gstomxvp8dec.c'
+  omx_sources += 'gstomxvp8enc.c'
 endif
 
 if have_omx_theora
@@ -48,6 +51,13 @@ if gstgl_dep.found()
   extra_c_args += ['-DGST_USE_UNSTABLE_API']
 endif
 
+if omx_target == 'rcar'
+  omx_sources += 'gstomxh265dec.c'
+  if have_mmngrbuf
+    optional_deps += lib_mmngrbuf
+  endif
+endif
+
 gstomx = library('gstomx',
   omx_sources,
   c_args : gst_omx_args + extra_c_args,
From 7770796772f39ce9115e9cc84c71d57475328ecf Mon Sep 17 00:00:00 2001
From: Son Lam <son.lam.ym@rvc.renesas.com>
Date: Tue, 29 Jan 2019 09:28:02 +0700
Subject: [PATCH] omxvideodec: don't drop frame if it contains header data

handle_frame() will drop frame until a sync point is found.
It is not wrong because frame cannot be decoded properly without
a sync point (I frame).
However, if the frame with header data (SPS, PPS) is discarded
completely and never appear again, video cannot be decoded at all.

Avoid this issue by not dropping header data frame.
Note that this only change the behaviour with video which have late
sync point.
Before this change, video cannot be decoded.
After this change, video can be decoded, but some early frames
before sync points can be decoded wrongly.

Signed-off-by: Hung Tran <hung.tran.jy@renesas.com>
Signed-off-by: Son Lam <son.lam.ym@rvc.renesas.com>
---
 omx/gstomxvideodec.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c
index 1dabfad..c5d5bf1 100644
--- a/omx/gstomxvideodec.c
+++ b/omx/gstomxvideodec.c
@@ -2523,7 +2523,8 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder,
   GST_DEBUG_OBJECT (self, "Handling frame");
 
   if (!self->started) {
-    if (!GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)) {
+    if (!GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame) &&
+        !GST_BUFFER_FLAG_IS_SET (frame->input_buffer, GST_BUFFER_FLAG_HEADER)) {
       gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
       return GST_FLOW_OK;
     }
-- 
2.7.4
From b02611adff81138dbe29c3d0ee888e74668e4ee9 Mon Sep 17 00:00:00 2001
From: Nhat Thieu <nhat.thieu.xr@renesas.com>
Date: Thu, 21 Jul 2022 19:12:59 +0700
Subject: [PATCH 1/3] Support Bypass mode

    In Bypass mode, OMX does not generate reconfigure signal.
    However, gstreamer needs reconfigure signal to allocate output buffer pool.
    This patch will help gstreamer allocate output buffer pool without reconfigure signal in Bypass mode only.

Signed-off-by: Nhat Thieu <nhat.thieu.xr@renesas.com>
---
 omx/gstomxvideodec.c | 142 ++++++++++++++++++++++++++++++++++++++++---
 omx/gstomxvideodec.h |   2 +
 2 files changed, 137 insertions(+), 7 deletions(-)

diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c
index ec3a1c3..a30e271 100644
--- a/omx/gstomxvideodec.c
+++ b/omx/gstomxvideodec.c
@@ -100,7 +100,8 @@ enum
   PROP_NO_COPY,
   PROP_NO_REORDER,
   PROP_LOSSY_COMPRESS,
-  PROP_ENABLE_CROP
+  PROP_ENABLE_CROP,
+  PROP_BYPASS
 };
 
 #define GST_OMX_VIDEO_DEC_INTERNAL_ENTROPY_BUFFERS_DEFAULT (5)
@@ -136,15 +137,30 @@ gst_omx_video_dec_set_property (GObject * object, guint prop_id,
       self->use_dmabuf = g_value_get_boolean (value);
       self->has_set_property = TRUE;
       break;
+    case PROP_ENABLE_CROP:
+      self->enable_crop = g_value_get_boolean (value);
+      break;
+#ifdef HAVE_VIDEODEC_EXT
     case PROP_NO_REORDER:
       self->no_reorder = g_value_get_boolean (value);
       break;
     case PROP_LOSSY_COMPRESS:
       self->lossy_compress = g_value_get_boolean (value);
       break;
-    case PROP_ENABLE_CROP:
-      self->enable_crop = g_value_get_boolean (value);
+    case PROP_BYPASS:
+      self->bypass = g_value_get_boolean (value);
+      break;
+#else
+    case PROP_NO_REORDER:
+      GST_WARNING_OBJECT (self, "HAVE_VIDEODEC_EXT not enabled. Couldn't configure property no-reorder (require vendor specific implement).\n");
+      break;
+    case PROP_LOSSY_COMPRESS:
+      GST_WARNING_OBJECT (self, "HAVE_VIDEODEC_EXT not enabled. Couldn't configure property lossy-compress (require vendor specific implement).\n");
+      break;
+    case PROP_BYPASS:
+      GST_WARNING_OBJECT (self, "HAVE_VIDEODEC_EXT not enabled. Couldn't configure property bypass (require vendor specific implement).\n");
       break;
+#endif
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -178,6 +194,9 @@ gst_omx_video_dec_get_property (GObject * object, guint prop_id,
     case PROP_ENABLE_CROP:
       g_value_set_boolean (value, self->enable_crop);
       break;
+    case PROP_BYPASS:
+      g_value_set_boolean (value, self->bypass);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -233,6 +252,12 @@ gst_omx_video_dec_class_init (GstOMXVideoDecClass * klass)
           "Whether or not to enable cropping if there is cropping information on SPS",
           FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
           GST_PARAM_MUTABLE_READY));
+  g_object_class_install_property (gobject_class, PROP_BYPASS,
+      g_param_spec_boolean ("bypass",
+          "Use Bypass function",
+          "Whether or not to use Bypass mode in OMX",
+          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+          GST_PARAM_MUTABLE_READY));
 
   element_class->change_state =
       GST_DEBUG_FUNCPTR (gst_omx_video_dec_change_state);
@@ -278,6 +303,7 @@ gst_omx_video_dec_init (GstOMXVideoDec * self)
   self->lossy_compress = FALSE;
   self->has_set_property = FALSE;
   self->enable_crop = FALSE;
+  self->bypass = FALSE;
 
   gst_video_decoder_set_packetized (GST_VIDEO_DECODER (self), TRUE);
   gst_video_decoder_set_use_default_pad_acceptcaps (GST_VIDEO_DECODER_CAST
@@ -1630,7 +1656,74 @@ enable_port:
     goto done;
 
 done:
+  return err;
+}
+
+/* Allocate and configure output buffers for Bypass mode */
+static OMX_ERRORTYPE
+gst_omx_video_dec_configure_bypass (GstOMXVideoDec * self)
+{
+  GstOMXPort *port;
+  OMX_ERRORTYPE err;
+  GstVideoCodecState *state;
+  OMX_PARAM_PORTDEFINITIONTYPE port_def;
+  GstVideoFormat format;
+  GstOMXVideoDecClass *klass = GST_OMX_VIDEO_DEC_GET_CLASS (self);
+
+  port = self->dec_out_port;
+
+  /* Update caps */
+  GST_VIDEO_DECODER_STREAM_LOCK (self);
+
+  gst_omx_port_get_port_definition (port, &port_def);
+  g_assert (port_def.format.video.eCompressionFormat == OMX_VIDEO_CodingUnused);
+
+  format =
+      gst_omx_video_get_format_from_omx (port_def.format.video.eColorFormat);
+
+  if (format == GST_VIDEO_FORMAT_UNKNOWN) {
+    GST_ERROR_OBJECT (self, "Unsupported color format: %d",
+        port_def.format.video.eColorFormat);
+    GST_VIDEO_DECODER_STREAM_UNLOCK (self);
+    err = OMX_ErrorUndefined;
+    goto done;
+  }
 
+  GST_DEBUG_OBJECT (self,
+      "Setting output state: format %s (%d), width %u, height %u",
+      gst_video_format_to_string (format),
+      port_def.format.video.eColorFormat,
+      (guint) port_def.format.video.nFrameWidth,
+      (guint) port_def.format.video.nFrameHeight);
+
+  state = gst_video_decoder_set_output_state (GST_VIDEO_DECODER (self),
+      format, port_def.format.video.nFrameWidth,
+      port_def.format.video.nFrameHeight, self->input_state);
+
+  if (klass->cdata.hacks & GST_OMX_HACK_DEFAULT_PIXEL_ASPECT_RATIO) {
+    /* Set pixel-aspect-ratio is 1/1. It means that always keep
+     * original image when display   */
+    state->info.par_d = state->info.par_n;
+  }
+
+  if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
+    gst_video_codec_state_unref (state);
+    GST_ERROR_OBJECT (self, "Failed to negotiate");
+    err = OMX_ErrorUndefined;
+    GST_VIDEO_DECODER_STREAM_UNLOCK (self);
+    goto done;
+  }
+
+  gst_video_codec_state_unref (state);
+
+  GST_VIDEO_DECODER_STREAM_UNLOCK (self);
+
+  err = gst_omx_video_dec_allocate_output_buffers (self);
+  if (err != OMX_ErrorNone) {
+    goto done;
+  }
+
+done:
   return err;
 }
 
@@ -2686,8 +2779,16 @@ gst_omx_video_dec_enable (GstOMXVideoDec * self, GstBuffer * input)
       /* Need to allocate buffers to reach Idle state */
       if (!gst_omx_video_dec_allocate_in_buffers (self))
         return FALSE;
-      if (gst_omx_port_allocate_buffers (self->dec_out_port) != OMX_ErrorNone)
-        return FALSE;
+
+      if (self->bypass) {
+        /* In G2L Bypass mode, allocate output buffers here instead
+         * of waiting for Event PortSettingChanged */
+        if (gst_omx_video_dec_configure_bypass(self))
+          return FALSE;
+      } else {
+        if (gst_omx_port_allocate_buffers (self->dec_out_port) != OMX_ErrorNone)
+          return FALSE;
+      }
     }
 
     if (gst_omx_component_get_state (self->dec,
@@ -2917,6 +3018,27 @@ gst_omx_video_dec_set_format (GstVideoDecoder * decoder,
     gst_omx_component_set_parameter (self->dec,
         OMXR_MC_IndexParamVideoLossyCompression, &sLossy);
   }
+
+  if (!needs_disable) {
+    /* Setting bypass mode (output port) */
+    OMXR_MC_VIDEO_PARAM_BYPASS_POSTPROCESSINGTYPE sBypass;
+    GST_OMX_INIT_STRUCT (&sBypass);
+    sBypass.nPortIndex = self->dec_out_port->index;
+
+    if (self->bypass == TRUE)
+      sBypass.bEnable = OMX_TRUE;
+    else
+      sBypass.bEnable = OMX_FALSE;
+
+    gst_omx_component_set_parameter (self->dec,
+        OMXR_MC_IndexParamVideoBypassPostprocessing, &sBypass);
+    gst_omx_component_get_parameter (self->dec,
+        OMXR_MC_IndexParamVideoBypassPostprocessing, &sBypass);
+    if (self->bypass != sBypass.bEnable) {
+      GST_WARNING_OBJECT (self, "Could not set Bypass mode");
+      self->bypass = sBypass.bEnable;
+    }
+  }
 #else
   if (self->no_reorder != FALSE)
     GST_ERROR_OBJECT (self,
@@ -2940,8 +3062,14 @@ gst_omx_video_dec_set_format (GstVideoDecoder * decoder,
       out_port_def.format.video.nStride = 192;
       out_port_def.format.video.nSliceHeight = 192;
     } else {
-      out_port_def.format.video.nStride = 128;
-      out_port_def.format.video.nSliceHeight = 128;
+      if (self->bypass) {
+        /* In G2L Bypass mode, OMX will not send Event PortSettingChanged
+         * so application has to set parameters for output port manually */
+        out_port_def.format.video.nFrameWidth =  info->width;
+        out_port_def.format.video.nFrameHeight =  info->height;
+        out_port_def.format.video.nStride = (info->width+127)/128*128;
+        out_port_def.format.video.nSliceHeight = (info->height+15)/16*16;
+      }
     }
 
     if (gst_omx_port_update_port_definition (self->dec_out_port,
diff --git a/omx/gstomxvideodec.h b/omx/gstomxvideodec.h
index 06645ee..4c8010f 100644
--- a/omx/gstomxvideodec.h
+++ b/omx/gstomxvideodec.h
@@ -121,6 +121,8 @@ struct _GstOMXVideoDec
   gboolean has_set_property;
   /* Set TRUE to crop as info of conf_win_left_offset and conf_win_top_offset */
   gboolean enable_crop;
+  /* Set TRUE to use Bypass mode in OMX */
+  gboolean bypass;
 };
 
 struct _GstOMXVideoDecClass
-- 
2.25.1

From ecdeb8231f40361d229bb6799deb3ad72be3ee36 Mon Sep 17 00:00:00 2001
From: Nhat Thieu <nhat.thieu.xr@renesas.com>
Date: Thu, 21 Jul 2022 19:17:31 +0700
Subject: [PATCH 2/3] Fix error Resolution do not match in running case fill
 buffer

This error can happen because port_def is not updated in gst_omx_video_dec_loop before run gst_omx_video_dec_fill_buffer.
This patch fixed that error.

Signed-off-by: Nhat Thieu <nhat.thieu.xr@renesas.com>
---
 omx/gstomxvideodec.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c
index a30e271..0ff1591 100644
--- a/omx/gstomxvideodec.c
+++ b/omx/gstomxvideodec.c
@@ -1930,7 +1930,7 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self)
   if (!gst_pad_has_current_caps (GST_VIDEO_DECODER_SRC_PAD (self)) ||
       acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) {
     GstVideoCodecState *state;
-    OMX_PARAM_PORTDEFINITIONTYPE port_def;
+    OMX_PARAM_PORTDEFINITIONTYPE *port_def = &self->dec_out_port->port_def;
     GstVideoFormat format;
 
     GST_DEBUG_OBJECT (self, "Port settings have changed, updating caps");
@@ -1963,17 +1963,17 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self)
       /* Just update caps */
       GST_VIDEO_DECODER_STREAM_LOCK (self);
 
-      gst_omx_port_get_port_definition (port, &port_def);
-      g_assert (port_def.format.video.eCompressionFormat ==
+      gst_omx_port_get_port_definition (port, port_def);
+      g_assert (port_def->format.video.eCompressionFormat ==
           OMX_VIDEO_CodingUnused);
 
       format =
-          gst_omx_video_get_format_from_omx (port_def.format.video.
+          gst_omx_video_get_format_from_omx (port_def->format.video.
           eColorFormat);
 
       if (format == GST_VIDEO_FORMAT_UNKNOWN) {
         GST_ERROR_OBJECT (self, "Unsupported color format: %d",
-            port_def.format.video.eColorFormat);
+            port_def->format.video.eColorFormat);
         if (buf)
           gst_omx_port_release_buffer (port, buf);
         GST_VIDEO_DECODER_STREAM_UNLOCK (self);
@@ -1983,13 +1983,13 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self)
       GST_DEBUG_OBJECT (self,
           "Setting output state: format %s (%d), width %u, height %u",
           gst_video_format_to_string (format),
-          port_def.format.video.eColorFormat,
-          (guint) port_def.format.video.nFrameWidth,
-          (guint) port_def.format.video.nFrameHeight);
+          port_def->format.video.eColorFormat,
+          (guint) port_def->format.video.nFrameWidth,
+          (guint) port_def->format.video.nFrameHeight);
 
       state = gst_video_decoder_set_output_state (GST_VIDEO_DECODER (self),
-          format, port_def.format.video.nFrameWidth,
-          port_def.format.video.nFrameHeight, self->input_state);
+          format, port_def->format.video.nFrameWidth,
+          port_def->format.video.nFrameHeight, self->input_state);
 
       /* Take framerate and pixel-aspect-ratio from sinkpad caps */
       if (klass->cdata.hacks & GST_OMX_HACK_DEFAULT_PIXEL_ASPECT_RATIO) {
-- 
2.25.1

From 57c38d1e4cbec3c4616b42cf425c4d8cb4ef5336 Mon Sep 17 00:00:00 2001
From: Nhat Thieu <nhat.thieu.xr@renesas.com>
Date: Thu, 21 Jul 2022 18:05:30 +0700
Subject: [PATCH 3/3] Add lossy compress option

Lossy compress option: suppporting customer on/off lossy conpress property.

Signed-off-by: Nhat Thieu <nhat.thieu.xr@renesas.com>
---
 meson.build          | 12 ++++++++++++
 meson_options.txt    |  2 ++
 omx/gstomxvideodec.c |  4 ++++
 3 files changed, 18 insertions(+)

diff --git a/meson.build b/meson.build
index c48c19a..c6ca601 100644
--- a/meson.build
+++ b/meson.build
@@ -170,6 +170,11 @@ else
   omx_inc = include_directories (join_paths ('omx', 'openmax'))
 endif
 
+lossy_compress = get_option('with_lossy_compress')
+if  lossy_compress
+   cdata.set('HAVE_LOSSY_COMPRESS', 1)
+endif
+
 default_omx_struct_packing = 0
 omx_target = get_option ('target')
 if omx_target == 'generic'
@@ -239,6 +244,13 @@ elif omx_target == 'rcar'
     cdata.set ('HAVE_VP8ENC_EXT', 1)
   endif
 
+  # check OMXR_Extension_vp8e.h
+  if cc.has_header (
+    'OMXR_Extension_vdcmn.h',
+    args : gst_omx_args)
+    cdata.set ('HAVE_VIDEODEC_EXT', 1)
+  endif
+
   # check OMXR_Extension_aapd.h
   if cc.has_header (
       'OMXR_Extension_aapd.h',
diff --git a/meson_options.txt b/meson_options.txt
index 0afb142..3716507 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,5 +1,7 @@
 option('header_path', type : 'string', value : '',
     description : 'An extra include directory to find the OpenMax headers')
+option('with_lossy_compress', type : 'boolean', value : false,
+    description : 'Whether or not to support lossy compress property')
 option('target', type : 'combo',
     choices : ['none', 'generic', 'rpi', 'bellagio', 'tizonia', 'zynqultrascaleplus', 'rcar'], value : 'none',
     description : 'The OMX platform to target')
diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c
index 0ff1591..b35dfe1 100644
--- a/omx/gstomxvideodec.c
+++ b/omx/gstomxvideodec.c
@@ -144,9 +144,11 @@ gst_omx_video_dec_set_property (GObject * object, guint prop_id,
     case PROP_NO_REORDER:
       self->no_reorder = g_value_get_boolean (value);
       break;
+#ifdef HAVE_LOSSY_COMPRESS
     case PROP_LOSSY_COMPRESS:
       self->lossy_compress = g_value_get_boolean (value);
       break;
+#endif
     case PROP_BYPASS:
       self->bypass = g_value_get_boolean (value);
       break;
@@ -3004,6 +3006,7 @@ gst_omx_video_dec_set_format (GstVideoDecoder * decoder,
         &sReorder);
   }
 
+#ifdef HAVE_LOSSY_COMPRESS
   if (!needs_disable) {
     /* Setting lossy compression mode (output port) */
     OMXR_MC_VIDEO_PARAM_LOSSY_COMPRESSIONTYPE sLossy;
@@ -3018,6 +3021,7 @@ gst_omx_video_dec_set_format (GstVideoDecoder * decoder,
     gst_omx_component_set_parameter (self->dec,
         OMXR_MC_IndexParamVideoLossyCompression, &sLossy);
   }
+#endif
 
   if (!needs_disable) {
     /* Setting bypass mode (output port) */
-- 
2.25.1

From 92c7a1700640c87a4220219c916a3117b4cee0fc Mon Sep 17 00:00:00 2001
From: trungvanle <trung.le.xk@renesas.com>
Date: Thu, 10 Nov 2022 23:59:50 +0700
Subject: [PATCH] gst-pipeline cannot corectly decode with vspmfilter and
 filesink/fakesink

The error conditions are that:
	1. Videosink is fakesink or filesink
	2. Using vspmfilter in dmabuf-use, or outbuf-alloc mode
	3. Do not scale
	4. Output video format has 2 or 3 planes

In above conditions, the API "GST_VIDEO_META_API_TYPE" is not added to query from downstream.
This means that omxh264dec will not set "GST_BUFFER_POOL_OPTION_VIDEO_META" config to
buffer pool when allocating output buffers. As a result, the buffers are sent to
vspmfilter from omxh264dec which maps by buffermap instead of framemap. Hence, if the
video format has 2 or 3 planes, the mapping will be incorrect. Because of wrong address,
it causes 2 difference phenomena on RZG2L and RZG2 series:
	1. RZG2L: Error -412 will be output if use fakesink/filesink
	2. RZG2 series: Output file will be wrong if use filesink

-> Solution: Flag GST_BUFFER_POOL_OPTION_VIDEO_META will be added to the buffer pool as
default to ensure that framemap is always being used to map the buffers instead of buffermap
in case that framemap is required from downstream. Based on meta information, the buffer is mapped
correctly. So the error will be fixed

Signed-off-by: trungvanle <trung.le.xk@renesas.com>
---
 omx/gstomxvideodec.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c
index b35dfe1..08a26fd 100644
--- a/omx/gstomxvideodec.c
+++ b/omx/gstomxvideodec.c
@@ -3749,10 +3749,15 @@ gst_omx_video_dec_decide_allocation (GstVideoDecoder * bdec, GstQuery * query)
   g_assert (pool != NULL);
 
   config = gst_buffer_pool_get_config (pool);
-  if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) {
-    gst_buffer_pool_config_add_option (config,
-        GST_BUFFER_POOL_OPTION_VIDEO_META);
-  }
+
+  /* The GST_BUFFER_POOL_OPTION_VIDEO_META config must be set 
+   * to buffer pool in order to always add videometa to buffers and then
+   * map buffers using frame map. 
+   *
+   * Frame map should be used instead of buffer map because it will map the
+   * buffer correctly based on the meta information.*/
+  gst_buffer_pool_config_add_option (config,
+      GST_BUFFER_POOL_OPTION_VIDEO_META);
   gst_buffer_pool_set_config (pool, config);
   gst_object_unref (pool);
 
-- 
2.17.1

From 0e76d00beebc84982c6d01eedccc84677d38e65e Mon Sep 17 00:00:00 2001
From: trungvanle <trung.le.xk@renesas.com>
Date: Mon, 31 Jul 2023 13:55:05 +0700
Subject: [PATCH] Add number of output buffers option

Bypass mode has limitation with B-frames when reorder. This option is
added to solve this limitation.
Please note that this option is also supported in other modes.

Signed-off-by: trungvanle <trung.le.xk@renesas.com>
---
 omx/gstomxvideodec.c | 35 ++++++++++++++++++++++++++++++++---
 omx/gstomxvideodec.h |  2 ++
 2 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c
index 08a26fd..76cc618 100644
--- a/omx/gstomxvideodec.c
+++ b/omx/gstomxvideodec.c
@@ -101,10 +101,13 @@ enum
   PROP_NO_REORDER,
   PROP_LOSSY_COMPRESS,
   PROP_ENABLE_CROP,
-  PROP_BYPASS
+  PROP_BYPASS,
+  PROP_NUM_OUTPUT_BUFFER
 };
 
 #define GST_OMX_VIDEO_DEC_INTERNAL_ENTROPY_BUFFERS_DEFAULT (5)
+#define GST_OMX_VIDEO_DEC_NUMBER_OUTPUT_BUFFERS_DEFAULT    (0)
+#define GST_OMX_VIDEO_DEC_NUMBER_OUTPUT_BUFFERS_MAXIMUM    (32)
 
 /* class initialization */
 
@@ -152,6 +155,9 @@ gst_omx_video_dec_set_property (GObject * object, guint prop_id,
     case PROP_BYPASS:
       self->bypass = g_value_get_boolean (value);
       break;
+    case PROP_NUM_OUTPUT_BUFFER:
+      self->num_outbufs = g_value_get_uint (value);
+      break;
 #else
     case PROP_NO_REORDER:
       GST_WARNING_OBJECT (self, "HAVE_VIDEODEC_EXT not enabled. Couldn't configure property no-reorder (require vendor specific implement).\n");
@@ -199,6 +205,9 @@ gst_omx_video_dec_get_property (GObject * object, guint prop_id,
     case PROP_BYPASS:
       g_value_set_boolean (value, self->bypass);
       break;
+    case PROP_NUM_OUTPUT_BUFFER:
+      g_value_set_uint (value, self->num_outbufs);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -260,6 +269,14 @@ gst_omx_video_dec_class_init (GstOMXVideoDecClass * klass)
           "Whether or not to use Bypass mode in OMX",
           FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
           GST_PARAM_MUTABLE_READY));
+   g_object_class_install_property (gobject_class, PROP_NUM_OUTPUT_BUFFER,
+      g_param_spec_uint ("num-outbufs",
+          "Number of output buffers",
+          "Number of buffers that are required on output port",
+          0, GST_OMX_VIDEO_DEC_NUMBER_OUTPUT_BUFFERS_MAXIMUM,
+          GST_OMX_VIDEO_DEC_NUMBER_OUTPUT_BUFFERS_DEFAULT,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+          GST_PARAM_MUTABLE_READY));
 
   element_class->change_state =
       GST_DEBUG_FUNCPTR (gst_omx_video_dec_change_state);
@@ -306,6 +323,9 @@ gst_omx_video_dec_init (GstOMXVideoDec * self)
   self->has_set_property = FALSE;
   self->enable_crop = FALSE;
   self->bypass = FALSE;
+  /* The default value is 0, which means the number of output buffers will be
+   * automatically updated when allocated */
+  self->num_outbufs = GST_OMX_VIDEO_DEC_NUMBER_OUTPUT_BUFFERS_DEFAULT;
 
   gst_video_decoder_set_packetized (GST_VIDEO_DECODER (self), TRUE);
   gst_video_decoder_set_use_default_pad_acceptcaps (GST_VIDEO_DECODER_CAST
@@ -899,6 +919,7 @@ gst_omx_video_dec_allocate_output_buffers (GstOMXVideoDec * self)
   gboolean eglimage = FALSE, add_videometa = FALSE;
   GstCaps *caps = NULL;
   guint min = 0, max = 0;
+  guint min_outbuf = 0;
   GstVideoCodecState *state =
       gst_video_decoder_get_output_state (GST_VIDEO_DECODER (self));
 
@@ -926,8 +947,16 @@ gst_omx_video_dec_allocate_output_buffers (GstOMXVideoDec * self)
       goto done;
     }
 
-    /* Need at least 4 buffers for anything meaningful */
-    min = MAX (min + port->port_def.nBufferCountMin, 4);
+    /* Need at least 4 buffers for anything meaningful but Bypass mode need
+     * at least 5 buffers */
+    min_outbuf = self->bypass ? 5 : 4;
+    if (self->num_outbufs)
+      min = MAX (min + port->port_def.nBufferCountMin,
+                 (self->num_outbufs > min_outbuf) ?
+                  self->num_outbufs : min_outbuf);
+    else
+      min = MAX (min + port->port_def.nBufferCountMin, min_outbuf);
+
     if (max == 0) {
       max = min;
     } else if (max < min) {
diff --git a/omx/gstomxvideodec.h b/omx/gstomxvideodec.h
index 4c8010f..879c03b 100644
--- a/omx/gstomxvideodec.h
+++ b/omx/gstomxvideodec.h
@@ -123,6 +123,8 @@ struct _GstOMXVideoDec
   gboolean enable_crop;
   /* Set TRUE to use Bypass mode in OMX */
   gboolean bypass;
+  /* Number of output buffers that are required on output port */
+  guint32 num_outbufs;
 };
 
 struct _GstOMXVideoDecClass
-- 
2.25.1

From aca1b3f2ea3ff8918038d6944ec728c2d4efceec Mon Sep 17 00:00:00 2001
From: trungvanle <trung.le.xk@renesas.com>
Date: Fri, 8 Sep 2023 11:43:48 +0700
Subject: [PATCH] Set output framerate same as input framerate

Need to set input framerate same as output framerate for accurate
target bitrate calculation. So, this patch will set output
framerate of VUI property to match input framerate from caps.

Signed-off-by: trungvanle <trung.le.xk@renesas.com>
---
 omx/gstomxvideoenc.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c
index e19a29e..5360518 100644
--- a/omx/gstomxvideoenc.c
+++ b/omx/gstomxvideoenc.c
@@ -36,6 +36,7 @@
 #if defined (HAVE_MMNGRBUF) && defined (HAVE_VIDEOR_EXT)
 #include "mmngr_buf_user_public.h"
 #include "OMXR_Extension_video.h"
+#include "OMXR_Extension_h264e.h"
 #endif
 
 #ifdef USE_OMX_TARGET_RPI
@@ -2655,6 +2656,40 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder,
     port_def.format.video.xFramerate =
         gst_omx_video_calculate_framerate_q16 (info);
 
+#if defined (HAVE_VIDEOR_EXT)
+  {
+    OMX_ERRORTYPE err;
+    OMXR_MC_VIDEO_PARAM_AVC_VUI_PROPERTY vui_param;
+
+    GST_OMX_INIT_STRUCT (&vui_param);
+
+    if (info->fps_n) {
+      err = gst_omx_component_get_parameter(self->enc, OMXR_MC_IndexParamVideoAVCVuiProperty,
+          &vui_param);
+      if (err == OMX_ErrorUnsupportedSetting) {
+        GST_WARNING_OBJECT (self,
+            "Settings of VUI not supported by the component");
+      } else if (err != OMX_ErrorNone) {
+        GST_ERROR_OBJECT (self,
+            "Failed to get vui propety: %s (0x%08x)",
+            gst_omx_error_to_string (err), err);
+      } else {
+        vui_param.bFixedFrameRateFlag = TRUE;
+        vui_param.bTimingInfoPresentFlag = TRUE;
+        vui_param.u32NumUnitsInTick = info->fps_d;
+        vui_param.u32TimeScale = info->fps_n * 2;
+        err = gst_omx_component_set_parameter(self->enc, OMXR_MC_IndexParamVideoAVCVuiProperty,
+            &vui_param);
+        if (err != OMX_ErrorNone) {
+          GST_ERROR_OBJECT (self,
+              "Failed to set vui propety: %s (0x%08x)",
+              gst_omx_error_to_string (err), err);
+        }
+      }
+    }
+  }
+#endif
+
   GST_DEBUG_OBJECT (self, "Setting inport port definition");
   if (!gst_omx_video_enc_update_input_port (self, port_def, info->width,
           info->height))
-- 
2.25.1

From bc7cbc04a77b81b1ec1fd522b8f19329c48c5a0c Mon Sep 17 00:00:00 2001
From: Kiet Pham <kiet.pham.xb@renesas.com>
Date: Thu, 21 Dec 2023 15:35:12 +0700
Subject: [PATCH] Fix error Adaptive playback ignores user settings

In streaming use case, if sender stops the current video stream and change to
the new one with different format, receiver will create new OMX component with
default configurations.

If user settings are different to default, this phenomenon will create
unexpected output. So, we need to update user settings every time
that receiver detects any format change.

Signed-off-by: Kiet Pham <kiet.pham.xb@renesas.com>
---
 omx/gstomxvideodec.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c
index 8ea4db9..e09129d 100644
--- a/omx/gstomxvideodec.c
+++ b/omx/gstomxvideodec.c
@@ -3020,7 +3020,7 @@ gst_omx_video_dec_set_format (GstVideoDecoder * decoder,
     }
   }
 #ifdef HAVE_VIDEODEC_EXT
-  if (!needs_disable) {
+  if (!self->disabled) {
     /* Setting reorder mode (output port only) */
     OMXR_MC_VIDEO_PARAM_REORDERTYPE sReorder;
     GST_OMX_INIT_STRUCT (&sReorder);
@@ -3036,7 +3036,7 @@ gst_omx_video_dec_set_format (GstVideoDecoder * decoder,
   }
 
 #ifdef HAVE_LOSSY_COMPRESS
-  if (!needs_disable) {
+  if (!self->disabled) {
     /* Setting lossy compression mode (output port) */
     OMXR_MC_VIDEO_PARAM_LOSSY_COMPRESSIONTYPE sLossy;
     GST_OMX_INIT_STRUCT (&sLossy);
@@ -3052,7 +3052,7 @@ gst_omx_video_dec_set_format (GstVideoDecoder * decoder,
   }
 #endif
 
-  if (!needs_disable) {
+  if (!self->disabled) {
     /* Setting bypass mode (output port) */
     OMXR_MC_VIDEO_PARAM_BYPASS_POSTPROCESSINGTYPE sBypass;
     GST_OMX_INIT_STRUCT (&sBypass);
@@ -3084,7 +3084,7 @@ gst_omx_video_dec_set_format (GstVideoDecoder * decoder,
 
   GST_DEBUG_OBJECT (self, "Updating ports definition");
 #ifdef USE_OMX_TARGET_RCAR
-  if (!needs_disable) {
+  if (!self->disabled) {
     OMX_PARAM_PORTDEFINITIONTYPE out_port_def;
 
     /* Initialize default output allocation align for page size
-- 
2.17.1

From a62617f23fd0a27906b773848b4e4782996bcec9 Mon Sep 17 00:00:00 2001
From: trungvanle <trung.le.xk@renesas.com>
Date: Tue, 5 Mar 2024 16:15:54 +0700
Subject: [PATCH] Support updating stride and sliceheight using input buffer
 metadata

When using vspmfilter as upstream, the stride of output from vspmfilter may
round up due to ISU limitations. However, omxh264enc retrieves information from
caps and sets frame width as stride to input port that is not updated. This results
in wrong display output.
To solve this issue, we need to update stride and sliceheight based on input buffer
metadata provided from upstream when enabling component.
---
 omx/gstomxvideoenc.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c
index 5360518..211b81b 100644
--- a/omx/gstomxvideoenc.c
+++ b/omx/gstomxvideoenc.c
@@ -2082,7 +2082,6 @@ gst_omx_video_enc_ensure_nb_in_buffers (GstOMXVideoEnc * self)
   return TRUE;
 }
 
-#ifndef USE_OMX_TARGET_RCAR
 static gboolean
 gst_omx_video_enc_configure_input_buffer (GstOMXVideoEnc * self,
     GstBuffer * input)
@@ -2115,7 +2114,6 @@ gst_omx_video_enc_configure_input_buffer (GstOMXVideoEnc * self,
   return gst_omx_video_enc_update_input_port (self, port_def, stride,
       slice_height);
 }
-#endif
 
 static gboolean
 gst_omx_video_enc_allocate_in_buffers (GstOMXVideoEnc * self)
@@ -2418,10 +2416,8 @@ gst_omx_video_enc_enable (GstOMXVideoEnc * self, GstBuffer * input)
   }
 
   if (!self->in_pool_used) {
-#ifndef USE_OMX_TARGET_RCAR
     if (!gst_omx_video_enc_configure_input_buffer (self, input))
       return FALSE;
-#endif
 
     self->input_allocation = gst_omx_video_enc_pick_input_allocation_mode (self,
         input);
-- 
2.17.1
