quicktime.c 35.9 KB
Newer Older
hartman's avatar
hartman committed
1
2
3
4
/*****************************************************************************
 * quicktime.c: a quicktime decoder that uses the QT library/dll
 *****************************************************************************
 * Copyright (C) 2003 VideoLAN
5
 * $Id$
hartman's avatar
hartman committed
6
7
8
9
10
11
12
13
 *
 * Authors: Laurent Aimar <fenrir at via.ecp.fr>
 *          Derk-Jan Hartman <thedj at users.sf.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
14
 *
hartman's avatar
hartman committed
15
16
17
18
19
20
21
22
23
24
25
26
27
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
28

hartman's avatar
hartman committed
29
30
31
32
33
34
35
36
37
38
39
#include <vlc/vlc.h>
#include <vlc/aout.h>
#include <vlc/vout.h>
#include <vlc/decoder.h>

#ifdef SYS_DARWIN
#include <QuickTime/QuickTimeComponents.h>
#include <QuickTime/Movies.h>
#include <QuickTime/ImageCodec.h>
#endif

40
41
42
43
44
/* for windows do we require Quicktime compents header? */
#ifdef LOADER
#include "w32dll/loader/qtx/qtxsdk/components.h"
#include "w32dll/loader/wine/windef.h"
#include "w32dll/loader/ldt_keeper.h"
gbazin's avatar
   
gbazin committed
45
46
47
48
49

HMODULE   WINAPI LoadLibraryA(LPCSTR);
FARPROC   WINAPI GetProcAddress(HMODULE,LPCSTR);
int       WINAPI FreeLibrary(HMODULE);

50
51
#endif

hartman's avatar
hartman committed
52
53
54
/*****************************************************************************
 * Module descriptor
 *****************************************************************************/
55
56
static int  Open ( vlc_object_t * );
static void Close( vlc_object_t * );
hartman's avatar
hartman committed
57
58

vlc_module_begin();
59
    set_description( _("QuickTime library decoder") );
60
    set_capability( "decoder", 10 );
61
    set_callbacks( Open, Close );
hartman's avatar
hartman committed
62
63
64
65
66

    /* create a mutex */
    var_Create( p_module->p_libvlc, "qt_mutex", VLC_VAR_MUTEX );
vlc_module_end();

67
68
69
70
71
72
73
74
75
76

/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
static int           OpenAudio( decoder_t * );
static int           OpenVideo( decoder_t * );

static aout_buffer_t *DecodeAudio( decoder_t *, block_t ** );
static picture_t     *DecodeVideo( decoder_t *, block_t ** );

hartman's avatar
hartman committed
77
78
79
#define FCC( a, b , c, d ) \
    ((uint32_t)( ((a)<<24)|((b)<<16)|((c)<<8)|(d)))

80
#ifndef SYS_DARWIN
hartman's avatar
hartman committed
81
typedef struct OpaqueSoundConverter*    SoundConverter;
82
#ifndef LOADER
gbazin's avatar
   
gbazin committed
83
84
typedef long                            OSType;
typedef int                             OSErr;
85
#endif
hartman's avatar
hartman committed
86
typedef unsigned long                   UnsignedFixed;
gbazin's avatar
   
gbazin committed
87
88
typedef uint8_t                         Byte;

hartman's avatar
hartman committed
89
90
91
92
93
94
95
96
97
98
typedef struct SoundComponentData {
    long                            flags;
    OSType                          format;
    short                           numChannels;
    short                           sampleSize;
    UnsignedFixed                   sampleRate;
    long                            sampleCount;
    Byte *                          buffer;
    long                            reserved;
} SoundComponentData;
gbazin's avatar
   
gbazin committed
99

100
#endif /* SYS_DARWIN */
hartman's avatar
hartman committed
101

102
struct decoder_sys_t
hartman's avatar
hartman committed
103
104
{
    /* library */
105
#ifndef SYS_DARWIN
hartman's avatar
hartman committed
106
107
#ifdef LOADER
    ldt_fs_t    *ldt_fs;
gbazin's avatar
   
gbazin committed
108

109
#endif /* LOADER */
gbazin's avatar
   
gbazin committed
110
111
112
    HMODULE qtml;
    OSErr (*InitializeQTML)             ( long flags );
    OSErr (*TerminateQTML)              ( void );
113
#endif /* SYS_DARWIN */
gbazin's avatar
   
gbazin committed
114

115
    /* Audio */
gbazin's avatar
   
gbazin committed
116
117
118
119
120
121
122
123
124
125
126
127
128
129
    int (*SoundConverterOpen)           ( const SoundComponentData *,
                                          const SoundComponentData *,
                                          SoundConverter* );
    int (*SoundConverterClose)          ( SoundConverter );
    int (*SoundConverterSetInfo)        ( SoundConverter , OSType, void * );
    int (*SoundConverterGetBufferSizes) ( SoundConverter, unsigned long,
                                          unsigned long*, unsigned long*,
                                          unsigned long* );
    int (*SoundConverterBeginConversion)( SoundConverter );
    int (*SoundConverterEndConversion)  ( SoundConverter, void *,
                                          unsigned long *, unsigned long *);
    int (*SoundConverterConvertBuffer)  ( SoundConverter, const void *,
                                          unsigned long, void *,
                                          unsigned long *, unsigned long * );
hartman's avatar
hartman committed
130
131
132
133
134
135
136
    SoundConverter      myConverter;
    SoundComponentData  InputFormatInfo, OutputFormatInfo;

    long            FramesToGet;
    unsigned int    InFrameSize;
    unsigned int    OutFrameSize;

137
#ifndef WIN32
138
    /* Video */
gbazin's avatar
   
gbazin committed
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
    Component         (*FindNextComponent)
        ( Component prev, ComponentDescription* desc );

    ComponentInstance (*OpenComponent)
        ( Component c );

    ComponentResult   (*ImageCodecInitialize)
        ( ComponentInstance ci, ImageSubCodecDecompressCapabilities * cap);

    ComponentResult   (*ImageCodecGetCodecInfo)
        ( ComponentInstance ci, CodecInfo *info );

    ComponentResult   (*ImageCodecPreDecompress)
        ( ComponentInstance ci, CodecDecompressParams * params );

    ComponentResult   (*ImageCodecBandDecompress)
        ( ComponentInstance ci, CodecDecompressParams * params );

    PixMapHandle      (*GetGWorldPixMap)
        ( GWorldPtr offscreenGWorld );

    OSErr             (*QTNewGWorldFromPtr)
        ( GWorldPtr *gw, OSType pixelFormat, const Rect *boundsRect,
          CTabHandle cTable, /*GDHandle*/ void *aGDevice, /*unused*/
          GWorldFlags flags, void *baseAddr, long rowBytes );

165
    OSErr             (*NewHandleClear)( Size byteCount );
166
167
168
169
170
171
172
173

    ComponentInstance       ci;
    Rect                    OutBufferRect;   /* the dimensions of our GWorld */
    GWorldPtr               OutBufferGWorld; /* a GWorld is some kind of
                                                description for a drawing
                                                environment */
    ImageDescriptionHandle  framedescHandle;

gbazin's avatar
   
gbazin committed
174
    CodecDecompressParams   decpar;          /* for ImageCodecPreDecompress()*/
175
    CodecCapabilities       codeccap;        /* for decpar */
176
#endif
177
178
179
180

    /* Output properties */
    uint8_t *           plane;
    mtime_t             pts;
181
182
183
    audio_date_t        date;

    int                 i_late; /* video */
184
185
186

    /* buffer */
    unsigned int        i_buffer;
187
    unsigned int        i_buffer_size;
188
189
    uint8_t             *p_buffer;

190
191
192
193
194
    /* Audio only */
    uint8_t             out_buffer[1000000];    /* FIXME */
    int                 i_out_frames;
    int                 i_out;
};
hartman's avatar
hartman committed
195
196
197
198
199
200
201
202
203
204
205
206

