[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