[vlc-devel] [PATCH] androidsurface: setup format depending on surface format

Edward Wang edward.c.wang at compdigitec.com
Wed Jan 2 18:42:51 CET 2013


From: Rui Zhang <bbcallen at gmail.com>

Modified-by: Edward Wang <edward.c.wang at compdigitec.com>
Signed-off-by: Edward Wang <edward.c.wang at compdigitec.com>
---
 modules/video_output/androidsurface.c |  116 ++++++++++++++++++++++++++++-----
 1 files changed, 100 insertions(+), 16 deletions(-)

diff --git a/modules/video_output/androidsurface.c b/modules/video_output/androidsurface.c
index 1b757ee..ed9b741 100644
--- a/modules/video_output/androidsurface.c
+++ b/modules/video_output/androidsurface.c
@@ -46,6 +46,11 @@
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
+#define CHROMA_TEXT N_("Chroma used")
+#define CHROMA_LONGTEXT N_(\
+    "Force use of a specific chroma for output. Default is I420.")
+
+#define CFG_PREFIX "androidsurface-"
 
 static int  Open (vlc_object_t *);
 static void Close(vlc_object_t *);
@@ -57,6 +62,7 @@ vlc_module_begin()
     set_description(N_("Android Surface video output"))
     set_capability("vout display", 155)
     add_shortcut("androidsurface", "android")
+    add_string(CFG_PREFIX "chroma", NULL, CHROMA_TEXT, CHROMA_LONGTEXT, true)
     set_callbacks(Open, Close)
 vlc_module_end()
 
@@ -84,6 +90,17 @@ static void             Display(vout_display_t *, picture_t *, subpicture_t *);
 static int              Control(vout_display_t *, int, va_list);
 
 /* */