static int pi_channels_maps[6] =
{
    0,
    AOUT_CHAN_CENTER,
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER,
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT,
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
     | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT
};

207
208
static int QTAudioInit( decoder_t * );
static int QTVideoInit( decoder_t * );
hartman's avatar
hartman committed
209
210

/*****************************************************************************
211
 * Open: probe the decoder and return score
hartman's avatar
hartman committed
212
213
214
215
 *****************************************************************************
 * Tries to launch a decoder and return score so that the interface is able
 * to choose.
 *****************************************************************************/
216
static int Open( vlc_object_t *p_this )
hartman's avatar
hartman committed
217
{
gbazin's avatar
   
gbazin committed
218
    decoder_t *p_dec = (decoder_t*)p_this;
hartman's avatar
hartman committed
219

220
    switch( p_dec->fmt_in.i_codec )
hartman's avatar
hartman committed
221
    {
222
        case VLC_FOURCC('S','V','Q','3'): /* Sorenson v3 */
223
    /*    case VLC_FOURCC('S','V','Q','1'):  Sorenson v1 
224
225
        case VLC_FOURCC('Z','y','G','o'):
        case VLC_FOURCC('V','P','3','1'):
226
        case VLC_FOURCC('3','I','V','1'): */
227
228
229
        case VLC_FOURCC('r','l','e',' '): /* QuickTime animation (RLE) */
        case VLC_FOURCC('r','p','z','a'): /* QuickTime Apple Video */
        case VLC_FOURCC('a','z','p','r'): /* QuickTime animation (RLE) */
230
231
232
#ifdef LOADER
            p_dec->p_sys = NULL;
            p_dec->pf_decode_video = DecodeVideo;
233
            return VLC_SUCCESS;
234
235
236
#else
            return OpenVideo( p_dec );
#endif
237

238
        case VLC_FOURCC('s','a','m','r'): /* 3GPP AMR audio */
gbazin's avatar
   
gbazin committed
239
        case VLC_FOURCC('m','p','4','a'): /* MPEG-4 audio */
hartman's avatar
hartman committed
240
241
242
243
244
245
        case VLC_FOURCC('Q','D','M','C'): /* QDesign */
        case VLC_FOURCC('Q','D','M','2'): /* QDesign* 2 */
        case VLC_FOURCC('Q','c','l','p'): /* Qualcomm Purevoice Codec */
        case VLC_FOURCC('Q','C','L','P'): /* Qualcomm Purevoice Codec */
        case VLC_FOURCC('M','A','C','3'): /* MACE3 audio decoder */
        case VLC_FOURCC('M','A','C','6'): /* MACE6 audio decoder */
246
247
248
249
250
251
        case VLC_FOURCC('d','v','c','a'): /* DV Audio */
        case VLC_FOURCC('s','o','w','t'): /* 16-bit Little Endian */
        case VLC_FOURCC('t','w','o','s'): /* 16-bit Big Endian */
        case VLC_FOURCC('a','l','a','w'): /* ALaw 2:1 */
        case VLC_FOURCC('u','l','a','w'): /* mu-Law 2:1 */
        case VLC_FOURCC('r','a','w',' '): /* 8-bit offset binaries */
252
253
254
255
        case VLC_FOURCC('f','l','3','2'): /* 32-bit Floating Point */
        case VLC_FOURCC('f','l','6','4'): /* 64-bit Floating Point */
        case VLC_FOURCC('i','n','2','4'): /* 24-bit Interger */
        case VLC_FOURCC('i','n','3','2'): /* 32-bit Integer */
gbazin's avatar
   
gbazin committed
256
257
258
        case 0x0011:                            /* DVI IMA */
        case 0x6D730002:                        /* Microsoft ADPCM-ACM */
        case 0x6D730011:                        /* DVI Intel IMAADPCM-ACM */
259
260
261
#ifdef LOADER
            p_dec->p_sys = NULL;
            p_dec->pf_decode_audio = DecodeAudio;
hartman's avatar
hartman committed
262
            return VLC_SUCCESS;
263
264
265
266
#else
            return OpenAudio( p_dec );
#endif

hartman's avatar
hartman committed
267
268
269
270
271
        default:
            return VLC_EGENERIC;
    }
}

272
273
274
275
/*****************************************************************************
 * Close:
 *****************************************************************************/
