- Hardware YUV overlay (SDL) with real colors ;p It may suck for non

4:2:0 streams.
  - Removed vout code found in intf file to support fullscreen switching.
    Now only vout_SDL updates SDL data and intf only switch flags such as
    b_reopen_display and b_fullscreen in p_vout->p_sys.
  - Fixed a var name typo in input_programs.c which prevents vlc from
    compiling with --enable-debug option. (i_es_pid -> i_es_id :)

There's a segfault in the termination process due to sdl, I don't really
know what is the problem and I have to work today. Help me!

Good night suckers. I love you too :p
This commit is contained in:
Arnaud de Bossoreille de Ribou 2000-12-18 02:47:09 +00:00
parent 07672a422c
commit 9632f78e4e
4 changed files with 127 additions and 138 deletions

View File

@ -1,5 +1,7 @@
0.1.99j: 0.1.99j:
* Added hardware YUV overlay support (SDL). Huge performance
increase.
* Minor changes in the Debian files. * Minor changes in the Debian files.
* Fixed fps display. * Fixed fps display.
* Fixed MPEG1 video decoding. We don't read MPEG 1 PS files for the * Fixed MPEG1 video decoding. We don't read MPEG 1 PS files for the

View File

@ -64,6 +64,9 @@ typedef struct intf_sys_s
typedef struct vout_sys_s typedef struct vout_sys_s
{ {
SDL_Surface * p_display; /* display device */ SDL_Surface * p_display; /* display device */
SDL_Overlay * p_overlay;
boolean_t b_fullscreen;
boolean_t b_reopen_display;
Uint8 * p_buffer[2]; Uint8 * p_buffer[2];
/* Buffers informations */ /* Buffers informations */
boolean_t b_must_acquire; /* must be acquired before writing */ boolean_t b_must_acquire; /* must be acquired before writing */
@ -146,14 +149,14 @@ void intf_SDLDestroy( intf_thread_t *p_intf )
*****************************************************************************/ *****************************************************************************/
void intf_SDLManage( intf_thread_t *p_intf ) void intf_SDLManage( intf_thread_t *p_intf )
{ {
SDL_Event event; /* SDL event */ SDL_Event event; /* SDL event */
Uint8 i_key; Uint8 i_key;
while ( SDL_PollEvent(&event) ) while ( SDL_PollEvent(&event) )
{ {
i_key = event.key.keysym.sym; /* forward it */ i_key = event.key.keysym.sym; /* forward it */
switch (event.type) { switch (event.type) {
case SDL_KEYDOWN: /* if a key is pressed */ case SDL_KEYDOWN: /* if a key is pressed */
switch(i_key) { switch(i_key) {
/* switch to fullscreen */ /* switch to fullscreen */
@ -166,7 +169,7 @@ void intf_SDLManage( intf_thread_t *p_intf )
default : default :
if( intf_ProcessKey( p_intf, (char ) i_key ) ) if( intf_ProcessKey( p_intf, (char ) i_key ) )
{ {
intf_DbgMsg( "unhandled key '%c' (%i)\n", intf_DbgMsg( "unhandled key '%c' (%i)\n",
(char) i_key, i_key ); (char) i_key, i_key );
} }
break; break;
@ -190,71 +193,8 @@ void intf_SDL_YUVSwitch(intf_thread_t * p_intf)
} }
void intf_SDL_Fullscreen(intf_thread_t * p_intf) void intf_SDL_Fullscreen(intf_thread_t * p_intf)
{ {
SDL_Rect clipping_rect; p_intf->p_vout->p_sys->b_fullscreen = 1-p_intf->p_vout->p_sys->b_fullscreen;
p_intf->p_vout->p_sys->b_reopen_display = 1;
SDL_FreeSurface( p_intf->p_vout->p_sys->p_display );
if(p_intf->p_sys->b_Fullscreen == 0)
{
p_intf->p_vout->p_sys->p_display =
SDL_SetVideoMode(
p_intf->p_vout->i_width,
p_intf->p_vout->i_height,
0,
SDL_ANYFORMAT |
SDL_HWSURFACE |
SDL_DOUBLEBUF);
p_intf->p_sys->b_Fullscreen = 1;
SDL_ShowCursor( 1 );
}
else
{
p_intf->p_vout->p_sys->p_display =
SDL_SetVideoMode(
p_intf->p_vout->i_width,
p_intf->p_vout->i_height,
0,
SDL_ANYFORMAT |
SDL_HWSURFACE |
SDL_DOUBLEBUF |
SDL_FULLSCREEN );
p_intf->p_sys->b_Fullscreen = 0;
SDL_ShowCursor( 0 );
}
SDL_WM_SetCaption( VOUT_TITLE , VOUT_TITLE );
SDL_EventState(SDL_KEYUP , SDL_IGNORE);
p_intf->p_vout->p_sys->p_buffer[ 0 ] = p_intf->p_vout->p_sys->p_display->pixels;
SDL_Flip(p_intf->p_vout->p_sys->p_display);
p_intf->p_vout->p_sys->p_buffer[ 1 ] = p_intf->p_vout->p_sys->p_display->pixels;
SDL_Flip(p_intf->p_vout->p_sys->p_display);
/* Clipping zone for the text */
clipping_rect.x = 0;
clipping_rect.y = 0;
clipping_rect.w = p_intf->p_vout->p_sys->p_display->w;
clipping_rect.h = p_intf->p_vout->p_sys->p_display->h;
SDL_SetClipRect(p_intf->p_vout->p_sys->p_display, &clipping_rect);
p_intf->p_vout->i_width = p_intf->p_vout->p_sys->p_display->w;
p_intf->p_vout->i_height = p_intf->p_vout->p_sys->p_display->h;
p_intf->p_vout->i_bytes_per_line =
p_intf->p_vout->p_sys->p_display->format->BytesPerPixel
*
p_intf->p_vout->p_sys->p_display->w ;
p_intf->p_vout->i_screen_depth =
p_intf->p_vout->p_sys->p_display->format->BitsPerPixel;
p_intf->p_vout->i_bytes_per_pixel =
p_intf->p_vout->p_sys->p_display->format->BytesPerPixel;
p_intf->p_vout->i_red_mask =
p_intf->p_vout->p_sys->p_display->format->Rmask;
p_intf->p_vout->i_green_mask =
p_intf->p_vout->p_sys->p_display->format->Gmask;
p_intf->p_vout->i_blue_mask =
p_intf->p_vout->p_sys->p_display->format->Bmask;
} }

View File

@ -51,6 +51,9 @@
typedef struct vout_sys_s typedef struct vout_sys_s
{ {
SDL_Surface * p_display; /* display device */ SDL_Surface * p_display; /* display device */
SDL_Overlay * p_overlay; /* overlay device */
boolean_t b_fullscreen;
boolean_t b_reopen_display;
Uint8 * p_buffer[2]; Uint8 * p_buffer[2];
/* Buffers informations */ /* Buffers informations */
boolean_t b_must_acquire; /* must be acquired before writing */ boolean_t b_must_acquire; /* must be acquired before writing */
@ -59,8 +62,7 @@ typedef struct vout_sys_s
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
static int SDLOpenDisplay ( vout_thread_t *p_vout, static int SDLOpenDisplay ( vout_thread_t *p_vout );
char *psz_display, void *p_data );
static void SDLCloseDisplay ( vout_thread_t *p_vout ); static void SDLCloseDisplay ( vout_thread_t *p_vout );
/***************************************************************************** /*****************************************************************************
@ -73,7 +75,6 @@ static void SDLCloseDisplay ( vout_thread_t *p_vout );
int vout_SDLCreate( vout_thread_t *p_vout, char *psz_display, int vout_SDLCreate( vout_thread_t *p_vout, char *psz_display,
int i_root_window, void *p_data ) int i_root_window, void *p_data )
{ {
SDL_Overlay * screen;
/* Allocate structure */ /* Allocate structure */
p_vout->p_sys = malloc( sizeof( vout_sys_t ) ); p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
if( p_vout->p_sys == NULL ) if( p_vout->p_sys == NULL )
@ -82,28 +83,39 @@ int vout_SDLCreate( vout_thread_t *p_vout, char *psz_display,
return( 1 ); return( 1 );
} }
/* Open and initialize device */ p_vout->p_sys->p_display = NULL;
p_vout->p_sys->p_overlay = NULL;
if( SDLOpenDisplay( p_vout, psz_display, p_data ) )
/* Initialize library */
if( SDL_Init(SDL_INIT_VIDEO) < 0 )
{ {
intf_ErrMsg( "error: can't initialize SDL display\n" ); intf_ErrMsg( "error: can't initialize SDL library: %s\n",
SDL_GetError() );
free( p_vout->p_sys ); free( p_vout->p_sys );
return( 1 ); return( 1 );
} }
if( SDLOpenDisplay(p_vout) )
screen = SDL_CreateYUVOverlay(
10,
10,
SDL_IYUV_OVERLAY,
p_vout->p_sys->p_display
);
intf_ErrMsg("[YUV acceleration] : %d",screen->hw_overlay);
if(screen->hw_overlay)
{ {
//hw_acceleration ! intf_ErrMsg( "error: can't initialize SDL library: %s\n",
p_vout->b_need_render = 0; SDL_GetError() );
free( p_vout->p_sys );
return( 1 );
} }
/* Force the software yuv even if it is not used */
/* If we don't do this, p_vout is not correctly initialized
and it's impossible to switch between soft/hard yuv */
p_vout->b_need_render = 1;
if(psz_display != NULL && strcmp(psz_display,"fullscreen")==0)
{
p_vout->p_sys->b_fullscreen = 1;
} else {
p_vout->p_sys->b_fullscreen = 0;
}
p_vout->p_sys->b_reopen_display = 1;
return( 0 ); return( 0 );
} }
@ -117,7 +129,7 @@ int vout_SDLInit( vout_thread_t *p_vout )
/* Acquire first buffer */ /* Acquire first buffer */
if( p_vout->p_sys->b_must_acquire ) if( p_vout->p_sys->b_must_acquire )
{ {
SDL_LockSurface(p_vout->p_sys->p_display); SDL_LockSurface(p_vout->p_sys->p_display);
} }
return( 0 ); return( 0 );
@ -157,7 +169,28 @@ void vout_SDLDestroy( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
int vout_SDLManage( vout_thread_t *p_vout ) int vout_SDLManage( vout_thread_t *p_vout )
{ {
/* FIXME: 8bpp: change palette ?? */ /* If the display has to be reopened we do so */
if( p_vout->p_sys->b_reopen_display )
{
p_vout->p_sys->b_must_acquire = 0;
if( p_vout->p_sys->p_display )
{
if( p_vout->p_sys->p_overlay )
{
SDL_FreeYUVOverlay(p_vout->p_sys->p_overlay);
p_vout->p_sys->p_overlay = NULL;
}
SDL_FreeSurface( p_vout->p_sys->p_display );
p_vout->p_sys->p_display = NULL;
}
if( SDLOpenDisplay(p_vout) )
{
intf_ErrMsg( "error: can't open DISPLAY default display\n" );
return( 1 );
}
p_vout->p_sys->b_reopen_display = 0;
}
return( 0 ); return( 0 );
} }
@ -169,7 +202,6 @@ int vout_SDLManage( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
void vout_SDLDisplay( vout_thread_t *p_vout ) void vout_SDLDisplay( vout_thread_t *p_vout )
{ {
SDL_Overlay * screen;
SDL_Rect disp; SDL_Rect disp;
if(p_vout->b_need_render) if(p_vout->b_need_render)
{ {
@ -179,48 +211,59 @@ void vout_SDLDisplay( vout_thread_t *p_vout )
SDL_Flip( p_vout->p_sys->p_display ); SDL_Flip( p_vout->p_sys->p_display );
//Swap buffers and change write frame /* Swap buffers and change write frame */
SDL_LockSurface ( p_vout->p_sys->p_display ); SDL_LockSurface ( p_vout->p_sys->p_display );
} }
} else { }
else
{
/* /*
* p_vout->yuv.p_buffer contains the YUV buffer to render * p_vout->p_rendered_pic->p_y/u/v contains the YUV buffers to render
*/ */
if( p_vout->p_sys->b_must_acquire )
screen = SDL_CreateYUVOverlay( {
p_vout->p_rendered_pic->i_width, /* TODO: support for streams other than 4:2:0 */
p_vout->p_rendered_pic->i_height, /* create the overlay if necessary */
SDL_IYUV_OVERLAY, if( !p_vout->p_sys->p_overlay )
p_vout->p_sys->p_display {
); p_vout->p_sys->p_overlay = SDL_CreateYUVOverlay(
p_vout->p_rendered_pic->i_width,
SDL_LockYUVOverlay(screen); p_vout->p_rendered_pic->i_height,
//* screen->pixels = calloc( p_vout->i_width * p_vout->i_height * 3, 1); SDL_YV12_OVERLAY,
//*screen->pixels = p_vout->yuv.p_buffer; p_vout->p_sys->p_display
/* *screen->pixels = malloc( p_vout->i_width * p_vout->i_height * 3 ); );
memcpy( *screen->pixels, p_vout->p_rendered_pic->p_y, p_vout->i_width * p_vout->i_height ); intf_Msg("[YUV acceleration] : %d\n",
memcpy( *screen->pixels + p_vout->i_width * p_vout->i_height, p_vout->p_sys->p_overlay->hw_overlay);
p_vout->p_rendered_pic->p_u, }
p_vout->i_width * p_vout->i_height );
memcpy( *screen->pixels + p_vout->i_width * p_vout->i_height * 2,
p_vout->p_rendered_pic->p_v,
p_vout->i_width * p_vout->i_height ); */
// *screen->pixels = p_vout->p_rendered_pic->p_y; SDL_LockYUVOverlay(p_vout->p_sys->p_overlay);
*screen->pixels = p_vout->p_rendered_pic->p_data; /* copy the data into video buffers */
/* Y first */
memcpy(p_vout->p_sys->p_overlay->pixels[0],
p_vout->p_rendered_pic->p_y,
p_vout->p_sys->p_overlay->h *
p_vout->p_sys->p_overlay->pitches[0]);
/* then V */
memcpy(p_vout->p_sys->p_overlay->pixels[1],
p_vout->p_rendered_pic->p_v,
p_vout->p_sys->p_overlay->h *
p_vout->p_sys->p_overlay->pitches[1] / 2);
/* and U */
memcpy(p_vout->p_sys->p_overlay->pixels[2],
p_vout->p_rendered_pic->p_u,
p_vout->p_sys->p_overlay->h *
p_vout->p_sys->p_overlay->pitches[2] / 2);
disp.x = 0; disp.x = 0;
disp.y = 0; disp.y = 0;
disp.w = p_vout->i_width; disp.w = p_vout->i_width;
disp.h = p_vout->i_height; disp.h = p_vout->i_height;
SDL_UnlockYUVOverlay(screen);
SDL_DisplayYUVOverlay( screen , &disp ); SDL_DisplayYUVOverlay( p_vout->p_sys->p_overlay , &disp );
// free(* screen -> pixels); SDL_UnlockYUVOverlay(p_vout->p_sys->p_overlay);
SDL_FreeYUVOverlay(screen); }
} }
} }
/* following functions are local */ /* following functions are local */
@ -231,22 +274,14 @@ void vout_SDLDisplay( vout_thread_t *p_vout )
* Open and initialize display according to preferences specified in the vout * Open and initialize display according to preferences specified in the vout
* thread fields. * thread fields.
*****************************************************************************/ *****************************************************************************/
static int SDLOpenDisplay( vout_thread_t *p_vout, char *psz_display, void *p_data ) static int SDLOpenDisplay( vout_thread_t *p_vout )
{ {
SDL_Rect clipping_rect; SDL_Rect clipping_rect;
/* Initialize library */
if( SDL_Init(SDL_INIT_VIDEO) < 0 )
{
intf_ErrMsg( "error: can't initialize SDL library: %s\n",
SDL_GetError() );
return( 1 );
}
/* Open display /* Open display
* TODO: Check that we can request for a DOUBLEBUF HWSURFACE display * TODO: Check that we can request for a DOUBLEBUF HWSURFACE display
*/ */
if(psz_display != NULL && strcmp(psz_display,"fullscreen")==0) if( p_vout->p_sys->b_fullscreen )
{ {
p_vout->p_sys->p_display = SDL_SetVideoMode(p_vout->i_width, p_vout->p_sys->p_display = SDL_SetVideoMode(p_vout->i_width,
p_vout->i_height, p_vout->i_height,
@ -266,6 +301,7 @@ static int SDLOpenDisplay( vout_thread_t *p_vout, char *psz_display, void *p_dat
intf_ErrMsg( "error: can't open DISPLAY default display\n" ); intf_ErrMsg( "error: can't open DISPLAY default display\n" );
return( 1 ); return( 1 );
} }
p_vout->p_sys->p_overlay = NULL;
SDL_WM_SetCaption( VOUT_TITLE , VOUT_TITLE ); SDL_WM_SetCaption( VOUT_TITLE , VOUT_TITLE );
SDL_EventState(SDL_KEYUP , SDL_IGNORE); /* ignore keys up */ SDL_EventState(SDL_KEYUP , SDL_IGNORE); /* ignore keys up */
@ -334,7 +370,18 @@ static int SDLOpenDisplay( vout_thread_t *p_vout, char *psz_display, void *p_dat
*****************************************************************************/ *****************************************************************************/
static void SDLCloseDisplay( vout_thread_t *p_vout ) static void SDLCloseDisplay( vout_thread_t *p_vout )
{ {
SDL_FreeSurface( p_vout->p_sys->p_display ); if( p_vout->p_sys->p_display )
{
p_vout->p_sys->b_must_acquire = 0;
if( p_vout->p_sys->p_overlay )
{
SDL_FreeYUVOverlay(p_vout->p_sys->p_overlay);
p_vout->p_sys->p_overlay = NULL;
}
SDL_FreeSurface( p_vout->p_sys->p_display );
p_vout->p_sys->p_display = NULL;
}
SDL_Quit(); SDL_Quit();
} }

View File

@ -199,7 +199,7 @@ es_descriptor_t * input_AddES( input_thread_t * p_input,
p_es = &p_input->p_es[i_index]; p_es = &p_input->p_es[i_index];
p_es->i_id = i_es_id; p_es->i_id = i_es_id;
intf_DbgMsg("Slot %d in p_es table assigned to ES %d", intf_DbgMsg("Slot %d in p_es table assigned to ES %d",
i_index, i_es_pid); i_index, i_es_id);
/* Init its values */ /* Init its values */
p_es->b_discontinuity = 0; p_es->b_discontinuity = 0;