[vlc-devel] [PATCH 2/2] MediaCodec: use SSE copy function from the avcodec module if the CPU supports it.

Felix Abecassis felix.abecassis at gmail.com
Fri Oct 25 15:26:57 CEST 2013


---
 modules/codec/Makefile.am                |  7 +++--
 modules/codec/omxil/android_mediacodec.c | 10 +++++-
 modules/codec/omxil/omxil.c              |  2 +-
 modules/codec/omxil/omxil_utils.h        | 15 ++++++++-
 modules/codec/omxil/utils.c              | 52 +++++++++++++++++++++++++++++++-
 5 files changed, 79 insertions(+), 7 deletions(-)

diff --git a/modules/codec/Makefile.am b/modules/codec/Makefile.am
index 6e21d58..12f9f4a 100644
--- a/modules/codec/Makefile.am
+++ b/modules/codec/Makefile.am
@@ -317,12 +317,13 @@ libomxil_plugin_la_SOURCES = \
 	codec/omxil/utils.c codec/omxil/omxil_utils.h \
 	codec/h264_nal.h \
 	codec/omxil/qcom.c codec/omxil/qcom.h \
-	codec/omxil/omxil.c codec/omxil/omxil.h codec/omxil/omxil_core.c codec/omxil/omxil_core.h
+	codec/omxil/omxil.c codec/omxil/omxil.h codec/omxil/omxil_core.c codec/omxil/omxil_core.h \
+	video_chroma/copy.c
 libomxil_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/codec/omxil $(CFLAGS_omxil)
 libomxil_plugin_la_LIBADD = $(LIBDL)
 libomxil_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(codecdir)'
 
-libomxil_vout_plugin_la_SOURCES = codec/omxil/vout.c codec/omxil/omxil_core.c codec/omxil/utils.c codec/omxil/qcom.c
+libomxil_vout_plugin_la_SOURCES = codec/omxil/vout.c codec/omxil/omxil_core.c codec/omxil/utils.c codec/omxil/qcom.c video_chroma/copy.c
 libomxil_vout_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/codec/omxil $(CFLAGS_omxil_vout)
 libomxil_vout_plugin_la_LIBADD = $(LIBDL)
 libomxil_vout_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(codecdir)'
@@ -332,7 +333,7 @@ libiomx_plugin_la_CPPFLAGS = $(libomxil_plugin_la_CPPFLAGS) -DUSE_IOMX
 libiomx_plugin_la_LIBADD = $(libomxil_plugin_la_LIBADD)
 
 libmediacodec_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/codec/omxil
-libmediacodec_plugin_la_SOURCES = codec/omxil/android_mediacodec.c codec/omxil/utils.c
+libmediacodec_plugin_la_SOURCES = codec/omxil/android_mediacodec.c codec/omxil/utils.c video_chroma/copy.c
 
 codec_LTLIBRARIES += $(LTLIBomxil) $(LTLIBomxil_vout)
 EXTRA_LTLIBRARIES += libomxil_plugin.la libomxil_vout_plugin.la
diff --git a/modules/codec/omxil/android_mediacodec.c b/modules/codec/omxil/android_mediacodec.c
index d8cf09f..fb435b4 100644
--- a/modules/codec/omxil/android_mediacodec.c
+++ b/modules/codec/omxil/android_mediacodec.c
@@ -75,6 +75,8 @@ struct decoder_sys_t
 
     int started;
     int decoded;
+
+    ArchitectureSpecificCopyData architecture_specific_data;
 };
 
 enum Types
@@ -389,6 +391,7 @@ static void CloseDecoder(vlc_object_t *p_this)
     (*myVm)->DetachCurrentThread(myVm);
 
     free(p_sys->name);
+    ArchitectureSpecificCopyHooksDestroy(p_sys->pixel_format, &p_sys->architecture_specific_data);
     free(p_sys);
 }
 