static void Close( vlc_object_t *p_this )
hartman's avatar
hartman committed
276
{
277
278
279
    decoder_t     *p_dec = (decoder_t*)p_this;
    decoder_sys_t *p_sys = p_dec->p_sys;
    vlc_value_t   lockval;
hartman's avatar
hartman committed
280

281
282
283
284
285
286
287
    /* get lock, avoid segfault */
    var_Get( p_dec->p_libvlc, "qt_mutex", &lockval );
    vlc_mutex_lock( lockval.p_address );
#ifdef SYS_DARWIN
    /* on OS X QT is not threadsafe */
    vlc_mutex_lock( &p_dec->p_vlc->quicktime_lock );
#endif
hartman's avatar
hartman committed
288

289
    if( p_dec->fmt_out.i_cat == AUDIO_ES )
hartman's avatar
hartman committed
290
    {
291
292
293
        int i_error;
        unsigned long ConvertedFrames=0;
        unsigned long ConvertedBytes=0;
hartman's avatar
hartman committed
294

295
296
297
298
        i_error = p_sys->SoundConverterEndConversion( p_sys->myConverter, NULL,
                                                      &ConvertedFrames,
                                                      &ConvertedBytes );
        msg_Dbg( p_dec, "SoundConverterEndConversion => %d", i_error );
hartman's avatar
hartman committed
299

300
301
        i_error = p_sys->SoundConverterClose( p_sys->myConverter );
        msg_Dbg( p_dec, "SoundConverterClose => %d", i_error );
hartman's avatar
hartman committed
302

303
        free( p_sys->p_buffer );
hartman's avatar
hartman committed
304
    }
305
    else if( p_dec->fmt_out.i_cat == VIDEO_ES )
hartman's avatar
hartman committed
306
    {
307
        free( p_sys->plane );
hartman's avatar
hartman committed
308
309
    }

310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
#ifndef SYS_DARWIN
    FreeLibrary( p_sys->qtml );
    msg_Dbg( p_dec, "FreeLibrary ok." );
#endif

#ifdef SYS_DARWIN
    ExitMovies();
#endif

#if 0
    /* Segfault */
#ifdef LOADER
    Restore_LDT_Keeper( p_sys->ldt_fs );
    msg_Dbg( p_dec, "Restore_LDT_Keeper" );
#endif
#endif

#ifdef SYS_DARWIN
    vlc_mutex_unlock( &p_dec->p_vlc->quicktime_lock );
#endif
    vlc_mutex_unlock( lockval.p_address );

    free( p_sys );
hartman's avatar
hartman committed
333
334
}

335
336
337
338
/*****************************************************************************
 * OpenAudio:
 *****************************************************************************/
