[vlc-devel] [PATCH 10/11] Add KVA video output module for OS/2

Rémi Denis-Courmont remi at remlab.net
Thu Nov 10 21:33:08 CET 2011


Le dimanche 6 novembre 2011 11:58:29 KO Myung-Hun, vous avez écrit :
> +/*************************************************************************
> **** + * Manage: handle Sys events
> +
> **************************************************************************
> *** + * This function should be called regularly by video output thread. It
> returns + * a non null value if an error occurred.
> +
> **************************************************************************
> ***/ +static void Manage( vout_display_t *vd )
> +{
> +    vout_display_sys_t * sys = vd->sys;
> +
> +    /* Let a window procedure manage instead because if resizing a frame
> window +     * here, WM_SIZE is not sent to its child window.
> +     * Maybe, is this due to the different threads ? */
> +    WinPostMsg( sys->client, WM_VLC_MANAGE, 0, 0 );
> +}

I don't understand why you need this if you have a dedicated thread anyway. 
You should leave pf_manage to NULL.

> +
> +/*************************************************************************
> **** + * Control: control facility for the vout
> +
> **************************************************************************
> ***/ +static int Control( vout_display_t *vd, int query, va_list args ) +{
> +    vout_display_sys_t *sys = vd->sys;
> +
> +    switch (query)
> +    {
> +    case VOUT_DISPLAY_HIDE_MOUSE:
> +    {
> +        POINTL ptl;
> +
> +        WinQueryPointerPos( HWND_DESKTOP, &ptl );
> +        if( WinWindowFromPoint( HWND_DESKTOP, &ptl, TRUE ) == sys->client
> ) +        {
> +            WinShowPointer( HWND_DESKTOP, FALSE );
> +            sys->is_mouse_hidden = true;
> +        }
> +
> +        return VLC_SUCCESS;
> +    }
> +
> +    case VOUT_DISPLAY_CHANGE_FULLSCREEN:
> +    {
> +        vout_display_cfg_t cfg = *va_arg(args, const vout_display_cfg_t
> *); +
> +        if( sys->parent_window )
> +            vout_window_SetFullScreen(sys->parent_window,
> cfg.is_fullscreen); +        else
> +            sys->i_changes |= KVA_FULLSCREEN_CHANGE;

The way you use sys->i_changes does not seem thread-safe.

> +
> +        return VLC_SUCCESS;
> +    }
> +
> +    case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE:
> +    {
> +        const vout_display_cfg_t *cfg = va_arg(args, const
> vout_display_cfg_t *); +        bool  is_forced = va_arg(args, int);
> +
> +        if( is_forced )
> +        {
> +            if( sys->parent_window )
> +            {
> +                vout_window_SetSize(sys->parent_window,
> +                                    cfg->display.width,
> cfg->display.height); +
> +                /* Workaround :
> +                 * If changing aspect ratio after resizing a main window,
> +                 * an embedded window is misplaced. So reposition it,
> here. +                 */
> +                WinSetWindowPos( WinQueryWindow( sys->parent, QW_PARENT ),
> +                                 HWND_TOP, 0, 1, 0, 0, SWP_MOVE );
> +                WinSetWindowPos( WinQueryWindow( sys->parent, QW_PARENT ),
> +                                 HWND_TOP, 0, 0, 0, 0, SWP_MOVE );
> +            }
> +            else
> +            {
> +                sys->szlSize.cx = cfg->display.width;
> +                sys->szlSize.cy = cfg->display.height;
> +
> +                sys->i_changes |= KVA_SIZE_CHANGE;
> +            }
> +        }
> +
> +        return VLC_SUCCESS;
> +    }
> +
> +    case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
> +    case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
> +    {
> +        const video_format_t *source = va_arg(args, const video_format_t
> *); +
> +        if( query == VOUT_DISPLAY_CHANGE_SOURCE_ASPECT )
> +        {
> +            sys->kvas.ulAspectWidth  = ( int64_t )source->i_width *
> +                                       source->i_sar_num /
> source->i_sar_den; +            sys->kvas.ulAspectHeight =
> source->i_height;
> +        }
> +        else
> +        {
> +            sys->kvas.rclSrcRect.xLeft   = source->i_x_offset;
> +            sys->kvas.rclSrcRect.yTop    = source->i_y_offset;
> +            sys->kvas.rclSrcRect.xRight  = source->i_x_offset +
> +                                           source->i_visible_width;
> +            sys->kvas.rclSrcRect.yBottom = source->i_y_offset +
> +                                           source->i_visible_height;
> +        }
> +
> +        kvaSetup( &sys->kvas );
> +
> +        return VLC_SUCCESS;
> +    }
> +
> +    case VOUT_DISPLAY_RESET_PICTURES:
> +    case VOUT_DISPLAY_CHANGE_WINDOW_STATE:
> +    case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED:
> +    case VOUT_DISPLAY_CHANGE_ZOOM:
> +    case VOUT_DISPLAY_GET_OPENGL:
> +        /* TODO */
> +        break;
> +    }
> +
> +    msg_Err(vd, "Unsupported query(=%d) in vout display KVA", query);
> +    return VLC_EGENERIC;
> +}