@@ -422,7 +425,7 @@ static void GetOutput(decoder_t *p_dec, JNIEnv *env, picture_t **pp_pic, int loo
                 GetVlcChromaSizes(p_dec->fmt_out.i_codec, p_dec->fmt_out.video.i_width,
                                   p_dec->fmt_out.video.i_height, NULL, NULL, &chroma_div);
                 CopyOmxPicture(p_sys->pixel_format, p_pic, p_sys->slice_height, p_sys->stride,
-                               ptr, chroma_div);
+                               ptr, chroma_div, &p_sys->architecture_specific_data);
             }
             (*env)->CallVoidMethod(env, p_sys->codec, p_sys->release_output_buffer, index, false);
             jthrowable exception = (*env)->ExceptionOccurred(env);
@@ -452,6 +455,8 @@ static void GetOutput(decoder_t *p_dec, JNIEnv *env, picture_t **pp_pic, int loo
             msg_Dbg(p_dec, "output format changed: %.*s", format_len, format_ptr);
             (*env)->ReleaseStringUTFChars(env, format_string, format_ptr);
 
+            ArchitectureSpecificCopyHooksDestroy(p_sys->pixel_format, &p_sys->architecture_specific_data);
+
             int width           = GET_INTEGER(format, "width");
             int height          = GET_INTEGER(format, "height");
             p_sys->stride       = GET_INTEGER(format, "stride");
@@ -476,6 +481,9 @@ static void GetOutput(decoder_t *p_dec, JNIEnv *env, picture_t **pp_pic, int loo
                 p_sys->slice_height = height;
             if ((*env)->ExceptionOccurred(env))
                 (*env)->ExceptionClear(env);
+
+            ArchitectureSpecificCopyHooks(p_dec, p_sys->pixel_format, p_sys->slice_height,
+                                          p_sys->stride, &p_sys->architecture_specific_data);
             if (p_sys->pixel_format == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
                 p_sys->slice_height -= p_sys->crop_top/2;
                 /* Reset crop top/left here, since the offset parameter already includes this.
diff --git a/modules/codec/omxil/omxil.c b/modules/codec/omxil/omxil.c
index da86e23..3e4c104 100644
--- a/modules/codec/omxil/omxil.c
+++ b/modules/codec/omxil/omxil.c
@@ -1271,7 +1271,7 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
                                    p_pic, p_sys->out.definition.format.video.nSliceHeight,
                                    p_sys->out.i_frame_stride,
                                    p_header->pBuffer + p_header->nOffset,
-                                   p_sys->out.i_frame_stride_chroma_div);
+                                   p_sys->out.i_frame_stride_chroma_div, NULL);
             }
 
             if (p_pic)
diff --git a/modules/codec/omxil/omxil_utils.h b/modules/codec/omxil/omxil_utils.h
index 1a99dfc..6aa9e12 100644
--- a/modules/codec/omxil/omxil_utils.h
+++ b/modules/codec/omxil/omxil_utils.h
@@ -180,9 +180,22 @@ void PrintOmxEvent(vlc_object_t *p_this, OMX_EVENTTYPE event, OMX_U32 data_1,
 /*****************************************************************************
  * Picture utility functions
  *****************************************************************************/
+typedef struct ArchitectureSpecificCopyData
+{
+    void *data;
+} ArchitectureSpecificCopyData;
+
+void ArchitectureSpecificCopyHooks( decoder_t *p_dec, int i_color_format,
+                                    int i_slice_height, int i_src_stride,
+                                    ArchitectureSpecificCopyData *p_architecture_specific );
+
+void ArchitectureSpecificCopyHooksDestroy( int i_color_format,
+                                           ArchitectureSpecificCopyData *p_architecture_specific );
+
 void CopyOmxPicture( int i_color_format, picture_t *p_pic,
                      int i_slice_height,
-                     int i_src_stride, uint8_t *p_src, int i_chroma_div );
+                     int i_src_stride, uint8_t *p_src, int i_chroma_div,
+                     ArchitectureSpecificCopyData *p_architecture_specific );
 
 void CopyVlcPicture( decoder_t *, OMX_BUFFERHEADERTYPE *, picture_t * );
 
diff --git a/modules/codec/omxil/utils.c b/modules/codec/omxil/utils.c
index e4665c5..7913318 100644
--- a/modules/codec/omxil/utils.c
+++ b/modules/codec/omxil/utils.c
@@ -36,6 +36,7 @@
 
 #include "omxil.h"
 #include "qcom.h"
+#include "../../video_chroma/copy.h"
 
 /*****************************************************************************
  * Events utility functions
@@ -163,9 +164,47 @@ void PrintOmxEvent(vlc_object_t *p_this, OMX_EVENTTYPE event, OMX_U32 data_1,
 /*****************************************************************************
  * Picture utility functions
  *****************************************************************************/
+void ArchitectureSpecificCopyHooks( decoder_t *p_dec, int i_color_format,
+                                    int i_slice_height, int i_src_stride,
+                                    ArchitectureSpecificCopyData *p_architecture_specific )
+{
+    (void)i_slice_height;
+
+#ifdef CAN_COMPILE_SSE2
+    if( i_color_format == OMX_COLOR_FormatYUV420SemiPlanar && vlc_CPU_SSE2() )
+    {
+        copy_cache_t *p_surface_cache = malloc( sizeof(copy_cache_t) );
+        if( !p_surface_cache || CopyInitCache( p_surface_cache, i_src_stride ) )
+        {
+            free( p_surface_cache );
+            return;
+        }
+        p_architecture_specific->data = p_surface_cache;
+        p_dec->fmt_out.i_codec = VLC_CODEC_YV12;
+    }
+#endif
+}
+
+void ArchitectureSpecificCopyHooksDestroy( int i_color_format,
+                                           ArchitectureSpecificCopyData *p_architecture_specific )
+{
+    if (!p_architecture_specific->data)
+        return;
+#ifdef CAN_COMPILE_SSE2
+    if( i_color_format == OMX_COLOR_FormatYUV420SemiPlanar && vlc_CPU_SSE2() )
+    {
+        copy_cache_t *p_surface_cache = (copy_cache_t*)p_architecture_specific->data;
+        CopyCleanCache(p_surface_cache);
+    }
+#endif
+    free(p_architecture_specific->data);
+    p_architecture_specific->data = NULL;
+}
+
 void CopyOmxPicture( int i_color_format, picture_t *p_pic,
                      int i_slice_height,
-                     int i_src_stride, uint8_t *p_src, int i_chroma_div )
+                     int i_src_stride, uint8_t *p_src, int i_chroma_div,
+                     ArchitectureSpecificCopyData *p_architecture_specific )
 {
     uint8_t *p_dst;
     int i_dst_stride;
@@ -175,6 +214,17 @@ void CopyOmxPicture( int i_color_format, picture_t *p_pic,
         qcom_convert(p_src, p_pic);
         return;
     }
+#ifdef CAN_COMPILE_SSE2
+    if( i_color_format == OMX_COLOR_FormatYUV420SemiPlanar
+        && vlc_CPU_SSE2() && p_architecture_specific )
+    {
+        copy_cache_t *p_surface_cache = (copy_cache_t*)p_architecture_specific->data;
+        uint8_t *ppi_src_pointers[2] = { p_src, p_src + i_src_stride * i_slice_height };
+        size_t pi_src_strides[2] = { i_src_stride, i_src_stride };
+        CopyFromNv12( p_pic, ppi_src_pointers, pi_src_strides, i_src_stride, i_slice_height, p_surface_cache );
+        return;
+    }
+#endif
 
     for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
     {
-- 
1.8.3.2




More information about the vlc-devel mailing list