static int OpenAudio( decoder_t *p_dec )
hartman's avatar
hartman committed
339
{
340
341
    decoder_sys_t *p_sys = malloc( sizeof( decoder_sys_t ) );

hartman's avatar
hartman committed
342
343
344
345
346
347
348
    vlc_value_t     lockval;
    int             i_error;
    char            fcc[4];
    unsigned long   WantedBufferSize;
    unsigned long   InputBufferSize = 0;
    unsigned long   OutputBufferSize = 0;

349
    memset( p_sys, 0, sizeof( decoder_sys_t ) );
hartman's avatar
hartman committed
350

351
352
353
354
    p_dec->p_sys = p_sys;
    p_dec->pf_decode_audio = DecodeAudio;

    memcpy( fcc, &p_dec->fmt_in.i_codec, 4 );
hartman's avatar
hartman committed
355
356

    /* get lock, avoid segfault */
357
    var_Get( p_dec->p_libvlc, "qt_mutex", &lockval );
hartman's avatar
hartman committed
358
    vlc_mutex_lock( lockval.p_address );
359
360
361
362
#ifdef SYS_DARWIN
    /* on OS X QT is not threadsafe */
    vlc_mutex_lock( &p_dec->p_vlc->quicktime_lock );
#endif
gbazin's avatar
   
gbazin committed
363

hartman's avatar
hartman committed
364
365
#ifdef SYS_DARWIN
    EnterMovies();
gbazin's avatar
   
gbazin committed
366
#endif
hartman's avatar
hartman committed
367

368
    if( QTAudioInit( p_dec ) )
hartman's avatar
hartman committed
369
    {
370
        msg_Err( p_dec, "cannot initialize QT");
hartman's avatar
hartman committed
371
372
373
        goto exit_error;
    }

gbazin's avatar
   
gbazin committed
374
#ifndef SYS_DARWIN
375
    if( ( i_error = p_sys->InitializeQTML( 6 + 16 ) ) )
hartman's avatar
hartman committed
376
    {
bigben's avatar
bigben committed
377
        msg_Dbg( p_dec, "error on InitializeQTML = %d", i_error );
hartman's avatar
hartman committed
378
379
380
381
382
        goto exit_error;
    }
#endif

    /* input format settings */
383
384
385
386
387
388
389
390
    p_sys->InputFormatInfo.flags       = 0;
    p_sys->InputFormatInfo.sampleCount = 0;
    p_sys->InputFormatInfo.buffer      = NULL;
    p_sys->InputFormatInfo.reserved    = 0;
    p_sys->InputFormatInfo.numChannels = p_dec->fmt_in.audio.i_channels;
    p_sys->InputFormatInfo.sampleSize  = p_dec->fmt_in.audio.i_bitspersample;
    p_sys->InputFormatInfo.sampleRate  = p_dec->fmt_in.audio.i_rate;
    p_sys->InputFormatInfo.format      = FCC( fcc[0], fcc[1], fcc[2], fcc[3] );
hartman's avatar
hartman committed
391
392

    /* output format settings */
393
394
395
396
397
398
399
400
401
402
403
404
405
    p_sys->OutputFormatInfo.flags       = 0;
    p_sys->OutputFormatInfo.sampleCount = 0;
    p_sys->OutputFormatInfo.buffer      = NULL;
    p_sys->OutputFormatInfo.reserved    = 0;
    p_sys->OutputFormatInfo.numChannels = p_dec->fmt_in.audio.i_channels;
    p_sys->OutputFormatInfo.sampleSize  = 16;
    p_sys->OutputFormatInfo.sampleRate  = p_dec->fmt_in.audio.i_rate;
    p_sys->OutputFormatInfo.format      = FCC( 'N', 'O', 'N', 'E' );


    i_error = p_sys->SoundConverterOpen( &p_sys->InputFormatInfo,
                                         &p_sys->OutputFormatInfo,
                                         &p_sys->myConverter );
hartman's avatar
hartman committed
406
407
    if( i_error )
    {
bigben's avatar
bigben committed
408
        msg_Err( p_dec, "error on SoundConverterOpen = %d", i_error );
hartman's avatar
hartman committed
409
410
411
        goto exit_error;
    }

gbazin's avatar
   
gbazin committed
412
413
414
415
416
417
#if 0
    /* tell the sound converter we accept VBR formats */
    i_error = SoundConverterSetInfo( p_dec->myConverter, siClientAcceptsVBR,
                                     (void *)true );
#endif

418
    if( p_dec->fmt_in.i_extra > 36 + 8 )
hartman's avatar
hartman committed
419
    {
420
421
422
423
        i_error = p_sys->SoundConverterSetInfo( p_sys->myConverter,
                                                FCC( 'w', 'a', 'v', 'e' ),
                                                ((uint8_t*)p_dec->fmt_in.p_extra) + 36 + 8 );

bigben's avatar
bigben committed
424
        msg_Dbg( p_dec, "error on SoundConverterSetInfo = %d", i_error );
hartman's avatar
hartman committed
425
426
    }

427
428
429
    WantedBufferSize = p_sys->OutputFormatInfo.numChannels *
                       p_sys->OutputFormatInfo.sampleRate * 2;
    p_sys->FramesToGet = 0;
gbazin's avatar
   
gbazin committed
430

431
432
433
434
435
    i_error = p_sys->SoundConverterGetBufferSizes( p_sys->myConverter,
                                                   WantedBufferSize,
                                                   &p_sys->FramesToGet,
                                                   &InputBufferSize,
                                                   &OutputBufferSize );
hartman's avatar
hartman committed
436

437
438
439
440
    msg_Dbg( p_dec, "WantedBufferSize=%li InputBufferSize=%li "
             "OutputBufferSize=%li FramesToGet=%li",
             WantedBufferSize, InputBufferSize, OutputBufferSize,
             p_sys->FramesToGet );
hartman's avatar
hartman committed
441

442
443
444
    p_sys->InFrameSize  = (InputBufferSize + p_sys->FramesToGet - 1 ) /
                            p_sys->FramesToGet;
    p_sys->OutFrameSize = OutputBufferSize / p_sys->FramesToGet;
hartman's avatar
hartman committed
445

446
447
    msg_Dbg( p_dec, "frame size %d -> %d",
             p_sys->InFrameSize, p_sys->OutFrameSize );
hartman's avatar
hartman committed
448

449
    if( (i_error = p_sys->SoundConverterBeginConversion(p_sys->myConverter)) )
hartman's avatar
hartman committed
450
    {
451
        msg_Err( p_dec,
bigben's avatar
bigben committed
452
                 "error on SoundConverterBeginConversion = %d", i_error );
hartman's avatar
hartman committed
453
454
455
        goto exit_error;
    }

456

457
458
459
460
461
462
463
464
465
466
467
468
    es_format_Init( &p_dec->fmt_out, AUDIO_ES, AOUT_FMT_S16_NE );
    p_dec->fmt_out.audio.i_rate = p_sys->OutputFormatInfo.sampleRate;
    p_dec->fmt_out.audio.i_channels = p_sys->OutputFormatInfo.numChannels;
    p_dec->fmt_out.audio.i_physical_channels =
    p_dec->fmt_out.audio.i_original_channels =
        pi_channels_maps[p_sys->OutputFormatInfo.numChannels];

    aout_DateInit( &p_sys->date, p_dec->fmt_out.audio.i_rate );

    p_sys->i_buffer      = 0;
    p_sys->i_buffer_size = 100*1000;
    p_sys->p_buffer      = malloc( p_sys->i_buffer_size );
hartman's avatar
hartman committed
469

470
471
    p_sys->i_out = 0;
    p_sys->i_out_frames = 0;
hartman's avatar
hartman committed
472

473
474
475
#ifdef SYS_DARWIN
    vlc_mutex_unlock( &p_dec->p_vlc->quicktime_lock );
#endif
hartman's avatar
hartman committed
476
477
478
479
    vlc_mutex_unlock( lockval.p_address );
    return VLC_SUCCESS;

exit_error:
480

481
#ifdef LOADER
482
483
484
485
    Restore_LDT_Keeper( p_sys->ldt_fs );
#endif
#ifdef SYS_DARWIN
    vlc_mutex_unlock( &p_dec->p_vlc->quicktime_lock );
hartman's avatar
hartman committed
486
487
#endif
    vlc_mutex_unlock( lockval.p_address );
488
489

    free( p_sys );
hartman's avatar
hartman committed
490
491
    return VLC_EGENERIC;
}
gbazin's avatar
   
gbazin committed
492

493
494
495
496
/*****************************************************************************
 * DecodeAudio:
 *****************************************************************************/
