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

Rafaël Carré funman at videolan.org
Tue Jan 1 22:43:05 CET 2013


Hello,

Le 01/01/2013 18:31, Edward Wang a écrit :
> 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 |  124 ++++++++++++++++++++++++++++-----
>  1 files changed, 106 insertions(+), 18 deletions(-)
> 
> diff --git a/modules/video_output/androidsurface.c b/modules/video_output/androidsurface.c
> index 1b757ee..57f2edd 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 SetupPictureRGB565( SurfaceInfo* p_surfaceInfo, picture_t *p_picture );
> +static void SetupPictureRGBX8888( SurfaceInfo* p_surfaceInfo, picture_t *p_picture );

I think RGB32 is much better than "RGBX8888", and RGB16 a bit better
than RGB565, especially since it's the names that VLC uses already.

> +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;

This is confusing me: YV12 or I420 ?

If the fastest path is asking for I420 because most codecs output I420,
then use "I420" everywhere, and leave a comment perhaps that we swap
buffers to write into a YV12 surface.

(From the comment I assume YV12 is I420 with U&V swapped, please correct
me if I'm wrong)

> +            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 = &SetupPictureRGB565;
> +            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 = &SetupPictureRGBX8888;
> +            break;
> +
> +        default:
> +            return VLC_EGENERIC;
> +            break;
> +    }
>      video_format_FixRgb(&fmt);
>  
>      /* Create the associated picture */
> @@ -251,6 +297,50 @@ static picture_pool_t *Pool(vout_display_t *vd, unsigned count) {
>      return sys->pool;
>  }
>  
> +static void SetupPictureRGB565( SurfaceInfo* p_surfaceInfo, picture_t *p_picture )
> +{
> +    p_picture->p->p_pixels = (uint8_t*)p_surfaceInfo->bits;
> +    p_picture->p->i_pitch = 2 * p_surfaceInfo->s;
> +    p_picture->p->i_lines = p_surfaceInfo->h;

Setting p_pixels and i_lines should be factored out of these 3 functions.

> +}
> +
> +static void SetupPictureRGBX8888( SurfaceInfo* p_surfaceInfo, picture_t *p_picture )
> +{
> +    p_picture->p->p_pixels = (uint8_t*)p_surfaceInfo->bits;
> +    p_picture->p->i_pitch = 4 * p_surfaceInfo->s;
> +    p_picture->p->i_lines = p_surfaceInfo->h;
> +}
> +
> +#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->p_pixels = (uint8_t*)p_surfaceInfo->bits;
> +    p_picture->p->i_pitch = i_stride;
> +    p_picture->p->i_lines = p_surfaceInfo->h;
> +
> +    /* 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;
> @@ -283,9 +373,7 @@ static int  AndroidLockSurface(picture_t *picture) {
>          return VLC_EGENERIC;
>      }
>  
> -    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;
>  }
> 




More information about the vlc-devel mailing list