X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcodec%2Fquicktime.c;h=dd1255668bcd5ec586f007d5458cc96d621dcf07;hb=e72ecce9ec4febce33d043eb88bed83a32466ed0;hp=92c266f9508f7a59ffa4d6a6eb06cd13e6b1d979;hpb=97034b01b0511b9083bc501b42f3bfcb676f5041;p=vlc diff --git a/modules/codec/quicktime.c b/modules/codec/quicktime.c index 92c266f950..dd1255668b 100644 --- a/modules/codec/quicktime.c +++ b/modules/codec/quicktime.c @@ -26,16 +26,21 @@ * Preamble *****************************************************************************/ -#include -#include -#include -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include -#if !defined (SYS_DARWIN) && !defined(WIN32) +#if !defined (__APPLE__) && !defined(WIN32) # define LOADER 1 #endif -#ifdef SYS_DARWIN +#ifdef __APPLE__ #include #include #include @@ -60,14 +65,12 @@ static int Open ( vlc_object_t * ); static void Close( vlc_object_t * ); vlc_module_begin(); - set_description( _("QuickTime library decoder") ); - set_capability( "decoder", 10 ); + set_description( N_("QuickTime library decoder") ); + set_capability( "decoder", 100 ); set_category( CAT_INPUT ); set_subcategory( SUBCAT_INPUT_VCODEC ); set_callbacks( Open, Close ); - /* create a mutex */ - var_Create( p_module->p_libvlc, "qt_mutex", VLC_VAR_MUTEX ); vlc_module_end(); @@ -83,7 +86,7 @@ static picture_t *DecodeVideo( decoder_t *, block_t ** ); #define FCC( a, b , c, d ) \ ((uint32_t)( ((a)<<24)|((b)<<16)|((c)<<8)|(d))) -#ifndef SYS_DARWIN +#ifndef __APPLE__ typedef struct OpaqueSoundConverter* SoundConverter; #ifndef LOADER typedef long OSType; @@ -103,21 +106,21 @@ typedef struct SoundComponentData { long reserved; } SoundComponentData; -#endif /* SYS_DARWIN */ +#endif /* __APPLE__ */ struct decoder_sys_t { /* library */ -#ifndef SYS_DARWIN +#ifndef __APPLE__ #ifdef LOADER ldt_fs_t *ldt_fs; #endif /* LOADER */ HMODULE qtml; - HINSTANCE qtime_qts; + HINSTANCE qts; OSErr (*InitializeQTML) ( long flags ); OSErr (*TerminateQTML) ( void ); -#endif /* SYS_DARWIN */ +#endif /* __APPLE__ */ /* Audio */ int (*SoundConverterOpen) ( const SoundComponentData *, @@ -224,10 +227,31 @@ static int Open( vlc_object_t *p_this ) { decoder_t *p_dec = (decoder_t*)p_this; +#ifdef __APPLE__ + OSErr err; + SInt32 qtVersion; + + err = Gestalt(gestaltQuickTimeVersion, &qtVersion); +#endif + switch( p_dec->fmt_in.i_codec ) { + case VLC_FOURCC('h','2','6','4'): /* H.264 */ + case VLC_FOURCC('a','v','c','1'): /* dto. */ + case VLC_FOURCC('c','v','i','d'): /* Cinepak */ + case VLC_FOURCC('I','V','4','1'): /* Indeo Video IV */ + case VLC_FOURCC('i','v','4','1'): /* dto. */ +#ifdef __APPLE__ + case VLC_FOURCC('p','x','l','t'): /* Pixlet */ +#endif + case VLC_FOURCC('d','v','1','n'): /* DVC Pro 100 NTSC */ + case VLC_FOURCC('d','v','1','p'): /* DVC Pro 100 PAL */ + case VLC_FOURCC('d','v','h','p'): /* DVC PRO HD 720p */ + case VLC_FOURCC('d','v','h','6'): /* DVC PRO HD 1080i 60 */ + case VLC_FOURCC('d','v','h','5'): /* DVC PRO HD 1080i 50 */ + case VLC_FOURCC('S','V','Q','3'): /* Sorenson v3 */ - /* case VLC_FOURCC('S','V','Q','1'): Sorenson v1 + /* case VLC_FOURCC('S','V','Q','1'): Sorenson v1 case VLC_FOURCC('Z','y','G','o'): case VLC_FOURCC('V','P','3','1'): case VLC_FOURCC('3','I','V','1'): */ @@ -242,7 +266,16 @@ static int Open( vlc_object_t *p_this ) return OpenVideo( p_dec ); #endif +#ifdef __APPLE__ + case VLC_FOURCC('I','L','B','C'): /* iLBC */ + if ((err != noErr) || (qtVersion < 0x07500000)) + return VLC_EGENERIC; + case VLC_FOURCC('i','l','b','c'): /* iLBC */ + if ((err != noErr) || (qtVersion < 0x07500000)) + return VLC_EGENERIC; +#endif case VLC_FOURCC('s','a','m','r'): /* 3GPP AMR audio */ + case VLC_FOURCC('s','a','m','b'): /* 3GPP AMR-WB audio */ case VLC_FOURCC('m','p','4','a'): /* MPEG-4 audio */ case VLC_FOURCC('Q','D','M','C'): /* QDesign */ case VLC_FOURCC('Q','D','M','2'): /* QDesign* 2 */ @@ -283,15 +316,10 @@ static void Close( vlc_object_t *p_this ) { decoder_t *p_dec = (decoder_t*)p_this; decoder_sys_t *p_sys = p_dec->p_sys; - vlc_value_t lockval; + vlc_mutex_t *lock; /* 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 + lock = var_AcquireMutex( "qt_mutex" ); if( p_dec->fmt_out.i_cat == AUDIO_ES ) { @@ -307,14 +335,14 @@ static void Close( vlc_object_t *p_this ) i_error = p_sys->SoundConverterClose( p_sys->myConverter ); msg_Dbg( p_dec, "SoundConverterClose => %d", i_error ); - if( p_sys->p_buffer ) free( p_sys->p_buffer ); + free( p_sys->p_buffer ); } else if( p_dec->fmt_out.i_cat == VIDEO_ES ) { - if( p_sys->plane) free( p_sys->plane ); + free( p_sys->plane ); } -#ifndef SYS_DARWIN +#ifndef __APPLE__ FreeLibrary( p_sys->qtml ); FreeLibrary( p_sys->qts ); msg_Dbg( p_dec, "FreeLibrary ok." ); @@ -330,10 +358,7 @@ static void Close( vlc_object_t *p_this ) #endif #endif -#ifdef SYS_DARWIN - vlc_mutex_unlock( &p_dec->p_vlc->quicktime_lock ); -#endif - vlc_mutex_unlock( lockval.p_address ); + vlc_mutex_unlock( lock ); free( p_sys ); } @@ -343,31 +368,26 @@ static void Close( vlc_object_t *p_this ) *****************************************************************************/ static int OpenAudio( decoder_t *p_dec ) { - decoder_sys_t *p_sys = malloc( sizeof( decoder_sys_t ) ); + decoder_sys_t *p_sys; - vlc_value_t lockval; int i_error; char fcc[4]; unsigned long WantedBufferSize; unsigned long InputBufferSize = 0; unsigned long OutputBufferSize = 0; - memset( p_sys, 0, sizeof( decoder_sys_t ) ); + /* get lock, avoid segfault */ + vlc_mutex_t *lock = var_AcquireMutex( "qt_mutex" ); + if( lock == NULL ) + return VLC_EGENERIC; + p_sys = calloc( sizeof( decoder_sys_t ), 1 ); p_dec->p_sys = p_sys; p_dec->pf_decode_audio = DecodeAudio; memcpy( fcc, &p_dec->fmt_in.i_codec, 4 ); - /* 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 - -#ifdef SYS_DARWIN +#ifdef __APPLE__ EnterMovies(); #endif @@ -377,7 +397,7 @@ static int OpenAudio( decoder_t *p_dec ) goto exit_error; } -#ifndef SYS_DARWIN +#ifndef __APPLE__ if( ( i_error = p_sys->InitializeQTML( 6 + 16 ) ) ) { msg_Dbg( p_dec, "error on InitializeQTML = %d", i_error ); @@ -472,14 +492,13 @@ static int OpenAudio( decoder_t *p_dec ) p_sys->i_buffer = 0; p_sys->i_buffer_size = 100*1000; p_sys->p_buffer = malloc( p_sys->i_buffer_size ); + if( !p_sys->p_buffer ) + goto exit_error; p_sys->i_out = 0; p_sys->i_out_frames = 0; -#ifdef SYS_DARWIN - vlc_mutex_unlock( &p_dec->p_vlc->quicktime_lock ); -#endif - vlc_mutex_unlock( lockval.p_address ); + vlc_mutex_unlock( lock ); return VLC_SUCCESS; exit_error: @@ -487,10 +506,7 @@ exit_error: #ifdef LOADER Restore_LDT_Keeper( p_sys->ldt_fs ); #endif -#ifdef SYS_DARWIN - vlc_mutex_unlock( &p_dec->p_vlc->quicktime_lock ); -#endif - vlc_mutex_unlock( lockval.p_address ); + vlc_mutex_unlock( lock ); free( p_sys ); return VLC_EGENERIC; @@ -503,7 +519,6 @@ static aout_buffer_t *DecodeAudio( decoder_t *p_dec, block_t **pp_block ) { decoder_sys_t *p_sys = p_dec->p_sys; - vlc_value_t lockval; block_t *p_block; int i_error; @@ -515,7 +530,7 @@ static aout_buffer_t *DecodeAudio( decoder_t *p_dec, block_t **pp_block ) if( OpenAudio( p_dec ) ) { /* Fatal */ - p_dec->b_error = VLC_TRUE; + p_dec->b_error = true; return NULL; } @@ -541,7 +556,8 @@ static aout_buffer_t *DecodeAudio( decoder_t *p_dec, block_t **pp_block ) if( p_sys->i_out_frames <= 0 ) { - if( ( p_sys->pts = p_block->i_pts ) < mdate() ) + p_sys->pts = p_block->i_pts; + if( decoder_GetDisplayDate( p_dec, p_block->i_pts ) < mdate() ) { block_Release( p_block ); *pp_block = NULL; @@ -562,16 +578,15 @@ static aout_buffer_t *DecodeAudio( decoder_t *p_dec, block_t **pp_block ) { int i_frames = p_sys->i_buffer / p_sys->InFrameSize; unsigned long i_out_frames, i_out_bytes; + vlc_mutex_t *lock = var_AcquireMutex( "qt_mutex "); - var_Get( p_dec->p_libvlc, "qt_mutex", &lockval ); - vlc_mutex_lock( lockval.p_address ); i_error = p_sys->SoundConverterConvertBuffer( p_sys->myConverter, p_sys->p_buffer, i_frames, p_sys->out_buffer, &i_out_frames, &i_out_bytes ); - vlc_mutex_unlock( lockval.p_address ); + vlc_mutex_unlock( lock ); /* msg_Dbg( p_dec, "decoded %d frames -> %ld frames (error=%d)", @@ -638,9 +653,11 @@ static aout_buffer_t *DecodeAudio( decoder_t *p_dec, block_t **pp_block ) static int OpenVideo( decoder_t *p_dec ) { decoder_sys_t *p_sys = malloc( sizeof( decoder_sys_t ) ); + if( !p_sys ) + return VLC_ENOMEM; #ifndef WIN32 - vlc_value_t lockval; + vlc_mutex_t *lock; long i_result; ComponentDescription desc; Component prev; @@ -669,10 +686,9 @@ static int OpenVideo( decoder_t *p_dec ) fcc, p_dec->fmt_in.video.i_width, p_dec->fmt_in.video.i_height ); /* get lock, avoid segfault */ - var_Get( p_dec->p_libvlc, "qt_mutex", &lockval ); - vlc_mutex_lock( lockval.p_address ); + lock = var_AcquireMutex( "qt_mutex" ); -#ifdef SYS_DARWIN +#ifdef __APPLE__ EnterMovies(); #endif @@ -682,7 +698,7 @@ static int OpenVideo( decoder_t *p_dec ) goto exit_error; } -#ifndef SYS_DARWIN +#ifndef __APPLE__ if( ( i_result = p_sys->InitializeQTML( 6 + 16 ) ) ) { msg_Dbg( p_dec, "error on InitializeQTML = %d", (int)i_result ); @@ -710,13 +726,16 @@ static int OpenVideo( decoder_t *p_dec ) memset( &icap, 0, sizeof( ImageSubCodecDecompressCapabilities ) ); cres = p_sys->ImageCodecInitialize( p_sys->ci, &icap ); - msg_Dbg( p_dec, "ImageCodecInitialize->0x%X size=%ld (%ld)\n",(int)cres,icap.recordSize,icap.decompressRecordSize); + msg_Dbg( p_dec, "ImageCodecInitialize->0x%X size=%d (%d)\n", + (int)cres, (int)icap.recordSize, (int)icap.decompressRecordSize); memset( &cinfo, 0, sizeof( CodecInfo ) ); cres = p_sys->ImageCodecGetCodecInfo( p_sys->ci, &cinfo ); msg_Dbg( p_dec, - "Flags: compr: 0x%lx decomp: 0x%lx format: 0x%lx\n", - cinfo.compressFlags, cinfo.decompressFlags, cinfo.formatFlags ); + "Flags: compr: 0x%x decomp: 0x%x format: 0x%x\n", + (unsigned int)cinfo.compressFlags, + (unsigned int)cinfo.decompressFlags, + (unsigned int)cinfo.formatFlags ); msg_Dbg( p_dec, "quicktime_video: Codec name: %.*s\n", ((unsigned char*)&cinfo.typeName)[0], ((unsigned char*)&cinfo.typeName)+1 ); @@ -731,6 +750,8 @@ static int OpenVideo( decoder_t *p_dec ) /* codec data FIXME use codec not SVQ3 */ msg_Dbg( p_dec, "vide = %d", i_vide ); id = malloc( sizeof( ImageDescription ) + ( i_vide - 70 ) ); + if( !id ) + goto exit_error; id->idSize = sizeof( ImageDescription ) + ( i_vide - 70 ); id->cType = FCC( fcc[0], fcc[1], fcc[2], fcc[3] ); id->version = GetWBE ( p_vide + 0 ); @@ -752,22 +773,23 @@ static int OpenVideo( decoder_t *p_dec ) memcpy( ((char*)&id->clutID) + 2, p_vide + 70, i_vide - 70 ); } - msg_Dbg( p_dec, "idSize=%ld ver=%d rev=%d vendor=%ld tempQ=%d " + msg_Dbg( p_dec, "idSize=%d ver=%d rev=%d vendor=%d tempQ=%d " "spaQ=%d w=%d h=%d dpi=%d%d dataSize=%d depth=%d frameCount=%d clutID=%d", - id->idSize, id->version, id->revisionLevel, id->vendor, + (int)id->idSize, id->version, id->revisionLevel, (int)id->vendor, (int)id->temporalQuality, (int)id->spatialQuality, - id->width, id->height, + (int)id->width, (int)id->height, (int)id->hRes, (int)id->vRes, (int)id->dataSize, id->depth, id->frameCount, id->clutID ); - p_sys->framedescHandle = - (ImageDescriptionHandle) p_sys->NewHandleClear( id->idSize ); + p_sys->framedescHandle = (ImageDescriptionHandle) NewHandleClear( id->idSize ); memcpy( *p_sys->framedescHandle, id, id->idSize ); p_sys->plane = malloc( p_dec->fmt_in.video.i_width * p_dec->fmt_in.video.i_height * 3 ); + if( !p_sys->plane ) + goto exit_error; i_result = p_sys->QTNewGWorldFromPtr( &p_sys->OutBufferGWorld, /*pixel format of new GWorld==YUY2 */ @@ -800,20 +822,19 @@ static int OpenVideo( decoder_t *p_dec ) msg_Dbg( p_dec, "quicktime_video: ImageCodecPreDecompress cres=0x%X\n", (int)cres ); - p_dec->fmt_out.i_codec = VLC_FOURCC( 'Y', 'U', 'Y', '2' ); + es_format_Init( &p_dec->fmt_out, VIDEO_ES, 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; - - - vlc_mutex_unlock( lockval.p_address ); + + vlc_mutex_unlock( lock ); return VLC_SUCCESS; exit_error: #ifdef LOADER Restore_LDT_Keeper( p_sys->ldt_fs ); #endif - vlc_mutex_unlock( lockval.p_address ); + vlc_mutex_unlock( lock ); #endif /* !WIN32 */ @@ -827,7 +848,7 @@ exit_error: static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) { decoder_sys_t *p_sys = p_dec->p_sys; - vlc_value_t lockval; + vlc_mutex_t *lock; block_t *p_block; picture_t *p_pic; mtime_t i_pts; @@ -842,7 +863,7 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) if( OpenVideo( p_dec ) ) { /* Fatal */ - p_dec->b_error = VLC_TRUE; + p_dec->b_error = true; return NULL; } p_sys = p_dec->p_sys; @@ -854,16 +875,11 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) return NULL; } p_block = *pp_block; - - if( !p_block->i_buffer ) - { - block_Release( p_block ); - return NULL; - } - + *pp_block = NULL; + i_pts = p_block->i_pts ? p_block->i_pts : p_block->i_dts; - if( i_pts < mdate() ) + if( decoder_GetDisplayDate( p_dec, i_pts ) < mdate() ) { p_sys->i_late++; } @@ -871,7 +887,7 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) { p_sys->i_late = 0; } - msg_Dbg( p_dec, "bufsize: %d",p_block->i_buffer); + msg_Dbg( p_dec, "bufsize: %d", p_block->i_buffer); if( p_sys->i_late > 10 ) { @@ -879,9 +895,8 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) block_Release( p_block ); return NULL; } - - var_Get( p_dec->p_libvlc, "qt_mutex", &lockval ); - vlc_mutex_lock( lockval.p_address ); + + lock = var_AcquireMutex( "qt_mutex" ); if( ( p_pic = p_dec->pf_vout_buffer_new( p_dec ) ) ) { @@ -904,9 +919,8 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) p_dec->fmt_in.video.i_width * p_dec->fmt_in.video.i_height * 2 ); p_pic->date = i_pts; } - else - - vlc_mutex_unlock( lockval.p_address ); + + vlc_mutex_unlock( lock ); block_Release( p_block ); return p_pic; @@ -920,7 +934,7 @@ static int QTAudioInit( decoder_t *p_dec ) { decoder_sys_t *p_sys = p_dec->p_sys; -#ifdef SYS_DARWIN +#ifdef __APPLE__ p_sys->SoundConverterOpen = (void*)SoundConverterOpen; p_sys->SoundConverterClose = (void*)SoundConverterClose; p_sys->SoundConverterSetInfo = (void*)SoundConverterSetInfo; @@ -974,8 +988,8 @@ static int QTAudioInit( decoder_t *p_dec ) return VLC_EGENERIC; } - msg_Dbg( p_dec, "Standard init done" ); -#endif /* else SYS_DARWIN */ + msg_Dbg( p_dec, "standard init done" ); +#endif /* else __APPLE__ */ return VLC_SUCCESS; } @@ -988,7 +1002,7 @@ static int QTVideoInit( decoder_t *p_dec ) { decoder_sys_t *p_sys = p_dec->p_sys; -#ifdef SYS_DARWIN +#ifdef __APPLE__ p_sys->FindNextComponent = (void*)FindNextComponent; p_sys->OpenComponent = (void*)OpenComponent; p_sys->ImageCodecInitialize = (void*)ImageCodecInitialize; @@ -1048,7 +1062,7 @@ static int QTVideoInit( decoder_t *p_dec ) msg_Err( p_dec, "failed getting proc address" ); return VLC_EGENERIC; } -#endif /* SYS_DARWIN */ +#endif /* __APPLE__ */ return VLC_SUCCESS; }