static aout_buffer_t *DecodeAudio( decoder_t *p_dec, block_t **pp_block )
hartman's avatar
hartman committed
497
{
498
    decoder_sys_t *p_sys = p_dec->p_sys;
hartman's avatar
hartman committed
499

500
501
502
    vlc_value_t lockval;
    block_t     *p_block;
    int         i_error;
hartman's avatar
hartman committed
503

504
505
506
507
#ifdef LOADER
    /* We must do open and close in the same thread (unless we do
     * Setup_LDT_Keeper in the main thread before all others */
    if( p_sys == NULL )
hartman's avatar
hartman committed
508
    {
509
510
511
512
513
514
515
516
        if( OpenAudio( p_dec ) )
        {
            /* Fatal */
            p_dec->b_error = VLC_TRUE;
            return NULL;
        }

        p_sys = p_dec->p_sys;
hartman's avatar
hartman committed
517
    }
518
#endif
gbazin's avatar
   
gbazin committed
519

520
521
522
523
524
    if( pp_block == NULL || *pp_block == NULL )
    {
        return NULL;
    }
    p_block = *pp_block;
hartman's avatar
hartman committed
525

526
    if( p_sys->i_out_frames > 0 && p_sys->i_out >= p_sys->i_out_frames )
hartman's avatar
hartman committed
527
    {
528
529
530
531
532
533
534
        /* Ask new data */
        p_sys->i_out = 0;
        p_sys->i_out_frames = 0;

        *pp_block = NULL;
        return NULL;
    }
hartman's avatar
hartman committed
535

536
537
538
    if( p_sys->i_out_frames <= 0 )
    {
        if( ( p_sys->pts = p_block->i_pts ) < mdate() )
hartman's avatar
hartman committed
539
        {
540
541
542
            block_Release( p_block );
            *pp_block = NULL;
            return NULL;
hartman's avatar
hartman committed
543
544
        }

545
546
547
548
549
550
551
552
553
        /* Append data */
        if( p_sys->i_buffer_size < p_sys->i_buffer + p_block->i_buffer )
        {
            p_sys->i_buffer_size = p_sys->i_buffer + p_block->i_buffer + 1024;
            p_sys->p_buffer = realloc( p_sys->p_buffer, p_sys->i_buffer_size );
        }
        memcpy( &p_sys->p_buffer[p_sys->i_buffer], p_block->p_buffer,
                p_block->i_buffer );
        p_sys->i_buffer += p_block->i_buffer;
hartman's avatar
hartman committed
554

555
        if( p_sys->i_buffer > p_sys->InFrameSize )
hartman's avatar
hartman committed
556
        {
557
            int i_frames = p_sys->i_buffer / p_sys->InFrameSize;
hartman's avatar
hartman committed
558
559
            long i_out_frames, i_out_bytes;

560
            var_Get( p_dec->p_libvlc, "qt_mutex", &lockval );
hartman's avatar
hartman committed
561
            vlc_mutex_lock( lockval.p_address );
562
563
            i_error = p_sys->SoundConverterConvertBuffer( p_sys->myConverter,
                                                          p_sys->p_buffer,
hartman's avatar
hartman committed
564
                                                          i_frames,
565
                                                          p_sys->out_buffer,
gbazin's avatar
   
gbazin committed
566
567
                                                          &i_out_frames,
                                                          &i_out_bytes );
hartman's avatar
hartman committed
568
569
            vlc_mutex_unlock( lockval.p_address );

gbazin's avatar
   
gbazin committed
570
            /*
571
            msg_Dbg( p_dec, "decoded %d frames -> %ld frames (error=%d)",
hartman's avatar
hartman committed
572
573
                     i_frames, i_out_frames, i_error );

574
            msg_Dbg( p_dec, "decoded %ld frames = %ld bytes",
gbazin's avatar
   
gbazin committed
575
576
577
                     i_out_frames, i_out_bytes );
            */

578
579
580
581
582
583
584
585
586
587
588
589
590
591
            p_sys->i_buffer -= i_frames * p_sys->InFrameSize;
            if( p_sys->i_buffer > 0 )
            {
                memmove( &p_sys->p_buffer[0],
                         &p_sys->p_buffer[i_frames * p_sys->InFrameSize],
                         p_sys->i_buffer );
            }

            if( p_sys->pts != 0 &&
                p_sys->pts != aout_DateGet( &p_sys->date ) )
            {
                aout_DateSet( &p_sys->date, p_sys->pts );
            }
            else if( !aout_DateGet( &p_sys->date ) )
hartman's avatar
hartman committed
592
            {
593
                return NULL;
hartman's avatar
hartman committed
594
595
            }

gbazin's avatar
   
gbazin committed
596
            if( !i_error && i_out_frames > 0 )
hartman's avatar
hartman committed
597
            {
598
599
600
                /* we have others samples */
                p_sys->i_out_frames = i_out_frames;
                p_sys->i_out = 0;
hartman's avatar
hartman committed
601
602
603
604
            }
        }
    }

605
    if( p_sys->i_out < p_sys->i_out_frames )
gbazin's avatar
   
gbazin committed
606
    {
607
608
        aout_buffer_t *p_out;
        int  i_frames = __MIN( p_sys->i_out_frames - p_sys->i_out, 1000 );
gbazin's avatar
   
gbazin committed
609

610
        p_out = p_dec->pf_aout_buffer_new( p_dec, i_frames );
gbazin's avatar
   
gbazin committed
611

612
613
614
615
        if( p_out )
        {
            p_out->start_date = aout_DateGet( &p_sys->date );
            p_out->end_date = aout_DateIncrement( &p_sys->date, i_frames );
gbazin's avatar
   
gbazin committed
616

617
618
619
            memcpy( p_out->p_buffer,
                    &p_sys->out_buffer[2 * p_sys->i_out * p_dec->fmt_out.audio.i_channels],
                    p_out->i_nb_bytes );
gbazin's avatar
   
gbazin committed
620

621
622
623
            p_sys->i_out += i_frames;
        }
        return p_out;
gbazin's avatar
   
gbazin committed
624
625
    }

626
    return NULL;
gbazin's avatar
   
gbazin committed
627
}
hartman's avatar
hartman committed
628

629
630
631
632
/*****************************************************************************
 * OpenVideo:
 *****************************************************************************/