+typedef struct _SurfaceInfo {
+    uint32_t    w;
+    uint32_t    h;
+    uint32_t    s;
+    uint32_t    usage;
+    uint32_t    format;
+    uint32_t*   bits;
+    uint32_t    reserved[2];
+} SurfaceInfo;
+
+/* */
 struct vout_display_sys_t {
     picture_pool_t *pool;
     void *p_library;
@@ -93,22 +110,13 @@ struct vout_display_sys_t {
 
     picture_resource_t resource;
 
+    void (*pf_SetupPicture)( SurfaceInfo*, picture_t* );
+
     /* density */
     int i_sar_num;
     int i_sar_den;
 };
 
-/* */
-typedef struct _SurfaceInfo {
-    uint32_t    w;
-    uint32_t    h;
-    uint32_t    s;
-    uint32_t    usage;
-    uint32_t    format;
-    uint32_t*   bits;
-    uint32_t    reserved[2];
-} SurfaceInfo;
-
 struct picture_sys_t
 {
     void *surf;
@@ -119,6 +127,10 @@ struct picture_sys_t
 static int  AndroidLockSurface(picture_t *);
 static void AndroidUnlockSurface(picture_t *);
 
+static void SetupPictureRGB16( SurfaceInfo* p_surfaceInfo, picture_t *p_picture );
+static void SetupPictureRGB32( SurfaceInfo* p_surfaceInfo, picture_t *p_picture );
+static void SetupPictureYV12( SurfaceInfo* p_surfaceInfo, picture_t *p_picture );
+
 static vlc_mutex_t single_instance = VLC_STATIC_MUTEX;
 
 static inline void *LoadSurface(const char *psz_lib, vout_display_sys_t *sys) {
@@ -174,10 +186,44 @@ static int Open(vlc_object_t *p_this) {
 
     /* Setup chroma */
     video_format_t fmt = vd->fmt;
-    fmt.i_chroma = VLC_CODEC_RGB32;
-    fmt.i_rmask  = 0x000000ff;
-    fmt.i_gmask  = 0x0000ff00;
-    fmt.i_bmask  = 0x00ff0000;
+    char* psz_fcc = var_InheritString(vd, CFG_PREFIX "chroma");
+    vlc_fourcc_t requested_chroma;
+    if( !psz_fcc )
+        requested_chroma = VLC_CODEC_YV12;
+    else
+        requested_chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, psz_fcc);
+    switch( requested_chroma ) {
+        case VLC_CODEC_I420:
+        case VLC_CODEC_YV12:
+            msg_Dbg( vd, "ImageFormat.YV12" );
+            /* avoid swscale usage by asking for I420 instead since the
+             * vout already has code to swap the buffers */
+            fmt.i_chroma = VLC_CODEC_I420;
+            sys->pf_SetupPicture = &SetupPictureYV12;
+            break;
+
+        case VLC_CODEC_RGB16:
+            msg_Dbg( vd, "PixelFormat.RGB_565" );
+            fmt.i_chroma = VLC_CODEC_RGB16;
+            fmt.i_bmask = 0x0000001f;
+            fmt.i_gmask = 0x000007e0;
+            fmt.i_rmask = 0x0000f800;
+            sys->pf_SetupPicture = &SetupPictureRGB16;
+            break;
+
+        case VLC_CODEC_RGB32:
+            msg_Dbg( vd, "PixelFormat.RGBX_8888" );
+            fmt.i_chroma = VLC_CODEC_RGB32;
+            fmt.i_rmask  = 0x000000ff;
+            fmt.i_gmask  = 0x0000ff00;
+            fmt.i_bmask  = 0x00ff0000;
+            sys->pf_SetupPicture = &SetupPictureRGB32;
+            break;
+
+        default:
+            return VLC_EGENERIC;
+            break;
+    }
     video_format_FixRgb(&fmt);
 
     /* Create the associated picture */
@@ -251,6 +297,44 @@ static picture_pool_t *Pool(vout_display_t *vd, unsigned count) {
     return sys->pool;
 }
 
+static void SetupPictureRGB16( SurfaceInfo* p_surfaceInfo, picture_t *p_picture )
+{
+    p_picture->p->i_pitch = 2 * p_surfaceInfo->s;
+}
+
+static void SetupPictureRGB32( SurfaceInfo* p_surfaceInfo, picture_t *p_picture )
+{
+    p_picture->p->i_pitch = 4 * p_surfaceInfo->s;
+}
+
+#define ALIGN_16_PIXELS( x ) ( ( ( x ) + 15 ) / 16 * 16 )
+static void SetupPictureYV12( SurfaceInfo* p_surfaceInfo, picture_t *p_picture )
+{
+    /* according to document of android.graphics.ImageFormat.YV12 */
+    int i_stride = ALIGN_16_PIXELS( p_surfaceInfo->s );
+    int i_c_stride = ALIGN_16_PIXELS( i_stride / 2 );
+
+    p_picture->p->i_pitch = i_stride;
+
+    /* Fill chroma planes for planar YUV */
+    for( int n = 1; n < p_picture->i_planes; n++ )
+    {
+        const plane_t *o = &p_picture->p[n-1];
+        plane_t *p = &p_picture->p[n];
+
+        p->p_pixels = o->p_pixels + o->i_lines * o->i_pitch;
+        p->i_pitch  = i_c_stride;
+        p->i_lines  = p_picture->format.i_height / 2;
+    }
+
+    if( vlc_fourcc_AreUVPlanesSwapped( p_picture->format.i_chroma,
+                                       VLC_CODEC_YV12 ) ) {
+        uint8_t *p_tmp = p_picture->p[1].p_pixels;
+        p_picture->p[1].p_pixels = p_picture->p[2].p_pixels;
+        p_picture->p[2].p_pixels = p_tmp;
+    }
+}
+
 static int  AndroidLockSurface(picture_t *picture) {
     picture_sys_t *picsys = picture->p_sys;
     vout_display_sys_t *sys = picsys->sys;
@@ -284,8 +368,8 @@ static int  AndroidLockSurface(picture_t *picture) {
     }
 
     picture->p->p_pixels = (uint8_t*)info->bits;
-    picture->p->i_pitch = 4 * info->s;
     picture->p->i_lines = info->h;
+    sys->pf_SetupPicture( info, picture );
 
     return VLC_SUCCESS;
 }
-- 
1.7.5.4




More information about the vlc-devel mailing list