146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* 246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL - Simple DirectMedia Layer 346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Copyright (C) 1997-2003 Sam Lantinga 446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner This library is free software; you can redistribute it and/or 646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner modify it under the terms of the GNU Library General Public 746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner License as published by the Free Software Foundation; either 846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner version 2 of the License, or (at your option) any later version. 946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner This library is distributed in the hope that it will be useful, 1146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner but WITHOUT ANY WARRANTY; without even the implied warranty of 1246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Library General Public License for more details. 1446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner You should have received a copy of the GNU Library General Public 1646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner License along with this library; if not, write to the Free 1746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 1846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Sam Lantinga 2046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner slouken@libsdl.org 2146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner*/ 2246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_config.h" 2346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_QuartzVideo.h" 2546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_QuartzWindow.h" 2646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "../SDL_yuvfuncs.h" 2746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define yuv_idh (this->hidden->yuv_idh) 3046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define yuv_matrix (this->hidden->yuv_matrix) 3146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define yuv_codec (this->hidden->yuv_codec) 3246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define yuv_seq (this->hidden->yuv_seq) 3346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define yuv_pixmap (this->hidden->yuv_pixmap) 3446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define yuv_data (this->hidden->yuv_data) 3546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define yuv_width (this->hidden->yuv_width) 3646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define yuv_height (this->hidden->yuv_height) 3746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define yuv_port (this->hidden->yuv_port) 3846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 3946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int QZ_LockYUV (_THIS, SDL_Overlay *overlay) { 4146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return 0; 4346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 4446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void QZ_UnlockYUV (_THIS, SDL_Overlay *overlay) { 4646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner ; 4846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 4946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 5046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int QZ_DisplayYUV (_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst) { 5146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 5246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner OSErr err; 5346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner CodecFlags flags; 5446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 5546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (dst->x != 0 || dst->y != 0) { 5646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 5746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError ("Need a dst at (0,0)"); 5846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return -1; 5946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 6046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 6146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (dst->w != yuv_width || dst->h != yuv_height) { 6246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 6346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Fixed scale_x, scale_y; 6446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 6546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner scale_x = FixDiv ( Long2Fix (dst->w), Long2Fix (overlay->w) ); 6646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner scale_y = FixDiv ( Long2Fix (dst->h), Long2Fix (overlay->h) ); 6746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 6846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SetIdentityMatrix (yuv_matrix); 6946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner ScaleMatrix (yuv_matrix, scale_x, scale_y, Long2Fix (0), Long2Fix (0)); 7046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 7146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SetDSequenceMatrix (yuv_seq, yuv_matrix); 7246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 7346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner yuv_width = dst->w; 7446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner yuv_height = dst->h; 7546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 7646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 7746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if( ( err = DecompressSequenceFrameS( 7846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner yuv_seq, 7946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (void*)yuv_pixmap, 8046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner sizeof (PlanarPixmapInfoYUV420), 8146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner codecFlagUseImageBuffer, &flags, nil ) != noErr ) ) 8246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 8346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError ("DecompressSequenceFrameS failed"); 8446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 8546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 8646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return err != noErr; 8746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 8846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 8946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void QZ_FreeHWYUV (_THIS, SDL_Overlay *overlay) { 9046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 9146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner CDSequenceEnd (yuv_seq); 9246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner ExitMovies(); 9346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 9446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_free (overlay->hwfuncs); 9546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_free (overlay->pitches); 9646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_free (overlay->pixels); 9746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 9846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (SDL_VideoSurface->flags & SDL_FULLSCREEN) { 9946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner [ qz_window close ]; 10046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner qz_window = nil; 10146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 10246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 10346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_free (yuv_matrix); 10446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DisposeHandle ((Handle)yuv_idh); 10546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 10646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 10746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* check for 16 byte alignment, bail otherwise */ 10846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define CHECK_ALIGN(x) do { if ((Uint32)x & 15) { SDL_SetError("Alignment error"); return NULL; } } while(0) 10946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 11046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* align a byte offset, return how much to add to make it a multiple of 16 */ 11146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define ALIGN(x) ((16 - (x & 15)) & 15) 11246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 11346be48730333120a7b939116cef075e61c12c703David 'Digit' TurnerSDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height, 11446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Uint32 format, SDL_Surface *display) { 11546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 11646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Uint32 codec; 11746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner OSStatus err; 11846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner CGrafPtr port; 11946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_Overlay *overlay; 12046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 12146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (format == SDL_YV12_OVERLAY || 12246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner format == SDL_IYUV_OVERLAY) { 12346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 12446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner codec = kYUV420CodecType; 12546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 12646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner else { 12746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError ("Hardware: unsupported video format"); 12846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return NULL; 12946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 13046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 13146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner yuv_idh = (ImageDescriptionHandle) NewHandleClear (sizeof(ImageDescription)); 13246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (yuv_idh == NULL) { 13346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_OutOfMemory(); 13446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return NULL; 13546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 13646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 13746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner yuv_matrix = (MatrixRecordPtr) SDL_malloc (sizeof(MatrixRecord)); 13846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (yuv_matrix == NULL) { 13946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_OutOfMemory(); 14046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return NULL; 14146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 14246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 14346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( EnterMovies() != noErr ) { 14446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError ("Could not init QuickTime for YUV playback"); 14546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return NULL; 14646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 14746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 14846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner err = FindCodec (codec, bestSpeedCodec, nil, &yuv_codec); 14946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (err != noErr) { 15046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError ("Could not find QuickTime codec for format"); 15146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return NULL; 15246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 15346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 15446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (SDL_VideoSurface->flags & SDL_FULLSCREEN) { 15546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 15646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* 15746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Acceleration requires a window to be present. 15846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner A CGrafPtr that points to the screen isn't good enough 15946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner */ 16046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner NSRect content = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h); 16146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 16246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner qz_window = [ [ SDL_QuartzWindow alloc ] 16346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner initWithContentRect:content 16446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner styleMask:NSBorderlessWindowMask 16546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner backing:NSBackingStoreBuffered defer:NO ]; 16646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 16746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (qz_window == nil) { 16846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError ("Could not create the Cocoa window"); 16946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return NULL; 17046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 17146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 17246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner [ qz_window setContentView:[ [ NSQuickDrawView alloc ] init ] ]; 17346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner [ qz_window setReleasedWhenClosed:YES ]; 17446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner [ qz_window center ]; 17546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner [ qz_window setAcceptsMouseMovedEvents:YES ]; 17646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner [ qz_window setLevel:CGShieldingWindowLevel() ]; 17746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner [ qz_window makeKeyAndOrderFront:nil ]; 17846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 17946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner port = [ [ qz_window contentView ] qdPort ]; 18046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SetPort (port); 18146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 18246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* 18346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner BUG: would like to remove white flash when window kicks in 18446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 18546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Rect r; 18646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SetRect (&r, 0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h); 18746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner PaintRect (&r); 18846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner QDFlushPortBuffer (port, nil); 18946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 19046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner */ 19146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 19246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner else { 19346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner port = [ window_view qdPort ]; 19446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SetPort (port); 19546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 19646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 19746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SetIdentityMatrix (yuv_matrix); 19846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 19946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner HLock ((Handle)yuv_idh); 20046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 20146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (**yuv_idh).idSize = sizeof(ImageDescription); 20246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (**yuv_idh).cType = codec; 20346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (**yuv_idh).version = 1; 20446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (**yuv_idh).revisionLevel = 0; 20546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (**yuv_idh).width = width; 20646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (**yuv_idh).height = height; 20746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (**yuv_idh).hRes = Long2Fix(72); 20846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (**yuv_idh).vRes = Long2Fix(72); 20946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (**yuv_idh).spatialQuality = codecLosslessQuality; 21046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (**yuv_idh).frameCount = 1; 21146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (**yuv_idh).clutID = -1; 21246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (**yuv_idh).dataSize = 0; 21346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (**yuv_idh).depth = 24; 21446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 21546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner HUnlock ((Handle)yuv_idh); 21646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 21746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner err = DecompressSequenceBeginS ( 21846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner &yuv_seq, 21946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner yuv_idh, 22046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner NULL, 22146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 0, 22246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner port, 22346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner NULL, 22446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner NULL, 22546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner yuv_matrix, 22646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 0, 22746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner NULL, 22846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner codecFlagUseImageBuffer, 22946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner codecLosslessQuality, 23046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner yuv_codec); 23146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 23246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (err != noErr) { 23346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError ("Error trying to start YUV codec."); 23446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return NULL; 23546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 23646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 23746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner overlay = (SDL_Overlay*) SDL_malloc (sizeof(*overlay)); 23846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (overlay == NULL) { 23946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_OutOfMemory(); 24046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return NULL; 24146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 24246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 24346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner overlay->format = format; 24446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner overlay->w = width; 24546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner overlay->h = height; 24646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner overlay->planes = 3; 24746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner overlay->hw_overlay = 1; 24846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { 24946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int offset; 25046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Uint8 **pixels; 25146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Uint16 *pitches; 25246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int plane2, plane3; 25346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 25446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (format == SDL_IYUV_OVERLAY) { 25546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 25646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner plane2 = 1; /* Native codec format */ 25746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner plane3 = 2; 25846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 25946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner else if (format == SDL_YV12_OVERLAY) { 26046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 26146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* switch the U and V planes */ 26246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner plane2 = 2; /* U plane maps to plane 3 */ 26346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner plane3 = 1; /* V plane maps to plane 2 */ 26446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 26546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner else { 26646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("Unsupported YUV format"); 26746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return NULL; 26846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 26946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 27046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner pixels = (Uint8**) SDL_malloc (sizeof(*pixels) * 3); 27146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner pitches = (Uint16*) SDL_malloc (sizeof(*pitches) * 3); 27246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (pixels == NULL || pitches == NULL) { 27346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_OutOfMemory(); 27446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return NULL; 27546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 27646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 27746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Fix: jc.bertin@free.fr 27846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner PlanarPixmapInfoYUV420 is a big-endian struct */ 27946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner yuv_pixmap = (PlanarPixmapInfoYUV420*) 28046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_malloc (sizeof(PlanarPixmapInfoYUV420) + 28146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (width * height * 2)); 28246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (yuv_pixmap == NULL) { 28346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_OutOfMemory (); 28446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return NULL; 28546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 28646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 28746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* CHECK_ALIGN(yuv_pixmap); */ 28846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner offset = sizeof(PlanarPixmapInfoYUV420); 28946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* offset += ALIGN(offset); */ 29046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* CHECK_ALIGN(offset); */ 29146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 29246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner pixels[0] = (Uint8*)yuv_pixmap + offset; 29346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* CHECK_ALIGN(pixels[0]); */ 29446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 29546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner pitches[0] = width; 29646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner yuv_pixmap->componentInfoY.offset = EndianS32_NtoB(offset); 29746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner yuv_pixmap->componentInfoY.rowBytes = EndianU32_NtoB(width); 29846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 29946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner offset += width * height; 30046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner pixels[plane2] = (Uint8*)yuv_pixmap + offset; 30146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner pitches[plane2] = width / 2; 30246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner yuv_pixmap->componentInfoCb.offset = EndianS32_NtoB(offset); 30346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner yuv_pixmap->componentInfoCb.rowBytes = EndianU32_NtoB(width / 2); 30446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 30546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner offset += (width * height / 4); 30646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner pixels[plane3] = (Uint8*)yuv_pixmap + offset; 30746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner pitches[plane3] = width / 2; 30846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner yuv_pixmap->componentInfoCr.offset = EndianS32_NtoB(offset); 30946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner yuv_pixmap->componentInfoCr.rowBytes = EndianU32_NtoB(width / 2); 31046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 31146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner overlay->pixels = pixels; 31246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner overlay->pitches = pitches; 31346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 31446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 31546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner overlay->hwfuncs = SDL_malloc (sizeof(*overlay->hwfuncs)); 31646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (overlay->hwfuncs == NULL) { 31746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_OutOfMemory(); 31846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return NULL; 31946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 32046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 32146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner overlay->hwfuncs->Lock = QZ_LockYUV; 32246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner overlay->hwfuncs->Unlock = QZ_UnlockYUV; 32346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner overlay->hwfuncs->Display = QZ_DisplayYUV; 32446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner overlay->hwfuncs->FreeHW = QZ_FreeHWYUV; 32546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 32646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner yuv_width = overlay->w; 32746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner yuv_height = overlay->h; 32846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 32946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return overlay; 33046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 331