static int OpenVideo( decoder_t *p_dec )
633
{
634
    decoder_sys_t *p_sys = malloc( sizeof( decoder_sys_t ) );
635

636
#ifndef WIN32
gbazin's avatar
   
gbazin committed
637
638
639
640
641
642
643
644
    vlc_value_t                         lockval;
    long                                i_result;
    ComponentDescription                desc;
    Component                           prev;
    ComponentResult                     cres;
    ImageSubCodecDecompressCapabilities icap;   /* for ImageCodecInitialize() */
    CodecInfo                           cinfo;  /* for ImageCodecGetCodecInfo() */
    ImageDescription                    *id;
645
646

    char                fcc[4];
647
648
    int     i_vide = p_dec->fmt_in.i_extra;
    uint8_t *p_vide = p_dec->fmt_in.p_extra;
649

650
651
652
653
654
    p_dec->p_sys = p_sys;
    p_dec->pf_decode_video = DecodeVideo;
    p_sys->i_late = 0;

    if( i_vide <= 0 )
655
    {
656
657
        msg_Err( p_dec, "missing extra info" );
        free( p_sys );
658
659
        return VLC_EGENERIC;
    }
660
661
662
663

    memcpy( fcc, &p_dec->fmt_in.i_codec, 4 );
    msg_Dbg( p_dec, "quicktime_video %4.4s %dx%d",
             fcc, p_dec->fmt_in.video.i_width, p_dec->fmt_in.video.i_height );
664
665

    /* get lock, avoid segfault */
666
    var_Get( p_dec->p_libvlc, "qt_mutex", &lockval );
667
    vlc_mutex_lock( lockval.p_address );
668

669
670
#ifdef SYS_DARWIN
    EnterMovies();
671
#endif
672

673
    if( QTVideoInit( p_dec ) )
674
    {
675
        msg_Err( p_dec, "cannot initialize QT");
676
677
678
        goto exit_error;
    }

679
680
#ifndef SYS_DARWIN
    if( ( i_result = p_sys->InitializeQTML( 6 + 16 ) ) )
681
    {
bigben's avatar
bigben committed
682
        msg_Dbg( p_dec, "error on InitializeQTML = %d", (int)i_result );
683
684
685
686
687
688
689
690
691
692
693
694
        goto exit_error;
    }
#endif

    /* init ComponentDescription */
    memset( &desc, 0, sizeof( ComponentDescription ) );
    desc.componentType      = FCC( 'i', 'm', 'd', 'c' );
    desc.componentSubType   = FCC( fcc[0], fcc[1], fcc[2], fcc[3] );
    desc.componentManufacturer = 0;
    desc.componentFlags        = 0;
    desc.componentFlagsMask    = 0;

695
    if( !( prev = p_sys->FindNextComponent( NULL, &desc ) ) )
696
    {
697
        msg_Err( p_dec, "cannot find requested component" );
698
699
        goto exit_error;
    }
700
    msg_Dbg( p_dec, "component id=0x%p", prev );
701

702
703
    p_sys->ci =  p_sys->OpenComponent( prev );
    msg_Dbg( p_dec, "component instance p=0x%p", p_sys->ci );
704
705

    memset( &icap, 0, sizeof( ImageSubCodecDecompressCapabilities ) );
706
    cres =  p_sys->ImageCodecInitialize( p_sys->ci, &icap );
707
708
709
/*    msg_Dbg( p_dec->p_fifo, "ImageCodecInitialize->%p  size=%d (%d)\n",cres,icap.recordSize,icap.decompressRecordSize); */

    memset( &cinfo, 0, sizeof( CodecInfo ) );
710
711
    cres =  p_sys->ImageCodecGetCodecInfo( p_sys->ci, &cinfo );
    msg_Dbg( p_dec,
gbazin's avatar
   
gbazin committed
712
713
             "Flags: compr: 0x%lx  decomp: 0x%lx format: 0x%lx\n",
             cinfo.compressFlags, cinfo.decompressFlags, cinfo.formatFlags );
714
    msg_Dbg( p_dec, "quicktime_video: Codec name: %.*s\n",
gbazin's avatar
   
gbazin committed
715
716
             ((unsigned char*)&cinfo.typeName)[0],
             ((unsigned char*)&cinfo.typeName)+1 );
717
718

    /* make a yuy2 gworld */
719
720
721
722
    p_sys->OutBufferRect.top    = 0;
    p_sys->OutBufferRect.left   = 0;
    p_sys->OutBufferRect.right  = p_dec->fmt_in.video.i_width;
    p_sys->OutBufferRect.bottom = p_dec->fmt_in.video.i_height;
723
724
725


    /* codec data FIXME use codec not SVQ3 */
726
    msg_Dbg( p_dec, "vide = %d", i_vide  );
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
    id = malloc( sizeof( ImageDescription ) + ( i_vide - 70 ) );
    id->idSize          = sizeof( ImageDescription ) + ( i_vide - 70 );
    id->cType           = FCC( fcc[0], fcc[1], fcc[2], fcc[3] );
    id->version         = GetWBE ( p_vide +  0 );
    id->revisionLevel   = GetWBE ( p_vide +  2 );
    id->vendor          = GetDWBE( p_vide +  4 );
    id->temporalQuality = GetDWBE( p_vide +  8 );
    id->spatialQuality  = GetDWBE( p_vide + 12 );
    id->width           = GetWBE ( p_vide + 16 );
    id->height          = GetWBE ( p_vide + 18 );
    id->hRes            = GetDWBE( p_vide + 20 );
    id->vRes            = GetDWBE( p_vide + 24 );
    id->dataSize        = GetDWBE( p_vide + 28 );
    id->frameCount      = GetWBE ( p_vide + 32 );
    memcpy( &id->name, p_vide + 34, 32 );
    id->depth           = GetWBE ( p_vide + 66 );
    id->clutID          = GetWBE ( p_vide + 68 );
    if( i_vide > 70 )
    {
        memcpy( ((char*)&id->clutID) + 2, p_vide + 70, i_vide - 70 );
    }

749
    msg_Dbg( p_dec, "idSize=%ld ver=%d rev=%d vendor=%ld tempQ=%d "
gbazin's avatar
   
gbazin committed
750
             "spaQ=%d w=%d h=%d dpi=%d%d dataSize=%d frameCount=%d clutID=%d",
751
752
753
754
755
756
757
758
             id->idSize, id->version, id->revisionLevel, id->vendor,
             (int)id->temporalQuality, (int)id->spatialQuality,
             id->width, id->height,
             (int)id->hRes, (int)id->vRes,
             (int)id->dataSize,
             id->frameCount,
             id->clutID );

759
760
761
    p_sys->framedescHandle =
        (ImageDescriptionHandle) p_sys->NewHandleClear( id->idSize );
    memcpy( *p_sys->framedescHandle, id, id->idSize );
762

763
    p_sys->plane = malloc( p_dec->fmt_in.video.i_width * p_dec->fmt_in.video.i_height * 3 );
764

765
    i_result = p_sys->QTNewGWorldFromPtr( &p_sys->OutBufferGWorld,
gbazin's avatar
   
gbazin committed
766
767
768
769
                                          /*pixel format of new GWorld==YUY2 */
                                          kYUVSPixelFormat,
                                          /* we should benchmark if yvu9 is
                                           * faster for svq3, too */
770
                                          &p_sys->OutBufferRect,
gbazin's avatar
   
gbazin committed
771
                                          0, 0, 0,
772
773
                                          p_sys->plane,
                                          p_dec->fmt_in.video.i_width * 2 );
774

775
    msg_Dbg( p_dec, "NewGWorldFromPtr returned:%ld\n",
gbazin's avatar
   
gbazin committed
776
             65536 - ( i_result&0xffff ) );
777

778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
    memset( &p_sys->decpar, 0, sizeof( CodecDecompressParams ) );
    p_sys->decpar.imageDescription = p_sys->framedescHandle;
    p_sys->decpar.startLine        = 0;
    p_sys->decpar.stopLine         = ( **p_sys->framedescHandle ).height;
    p_sys->decpar.frameNumber      = 1;
    p_sys->decpar.matrixFlags      = 0;
    p_sys->decpar.matrixType       = 0;
    p_sys->decpar.matrix           = 0;
    p_sys->decpar.capabilities     = &p_sys->codeccap;
    p_sys->decpar.accuracy         = codecNormalQuality;
    p_sys->decpar.srcRect          = p_sys->OutBufferRect;
    p_sys->decpar.transferMode     = srcCopy;
    p_sys->decpar.dstPixMap        = **p_sys->GetGWorldPixMap( p_sys->OutBufferGWorld );/*destPixmap;  */

    cres =  p_sys->ImageCodecPreDecompress( p_sys->ci, &p_sys->decpar );
    msg_Dbg( p_dec, "quicktime_video: ImageCodecPreDecompress cres=0x%X\n",
gbazin's avatar
   
gbazin committed
794
             (int)cres );
795

796
797
798
799
    p_dec->fmt_out.i_codec = VLC_FOURCC( 'Y', 'U', 'Y', '2' );
    p_dec->fmt_out.video.i_width = p_dec->fmt_in.video.i_width;
    p_dec->fmt_out.video.i_height= p_dec->fmt_in.video.i_height;
    p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR * p_dec->fmt_in.video.i_width / p_dec->fmt_in.video.i_height;
800
801
802
803
804
805
806


    vlc_mutex_unlock( lockval.p_address );
    return VLC_SUCCESS;

exit_error:
#ifdef LOADER
807
    Restore_LDT_Keeper( p_sys->ldt_fs );
808
809
#endif
    vlc_mutex_unlock( lockval.p_address );
810
811
812

#endif /* !WIN32 */

813
814
815
    return VLC_EGENERIC;
}