> +static image_t *ImageCreate( int w, int h, vlc_fourcc_t i_chroma )
> +{
> +    int i_bpp;
> +    int i_chroma_shift;
> +    int size;
> +    image_t *p_image;
> +
> +    switch( i_chroma )
> +    {
> +        case VLC_CODEC_RGB15:
> +            i_bpp = 2;
> +            i_chroma_shift = 0;
> +            break;
> +
> +        case VLC_CODEC_RGB16:
> +            i_bpp = 2;
> +            i_chroma_shift = 0;
> +            break;
> +
> +        case VLC_CODEC_RGB24:
> +            i_bpp = 3;
> +            i_chroma_shift = 0;
> +            break;
> +
> +        case VLC_CODEC_YUYV:
> +            i_bpp = 2;
> +            i_chroma_shift = 0;
> +            break;
> +
> +        case VLC_CODEC_YV9:
> +            i_bpp = 1;
> +            i_chroma_shift = 2;
> +            break;
> +
> +        case VLC_CODEC_YV12:
> +        default:
> +            i_bpp = 1;
> +            i_chroma_shift = 1;
> +            break;
> +    }
> +
> +    size = h * w * i_bpp;
> +    if( i_chroma_shift )
> +        size += size >> ( i_chroma_shift << 1 ) << 1;
> +
> +    p_image = calloc( 1, sizeof( image_t ));
> +    if( !p_image )
> +        return NULL;
> +
> +    p_image->p = malloc( size );
> +    if( !p_image->p )
> +    {
> +        free( p_image );
> +
> +        return NULL;
> +    }
> +
> +    p_image->w = w;
> +    p_image->h = h;
> +    p_image->i_bpp = i_bpp;
> +    p_image->i_chroma_shift = i_chroma_shift;
> +
> +    p_image->data[ 0 ] = p_image->p;
> +    p_image->linesize[ 0 ] = w * i_bpp;
> +
> +    if( i_chroma_shift )
> +    {
> +        p_image->data[ 1 ] = p_image->data[ 0 ] + h * p_image->linesize[ 0
> ]; +        p_image->linesize[ 1 ] = p_image->linesize[ 0 ] >>
> i_chroma_shift; +
> +        p_image->data[ 2 ] = p_image->data[ 1 ] + ( h >> i_chroma_shift )
> * p_image->linesize[ 1 ]; +        p_image->linesize[ 2 ] =
> p_image->linesize[ 1 ];
> +    }
> +
> +    return p_image;
> +}
> +
> +static void ImageFree( image_t *p_image )
> +{
> +    free( p_image->p );
> +    free( p_image );
> +}
> +
> +static void ImageDisplay( image_t *p_image )
> +{
> +    PVOID p_kva_buffer;
> +    ULONG i_kva_bpl;
> +
> +    if (!kvaLockBuffer(&p_kva_buffer, &i_kva_bpl))
> +    {
> +        uint8_t *dst[ 3 ] = { NULL };
> +        int      dstStride[ 3 ] = { 0 };
> +        int      i_bpl, i_height;
> +
> +        /* Get packed or Y */
> +        dst[0]       = p_kva_buffer;
> +        dstStride[0] = i_kva_bpl;
> +
> +        i_bpl    = p_image->w * p_image->i_bpp;
> +        i_height = p_image->h;
> +
> +        /* Copy packed or Y */
> +        ImageCopy(dst[0], p_image->data[0], i_bpl, i_height,
> +                  dstStride[0], p_image->linesize[0]);
> +
> +        /* YV12 or YVU9 ? */
> +        if( p_image->i_chroma_shift )
> +        {
> +            /* Get V */
> +            dst[ 1 ]       = dst[ 0 ] + p_image->h * dstStride[ 0 ];
> +            dstStride[ 1 ] = dstStride[ 0 ] >> p_image->i_chroma_shift;
> +
> +            /* Get U */
> +            dst[ 2 ]       = dst[ 1 ] +
> +                           ( p_image->h >> p_image->i_chroma_shift ) *
> dstStride[ 1 ]; +            dstStride[ 2 ] = dstStride[ 1 ];
> +
> +            i_bpl >>= p_image->i_chroma_shift;
> +            i_height >>= p_image->i_chroma_shift;
> +
> +            /* Copy V */
> +            ImageCopy(dst[1], p_image->data[1], i_bpl, i_height,
> +                      dstStride[1], p_image->linesize[1]);
> +
> +            /* Copy U */
> +            ImageCopy(dst[2], p_image->data[2], i_bpl, i_height,
> +                      dstStride[2], p_image->linesize[2]);
> +        }

Ideally, you should copy the image from Render rather than Display.

In any case, you are going to copy the image to video buffers manually. So I 
don't see why you limit the picture pool to one single image. Nothing seems to 
prevent you from allocating more than one VLC picture. Laurent would know 
better, but I think a single picture is very suboptimal for decoding 
performance.

> +
> +        kvaUnlockBuffer();
> +    }
> +}

-- 
Rémi Denis-Courmont
http://www.remlab.net/
http://fi.linkedin.com/in/remidenis



More information about the vlc-devel mailing list