1 /*****************************************************************************
2 * sdl.c: SDL video output display method
3 *****************************************************************************
4 * Copyright (C) 1998-2001 VideoLAN
5 * $Id: sdl.c,v 1.6 2003/01/09 14:05:31 sam Exp $
7 * Authors: Samuel Hocevar <sam@zoy.org>
8 * Pierre Baillet <oct@zoy.org>
9 * Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
24 *****************************************************************************/
26 /*****************************************************************************
28 *****************************************************************************/
29 #include <errno.h> /* ENOMEM */
30 #include <stdlib.h> /* free() */
31 #include <string.h> /* strerror() */
37 #include <sys/types.h>
39 # include <netinet/in.h> /* BSD: struct in_addr */
42 #include SDL_INCLUDE_FILE
46 #define SDL_MAX_DIRECTBUFFERS 10
47 #define SDL_DEFAULT_BPP 16
49 /*****************************************************************************
50 * vout_sys_t: video output SDL method descriptor
51 *****************************************************************************
52 * This structure is part of the video output thread descriptor.
53 * It describes the SDL specific properties of an output thread.
54 *****************************************************************************/
57 SDL_Surface * p_display; /* display device */
63 SDL_Overlay * p_overlay; /* An overlay we keep to grab the XVideo port */
69 vlc_bool_t b_cursor_autohidden;
71 mtime_t i_lastpressed; /* to track dbl-clicks */
74 /*****************************************************************************
75 * picture_sys_t: direct buffer method descriptor
76 *****************************************************************************
77 * This structure is part of the picture descriptor, it describes the
78 * SDL specific properties of a direct buffer.
79 *****************************************************************************/
82 SDL_Overlay *p_overlay;
85 /*****************************************************************************
87 *****************************************************************************/
88 static int Open ( vlc_object_t * );
89 static void Close ( vlc_object_t * );
90 static int Init ( vout_thread_t * );
91 static void End ( vout_thread_t * );
92 static int Manage ( vout_thread_t * );
93 static void Display ( vout_thread_t *, picture_t * );
95 static int OpenDisplay ( vout_thread_t * );
96 static void CloseDisplay ( vout_thread_t * );
97 static int NewPicture ( vout_thread_t *, picture_t * );
98 static void SetPalette ( vout_thread_t *,
99 uint16_t *, uint16_t *, uint16_t * );
101 /*****************************************************************************
103 *****************************************************************************/
105 set_description( _("Simple DirectMedia Layer video module") );
106 set_capability( "video output", 60 );
107 add_shortcut( "sdl" );
108 set_callbacks( Open, Close );
111 /*****************************************************************************
112 * OpenVideo: allocate SDL video thread output method
113 *****************************************************************************
114 * This function allocate and initialize a SDL vout method. It uses some of the
115 * vout properties to choose the correct mode, and change them according to the
116 * mode actually used.
117 *****************************************************************************/
118 static int Open ( vlc_object_t *p_this )
120 vout_thread_t * p_vout = (vout_thread_t *)p_this;
126 if( SDL_WasInit( SDL_INIT_VIDEO ) != 0 )
131 /* Allocate structure */
132 p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
133 if( p_vout->p_sys == NULL )
135 msg_Err( p_vout, "out of memory" );
139 p_vout->pf_init = Init;
140 p_vout->pf_end = End;
141 p_vout->pf_manage = Manage;
142 p_vout->pf_render = NULL;
143 p_vout->pf_display = Display;
146 psz_method = config_GetPsz( p_vout, "vout" );
149 while( *psz_method && *psz_method != ':' )
156 setenv( "SDL_VIDEODRIVER", psz_method + 1, 1 );
161 /* Initialize library */
162 if( SDL_Init( SDL_INIT_VIDEO
164 /* Win32 SDL implementation doesn't support SDL_INIT_EVENTTHREAD yet*/
165 | SDL_INIT_EVENTTHREAD
168 /* In debug mode you may want vlc to dump a core instead of staying
170 | SDL_INIT_NOPARACHUTE
174 msg_Err( p_vout, "cannot initialize SDL (%s)", SDL_GetError() );
175 free( p_vout->p_sys );
179 p_vout->p_sys->b_cursor = 1;
180 p_vout->p_sys->b_cursor_autohidden = 0;
181 p_vout->p_sys->i_lastmoved = mdate();
183 if( OpenDisplay( p_vout ) )
185 msg_Err( p_vout, "cannot set up SDL (%s)", SDL_GetError() );
186 SDL_QuitSubSystem( SDL_INIT_VIDEO );
187 free( p_vout->p_sys );
194 /*****************************************************************************
195 * Init: initialize SDL video thread output method
196 *****************************************************************************
197 * This function initialize the SDL display device.
198 *****************************************************************************/
199 static int Init( vout_thread_t *p_vout )
204 p_vout->p_sys->i_surfaces = 0;
206 I_OUTPUTPICTURES = 0;
208 /* Initialize the output structure */
209 if( p_vout->p_sys->p_overlay == NULL )
211 /* All we have is an RGB image with square pixels */
212 p_vout->output.i_width = p_vout->p_sys->i_width;
213 p_vout->output.i_height = p_vout->p_sys->i_height;
214 p_vout->output.i_aspect = p_vout->output.i_width
216 / p_vout->output.i_height;
220 /* We may need to convert the chroma, but at least we keep the
222 p_vout->output.i_width = p_vout->render.i_width;
223 p_vout->output.i_height = p_vout->render.i_height;
224 p_vout->output.i_aspect = p_vout->render.i_aspect;
227 /* Try to initialize SDL_MAX_DIRECTBUFFERS direct buffers */
228 while( I_OUTPUTPICTURES < SDL_MAX_DIRECTBUFFERS )
232 /* Find an empty picture slot */
233 for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
235 if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
237 p_pic = p_vout->p_picture + i_index;
242 /* Allocate the picture if we found one */
243 if( p_pic == NULL || NewPicture( p_vout, p_pic ) )
248 p_pic->i_status = DESTROYED_PICTURE;
249 p_pic->i_type = DIRECT_PICTURE;
251 PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;
259 /*****************************************************************************
260 * End: terminate Sys video thread output method
261 *****************************************************************************
262 * Terminate an output method created by OpenVideo
263 *****************************************************************************/
264 static void End( vout_thread_t *p_vout )
268 /* Free the output buffers we allocated */
269 for( i_index = I_OUTPUTPICTURES ; i_index ; )
272 if( p_vout->p_sys->p_overlay == NULL )
278 SDL_UnlockYUVOverlay(
279 PP_OUTPUTPICTURE[ i_index ]->p_sys->p_overlay );
281 PP_OUTPUTPICTURE[ i_index ]->p_sys->p_overlay );
283 free( PP_OUTPUTPICTURE[ i_index ]->p_sys );
287 /*****************************************************************************
288 * CloseVideo: destroy Sys video thread output method
289 *****************************************************************************
290 * Terminate an output method created by vout_SDLCreate
291 *****************************************************************************/
292 static void Close ( vlc_object_t *p_this )
294 vout_thread_t * p_vout = (vout_thread_t *)p_this;
296 CloseDisplay( p_vout );
297 SDL_QuitSubSystem( SDL_INIT_VIDEO );
299 free( p_vout->p_sys );
302 /*****************************************************************************
303 * Manage: handle Sys events
304 *****************************************************************************
305 * This function should be called regularly by video output thread. It returns
306 * a non null value if an error occured.
307 *****************************************************************************/
308 static int Manage( vout_thread_t *p_vout )
310 SDL_Event event; /* SDL event */
312 int i_width, i_height, i_x, i_y;
315 while( SDL_PollEvent(&event) )
319 case SDL_VIDEORESIZE: /* Resizing of window */
320 /* Update dimensions */
321 p_vout->i_changes |= VOUT_SIZE_CHANGE;
322 p_vout->i_window_width = p_vout->p_sys->i_width = event.resize.w;
323 p_vout->i_window_height = p_vout->p_sys->i_height = event.resize.h;
326 case SDL_MOUSEMOTION:
327 vout_PlacePicture( p_vout, p_vout->p_sys->i_width,
328 p_vout->p_sys->i_height,
329 &i_x, &i_y, &i_width, &i_height );
331 val.i_int = ( event.motion.x - i_x )
332 * p_vout->render.i_width / i_width;
333 var_Set( p_vout, "mouse-x", val );
334 val.i_int = ( event.motion.y - i_y )
335 * p_vout->render.i_height / i_height;
336 var_Set( p_vout, "mouse-y", val );
338 val.b_bool = VLC_TRUE;
339 var_Set( p_vout, "mouse-moved", val );
341 if( p_vout->p_sys->b_cursor &&
342 (abs(event.motion.xrel) > 2 || abs(event.motion.yrel) > 2) )
344 if( p_vout->p_sys->b_cursor_autohidden )
346 p_vout->p_sys->b_cursor_autohidden = 0;
351 p_vout->p_sys->i_lastmoved = mdate();
356 case SDL_MOUSEBUTTONUP:
357 switch( event.button.button )
359 case SDL_BUTTON_LEFT:
360 val.b_bool = VLC_TRUE;
361 var_Set( p_vout, "mouse-clicked", val );
364 case SDL_BUTTON_RIGHT:
366 intf_thread_t *p_intf;
367 p_intf = vlc_object_find( p_vout, VLC_OBJECT_INTF,
371 p_intf->b_menu_change = 1;
372 vlc_object_release( p_intf );
379 case SDL_MOUSEBUTTONDOWN:
380 switch( event.button.button )
382 case SDL_BUTTON_LEFT:
383 /* In this part we will eventually manage
384 * clicks for DVD navigation for instance. */
386 /* detect double-clicks */
387 if( ( mdate() - p_vout->p_sys->i_lastpressed ) < 300000 )
388 p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
390 p_vout->p_sys->i_lastpressed = mdate();
394 input_Seek( p_vout, 15, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
398 input_Seek( p_vout, -15, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
404 p_vout->p_vlc->b_die = 1;
407 case SDL_KEYDOWN: /* if a key is pressed */
409 switch( event.key.keysym.sym )
412 if( p_vout->b_fullscreen )
414 p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
418 p_vout->p_vlc->b_die = 1;
422 case SDLK_q: /* quit */
423 p_vout->p_vlc->b_die = 1;
426 case SDLK_f: /* switch to fullscreen */
427 p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
430 case SDLK_c: /* toggle grayscale */
431 p_vout->b_grayscale = ! p_vout->b_grayscale;
432 p_vout->i_changes |= VOUT_GRAYSCALE_CHANGE;
435 case SDLK_i: /* toggle info */
436 p_vout->b_info = ! p_vout->b_info;
437 p_vout->i_changes |= VOUT_INFO_CHANGE;
440 case SDLK_s: /* toggle scaling */
441 p_vout->b_scale = ! p_vout->b_scale;
442 p_vout->i_changes |= VOUT_SCALE_CHANGE;
445 case SDLK_SPACE: /* toggle interface */
446 p_vout->b_interface = ! p_vout->b_interface;
447 p_vout->i_changes |= VOUT_INTF_CHANGE;
452 intf_thread_t *p_intf;
453 p_intf = vlc_object_find( p_vout, VLC_OBJECT_INTF,
457 p_intf->b_menu_change = 1;
458 vlc_object_release( p_intf );
464 input_Seek( p_vout, -5, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
468 input_Seek( p_vout, 5, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
472 input_Seek( p_vout, 60, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
476 input_Seek( p_vout, -60, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
479 case SDLK_F1: network_ChannelJoin( p_vout, 1 ); break;
480 case SDLK_F2: network_ChannelJoin( p_vout, 2 ); break;
481 case SDLK_F3: network_ChannelJoin( p_vout, 3 ); break;
482 case SDLK_F4: network_ChannelJoin( p_vout, 4 ); break;
483 case SDLK_F5: network_ChannelJoin( p_vout, 5 ); break;
484 case SDLK_F6: network_ChannelJoin( p_vout, 6 ); break;
485 case SDLK_F7: network_ChannelJoin( p_vout, 7 ); break;
486 case SDLK_F8: network_ChannelJoin( p_vout, 8 ); break;
487 case SDLK_F9: network_ChannelJoin( p_vout, 9 ); break;
488 case SDLK_F10: network_ChannelJoin( p_vout, 10 ); break;
489 case SDLK_F11: network_ChannelJoin( p_vout, 11 ); break;
490 case SDLK_F12: network_ChannelJoin( p_vout, 12 ); break;
494 aout_instance_t * p_aout;
495 audio_volume_t i_volume;
496 p_aout = vlc_object_find( p_vout, VLC_OBJECT_AOUT,
500 if ( !aout_VolumeDown( p_aout, 1, &i_volume ) )
502 msg_Dbg( p_vout, "audio volume is now %d", i_volume );
506 msg_Dbg( p_vout, "audio volume: operation not supported" );
508 vlc_object_release( (vlc_object_t *)p_aout );
515 aout_instance_t * p_aout;
516 audio_volume_t i_volume;
517 p_aout = vlc_object_find( p_vout, VLC_OBJECT_AOUT,
521 if ( !aout_VolumeUp( p_aout, 1, &i_volume ) )
523 msg_Dbg( p_vout, "audio volume is now %d", i_volume );
527 msg_Dbg( p_vout, "audio volume: operation not supported" );
529 vlc_object_release( (vlc_object_t *)p_aout );
544 /* Fullscreen change */
545 if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE )
547 p_vout->b_fullscreen = ! p_vout->b_fullscreen;
549 p_vout->p_sys->b_cursor_autohidden = 0;
550 SDL_ShowCursor( p_vout->p_sys->b_cursor &&
551 ! p_vout->p_sys->b_cursor_autohidden );
553 p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
554 p_vout->i_changes |= VOUT_SIZE_CHANGE;
560 if( p_vout->i_changes & VOUT_SIZE_CHANGE )
562 msg_Dbg( p_vout, "video display resized (%dx%d)",
563 p_vout->p_sys->i_width, p_vout->p_sys->i_height );
565 CloseDisplay( p_vout );
566 OpenDisplay( p_vout );
568 /* We don't need to signal the vout thread about the size change if
569 * we can handle rescaling ourselves */
570 if( p_vout->p_sys->p_overlay != NULL )
571 p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
576 if( ! p_vout->p_sys->b_cursor_autohidden &&
577 ( mdate() - p_vout->p_sys->i_lastmoved > 2000000 ) )
579 /* Hide the mouse automatically */
580 p_vout->p_sys->b_cursor_autohidden = 1;
587 /*****************************************************************************
588 * Display: displays previously rendered output
589 *****************************************************************************
590 * This function sends the currently rendered image to the display.
591 *****************************************************************************/
592 static void Display( vout_thread_t *p_vout, picture_t *p_pic )
597 vout_PlacePicture( p_vout, p_vout->p_sys->i_width, p_vout->p_sys->i_height,
604 if( p_vout->p_sys->p_overlay == NULL )
607 SDL_Flip( p_vout->p_sys->p_display );
611 /* Overlay picture */
612 SDL_UnlockYUVOverlay( p_pic->p_sys->p_overlay);
613 SDL_DisplayYUVOverlay( p_pic->p_sys->p_overlay , &disp );
614 SDL_LockYUVOverlay( p_pic->p_sys->p_overlay);
618 /* following functions are local */
620 /*****************************************************************************
621 * OpenDisplay: open and initialize SDL device
622 *****************************************************************************
623 * Open and initialize display according to preferences specified in the vout
625 *****************************************************************************/
626 static int OpenDisplay( vout_thread_t *p_vout )
631 /* Set main window's size */
632 p_vout->p_sys->i_width = p_vout->b_fullscreen ? p_vout->output.i_width :
633 p_vout->i_window_width;
634 p_vout->p_sys->i_height = p_vout->b_fullscreen ? p_vout->output.i_height :
635 p_vout->i_window_height;
637 /* Initialize flags and cursor */
638 i_flags = SDL_ANYFORMAT | SDL_HWPALETTE | SDL_HWSURFACE | SDL_DOUBLEBUF;
639 i_flags |= p_vout->b_fullscreen ? SDL_FULLSCREEN : SDL_RESIZABLE;
641 i_bpp = SDL_VideoModeOK( p_vout->p_sys->i_width, p_vout->p_sys->i_height,
642 SDL_DEFAULT_BPP, i_flags );
645 msg_Err( p_vout, "no video mode available" );
649 p_vout->p_sys->p_display = SDL_SetVideoMode( p_vout->p_sys->i_width,
650 p_vout->p_sys->i_height,
653 if( p_vout->p_sys->p_display == NULL )
655 msg_Err( p_vout, "cannot set video mode" );
659 SDL_LockSurface( p_vout->p_sys->p_display );
661 /* Choose the chroma we will try first. */
662 switch( p_vout->render.i_chroma )
664 case VLC_FOURCC('Y','U','Y','2'):
665 case VLC_FOURCC('Y','U','N','V'):
666 p_vout->output.i_chroma = SDL_YUY2_OVERLAY;
668 case VLC_FOURCC('U','Y','V','Y'):
669 case VLC_FOURCC('U','Y','N','V'):
670 case VLC_FOURCC('Y','4','2','2'):
671 p_vout->output.i_chroma = SDL_UYVY_OVERLAY;
673 case VLC_FOURCC('Y','V','Y','U'):
674 p_vout->output.i_chroma = SDL_YVYU_OVERLAY;
676 case VLC_FOURCC('Y','V','1','2'):
677 case VLC_FOURCC('I','4','2','0'):
678 case VLC_FOURCC('I','Y','U','V'):
680 p_vout->output.i_chroma = SDL_YV12_OVERLAY;
684 p_vout->p_sys->p_overlay =
685 SDL_CreateYUVOverlay( 32, 32, p_vout->output.i_chroma,
686 p_vout->p_sys->p_display );
687 /* FIXME: if the first overlay we find is software, don't stop,
688 * because we may find a hardware one later ... */
690 /* If this best choice failed, fall back to other chromas */
691 if( p_vout->p_sys->p_overlay == NULL )
693 p_vout->output.i_chroma = SDL_IYUV_OVERLAY;
694 p_vout->p_sys->p_overlay =
695 SDL_CreateYUVOverlay( 32, 32, p_vout->output.i_chroma,
696 p_vout->p_sys->p_display );
699 if( p_vout->p_sys->p_overlay == NULL )
701 p_vout->output.i_chroma = SDL_YV12_OVERLAY;
702 p_vout->p_sys->p_overlay =
703 SDL_CreateYUVOverlay( 32, 32, p_vout->output.i_chroma,
704 p_vout->p_sys->p_display );
707 if( p_vout->p_sys->p_overlay == NULL )
709 p_vout->output.i_chroma = SDL_YUY2_OVERLAY;
710 p_vout->p_sys->p_overlay =
711 SDL_CreateYUVOverlay( 32, 32, p_vout->output.i_chroma,
712 p_vout->p_sys->p_display );
715 if( p_vout->p_sys->p_overlay == NULL )
717 msg_Warn( p_vout, "no SDL overlay for 0x%.8x (%4.4s)",
718 p_vout->render.i_chroma, (char*)&p_vout->render.i_chroma );
720 switch( p_vout->p_sys->p_display->format->BitsPerPixel )
723 p_vout->output.i_chroma = VLC_FOURCC('R','G','B','2');
724 p_vout->output.pf_setpalette = SetPalette;
727 p_vout->output.i_chroma = VLC_FOURCC('R','V','1','5');
730 p_vout->output.i_chroma = VLC_FOURCC('R','V','1','6');
733 p_vout->output.i_chroma = VLC_FOURCC('R','V','2','4');
736 p_vout->output.i_chroma = VLC_FOURCC('R','V','3','2');
739 msg_Err( p_vout, "unknown screen depth %i",
740 p_vout->p_sys->p_display->format->BitsPerPixel );
741 SDL_UnlockSurface( p_vout->p_sys->p_display );
742 SDL_FreeSurface( p_vout->p_sys->p_display );
746 p_vout->output.i_rmask = p_vout->p_sys->p_display->format->Rmask;
747 p_vout->output.i_gmask = p_vout->p_sys->p_display->format->Gmask;
748 p_vout->output.i_bmask = p_vout->p_sys->p_display->format->Bmask;
750 SDL_WM_SetCaption( VOUT_TITLE " (software RGB SDL output)",
751 VOUT_TITLE " (software RGB SDL output)" );
755 if( p_vout->p_sys->p_overlay->hw_overlay )
757 SDL_WM_SetCaption( VOUT_TITLE " (hardware YUV SDL output)",
758 VOUT_TITLE " (hardware YUV SDL output)" );
762 SDL_WM_SetCaption( VOUT_TITLE " (software YUV SDL output)",
763 VOUT_TITLE " (software YUV SDL output)" );
767 SDL_EventState( SDL_KEYUP, SDL_IGNORE ); /* ignore keys up */
772 /*****************************************************************************
773 * CloseDisplay: close and reset SDL device
774 *****************************************************************************
775 * This function returns all resources allocated by OpenDisplay and restore
776 * the original state of the device.
777 *****************************************************************************/
778 static void CloseDisplay( vout_thread_t *p_vout )
780 SDL_FreeYUVOverlay( p_vout->p_sys->p_overlay );
781 SDL_UnlockSurface ( p_vout->p_sys->p_display );
782 SDL_FreeSurface( p_vout->p_sys->p_display );
785 /*****************************************************************************
786 * NewPicture: allocate a picture
787 *****************************************************************************
788 * Returns 0 on success, -1 otherwise
789 *****************************************************************************/
790 static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic )
792 int i_width = p_vout->output.i_width;
793 int i_height = p_vout->output.i_height;
795 if( p_vout->p_sys->p_overlay == NULL )
798 if( p_vout->p_sys->i_surfaces )
800 /* We already allocated this surface, return */
804 p_pic->p_sys = malloc( sizeof( picture_sys_t ) );
806 if( p_pic->p_sys == NULL )
811 switch( p_vout->p_sys->p_display->format->BitsPerPixel )
814 p_pic->p->i_pixel_pitch = 1;
818 p_pic->p->i_pixel_pitch = 2;
822 p_pic->p->i_pixel_pitch = 4;
828 p_pic->p->p_pixels = p_vout->p_sys->p_display->pixels;
829 p_pic->p->i_lines = p_vout->p_sys->p_display->h;
830 p_pic->p->i_pitch = p_vout->p_sys->p_display->pitch;
831 p_pic->p->i_visible_pitch =
832 p_pic->p->i_pixel_pitch * p_vout->p_sys->p_display->w;
834 p_vout->p_sys->i_surfaces++;
840 p_pic->p_sys = malloc( sizeof( picture_sys_t ) );
842 if( p_pic->p_sys == NULL )
847 p_pic->p_sys->p_overlay =
848 SDL_CreateYUVOverlay( i_width, i_height,
849 p_vout->output.i_chroma,
850 p_vout->p_sys->p_display );
852 if( p_pic->p_sys->p_overlay == NULL )
854 free( p_pic->p_sys );
858 SDL_LockYUVOverlay( p_pic->p_sys->p_overlay );
860 p_pic->Y_PIXELS = p_pic->p_sys->p_overlay->pixels[0];
861 p_pic->p[Y_PLANE].i_lines = p_pic->p_sys->p_overlay->h;
862 p_pic->p[Y_PLANE].i_pitch = p_pic->p_sys->p_overlay->pitches[0];
864 switch( p_vout->output.i_chroma )
866 case SDL_YV12_OVERLAY:
867 p_pic->p[Y_PLANE].i_pixel_pitch = 1;
868 p_pic->p[Y_PLANE].i_visible_pitch = p_pic->p_sys->p_overlay->w;
870 p_pic->U_PIXELS = p_pic->p_sys->p_overlay->pixels[2];
871 p_pic->p[U_PLANE].i_lines = p_pic->p_sys->p_overlay->h / 2;
872 p_pic->p[U_PLANE].i_pitch = p_pic->p_sys->p_overlay->pitches[2];
873 p_pic->p[U_PLANE].i_pixel_pitch = 1;
874 p_pic->p[U_PLANE].i_visible_pitch = p_pic->p_sys->p_overlay->w / 2;
876 p_pic->V_PIXELS = p_pic->p_sys->p_overlay->pixels[1];
877 p_pic->p[V_PLANE].i_lines = p_pic->p_sys->p_overlay->h / 2;
878 p_pic->p[V_PLANE].i_pitch = p_pic->p_sys->p_overlay->pitches[1];
879 p_pic->p[V_PLANE].i_pixel_pitch = 1;
880 p_pic->p[V_PLANE].i_visible_pitch = p_pic->p_sys->p_overlay->w / 2;
885 case SDL_IYUV_OVERLAY:
886 p_pic->p[Y_PLANE].i_pixel_pitch = 1;
887 p_pic->p[Y_PLANE].i_visible_pitch = p_pic->p_sys->p_overlay->w;
889 p_pic->U_PIXELS = p_pic->p_sys->p_overlay->pixels[1];
890 p_pic->p[U_PLANE].i_lines = p_pic->p_sys->p_overlay->h / 2;
891 p_pic->p[U_PLANE].i_pitch = p_pic->p_sys->p_overlay->pitches[1];
892 p_pic->p[U_PLANE].i_pixel_pitch = 1;
893 p_pic->p[U_PLANE].i_visible_pitch = p_pic->p_sys->p_overlay->w / 2;
895 p_pic->V_PIXELS = p_pic->p_sys->p_overlay->pixels[2];
896 p_pic->p[V_PLANE].i_lines = p_pic->p_sys->p_overlay->h / 2;
897 p_pic->p[V_PLANE].i_pitch = p_pic->p_sys->p_overlay->pitches[2];
898 p_pic->p[V_PLANE].i_pixel_pitch = 1;
899 p_pic->p[V_PLANE].i_visible_pitch = p_pic->p_sys->p_overlay->w / 2;
905 p_pic->p[Y_PLANE].i_pixel_pitch = 2;
906 p_pic->p[U_PLANE].i_visible_pitch = p_pic->p_sys->p_overlay->w * 2;
916 /*****************************************************************************
917 * SetPalette: sets an 8 bpp palette
918 *****************************************************************************/
919 static void SetPalette( vout_thread_t *p_vout,
920 uint16_t *red, uint16_t *green, uint16_t *blue )
922 SDL_Color colors[256];
925 /* Fill colors with color information */
926 for( i = 0; i < 256; i++ )
928 colors[ i ].r = red[ i ] >> 8;
929 colors[ i ].g = green[ i ] >> 8;
930 colors[ i ].b = blue[ i ] >> 8;
934 if( SDL_SetColors( p_vout->p_sys->p_display, colors, 0, 256 ) == 0 )
936 msg_Err( p_vout, "failed setting palette" );