816
#ifndef WIN32
817
818
819
820
/*****************************************************************************
 * DecodeVideo:
 *****************************************************************************/
static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
821
{
822
    decoder_sys_t *p_sys = p_dec->p_sys;
gbazin's avatar
   
gbazin committed
823
824
    block_t       *p_block;
    picture_t     *p_pic;
825
    mtime_t       i_pts;
gbazin's avatar
   
gbazin committed
826
827

    ComponentResult cres;
828

829
830
831
832
833
834
835
836
837
838
839
840
841
842
#ifdef LOADER
    /* We must do open and close in the same thread (unless we do
     * Setup_LDT_Keeper in the main thread before all others */
    if( p_sys == NULL )
    {
        if( OpenVideo( p_dec ) )
        {
            /* Fatal */
            p_dec->b_error = VLC_TRUE;
            return NULL;
        }
        p_sys = p_dec->p_sys;
    }
#endif
843

844
    if( pp_block == NULL || *pp_block == NULL )
845
    {
846
        return NULL;
847
    }
848
849
    p_block = *pp_block;
    *pp_block = NULL;
850

gbazin's avatar
   
gbazin committed
851
852
853
    i_pts = p_block->i_pts ? p_block->i_pts : p_block->i_dts;

    if( i_pts < mdate() )
854
855
856
857
    {
        p_sys->i_late++;
    }
    else
858
    {
859
        p_sys->i_late = 0;
860
861
    }

862
    if( p_sys->i_late > 10 )
863
    {
864
865
866
867
        msg_Dbg( p_dec, "too late buffer -> dropped" );
        block_Release( p_block );
        return NULL;
    }
868

869
870
871
    if( ( p_pic = p_dec->pf_vout_buffer_new( p_dec ) ) )
    {
        vlc_value_t     lockval;
872

873
874
875
        p_sys->decpar.data                  = p_block->p_buffer;
        p_sys->decpar.bufferSize            = p_block->i_buffer;
        (**p_sys->framedescHandle).dataSize = p_block->i_buffer;
876

877
        var_Get( p_dec->p_libvlc, "qt_mutex", &lockval );
878
        vlc_mutex_lock( lockval.p_address );
879
        cres = p_sys->ImageCodecBandDecompress( p_sys->ci, &p_sys->decpar );
880
881
        vlc_mutex_unlock( lockval.p_address );

882
        ++p_sys->decpar.frameNumber;
883
884
885

        if( cres &0xFFFF )
        {
886
            msg_Dbg( p_dec, "quicktime_video: ImageCodecBandDecompress"
gbazin's avatar
   
gbazin committed
887
                     " cres=0x%X (-0x%X) %d :(\n",
888
889
890
                     (int)cres,(int)-cres, (int)cres );
        }

gbazin's avatar
   
gbazin committed
891
        memcpy( p_pic->p[0].p_pixels, p_sys->plane,
892
                p_dec->fmt_in.video.i_width * p_dec->fmt_in.video.i_height * 2 );
gbazin's avatar
   
gbazin committed
893
        p_pic->date = i_pts;
894
    }
895
    block_Release( p_block );
896

897
    return p_pic;
898
}
899
#endif /* !WIN32 */
900

901
902
903
904
/*****************************************************************************
 * QTAudioInit:
 *****************************************************************************/
