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 #include <vlc/vlc.h>
00030 #include <vlc/aout.h>
00031 #include <vlc/vout.h>
00032 #include <vlc/decoder.h>
00033
00034 #if !defined (SYS_DARWIN) && !defined(WIN32)
00035 # define LOADER 1
00036 #endif
00037
00038 #ifdef SYS_DARWIN
00039 #include <QuickTime/QuickTimeComponents.h>
00040 #include <QuickTime/Movies.h>
00041 #include <QuickTime/ImageCodec.h>
00042 #endif
00043
00044
00045 #ifdef LOADER
00046 #include "qtx/qtxsdk/components.h"
00047 #include "wine/windef.h"
00048 #include "ldt_keeper.h"
00049
00050 HMODULE WINAPI LoadLibraryA(LPCSTR);
00051 FARPROC WINAPI GetProcAddress(HMODULE,LPCSTR);
00052 int WINAPI FreeLibrary(HMODULE);
00053
00054 #endif
00055
00056
00057
00058
00059 static int Open ( vlc_object_t * );
00060 static void Close( vlc_object_t * );
00061
00062 vlc_module_begin();
00063 set_description( _("QuickTime library decoder") );
00064 set_capability( "decoder", 10 );
00065 set_category( CAT_INPUT );
00066 set_subcategory( SUBCAT_INPUT_VCODEC );
00067 set_callbacks( Open, Close );
00068
00069
00070 var_Create( p_module->p_libvlc, "qt_mutex", VLC_VAR_MUTEX );
00071 vlc_module_end();
00072
00073
00074
00075
00076
00077 static int OpenAudio( decoder_t * );
00078 static int OpenVideo( decoder_t * );
00079
00080 static aout_buffer_t *DecodeAudio( decoder_t *, block_t ** );
00081 static picture_t *DecodeVideo( decoder_t *, block_t ** );
00082
00083 #define FCC( a, b , c, d ) \
00084 ((uint32_t)( ((a)<<24)|((b)<<16)|((c)<<8)|(d)))
00085
00086 #ifndef SYS_DARWIN
00087 typedef struct OpaqueSoundConverter* SoundConverter;
00088 #ifndef LOADER
00089 typedef long OSType;
00090 typedef int OSErr;
00091 #endif
00092 typedef unsigned long UnsignedFixed;
00093 typedef uint8_t Byte;
00094
00095 typedef struct SoundComponentData {
00096 long flags;
00097 OSType format;
00098 short numChannels;
00099 short sampleSize;
00100 UnsignedFixed sampleRate;
00101 long sampleCount;
00102 Byte * buffer;
00103 long reserved;
00104 } SoundComponentData;
00105
00106 #endif
00107
00108 struct decoder_sys_t
00109 {
00110
00111 #ifndef SYS_DARWIN
00112 #ifdef LOADER
00113 ldt_fs_t *ldt_fs;
00114
00115 #endif
00116 HMODULE qtml;
00117 OSErr (*InitializeQTML) ( long flags );
00118 OSErr (*TerminateQTML) ( void );
00119 #endif
00120
00121
00122 int (*SoundConverterOpen) ( const SoundComponentData *,
00123 const SoundComponentData *,
00124 SoundConverter* );
00125 int (*SoundConverterClose) ( SoundConverter );
00126 int (*SoundConverterSetInfo) ( SoundConverter , OSType, void * );
00127 int (*SoundConverterGetBufferSizes) ( SoundConverter, unsigned long,
00128 unsigned long*, unsigned long*,
00129 unsigned long* );
00130 int (*SoundConverterBeginConversion)( SoundConverter );
00131 int (*SoundConverterEndConversion) ( SoundConverter, void *,
00132 unsigned long *, unsigned long *);
00133 int (*SoundConverterConvertBuffer) ( SoundConverter, const void *,
00134 unsigned long, void *,
00135 unsigned long *, unsigned long * );
00136 SoundConverter myConverter;
00137 SoundComponentData InputFormatInfo, OutputFormatInfo;
00138
00139 long FramesToGet;
00140 unsigned int InFrameSize;
00141 unsigned int OutFrameSize;
00142
00143 #ifndef WIN32
00144
00145 Component (*FindNextComponent)
00146 ( Component prev, ComponentDescription* desc );
00147
00148 ComponentInstance (*OpenComponent)
00149 ( Component c );
00150
00151 ComponentResult (*ImageCodecInitialize)
00152 ( ComponentInstance ci, ImageSubCodecDecompressCapabilities * cap);
00153
00154 ComponentResult (*ImageCodecGetCodecInfo)
00155 ( ComponentInstance ci, CodecInfo *info );
00156
00157 ComponentResult (*ImageCodecPreDecompress)
00158 ( ComponentInstance ci, CodecDecompressParams * params );
00159
00160 ComponentResult (*ImageCodecBandDecompress)
00161 ( ComponentInstance ci, CodecDecompressParams * params );
00162
00163 PixMapHandle (*GetGWorldPixMap)
00164 ( GWorldPtr offscreenGWorld );
00165
00166 OSErr (*QTNewGWorldFromPtr)
00167 ( GWorldPtr *gw, OSType pixelFormat, const Rect *boundsRect,
00168 CTabHandle cTable, void *aGDevice,
00169 GWorldFlags flags, void *baseAddr, long rowBytes );
00170
00171 OSErr (*NewHandleClear)( Size byteCount );
00172
00173 ComponentInstance ci;
00174 Rect OutBufferRect;
00175 GWorldPtr OutBufferGWorld;
00176
00177
00178 ImageDescriptionHandle framedescHandle;
00179
00180 CodecDecompressParams decpar;
00181 CodecCapabilities codeccap;
00182 #endif
00183
00184
00185 uint8_t * plane;
00186 mtime_t pts;
00187 audio_date_t date;
00188
00189 int i_late;
00190
00191
00192 unsigned int i_buffer;
00193 unsigned int i_buffer_size;
00194 uint8_t *p_buffer;
00195
00196
00197 uint8_t out_buffer[1000000];
00198 int i_out_frames;
00199 int i_out;
00200 };
00201
00202 static int pi_channels_maps[6] =
00203 {
00204 0,
00205 AOUT_CHAN_CENTER,
00206 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
00207 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER,
00208 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT,
00209 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
00210 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT
00211 };
00212
00213 static int QTAudioInit( decoder_t * );
00214 static int QTVideoInit( decoder_t * );
00215
00216
00217
00218
00219
00220
00221
00222 static int Open( vlc_object_t *p_this )
00223 {
00224 decoder_t *p_dec = (decoder_t*)p_this;
00225
00226 switch( p_dec->fmt_in.i_codec )
00227 {
00228 case VLC_FOURCC('S','V','Q','3'):
00229
00230
00231
00232
00233 case VLC_FOURCC('r','l','e',' '):
00234 case VLC_FOURCC('r','p','z','a'):
00235 case VLC_FOURCC('a','z','p','r'):
00236 #ifdef LOADER
00237 p_dec->p_sys = NULL;
00238 p_dec->pf_decode_video = DecodeVideo;
00239 return VLC_SUCCESS;
00240 #else
00241 return OpenVideo( p_dec );
00242 #endif
00243
00244 case VLC_FOURCC('s','a','m','r'):
00245 case VLC_FOURCC('m','p','4','a'):
00246 case VLC_FOURCC('Q','D','M','C'):
00247 case VLC_FOURCC('Q','D','M','2'):
00248 case VLC_FOURCC('Q','c','l','p'):
00249 case VLC_FOURCC('Q','C','L','P'):
00250 case VLC_FOURCC('M','A','C','3'):
00251 case VLC_FOURCC('M','A','C','6'):
00252 case VLC_FOURCC('d','v','c','a'):
00253 case VLC_FOURCC('s','o','w','t'):
00254 case VLC_FOURCC('t','w','o','s'):
00255 case VLC_FOURCC('a','l','a','w'):
00256 case VLC_FOURCC('u','l','a','w'):
00257 case VLC_FOURCC('r','a','w',' '):
00258 case VLC_FOURCC('f','l','3','2'):
00259 case VLC_FOURCC('f','l','6','4'):
00260 case VLC_FOURCC('i','n','2','4'):
00261 case VLC_FOURCC('i','n','3','2'):
00262 case 0x0011:
00263 case 0x6D730002:
00264 case 0x6D730011:
00265 #ifdef LOADER
00266 p_dec->p_sys = NULL;
00267 p_dec->pf_decode_audio = DecodeAudio;
00268 return VLC_SUCCESS;
00269 #else
00270 return OpenAudio( p_dec );
00271 #endif
00272
00273 default:
00274 return VLC_EGENERIC;
00275 }
00276 }
00277
00278
00279
00280
00281 static void Close( vlc_object_t *p_this )
00282 {
00283 decoder_t *p_dec = (decoder_t*)p_this;
00284 decoder_sys_t *p_sys = p_dec->p_sys;
00285 vlc_value_t lockval;
00286
00287
00288 var_Get( p_dec->p_libvlc, "qt_mutex", &lockval );
00289 vlc_mutex_lock( lockval.p_address );
00290 #ifdef SYS_DARWIN
00291
00292 vlc_mutex_lock( &p_dec->p_vlc->quicktime_lock );
00293 #endif
00294
00295 if( p_dec->fmt_out.i_cat == AUDIO_ES )
00296 {
00297 int i_error;
00298 unsigned long ConvertedFrames=0;
00299 unsigned long ConvertedBytes=0;
00300
00301 i_error = p_sys->SoundConverterEndConversion( p_sys->myConverter, NULL,
00302 &ConvertedFrames,
00303 &ConvertedBytes );
00304 msg_Dbg( p_dec, "SoundConverterEndConversion => %d", i_error );
00305
00306 i_error = p_sys->SoundConverterClose( p_sys->myConverter );
00307 msg_Dbg( p_dec, "SoundConverterClose => %d", i_error );
00308
00309 free( p_sys->p_buffer );
00310 }
00311 else if( p_dec->fmt_out.i_cat == VIDEO_ES )
00312 {
00313 free( p_sys->plane );
00314 }
00315
00316 #ifndef SYS_DARWIN
00317 FreeLibrary( p_sys->qtml );
00318 msg_Dbg( p_dec, "FreeLibrary ok." );
00319 #endif
00320
00321 #ifdef SYS_DARWIN
00322 ExitMovies();
00323 #endif
00324
00325 #if 0
00326
00327 #ifdef LOADER
00328 Restore_LDT_Keeper( p_sys->ldt_fs );
00329 msg_Dbg( p_dec, "Restore_LDT_Keeper" );
00330 #endif
00331 #endif
00332
00333 #ifdef SYS_DARWIN
00334 vlc_mutex_unlock( &p_dec->p_vlc->quicktime_lock );
00335 #endif
00336 vlc_mutex_unlock( lockval.p_address );
00337
00338 free( p_sys );
00339 }
00340
00341
00342
00343
00344 static int OpenAudio( decoder_t *p_dec )
00345 {
00346 decoder_sys_t *p_sys = malloc( sizeof( decoder_sys_t ) );
00347
00348 vlc_value_t lockval;
00349 int i_error;
00350 char fcc[4];
00351 unsigned long WantedBufferSize;
00352 unsigned long InputBufferSize = 0;
00353 unsigned long OutputBufferSize = 0;
00354
00355 memset( p_sys, 0, sizeof( decoder_sys_t ) );
00356
00357 p_dec->p_sys = p_sys;
00358 p_dec->pf_decode_audio = DecodeAudio;
00359
00360 memcpy( fcc, &p_dec->fmt_in.i_codec, 4 );
00361
00362
00363 var_Get( p_dec->p_libvlc, "qt_mutex", &lockval );
00364 vlc_mutex_lock( lockval.p_address );
00365 #ifdef SYS_DARWIN
00366
00367 vlc_mutex_lock( &p_dec->p_vlc->quicktime_lock );
00368 #endif
00369
00370 #ifdef SYS_DARWIN
00371 EnterMovies();
00372 #endif
00373
00374 if( QTAudioInit( p_dec ) )
00375 {
00376 msg_Err( p_dec, "cannot initialize QT");
00377 goto exit_error;
00378 }
00379
00380 #ifndef SYS_DARWIN
00381 if( ( i_error = p_sys->InitializeQTML( 6 + 16 ) ) )
00382 {
00383 msg_Dbg( p_dec, "error on InitializeQTML = %d", i_error );
00384 goto exit_error;
00385 }
00386 #endif
00387
00388
00389 p_sys->InputFormatInfo.flags = 0;
00390 p_sys->InputFormatInfo.sampleCount = 0;
00391 p_sys->InputFormatInfo.buffer = NULL;
00392 p_sys->InputFormatInfo.reserved = 0;
00393 p_sys->InputFormatInfo.numChannels = p_dec->fmt_in.audio.i_channels;
00394 p_sys->InputFormatInfo.sampleSize = p_dec->fmt_in.audio.i_bitspersample;
00395 p_sys->InputFormatInfo.sampleRate = p_dec->fmt_in.audio.i_rate;
00396 p_sys->InputFormatInfo.format = FCC( fcc[0], fcc[1], fcc[2], fcc[3] );
00397
00398
00399 p_sys->OutputFormatInfo.flags = 0;
00400 p_sys->OutputFormatInfo.sampleCount = 0;
00401 p_sys->OutputFormatInfo.buffer = NULL;
00402 p_sys->OutputFormatInfo.reserved = 0;
00403 p_sys->OutputFormatInfo.numChannels = p_dec->fmt_in.audio.i_channels;
00404 p_sys->OutputFormatInfo.sampleSize = 16;
00405 p_sys->OutputFormatInfo.sampleRate = p_dec->fmt_in.audio.i_rate;
00406 p_sys->OutputFormatInfo.format = FCC( 'N', 'O', 'N', 'E' );
00407
00408
00409 i_error = p_sys->SoundConverterOpen( &p_sys->InputFormatInfo,
00410 &p_sys->OutputFormatInfo,
00411 &p_sys->myConverter );
00412 if( i_error )
00413 {
00414 msg_Err( p_dec, "error on SoundConverterOpen = %d", i_error );
00415 goto exit_error;
00416 }
00417
00418 #if 0
00419
00420 i_error = SoundConverterSetInfo( p_dec->myConverter, siClientAcceptsVBR,
00421 (void *)true );
00422 #endif
00423
00424 if( p_dec->fmt_in.i_extra > 36 + 8 )
00425 {
00426 i_error = p_sys->SoundConverterSetInfo( p_sys->myConverter,
00427 FCC( 'w', 'a', 'v', 'e' ),
00428 ((uint8_t*)p_dec->fmt_in.p_extra) + 36 + 8 );
00429
00430 msg_Dbg( p_dec, "error on SoundConverterSetInfo = %d", i_error );
00431 }
00432
00433 WantedBufferSize = p_sys->OutputFormatInfo.numChannels *
00434 p_sys->OutputFormatInfo.sampleRate * 2;
00435 p_sys->FramesToGet = 0;
00436
00437 i_error = p_sys->SoundConverterGetBufferSizes( p_sys->myConverter,
00438 WantedBufferSize,
00439 &p_sys->FramesToGet,
00440 &InputBufferSize,
00441 &OutputBufferSize );
00442
00443 msg_Dbg( p_dec, "WantedBufferSize=%li InputBufferSize=%li "
00444 "OutputBufferSize=%li FramesToGet=%li",
00445 WantedBufferSize, InputBufferSize, OutputBufferSize,
00446 p_sys->FramesToGet );
00447
00448 p_sys->InFrameSize = (InputBufferSize + p_sys->FramesToGet - 1 ) /
00449 p_sys->FramesToGet;
00450 p_sys->OutFrameSize = OutputBufferSize / p_sys->FramesToGet;
00451
00452 msg_Dbg( p_dec, "frame size %d -> %d",
00453 p_sys->InFrameSize, p_sys->OutFrameSize );
00454
00455 if( (i_error = p_sys->SoundConverterBeginConversion(p_sys->myConverter)) )
00456 {
00457 msg_Err( p_dec,
00458 "error on SoundConverterBeginConversion = %d", i_error );
00459 goto exit_error;
00460 }
00461
00462
00463 es_format_Init( &p_dec->fmt_out, AUDIO_ES, AOUT_FMT_S16_NE );
00464 p_dec->fmt_out.audio.i_rate = p_sys->OutputFormatInfo.sampleRate;
00465 p_dec->fmt_out.audio.i_channels = p_sys->OutputFormatInfo.numChannels;
00466 p_dec->fmt_out.audio.i_physical_channels =
00467 p_dec->fmt_out.audio.i_original_channels =
00468 pi_channels_maps[p_sys->OutputFormatInfo.numChannels];
00469
00470 aout_DateInit( &p_sys->date, p_dec->fmt_out.audio.i_rate );
00471
00472 p_sys->i_buffer = 0;
00473 p_sys->i_buffer_size = 100*1000;
00474 p_sys->p_buffer = malloc( p_sys->i_buffer_size );
00475
00476 p_sys->i_out = 0;
00477 p_sys->i_out_frames = 0;
00478
00479 #ifdef SYS_DARWIN
00480 vlc_mutex_unlock( &p_dec->p_vlc->quicktime_lock );
00481 #endif
00482 vlc_mutex_unlock( lockval.p_address );
00483 return VLC_SUCCESS;
00484
00485 exit_error:
00486
00487 #ifdef LOADER
00488 Restore_LDT_Keeper( p_sys->ldt_fs );
00489 #endif
00490 #ifdef SYS_DARWIN
00491 vlc_mutex_unlock( &p_dec->p_vlc->quicktime_lock );
00492 #endif
00493 vlc_mutex_unlock( lockval.p_address );
00494
00495 free( p_sys );
00496 return VLC_EGENERIC;
00497 }
00498
00499
00500
00501
00502 static aout_buffer_t *DecodeAudio( decoder_t *p_dec, block_t **pp_block )
00503 {
00504 decoder_sys_t *p_sys = p_dec->p_sys;
00505
00506 vlc_value_t lockval;
00507 block_t *p_block;
00508 int i_error;
00509
00510 #ifdef LOADER
00511
00512
00513 if( p_sys == NULL )
00514 {
00515 if( OpenAudio( p_dec ) )
00516 {
00517
00518 p_dec->b_error = VLC_TRUE;
00519 return NULL;
00520 }
00521
00522 p_sys = p_dec->p_sys;
00523 }
00524 #endif
00525
00526 if( pp_block == NULL || *pp_block == NULL )
00527 {
00528 return NULL;
00529 }
00530 p_block = *pp_block;
00531
00532 if( p_sys->i_out_frames > 0 && p_sys->i_out >= p_sys->i_out_frames )
00533 {
00534
00535 p_sys->i_out = 0;
00536 p_sys->i_out_frames = 0;
00537
00538 *pp_block = NULL;
00539 return NULL;
00540 }
00541
00542 if( p_sys->i_out_frames <= 0 )
00543 {
00544 if( ( p_sys->pts = p_block->i_pts ) < mdate() )
00545 {
00546 block_Release( p_block );
00547 *pp_block = NULL;
00548 return NULL;
00549 }
00550
00551
00552 if( p_sys->i_buffer_size < p_sys->i_buffer + p_block->i_buffer )
00553 {
00554 p_sys->i_buffer_size = p_sys->i_buffer + p_block->i_buffer + 1024;
00555 p_sys->p_buffer = realloc( p_sys->p_buffer, p_sys->i_buffer_size );
00556 }
00557 memcpy( &p_sys->p_buffer[p_sys->i_buffer], p_block->p_buffer,
00558 p_block->i_buffer );
00559 p_sys->i_buffer += p_block->i_buffer;
00560
00561 if( p_sys->i_buffer > p_sys->InFrameSize )
00562 {
00563 int i_frames = p_sys->i_buffer / p_sys->InFrameSize;
00564 long i_out_frames, i_out_bytes;
00565
00566 var_Get( p_dec->p_libvlc, "qt_mutex", &lockval );
00567 vlc_mutex_lock( lockval.p_address );
00568 i_error = p_sys->SoundConverterConvertBuffer( p_sys->myConverter,
00569 p_sys->p_buffer,
00570 i_frames,
00571 p_sys->out_buffer,
00572 &i_out_frames,
00573 &i_out_bytes );
00574 vlc_mutex_unlock( lockval.p_address );
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584 p_sys->i_buffer -= i_frames * p_sys->InFrameSize;
00585 if( p_sys->i_buffer > 0 )
00586 {
00587 memmove( &p_sys->p_buffer[0],
00588 &p_sys->p_buffer[i_frames * p_sys->InFrameSize],
00589 p_sys->i_buffer );
00590 }
00591
00592 if( p_sys->pts != 0 &&
00593 p_sys->pts != aout_DateGet( &p_sys->date ) )
00594 {
00595 aout_DateSet( &p_sys->date, p_sys->pts );
00596 }
00597 else if( !aout_DateGet( &p_sys->date ) )
00598 {
00599 return NULL;
00600 }
00601
00602 if( !i_error && i_out_frames > 0 )
00603 {
00604
00605 p_sys->i_out_frames = i_out_frames;
00606 p_sys->i_out = 0;
00607 }
00608 }
00609 }
00610
00611 if( p_sys->i_out < p_sys->i_out_frames )
00612 {
00613 aout_buffer_t *p_out;
00614 int i_frames = __MIN( p_sys->i_out_frames - p_sys->i_out, 1000 );
00615
00616 p_out = p_dec->pf_aout_buffer_new( p_dec, i_frames );
00617
00618 if( p_out )
00619 {
00620 p_out->start_date = aout_DateGet( &p_sys->date );
00621 p_out->end_date = aout_DateIncrement( &p_sys->date, i_frames );
00622
00623 memcpy( p_out->p_buffer,
00624 &p_sys->out_buffer[2 * p_sys->i_out * p_dec->fmt_out.audio.i_channels],
00625 p_out->i_nb_bytes );
00626
00627 p_sys->i_out += i_frames;
00628 }
00629 return p_out;
00630 }
00631
00632 return NULL;
00633 }
00634
00635
00636
00637
00638 static int OpenVideo( decoder_t *p_dec )
00639 {
00640 decoder_sys_t *p_sys = malloc( sizeof( decoder_sys_t ) );
00641
00642 #ifndef WIN32
00643 vlc_value_t lockval;
00644 long i_result;
00645 ComponentDescription desc;
00646 Component prev;
00647 ComponentResult cres;
00648 ImageSubCodecDecompressCapabilities icap;
00649 CodecInfo cinfo;
00650 ImageDescription *id;
00651
00652 char fcc[4];
00653 int i_vide = p_dec->fmt_in.i_extra;
00654 uint8_t *p_vide = p_dec->fmt_in.p_extra;
00655
00656 p_dec->p_sys = p_sys;
00657 p_dec->pf_decode_video = DecodeVideo;
00658 p_sys->i_late = 0;
00659
00660 if( i_vide <= 0 )
00661 {
00662 msg_Err( p_dec, "missing extra info" );
00663 free( p_sys );
00664 return VLC_EGENERIC;
00665 }
00666
00667 memcpy( fcc, &p_dec->fmt_in.i_codec, 4 );
00668 msg_Dbg( p_dec, "quicktime_video %4.4s %dx%d",
00669 fcc, p_dec->fmt_in.video.i_width, p_dec->fmt_in.video.i_height );
00670
00671
00672 var_Get( p_dec->p_libvlc, "qt_mutex", &lockval );
00673 vlc_mutex_lock( lockval.p_address );
00674
00675 #ifdef SYS_DARWIN
00676 EnterMovies();
00677 #endif
00678
00679 if( QTVideoInit( p_dec ) )
00680 {
00681 msg_Err( p_dec, "cannot initialize QT");
00682 goto exit_error;
00683 }
00684
00685 #ifndef SYS_DARWIN
00686 if( ( i_result = p_sys->InitializeQTML( 6 + 16 ) ) )
00687 {
00688 msg_Dbg( p_dec, "error on InitializeQTML = %d", (int)i_result );
00689 goto exit_error;
00690 }
00691 #endif
00692
00693
00694 memset( &desc, 0, sizeof( ComponentDescription ) );
00695 desc.componentType = FCC( 'i', 'm', 'd', 'c' );
00696 desc.componentSubType = FCC( fcc[0], fcc[1], fcc[2], fcc[3] );
00697 desc.componentManufacturer = 0;
00698 desc.componentFlags = 0;
00699 desc.componentFlagsMask = 0;
00700
00701 if( !( prev = p_sys->FindNextComponent( NULL, &desc ) ) )
00702 {
00703 msg_Err( p_dec, "cannot find requested component" );
00704 goto exit_error;
00705 }
00706 msg_Dbg( p_dec, "component id=0x%p", prev );
00707
00708 p_sys->ci = p_sys->OpenComponent( prev );
00709 msg_Dbg( p_dec, "component instance p=0x%p", p_sys->ci );
00710
00711 memset( &icap, 0, sizeof( ImageSubCodecDecompressCapabilities ) );
00712 cres = p_sys->ImageCodecInitialize( p_sys->ci, &icap );
00713
00714
00715 memset( &cinfo, 0, sizeof( CodecInfo ) );
00716 cres = p_sys->ImageCodecGetCodecInfo( p_sys->ci, &cinfo );
00717 msg_Dbg( p_dec,
00718 "Flags: compr: 0x%lx decomp: 0x%lx format: 0x%lx\n",
00719 cinfo.compressFlags, cinfo.decompressFlags, cinfo.formatFlags );
00720 msg_Dbg( p_dec, "quicktime_video: Codec name: %.*s\n",
00721 ((unsigned char*)&cinfo.typeName)[0],
00722 ((unsigned char*)&cinfo.typeName)+1 );
00723
00724
00725 p_sys->OutBufferRect.top = 0;
00726 p_sys->OutBufferRect.left = 0;
00727 p_sys->OutBufferRect.right = p_dec->fmt_in.video.i_width;
00728 p_sys->OutBufferRect.bottom = p_dec->fmt_in.video.i_height;
00729
00730
00731
00732 msg_Dbg( p_dec, "vide = %d", i_vide );
00733 id = malloc( sizeof( ImageDescription ) + ( i_vide - 70 ) );
00734 id->idSize = sizeof( ImageDescription ) + ( i_vide - 70 );
00735 id->cType = FCC( fcc[0], fcc[1], fcc[2], fcc[3] );
00736 id->version = GetWBE ( p_vide + 0 );
00737 id->revisionLevel = GetWBE ( p_vide + 2 );
00738 id->vendor = GetDWBE( p_vide + 4 );
00739 id->temporalQuality = GetDWBE( p_vide + 8 );
00740 id->spatialQuality = GetDWBE( p_vide + 12 );
00741 id->width = GetWBE ( p_vide + 16 );
00742 id->height = GetWBE ( p_vide + 18 );
00743 id->hRes = GetDWBE( p_vide + 20 );
00744 id->vRes = GetDWBE( p_vide + 24 );
00745 id->dataSize = GetDWBE( p_vide + 28 );
00746 id->frameCount = GetWBE ( p_vide + 32 );
00747 memcpy( &id->name, p_vide + 34, 32 );
00748 id->depth = GetWBE ( p_vide + 66 );
00749 id->clutID = GetWBE ( p_vide + 68 );
00750 if( i_vide > 70 )
00751 {
00752 memcpy( ((char*)&id->clutID) + 2, p_vide + 70, i_vide - 70 );
00753 }
00754
00755 msg_Dbg( p_dec, "idSize=%ld ver=%d rev=%d vendor=%ld tempQ=%d "
00756 "spaQ=%d w=%d h=%d dpi=%d%d dataSize=%d frameCount=%d clutID=%d",
00757 id->idSize, id->version, id->revisionLevel, id->vendor,
00758 (int)id->temporalQuality, (int)id->spatialQuality,
00759 id->width, id->height,
00760 (int)id->hRes, (int)id->vRes,
00761 (int)id->dataSize,
00762 id->frameCount,
00763 id->clutID );
00764
00765 p_sys->framedescHandle =
00766 (ImageDescriptionHandle) p_sys->NewHandleClear( id->idSize );
00767 memcpy( *p_sys->framedescHandle, id, id->idSize );
00768
00769 p_sys->plane = malloc( p_dec->fmt_in.video.i_width * p_dec->fmt_in.video.i_height * 3 );
00770
00771 i_result = p_sys->QTNewGWorldFromPtr( &p_sys->OutBufferGWorld,
00772
00773 kYUVSPixelFormat,
00774
00775
00776 &p_sys->OutBufferRect,
00777 0, 0, 0,
00778 p_sys->plane,
00779 p_dec->fmt_in.video.i_width * 2 );
00780
00781 msg_Dbg( p_dec, "NewGWorldFromPtr returned:%ld\n",
00782 65536 - ( i_result&0xffff ) );
00783
00784 memset( &p_sys->decpar, 0, sizeof( CodecDecompressParams ) );
00785 p_sys->decpar.imageDescription = p_sys->framedescHandle;
00786 p_sys->decpar.startLine = 0;
00787 p_sys->decpar.stopLine = ( **p_sys->framedescHandle ).height;
00788 p_sys->decpar.frameNumber = 1;
00789 p_sys->decpar.matrixFlags = 0;
00790 p_sys->decpar.matrixType = 0;
00791 p_sys->decpar.matrix = 0;
00792 p_sys->decpar.capabilities = &p_sys->codeccap;
00793 p_sys->decpar.accuracy = codecNormalQuality;
00794 p_sys->decpar.srcRect = p_sys->OutBufferRect;
00795 p_sys->decpar.transferMode = srcCopy;
00796 p_sys->decpar.dstPixMap = **p_sys->GetGWorldPixMap( p_sys->OutBufferGWorld );
00797
00798 cres = p_sys->ImageCodecPreDecompress( p_sys->ci, &p_sys->decpar );
00799 msg_Dbg( p_dec, "quicktime_video: ImageCodecPreDecompress cres=0x%X\n",
00800 (int)cres );
00801
00802 p_dec->fmt_out.i_codec = VLC_FOURCC( 'Y', 'U', 'Y', '2' );
00803 p_dec->fmt_out.video.i_width = p_dec->fmt_in.video.i_width;
00804 p_dec->fmt_out.video.i_height= p_dec->fmt_in.video.i_height;
00805 p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR * p_dec->fmt_in.video.i_width / p_dec->fmt_in.video.i_height;
00806
00807
00808 vlc_mutex_unlock( lockval.p_address );
00809 return VLC_SUCCESS;
00810
00811 exit_error:
00812 #ifdef LOADER
00813 Restore_LDT_Keeper( p_sys->ldt_fs );
00814 #endif
00815 vlc_mutex_unlock( lockval.p_address );
00816
00817 #endif
00818
00819 return VLC_EGENERIC;
00820 }
00821
00822 #ifndef WIN32
00823
00824
00825
00826 static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
00827 {
00828 decoder_sys_t *p_sys = p_dec->p_sys;
00829 block_t *p_block;
00830 picture_t *p_pic;
00831 mtime_t i_pts;
00832
00833 ComponentResult cres;
00834
00835 #ifdef LOADER
00836
00837
00838 if( p_sys == NULL )
00839 {
00840 if( OpenVideo( p_dec ) )
00841 {
00842
00843 p_dec->b_error = VLC_TRUE;
00844 return NULL;
00845 }
00846 p_sys = p_dec->p_sys;
00847 }
00848 #endif
00849
00850 if( pp_block == NULL || *pp_block == NULL )
00851 {
00852 return NULL;
00853 }
00854 p_block = *pp_block;
00855 *pp_block = NULL;
00856
00857 i_pts = p_block->i_pts ? p_block->i_pts : p_block->i_dts;
00858
00859 if( i_pts < mdate() )
00860 {
00861 p_sys->i_late++;
00862 }
00863 else
00864 {
00865 p_sys->i_late = 0;
00866 }
00867
00868 if( p_sys->i_late > 10 )
00869 {
00870 msg_Dbg( p_dec, "too late buffer -> dropped" );
00871 block_Release( p_block );
00872 return NULL;
00873 }
00874
00875 if( ( p_pic = p_dec->pf_vout_buffer_new( p_dec ) ) )
00876 {
00877 vlc_value_t lockval;
00878
00879 p_sys->decpar.data = p_block->p_buffer;
00880 p_sys->decpar.bufferSize = p_block->i_buffer;
00881 (**p_sys->framedescHandle).dataSize = p_block->i_buffer;
00882
00883 var_Get( p_dec->p_libvlc, "qt_mutex", &lockval );
00884 vlc_mutex_lock( lockval.p_address );
00885 cres = p_sys->ImageCodecBandDecompress( p_sys->ci, &p_sys->decpar );
00886 vlc_mutex_unlock( lockval.p_address );
00887
00888 ++p_sys->decpar.frameNumber;
00889
00890 if( cres &0xFFFF )
00891 {
00892 msg_Dbg( p_dec, "quicktime_video: ImageCodecBandDecompress"
00893 " cres=0x%X (-0x%X) %d :(\n",
00894 (int)cres,(int)-cres, (int)cres );
00895 }
00896
00897 memcpy( p_pic->p[0].p_pixels, p_sys->plane,
00898 p_dec->fmt_in.video.i_width * p_dec->fmt_in.video.i_height * 2 );
00899 p_pic->date = i_pts;
00900 }
00901 block_Release( p_block );
00902
00903 return p_pic;
00904 }
00905 #endif
00906
00907
00908
00909
00910 static int QTAudioInit( decoder_t *p_dec )
00911 {
00912 decoder_sys_t *p_sys = p_dec->p_sys;
00913
00914 #ifdef SYS_DARWIN
00915 p_sys->SoundConverterOpen = (void*)SoundConverterOpen;
00916 p_sys->SoundConverterClose = (void*)SoundConverterClose;
00917 p_sys->SoundConverterSetInfo = (void*)SoundConverterSetInfo;
00918 p_sys->SoundConverterGetBufferSizes = (void*)SoundConverterGetBufferSizes;
00919 p_sys->SoundConverterConvertBuffer = (void*)SoundConverterConvertBuffer;
00920 p_sys->SoundConverterBeginConversion= (void*)SoundConverterBeginConversion;
00921 p_sys->SoundConverterEndConversion = (void*)SoundConverterEndConversion;
00922 #else
00923
00924 #ifdef LOADER
00925 p_sys->ldt_fs = Setup_LDT_Keeper();
00926 #endif
00927
00928 p_sys->qtml = LoadLibraryA( "qtmlClient.dll" );
00929 if( p_sys->qtml == NULL )
00930 {
00931 msg_Dbg( p_dec, "failed loading qtmlClient.dll" );
00932 return VLC_EGENERIC;
00933 }
00934
00935 p_sys->InitializeQTML = (void *)GetProcAddress( p_sys->qtml, "InitializeQTML" );
00936 p_sys->TerminateQTML = (void *)GetProcAddress( p_sys->qtml, "TerminateQTML" );
00937 p_sys->SoundConverterOpen = (void *)GetProcAddress( p_sys->qtml, "SoundConverterOpen" );
00938 p_sys->SoundConverterClose = (void *)GetProcAddress( p_sys->qtml, "SoundConverterClose" );
00939 p_sys->SoundConverterSetInfo = (void *)GetProcAddress( p_sys->qtml, "SoundConverterSetInfo" );
00940 p_sys->SoundConverterGetBufferSizes = (void *)GetProcAddress( p_sys->qtml, "SoundConverterGetBufferSizes" );
00941 p_sys->SoundConverterConvertBuffer = (void *)GetProcAddress( p_sys->qtml, "SoundConverterConvertBuffer" );
00942 p_sys->SoundConverterEndConversion = (void *)GetProcAddress( p_sys->qtml, "SoundConverterEndConversion" );
00943 p_sys->SoundConverterBeginConversion= (void *)GetProcAddress( p_sys->qtml, "SoundConverterBeginConversion");
00944
00945 if( p_sys->InitializeQTML == NULL )
00946 {
00947 msg_Err( p_dec, "failed getting proc address InitializeQTML" );
00948 return VLC_EGENERIC;
00949 }
00950 if( p_sys->SoundConverterOpen == NULL ||
00951 p_sys->SoundConverterClose == NULL ||
00952 p_sys->SoundConverterSetInfo == NULL ||
00953 p_sys->SoundConverterGetBufferSizes == NULL ||
00954 p_sys->SoundConverterConvertBuffer == NULL ||
00955 p_sys->SoundConverterEndConversion == NULL ||
00956 p_sys->SoundConverterBeginConversion == NULL )
00957 {
00958 msg_Err( p_dec, "failed getting proc address" );
00959 return VLC_EGENERIC;
00960 }
00961
00962 msg_Dbg( p_dec, "Standard init done" );
00963 #endif
00964
00965 return VLC_SUCCESS;
00966 }
00967
00968 #ifndef WIN32
00969
00970
00971
00972 static int QTVideoInit( decoder_t *p_dec )
00973 {
00974 decoder_sys_t *p_sys = p_dec->p_sys;
00975
00976 #ifdef SYS_DARWIN
00977 p_sys->FindNextComponent = (void*)FindNextComponent;
00978 p_sys->OpenComponent = (void*)OpenComponent;
00979 p_sys->ImageCodecInitialize = (void*)ImageCodecInitialize;
00980 p_sys->ImageCodecGetCodecInfo = (void*)ImageCodecGetCodecInfo;
00981 p_sys->ImageCodecPreDecompress = (void*)ImageCodecPreDecompress;
00982 p_sys->ImageCodecBandDecompress = (void*)ImageCodecBandDecompress;
00983 p_sys->GetGWorldPixMap = (void*)GetGWorldPixMap;
00984 p_sys->QTNewGWorldFromPtr = (void*)QTNewGWorldFromPtr;
00985 p_sys->NewHandleClear = (void*)NewHandleClear;
00986 #else
00987
00988 #ifdef LOADER
00989 p_sys->ldt_fs = Setup_LDT_Keeper();
00990 #endif
00991 p_sys->qtml = LoadLibraryA( "qtmlClient.dll" );
00992 if( p_sys->qtml == NULL )
00993 {
00994 msg_Dbg( p_dec, "failed loading qtmlClient.dll" );
00995 return VLC_EGENERIC;
00996 }
00997 msg_Dbg( p_dec, "qtmlClient.dll loaded" );
00998
00999
01000 p_sys->InitializeQTML = (void*)GetProcAddress( p_sys->qtml, "InitializeQTML" );
01001 p_sys->FindNextComponent = (void*)GetProcAddress( p_sys->qtml, "FindNextComponent" );
01002 p_sys->OpenComponent = (void*)GetProcAddress( p_sys->qtml, "OpenComponent" );
01003 p_sys->ImageCodecInitialize = (void*)GetProcAddress( p_sys->qtml, "ImageCodecInitialize" );
01004 p_sys->ImageCodecGetCodecInfo = (void*)GetProcAddress( p_sys->qtml, "ImageCodecGetCodecInfo" );
01005 p_sys->ImageCodecPreDecompress = (void*)GetProcAddress( p_sys->qtml, "ImageCodecPreDecompress" );
01006 p_sys->ImageCodecBandDecompress = (void*)GetProcAddress( p_sys->qtml, "ImageCodecBandDecompress" );
01007 p_sys->GetGWorldPixMap = (void*)GetProcAddress( p_sys->qtml, "GetGWorldPixMap" );
01008 p_sys->QTNewGWorldFromPtr = (void*)GetProcAddress( p_sys->qtml, "QTNewGWorldFromPtr" );
01009 p_sys->NewHandleClear = (void*)GetProcAddress( p_sys->qtml, "NewHandleClear" );
01010
01011 if( p_sys->InitializeQTML == NULL )
01012 {
01013 msg_Dbg( p_dec, "failed getting proc address InitializeQTML" );
01014 return VLC_EGENERIC;
01015 }
01016 if( p_sys->FindNextComponent == NULL ||
01017 p_sys->OpenComponent == NULL ||
01018 p_sys->ImageCodecInitialize == NULL ||
01019 p_sys->ImageCodecGetCodecInfo == NULL ||
01020 p_sys->ImageCodecPreDecompress == NULL ||
01021 p_sys->ImageCodecBandDecompress == NULL ||
01022 p_sys->GetGWorldPixMap == NULL ||
01023 p_sys->QTNewGWorldFromPtr == NULL ||
01024 p_sys->NewHandleClear == NULL )
01025 {
01026 msg_Err( p_dec, "failed getting proc address" );
01027 return VLC_EGENERIC;
01028 }
01029 #endif
01030
01031 return VLC_SUCCESS;
01032 }
01033 #endif