00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <errno.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034
00035 #include <QuickTime/QuickTime.h>
00036
00037 #include <vlc_keys.h>
00038
00039 #include "intf.h"
00040 #include "vout.h"
00041
00042 #define QT_MAX_DIRECTBUFFERS 10
00043 #define VL_MAX_DISPLAYS 16
00044
00045
00046
00047
00048 @interface VLCQTView : NSQuickDrawView
00049 {
00050 vout_thread_t * p_vout;
00051 }
00052
00053 - (id) initWithVout:(vout_thread_t *)p_vout;
00054
00055 @end
00056
00057 struct vout_sys_t
00058 {
00059 NSAutoreleasePool *o_pool;
00060 VLCWindow * o_window;
00061 VLCQTView * o_qtview;
00062
00063 vlc_bool_t b_saved_frame;
00064 vlc_bool_t b_altivec;
00065 NSRect s_frame;
00066
00067 CodecType i_codec;
00068 CGrafPtr p_qdport;
00069 ImageSequence i_seq;
00070 MatrixRecordPtr p_matrix;
00071 DecompressorComponent img_dc;
00072 ImageDescriptionHandle h_img_descr;
00073
00074
00075 vlc_bool_t b_embedded;
00076 Rect clipping_rect;
00077 int portx, porty;
00078 };
00079
00080 struct picture_sys_t
00081 {
00082 void *p_data;
00083 unsigned int i_size;
00084
00085
00086 PlanarPixmapInfoYUV420 pixmap_i420;
00087 };
00088
00089
00090
00091
00092
00093 static int InitVideo ( vout_thread_t * );
00094 static void EndVideo ( vout_thread_t * );
00095 static int ManageVideo ( vout_thread_t * );
00096 static void DisplayVideo ( vout_thread_t *, picture_t * );
00097 static int ControlVideo ( vout_thread_t *, int, va_list );
00098
00099 static int CoToggleFullscreen( vout_thread_t *p_vout );
00100 static void QTScaleMatrix ( vout_thread_t * );
00101 static int QTCreateSequence ( vout_thread_t * );
00102 static void QTDestroySequence ( vout_thread_t * );
00103 static int QTNewPicture ( vout_thread_t *, picture_t * );
00104 static void QTFreePicture ( vout_thread_t *, picture_t * );
00105
00106
00107
00108
00109
00110
00111 int E_(OpenVideoQT) ( vlc_object_t *p_this )
00112 {
00113 vout_thread_t * p_vout = (vout_thread_t *)p_this;
00114 OSErr err;
00115 vlc_value_t value_drawable;
00116
00117 p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
00118 if( p_vout->p_sys == NULL )
00119 {
00120 msg_Err( p_vout, "out of memory" );
00121 return( 1 );
00122 }
00123
00124 memset( p_vout->p_sys, 0, sizeof( vout_sys_t ) );
00125
00126 p_vout->p_sys->o_pool = [[NSAutoreleasePool alloc] init];
00127
00128 p_vout->pf_init = InitVideo;
00129 p_vout->pf_end = EndVideo;
00130 p_vout->pf_manage = ManageVideo;
00131 p_vout->pf_render = NULL;
00132 p_vout->pf_display = DisplayVideo;
00133 p_vout->pf_control = ControlVideo;
00134
00135
00136
00137 var_Get( p_vout->p_vlc, "drawable", &value_drawable );
00138 if( value_drawable.i_int != 0 )
00139 p_vout->p_sys->b_embedded = VLC_TRUE;
00140 else
00141 p_vout->p_sys->b_embedded = VLC_FALSE;
00142
00143 p_vout->p_sys->b_altivec = p_vout->p_libvlc->i_cpu & CPU_CAPABILITY_ALTIVEC;
00144 msg_Dbg( p_vout, "We do%s have Altivec", p_vout->p_sys->b_altivec ? "" : "n't" );
00145
00146
00147 p_vout->p_sys->h_img_descr =
00148 (ImageDescriptionHandle)NewHandleClear( sizeof(ImageDescription) );
00149 p_vout->p_sys->p_matrix =
00150 (MatrixRecordPtr)malloc( sizeof(MatrixRecord) );
00151
00152 if( ( err = EnterMovies() ) != noErr )
00153 {
00154 msg_Err( p_vout, "EnterMovies failed: %d", err );
00155 free( p_vout->p_sys->p_matrix );
00156 DisposeHandle( (Handle)p_vout->p_sys->h_img_descr );
00157 free( p_vout->p_sys );
00158 return VLC_EGENERIC;
00159 }
00160
00161
00162 vlc_mutex_lock( &p_vout->p_vlc->quicktime_lock );
00163
00164
00165 if( p_vout->p_sys->b_altivec )
00166 {
00167 err = FindCodec( kYUVSPixelFormat, bestSpeedCodec,
00168 nil, &p_vout->p_sys->img_dc );
00169 }
00170 else
00171 {
00172 err = FindCodec( kYUV420CodecType, bestSpeedCodec,
00173 nil, &p_vout->p_sys->img_dc );
00174 }
00175 vlc_mutex_unlock( &p_vout->p_vlc->quicktime_lock );
00176
00177 if( err == noErr && p_vout->p_sys->img_dc != 0 )
00178 {
00179 if( p_vout->p_sys->b_altivec )
00180 {
00181 p_vout->output.i_chroma = VLC_FOURCC('Y','U','Y','2');
00182 p_vout->p_sys->i_codec = kYUVSPixelFormat;
00183 }
00184 else
00185 {
00186 p_vout->output.i_chroma = VLC_FOURCC('I','4','2','0');
00187 p_vout->p_sys->i_codec = kYUV420CodecType;
00188 }
00189 }
00190 else
00191 {
00192 msg_Err( p_vout, "failed to find an appropriate codec" );
00193 }
00194
00195 if( p_vout->p_sys->img_dc == 0 )
00196 {
00197 free( p_vout->p_sys->p_matrix );
00198 DisposeHandle( (Handle)p_vout->p_sys->h_img_descr );
00199 free( p_vout->p_sys );
00200 return VLC_EGENERIC;
00201 }
00202
00203 #define o_qtview p_vout->p_sys->o_qtview
00204 o_qtview = [[VLCQTView alloc] initWithVout: p_vout];
00205 [o_qtview autorelease];
00206
00207 if( p_vout->p_sys->b_embedded )
00208 {
00209
00210 p_vout->p_sys->clipping_rect.left = 0;
00211 p_vout->p_sys->clipping_rect.right = 0;
00212 p_vout->p_sys->clipping_rect.top = 0;
00213 p_vout->p_sys->clipping_rect.bottom = 0;
00214 }
00215 else
00216 {
00217
00218 p_vout->p_sys->o_window = [[VLCWindow alloc]
00219 initWithVout: p_vout view: o_qtview frame: nil];
00220 if( !p_vout->p_sys->o_window )
00221 {
00222 return VLC_EGENERIC;
00223 }
00224 }
00225
00226
00227 if( p_vout->p_sys->b_embedded )
00228 {
00229
00230
00231
00232 p_vout->p_sys->p_qdport = [o_qtview qdPort];
00233 }
00234 else
00235 {
00236 [o_qtview lockFocus];
00237 p_vout->p_sys->p_qdport = [o_qtview qdPort];
00238 [o_qtview unlockFocus];
00239 }
00240 #undef o_qtview
00241
00242 return VLC_SUCCESS;
00243 }
00244
00245
00246
00247
00248 void E_(CloseVideoQT) ( vlc_object_t *p_this )
00249 {
00250 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
00251 vout_thread_t * p_vout = (vout_thread_t *)p_this;
00252
00253 if( !p_vout->p_sys->b_embedded )
00254 [p_vout->p_sys->o_window close];
00255
00256
00257 ExitMovies();
00258 free( p_vout->p_sys->p_matrix );
00259 DisposeHandle( (Handle)p_vout->p_sys->h_img_descr );
00260
00261 [o_pool release];
00262 free( p_vout->p_sys );
00263 }
00264
00265
00266
00267
00268 static int InitVideo ( vout_thread_t *p_vout )
00269 {
00270 picture_t *p_pic;
00271 int i_index;
00272
00273 I_OUTPUTPICTURES = 0;
00274
00275
00276
00277
00278 p_vout->output.i_width = p_vout->render.i_width;
00279 p_vout->output.i_height = p_vout->render.i_height;
00280 p_vout->output.i_aspect = p_vout->render.i_aspect;
00281
00282
00283
00284
00285 if( p_vout->p_sys->b_embedded )
00286 {
00287 vlc_value_t val;
00288 var_Get( p_vout->p_vlc, "drawable", &val );
00289 p_vout->p_sys->p_qdport = (CGrafPtr) val.i_int;
00290 }
00291
00292 SetPort( p_vout->p_sys->p_qdport );
00293 QTScaleMatrix( p_vout );
00294
00295 if( QTCreateSequence( p_vout ) )
00296 {
00297 msg_Err( p_vout, "unable to create sequence" );
00298 return( 1 );
00299 }
00300
00301
00302 while( I_OUTPUTPICTURES < QT_MAX_DIRECTBUFFERS )
00303 {
00304 p_pic = NULL;
00305
00306
00307 for( i_index = 0; i_index < VOUT_MAX_PICTURES; i_index++ )
00308 {
00309 if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
00310 {
00311 p_pic = p_vout->p_picture + i_index;
00312 break;
00313 }
00314 }
00315
00316
00317 if( p_pic == NULL || QTNewPicture( p_vout, p_pic ) )
00318 {
00319 break;
00320 }
00321
00322 p_pic->i_status = DESTROYED_PICTURE;
00323 p_pic->i_type = DIRECT_PICTURE;
00324
00325 PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;
00326 I_OUTPUTPICTURES++;
00327 }
00328 return 0;
00329 }
00330
00331
00332
00333
00334 static void EndVideo( vout_thread_t *p_vout )
00335 {
00336 int i_index;
00337
00338 QTDestroySequence( p_vout );
00339
00340
00341 for( i_index = I_OUTPUTPICTURES; i_index; )
00342 {
00343 i_index--;
00344 QTFreePicture( p_vout, PP_OUTPUTPICTURE[ i_index ] );
00345 }
00346 }
00347
00348
00349
00350
00351
00352
00353
00354 static int ManageVideo( vout_thread_t *p_vout )
00355 {
00356 vlc_value_t val;
00357 var_Get( p_vout->p_vlc, "drawableredraw", &val );
00358
00359 if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE )
00360 {
00361 if( CoToggleFullscreen( p_vout ) )
00362 {
00363 return( 1 );
00364 }
00365
00366 p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
00367 }
00368
00369 if( p_vout->p_sys->b_embedded && val.i_int == 1 )
00370 {
00371
00372
00373
00374
00375 val.i_int = 0;
00376 var_Set( p_vout->p_vlc, "drawableredraw", val );
00377
00378 p_vout->i_changes |= VOUT_SIZE_CHANGE;
00379 }
00380
00381 if( p_vout->i_changes & VOUT_SIZE_CHANGE )
00382 {
00383 QTScaleMatrix( p_vout );
00384 SetDSequenceMatrix( p_vout->p_sys->i_seq,
00385 p_vout->p_sys->p_matrix );
00386 p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
00387 }
00388
00389 [p_vout->p_sys->o_window manage];
00390
00391 return( 0 );
00392 }
00393
00394
00395
00396
00397
00398
00399 static void DisplayVideo( vout_thread_t *p_vout, picture_t *p_pic )
00400 {
00401 OSErr err;
00402 CodecFlags flags;
00403
00404 Rect saved_rect;
00405 RgnHandle saved_clip;
00406
00407 saved_clip = NewRgn();
00408
00409 if( p_vout->p_sys->b_embedded )
00410 {
00411
00412
00413
00414
00415
00416
00417 GetPortBounds( p_vout->p_sys->p_qdport, &saved_rect );
00418 GetClip( saved_clip );
00419
00420
00421 LockPortBits( p_vout->p_sys->p_qdport );
00422
00423
00424
00425 SetPort( p_vout->p_sys->p_qdport );
00426 SetOrigin( p_vout->p_sys->portx , p_vout->p_sys->porty );
00427 ClipRect( &p_vout->p_sys->clipping_rect );
00428 }
00429
00430 if( ( err = DecompressSequenceFrameWhen(
00431 p_vout->p_sys->i_seq,
00432 p_pic->p_sys->p_data,
00433 p_pic->p_sys->i_size,
00434 codecFlagUseImageBuffer, &flags, NULL, NULL ) != noErr ) )
00435 {
00436 msg_Warn( p_vout, "DecompressSequenceFrameWhen failed: %d", err );
00437 }
00438 else
00439 {
00440 if( !p_vout->p_sys->b_embedded )
00441 QDFlushPortBuffer( p_vout->p_sys->p_qdport, nil );
00442 }
00443
00444 if( p_vout->p_sys->b_embedded )
00445 {
00446
00447
00448 SetOrigin( saved_rect.left, saved_rect.top );
00449 SetClip( saved_clip );
00450
00451 UnlockPortBits( p_vout->p_sys->p_qdport );
00452 }
00453 }
00454
00455
00456
00457
00458 static int ControlVideo( vout_thread_t *p_vout, int i_query, va_list args )
00459 {
00460 vlc_bool_t b_arg;
00461
00462 switch( i_query )
00463 {
00464 case VOUT_SET_STAY_ON_TOP:
00465 b_arg = va_arg( args, vlc_bool_t );
00466 [p_vout->p_sys->o_window setOnTop: b_arg];
00467 return VLC_SUCCESS;
00468
00469 case VOUT_CLOSE:
00470 case VOUT_REPARENT:
00471 default:
00472 return vout_vaControlDefault( p_vout, i_query, args );
00473 }
00474 }
00475
00476
00477
00478
00479
00480
00481 static int CoToggleFullscreen( vout_thread_t *p_vout )
00482 {
00483 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
00484
00485 QTDestroySequence( p_vout );
00486
00487 if( !p_vout->b_fullscreen )
00488 {
00489
00490 p_vout->p_sys->s_frame.size =
00491 [[p_vout->p_sys->o_window contentView] frame].size;
00492 p_vout->p_sys->s_frame.origin =
00493 [p_vout->p_sys->o_window frame].origin;
00494 p_vout->p_sys->b_saved_frame = VLC_TRUE;
00495 }
00496 [p_vout->p_sys->o_window close];
00497
00498 p_vout->b_fullscreen = !p_vout->b_fullscreen;
00499
00500 #define o_qtview p_vout->p_sys->o_qtview
00501 o_qtview = [[VLCQTView alloc] initWithVout: p_vout];
00502 [o_qtview autorelease];
00503
00504 if( p_vout->p_sys->b_saved_frame )
00505 {
00506 p_vout->p_sys->o_window = [[VLCWindow alloc]
00507 initWithVout: p_vout view: o_qtview
00508 frame: &p_vout->p_sys->s_frame];
00509 }
00510 else
00511 {
00512 p_vout->p_sys->o_window = [[VLCWindow alloc]
00513 initWithVout: p_vout view: o_qtview frame: nil];
00514 }
00515
00516
00517 [o_qtview lockFocus];
00518 p_vout->p_sys->p_qdport = [o_qtview qdPort];
00519 [o_qtview unlockFocus];
00520 #undef o_qtview
00521
00522 SetPort( p_vout->p_sys->p_qdport );
00523 QTScaleMatrix( p_vout );
00524
00525 if( QTCreateSequence( p_vout ) )
00526 {
00527 msg_Err( p_vout, "unable to create sequence" );
00528 return( 1 );
00529 }
00530
00531 [o_pool release];
00532 return 0;
00533 }
00534
00535
00536
00537
00538 static void QTScaleMatrix( vout_thread_t *p_vout )
00539 {
00540 Rect s_rect;
00541 vlc_value_t val;
00542 unsigned int i_width, i_height;
00543 Fixed factor_x, factor_y;
00544 unsigned int i_offset_x = 0;
00545 unsigned int i_offset_y = 0;
00546
00547 GetPortBounds( p_vout->p_sys->p_qdport, &s_rect );
00548
00549 i_width = s_rect.right - s_rect.left;
00550 i_height = s_rect.bottom - s_rect.top;
00551
00552 if( p_vout->p_sys->b_embedded )
00553 {
00554
00555
00556
00557
00558 vlc_value_t valt, vall, valb, valr, valx, valy, valw, valh,
00559 valportx, valporty;
00560
00561 var_Get( p_vout->p_vlc, "drawable", &val );
00562 var_Get( p_vout->p_vlc, "drawablet", &valt );
00563 var_Get( p_vout->p_vlc, "drawablel", &vall );
00564 var_Get( p_vout->p_vlc, "drawableb", &valb );
00565 var_Get( p_vout->p_vlc, "drawabler", &valr );
00566 var_Get( p_vout->p_vlc, "drawablex", &valx );
00567 var_Get( p_vout->p_vlc, "drawabley", &valy );
00568 var_Get( p_vout->p_vlc, "drawablew", &valw );
00569 var_Get( p_vout->p_vlc, "drawableh", &valh );
00570 var_Get( p_vout->p_vlc, "drawableportx", &valportx );
00571 var_Get( p_vout->p_vlc, "drawableporty", &valporty );
00572
00573 p_vout->p_sys->portx = valportx.i_int;
00574 p_vout->p_sys->porty = valporty.i_int;
00575 p_vout->p_sys->p_qdport = (CGrafPtr) val.i_int;
00576 i_width = valw.i_int;
00577 i_height = valh.i_int;
00578
00579 p_vout->p_sys->clipping_rect.top = 0;
00580 p_vout->p_sys->clipping_rect.left = 0;
00581 p_vout->p_sys->clipping_rect.bottom = valb.i_int - valt.i_int;
00582 p_vout->p_sys->clipping_rect.right = valr.i_int - vall.i_int;
00583 }
00584
00585 var_Get( p_vout, "macosx-stretch", &val );
00586 if( val.b_bool )
00587 {
00588 factor_x = FixDiv( Long2Fix( i_width ),
00589 Long2Fix( p_vout->output.i_width ) );
00590 factor_y = FixDiv( Long2Fix( i_height ),
00591 Long2Fix( p_vout->output.i_height ) );
00592
00593 }
00594 else if( i_height * p_vout->output.i_aspect < i_width * VOUT_ASPECT_FACTOR )
00595 {
00596 int i_adj_width = i_height * p_vout->output.i_aspect /
00597 VOUT_ASPECT_FACTOR;
00598
00599 factor_x = FixDiv( Long2Fix( i_adj_width ),
00600 Long2Fix( p_vout->output.i_width ) );
00601 factor_y = FixDiv( Long2Fix( i_height ),
00602 Long2Fix( p_vout->output.i_height ) );
00603
00604 i_offset_x = (i_width - i_adj_width) / 2;
00605 }
00606 else
00607 {
00608 int i_adj_height = i_width * VOUT_ASPECT_FACTOR /
00609 p_vout->output.i_aspect;
00610
00611 factor_x = FixDiv( Long2Fix( i_width ),
00612 Long2Fix( p_vout->output.i_width ) );
00613 factor_y = FixDiv( Long2Fix( i_adj_height ),
00614 Long2Fix( p_vout->output.i_height ) );
00615
00616 i_offset_y = (i_height - i_adj_height) / 2;
00617 }
00618
00619 SetIdentityMatrix( p_vout->p_sys->p_matrix );
00620
00621 ScaleMatrix( p_vout->p_sys->p_matrix,
00622 factor_x, factor_y,
00623 Long2Fix(0), Long2Fix(0) );
00624
00625 TranslateMatrix( p_vout->p_sys->p_matrix,
00626 Long2Fix(i_offset_x), Long2Fix(i_offset_y) );
00627 }
00628
00629
00630
00631
00632
00633
00634 static int QTCreateSequence( vout_thread_t *p_vout )
00635 {
00636 OSErr err;
00637 ImageDescriptionPtr p_descr;
00638
00639 HLock( (Handle)p_vout->p_sys->h_img_descr );
00640 p_descr = *p_vout->p_sys->h_img_descr;
00641
00642 p_descr->idSize = sizeof(ImageDescription);
00643 p_descr->cType = p_vout->p_sys->i_codec;
00644 p_descr->version = 2;
00645 p_descr->revisionLevel = 0;
00646 p_descr->vendor = 'mpla';
00647 p_descr->width = p_vout->output.i_width;
00648 p_descr->height = p_vout->output.i_height;
00649 p_descr->hRes = Long2Fix(72);
00650 p_descr->vRes = Long2Fix(72);
00651 p_descr->spatialQuality = codecLosslessQuality;
00652 p_descr->frameCount = 1;
00653 p_descr->clutID = -1;
00654 p_descr->dataSize = 0;
00655 p_descr->depth = 24;
00656
00657 HUnlock( (Handle)p_vout->p_sys->h_img_descr );
00658
00659 if( ( err = DecompressSequenceBeginS(
00660 &p_vout->p_sys->i_seq,
00661 p_vout->p_sys->h_img_descr,
00662 NULL,
00663 (p_descr->width * p_descr->height * 16) / 8,
00664 p_vout->p_sys->p_qdport,
00665 NULL, NULL,
00666 p_vout->p_sys->p_matrix,
00667 srcCopy, NULL,
00668 codecFlagUseImageBuffer,
00669 codecLosslessQuality,
00670 bestSpeedCodec ) ) )
00671 {
00672 msg_Err( p_vout, "DecompressSequenceBeginS failed: %d", err );
00673 return( 1 );
00674 }
00675
00676 return( 0 );
00677 }
00678
00679
00680
00681
00682 static void QTDestroySequence( vout_thread_t *p_vout )
00683 {
00684 CDSequenceEnd( p_vout->p_sys->i_seq );
00685 }
00686
00687
00688
00689
00690
00691
00692 static int QTNewPicture( vout_thread_t *p_vout, picture_t *p_pic )
00693 {
00694
00695
00696 p_pic->p_sys = malloc( sizeof( picture_sys_t ) );
00697
00698 if( p_pic->p_sys == NULL )
00699 {
00700 return( -1 );
00701 }
00702
00703 vout_InitPicture( VLC_OBJECT( p_vout), p_pic, p_vout->output.i_chroma,
00704 p_vout->output.i_width, p_vout->output.i_height,
00705 p_vout->output.i_aspect );
00706
00707 switch( p_vout->output.i_chroma )
00708 {
00709 case VLC_FOURCC('Y','U','Y','2'):
00710 p_pic->p_sys->i_size = p_vout->output.i_width * p_vout->output.i_height * 2;
00711
00712
00713 p_pic->p_data = vlc_memalign( &p_pic->p_data_orig,
00714 16, p_pic->p_sys->i_size );
00715
00716 p_pic->p[0].p_pixels = p_pic->p_data;
00717 p_pic->p[0].i_lines = p_vout->output.i_height;
00718 p_pic->p[0].i_visible_lines = p_vout->output.i_height;
00719 p_pic->p[0].i_pitch = p_vout->output.i_width * 2;
00720 p_pic->p[0].i_pixel_pitch = 1;
00721 p_pic->p[0].i_visible_pitch = p_vout->output.i_width * 2;
00722 p_pic->i_planes = 1;
00723
00724 p_pic->p_sys->p_data = (void *)p_pic->p[0].p_pixels;
00725
00726 break;
00727
00728 case VLC_FOURCC('I','4','2','0'):
00729 p_pic->p_sys->p_data = (void *)&p_pic->p_sys->pixmap_i420;
00730 p_pic->p_sys->i_size = sizeof(PlanarPixmapInfoYUV420);
00731
00732
00733 p_pic->p_data = vlc_memalign( &p_pic->p_data_orig,
00734 16, p_vout->output.i_width * p_vout->output.i_height * 3 / 2 );
00735
00736
00737 p_pic->Y_PIXELS = p_pic->p_data;
00738 p_pic->p[Y_PLANE].i_lines = p_vout->output.i_height;
00739 p_pic->p[Y_PLANE].i_visible_lines = p_vout->output.i_height;
00740 p_pic->p[Y_PLANE].i_pitch = p_vout->output.i_width;
00741 p_pic->p[Y_PLANE].i_pixel_pitch = 1;
00742 p_pic->p[Y_PLANE].i_visible_pitch = p_vout->output.i_width;
00743
00744
00745 p_pic->U_PIXELS = p_pic->Y_PIXELS + p_vout->output.i_height * p_vout->output.i_width;
00746 p_pic->p[U_PLANE].i_lines = p_vout->output.i_height / 2;
00747 p_pic->p[U_PLANE].i_visible_lines = p_vout->output.i_height / 2;
00748 p_pic->p[U_PLANE].i_pitch = p_vout->output.i_width / 2;
00749 p_pic->p[U_PLANE].i_pixel_pitch = 1;
00750 p_pic->p[U_PLANE].i_visible_pitch = p_vout->output.i_width / 2;
00751
00752
00753 p_pic->V_PIXELS = p_pic->U_PIXELS + p_vout->output.i_height * p_vout->output.i_width / 4;
00754 p_pic->p[V_PLANE].i_lines = p_vout->output.i_height / 2;
00755 p_pic->p[V_PLANE].i_visible_lines = p_vout->output.i_height / 2;
00756 p_pic->p[V_PLANE].i_pitch = p_vout->output.i_width / 2;
00757 p_pic->p[V_PLANE].i_pixel_pitch = 1;
00758 p_pic->p[V_PLANE].i_visible_pitch = p_vout->output.i_width / 2;
00759
00760
00761 p_pic->i_planes = 3;
00762
00763 #define P p_pic->p_sys->pixmap_i420
00764 P.componentInfoY.offset = (void *)p_pic->Y_PIXELS
00765 - p_pic->p_sys->p_data;
00766 P.componentInfoCb.offset = (void *)p_pic->U_PIXELS
00767 - p_pic->p_sys->p_data;
00768 P.componentInfoCr.offset = (void *)p_pic->V_PIXELS
00769 - p_pic->p_sys->p_data;
00770
00771 P.componentInfoY.rowBytes = p_vout->output.i_width;
00772 P.componentInfoCb.rowBytes = p_vout->output.i_width / 2;
00773 P.componentInfoCr.rowBytes = p_vout->output.i_width / 2;
00774 #undef P
00775 break;
00776
00777 default:
00778
00779 free( p_pic->p_sys );
00780 msg_Err( p_vout, "never heard of chroma 0x%.8x (%4.4s)",
00781 p_vout->output.i_chroma, (char*)&p_vout->output.i_chroma );
00782 p_pic->i_planes = 0;
00783 return( -1 );
00784 }
00785
00786 return( 0 );
00787 }
00788
00789
00790
00791
00792 static void QTFreePicture( vout_thread_t *p_vout, picture_t *p_pic )
00793 {
00794 switch( p_vout->output.i_chroma )
00795 {
00796 case VLC_FOURCC('I','4','2','0'):
00797 free( p_pic->p_data_orig );
00798 break;
00799 }
00800
00801 free( p_pic->p_sys );
00802 }
00803
00804
00805
00806
00807 @implementation VLCQTView
00808
00809 - (id) initWithVout:(vout_thread_t *)_p_vout
00810 {
00811 p_vout = _p_vout;
00812 return [super init];
00813 }
00814
00815 - (void)drawRect:(NSRect)rect
00816 {
00817 [[NSColor blackColor] set];
00818 NSRectFill( rect );
00819 [super drawRect: rect];
00820
00821 p_vout->i_changes |= VOUT_SIZE_CHANGE;
00822 }
00823
00824 @end