static int QTAudioInit( decoder_t *p_dec )
905
{
906
    decoder_sys_t *p_sys = p_dec->p_sys;
907

908
909
910
911
912
913
914
915
916
#ifdef SYS_DARWIN
    p_sys->SoundConverterOpen       = (void*)SoundConverterOpen;
    p_sys->SoundConverterClose      = (void*)SoundConverterClose;
    p_sys->SoundConverterSetInfo    = (void*)SoundConverterSetInfo;
    p_sys->SoundConverterGetBufferSizes = (void*)SoundConverterGetBufferSizes;
    p_sys->SoundConverterConvertBuffer  = (void*)SoundConverterConvertBuffer;
    p_sys->SoundConverterBeginConversion= (void*)SoundConverterBeginConversion;
    p_sys->SoundConverterEndConversion  = (void*)SoundConverterEndConversion;
#else
917
918

#ifdef LOADER
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
    p_sys->ldt_fs = Setup_LDT_Keeper();
#endif /* LOADER */

    p_sys->qtml = LoadLibraryA( "qtmlClient.dll" );
    if( p_sys->qtml == NULL )
    {
        msg_Dbg( p_dec, "failed loading qtmlClient.dll" );
        return VLC_EGENERIC;
    }

    p_sys->InitializeQTML               = (void *)GetProcAddress( p_sys->qtml, "InitializeQTML" );
    p_sys->TerminateQTML                = (void *)GetProcAddress( p_sys->qtml, "TerminateQTML" );
    p_sys->SoundConverterOpen           = (void *)GetProcAddress( p_sys->qtml, "SoundConverterOpen" );
    p_sys->SoundConverterClose          = (void *)GetProcAddress( p_sys->qtml, "SoundConverterClose" );
    p_sys->SoundConverterSetInfo        = (void *)GetProcAddress( p_sys->qtml, "SoundConverterSetInfo" );
    p_sys->SoundConverterGetBufferSizes = (void *)GetProcAddress( p_sys->qtml, "SoundConverterGetBufferSizes" );
    p_sys->SoundConverterConvertBuffer  = (void *)GetProcAddress( p_sys->qtml, "SoundConverterConvertBuffer" );
    p_sys->SoundConverterEndConversion  = (void *)GetProcAddress( p_sys->qtml, "SoundConverterEndConversion" );
    p_sys->SoundConverterBeginConversion= (void *)GetProcAddress( p_sys->qtml, "SoundConverterBeginConversion");

    if( p_sys->InitializeQTML == NULL )
    {
bigben's avatar
bigben committed
941
        msg_Err( p_dec, "failed getting proc address InitializeQTML" );
942
943
944
945
946
947
948
949
950
951
        return VLC_EGENERIC;
    }
    if( p_sys->SoundConverterOpen == NULL ||
        p_sys->SoundConverterClose == NULL ||
        p_sys->SoundConverterSetInfo == NULL ||
        p_sys->SoundConverterGetBufferSizes == NULL ||
        p_sys->SoundConverterConvertBuffer == NULL ||
        p_sys->SoundConverterEndConversion == NULL ||
        p_sys->SoundConverterBeginConversion == NULL )
    {
bigben's avatar
bigben committed
952
        msg_Err( p_dec, "failed getting proc address" );
953
954
955
956
957
958
959
960
961
        return VLC_EGENERIC;
    }

    msg_Dbg( p_dec, "Standard init done" );
#endif /* else SYS_DARWIN */

    return VLC_SUCCESS;
}

962
#ifndef WIN32
963
964
965
966
967
968
969
/*****************************************************************************
 * QTVideoInit:
 *****************************************************************************/
static int QTVideoInit( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

970
#ifdef SYS_DARWIN
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
    p_sys->FindNextComponent        = (void*)FindNextComponent;
    p_sys->OpenComponent            = (void*)OpenComponent;
    p_sys->ImageCodecInitialize     = (void*)ImageCodecInitialize;
    p_sys->ImageCodecGetCodecInfo   = (void*)ImageCodecGetCodecInfo;
    p_sys->ImageCodecPreDecompress  = (void*)ImageCodecPreDecompress;
    p_sys->ImageCodecBandDecompress = (void*)ImageCodecBandDecompress;
    p_sys->GetGWorldPixMap          = (void*)GetGWorldPixMap;
    p_sys->QTNewGWorldFromPtr       = (void*)QTNewGWorldFromPtr;
    p_sys->NewHandleClear           = (void*)NewHandleClear;
#else

#ifdef LOADER
    p_sys->ldt_fs = Setup_LDT_Keeper();
#endif /* LOADER */
    p_sys->qtml = LoadLibraryA( "qtmlClient.dll" );
    if( p_sys->qtml == NULL )
    {
        msg_Dbg( p_dec, "failed loading qtmlClient.dll" );
        return VLC_EGENERIC;
    }
    msg_Dbg( p_dec, "qtmlClient.dll loaded" );

    /* (void*) to shut up gcc */
    p_sys->InitializeQTML           = (void*)GetProcAddress( p_sys->qtml, "InitializeQTML" );
    p_sys->FindNextComponent        = (void*)GetProcAddress( p_sys->qtml, "FindNextComponent" );
    p_sys->OpenComponent            = (void*)GetProcAddress( p_sys->qtml, "OpenComponent" );
    p_sys->ImageCodecInitialize     = (void*)GetProcAddress( p_sys->qtml, "ImageCodecInitialize" );
    p_sys->ImageCodecGetCodecInfo   = (void*)GetProcAddress( p_sys->qtml, "ImageCodecGetCodecInfo" );
    p_sys->ImageCodecPreDecompress  = (void*)GetProcAddress( p_sys->qtml, "ImageCodecPreDecompress" );
    p_sys->ImageCodecBandDecompress = (void*)GetProcAddress( p_sys->qtml, "ImageCodecBandDecompress" );
    p_sys->GetGWorldPixMap          = (void*)GetProcAddress( p_sys->qtml, "GetGWorldPixMap" );
    p_sys->QTNewGWorldFromPtr       = (void*)GetProcAddress( p_sys->qtml, "QTNewGWorldFromPtr" );
    p_sys->NewHandleClear           = (void*)GetProcAddress( p_sys->qtml, "NewHandleClear" );

    if( p_sys->InitializeQTML == NULL )
    {
bigben's avatar
bigben committed
1007
        msg_Dbg( p_dec, "failed getting proc address InitializeQTML" );
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
        return VLC_EGENERIC;
    }
    if( p_sys->FindNextComponent == NULL ||
        p_sys->OpenComponent == NULL ||
        p_sys->ImageCodecInitialize == NULL ||
        p_sys->ImageCodecGetCodecInfo == NULL ||
        p_sys->ImageCodecPreDecompress == NULL ||
        p_sys->ImageCodecBandDecompress == NULL ||
        p_sys->GetGWorldPixMap == NULL ||
        p_sys->QTNewGWorldFromPtr == NULL ||
        p_sys->NewHandleClear == NULL )
    {
bigben's avatar
bigben committed
1020
        msg_Err( p_dec, "failed getting proc address" );
1021
1022
1023
1024
1025
        return VLC_EGENERIC;
    }
#endif /* SYS_DARWIN */

    return VLC_SUCCESS;
1026
}
1027
#endif /* !WIN32 */