/*****************************************************************************
* quicktime.c: a quicktime decoder that uses the QT library/dll
*****************************************************************************
- * Copyright (C) 2003 VideoLAN
- * $Id: quicktime.c,v 1.10 2003/08/01 20:06:43 gbazin Exp $
+ * Copyright (C) 2003, 2008 - 2009 the VideoLAN team
+ * $Id$
*
* Authors: Laurent Aimar <fenrir at via.ecp.fr>
- * Derk-Jan Hartman <thedj at users.sf.net>
+ * Derk-Jan Hartman <hartman at videolan.org>>
*
* 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.
- *
+ *
* 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
*
* 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.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
-#include <vlc/vlc.h>
-#include <vlc/aout.h>
-#include <vlc/vout.h>
-#include <vlc/decoder.h>
-#include <vlc/input.h>
-#include <stdlib.h> /* malloc(), free() */
-#include <string.h> /* strdup() */
-#include "codecs.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_aout.h>
+#include <vlc_codec.h>
-#ifdef SYS_DARWIN
+#if !defined (__APPLE__) && !defined(WIN32)
+# define LOADER 1
+#endif
+
+#ifdef __APPLE__
#include <QuickTime/QuickTimeComponents.h>
#include <QuickTime/Movies.h>
#include <QuickTime/ImageCodec.h>
#endif
/* 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"
+#include "qtx/qtxsdk/components.h"
+#include "wine/windef.h"
+#include "ldt_keeper.h"
HMODULE WINAPI LoadLibraryA(LPCSTR);
FARPROC WINAPI GetProcAddress(HMODULE,LPCSTR);
#endif
/*****************************************************************************
- * Local prototypes
+ * Module descriptor
*****************************************************************************/
-static int OpenDecoder ( vlc_object_t * );
+static int Open ( vlc_object_t * );
+static void Close( vlc_object_t * );
+
+vlc_module_begin ()
+ set_description( N_("QuickTime library decoder") )
+ set_capability( "decoder", 0 )
+ set_category( CAT_INPUT )
+ set_subcategory( SUBCAT_INPUT_VCODEC )
+ set_callbacks( Open, Close )
+
+vlc_module_end ()
-static int RunDecoderAudio( decoder_fifo_t * );
-static int RunDecoderVideo( decoder_fifo_t * );
/*****************************************************************************
- * Module descriptor
+ * Local prototypes
*****************************************************************************/
+static int OpenAudio( decoder_t * );
+static int OpenVideo( decoder_t * );
-vlc_module_begin();
- set_description( _("QuickTime library decoder") );
- set_capability( "decoder", 10 );
- set_callbacks( OpenDecoder, NULL );
-
- /* create a mutex */
- var_Create( p_module->p_libvlc, "qt_mutex", VLC_VAR_MUTEX );
-vlc_module_end();
+static aout_buffer_t *DecodeAudio( decoder_t *, block_t ** );
+#ifndef WIN32
+static picture_t *DecodeVideo( decoder_t *, block_t ** );
+#endif
#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;
typedef int OSErr;
+#endif
typedef unsigned long UnsignedFixed;
typedef uint8_t Byte;
long reserved;
} SoundComponentData;
-#endif /* SYS_DARWIN */
+#endif /* __APPLE__ */
-typedef struct
+struct decoder_sys_t
{
- /* Input properties */
- decoder_fifo_t *p_fifo;
-
/* library */
-#ifndef SYS_DARWIN
+#ifndef __APPLE__
#ifdef LOADER
ldt_fs_t *ldt_fs;
-
#endif /* LOADER */
+
HMODULE qtml;
+ HINSTANCE qts;
OSErr (*InitializeQTML) ( long flags );
OSErr (*TerminateQTML) ( void );
-#endif /* SYS_DARWIN */
+#endif /* __APPLE__ */
+ /* Audio */
int (*SoundConverterOpen) ( const SoundComponentData *,
const SoundComponentData *,
SoundConverter* );
SoundConverter myConverter;
SoundComponentData InputFormatInfo, OutputFormatInfo;
- long FramesToGet;
+ unsigned long FramesToGet;
unsigned int InFrameSize;
unsigned int OutFrameSize;
- /* Output properties */
- aout_instance_t * p_aout; /* opaque */
- aout_input_t * p_aout_input; /* opaque */
- audio_sample_format_t output_format;
-
- audio_date_t date;
- mtime_t pts;
-
- /* buffer */
- unsigned int i_buffer;
- unsigned int i_buffer_size;
- uint8_t *p_buffer;
-
- uint8_t buffer_out[1000000]; /* FIXME */
-
-} adec_thread_t;
-
#ifndef WIN32
-typedef struct
-{
- /* Input properties */
- decoder_fifo_t *p_fifo;
-
- /* library */
-#ifndef SYS_DARWIN
-#ifdef LOADER
- ldt_fs_t *ldt_fs;
-#endif /* LOADER */
- HMODULE qtml;
- OSErr (*InitializeQTML) ( long flags );
-
-#endif /* SYS_DARWIN */
+ /* Video */
Component (*FindNextComponent)
( Component prev, ComponentDescription* desc );
CTabHandle cTable, /*GDHandle*/ void *aGDevice, /*unused*/
GWorldFlags flags, void *baseAddr, long rowBytes );
- OSErr (*NewHandleClear)
- ( Size byteCount );
+ OSErr (*NewHandleClear)( Size byteCount );
ComponentInstance ci;
Rect OutBufferRect; /* the dimensions of our GWorld */
CodecDecompressParams decpar; /* for ImageCodecPreDecompress()*/
CodecCapabilities codeccap; /* for decpar */
-
+#endif
/* Output properties */
- vout_thread_t * p_vout;
uint8_t * plane;
mtime_t pts;
+ date_t date;
+
+ int i_late; /* video */
/* buffer */
unsigned int i_buffer;
+ unsigned int i_buffer_size;
uint8_t *p_buffer;
-} vdec_thread_t;
-#endif
+ /* Audio only */
+ uint8_t out_buffer[1000000]; /* FIXME */
+ int i_out_frames;
+ int i_out;
+};
-static int pi_channels_maps[6] =
+static const int pi_channels_maps[6] =
{
0,
AOUT_CHAN_CENTER,
| AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT
};
-
-static uint16_t GetWBE( uint8_t *p_buff )
-{
- return( (p_buff[0]<<8) + p_buff[1] );
-}
-
-static uint32_t GetDWBE( uint8_t *p_buff )
-{
- return( (p_buff[0] << 24) + ( p_buff[1] <<16 ) +
- ( p_buff[2] <<8 ) + p_buff[3] );
-}
-
-
-static int GetPESData( uint8_t *p_buf, int i_max, pes_packet_t *p_pes )
-{
- int i_copy;
- int i_count;
-
- data_packet_t *p_data;
-
- i_count = 0;
- p_data = p_pes->p_first;
- while( p_data != NULL && i_count < i_max )
- {
-
- i_copy = __MIN( p_data->p_payload_end - p_data->p_payload_start,
- i_max - i_count );
-
- if( i_copy > 0 )
- {
- memcpy( p_buf,
- p_data->p_payload_start,
- i_copy );
- }
-
- p_data = p_data->p_next;
- i_count += i_copy;
- p_buf += i_copy;
- }
-
- if( i_count < i_max )
- {
- memset( p_buf, 0, i_max - i_count );
- }
- return( i_count );
-}
+static int QTAudioInit( decoder_t * );
+#ifndef WIN32
+static int QTVideoInit( decoder_t * );
+#endif
/*****************************************************************************
- * OpenDecoder: probe the decoder and return score
+ * Open: probe the decoder and return score
*****************************************************************************
* Tries to launch a decoder and return score so that the interface is able
* to choose.
*****************************************************************************/
-static int OpenDecoder( vlc_object_t *p_this )
+static int Open( vlc_object_t *p_this )
{
- decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
+ decoder_t *p_dec = (decoder_t*)p_this;
+
+#ifdef __APPLE__
+ OSErr err;
+ SInt32 qtVersion, macosversion;
- switch( p_fifo->i_fourcc )
+ err = Gestalt(gestaltQuickTimeVersion, &qtVersion);
+ err = Gestalt(gestaltSystemVersion, &macosversion);
+#ifndef NDEBUG
+ msg_Dbg( p_this, "Mac OS version is %#lx", macosversion );
+ msg_Dbg( p_this, "Quicktime version is %#lx", qtVersion );
+#endif
+
+ /* bail out. This plugin is soo Carbon, that it can't be used on 10.5 at all */
+ msg_Info( p_dec, "Your Mac OS version is to new to use this plugin for anything." );
+ return VLC_EGENERIC;
+#endif
+
+ switch( p_dec->fmt_in.i_codec )
{
- case VLC_FOURCC('S','V','Q','3'): /* Sorenson v3 */
- /* case VLC_FOURCC('S','V','Q','1'): Sorenson v1
+ case VLC_CODEC_H264:
+ case VLC_CODEC_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_CODEC_DV:
+ case VLC_CODEC_SVQ3: /* Sorenson v3 */
+ /* case VLC_CODEC_SVQ1: Sorenson v1
case VLC_FOURCC('Z','y','G','o'):
case VLC_FOURCC('V','P','3','1'):
case VLC_FOURCC('3','I','V','1'): */
- 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) */
- p_fifo->pf_run = RunDecoderVideo;
- return VLC_SUCCESS;
+ case VLC_CODEC_QTRLE:
+ case VLC_CODEC_RPZA:
+#ifdef LOADER
+ p_dec->p_sys = NULL;
+ p_dec->pf_decode_video = DecodeVideo;
+ p_dec->fmt_out.i_cat = VIDEO_ES;
+ return VLC_SUCCESS;
+#else
+ return OpenVideo( p_dec );
+#endif
- case VLC_FOURCC('m','p','4','a'): /* MPEG-4 audio */
+#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_CODEC_AMR_NB: /* 3GPP AMR audio */
+ case VLC_FOURCC('s','a','m','b'): /* 3GPP AMR-WB audio */
+ case VLC_CODEC_MP4A: /* MPEG-4 audio */
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_CODEC_QDM2: /* QDesign* 2 */
+ case VLC_CODEC_QCELP: /* 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 */
+ case VLC_CODEC_MACE3: /* MACE3 audio decoder */
+ case VLC_CODEC_MACE6: /* MACE6 audio decoder */
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_CODEC_ALAW: /* ALaw 2:1 */
case VLC_FOURCC('u','l','a','w'): /* mu-Law 2:1 */
case VLC_FOURCC('r','a','w',' '): /* 8-bit offset binaries */
- case VLC_FOURCC('f','l','3','2'): /* 32-bit Floating Point */
- case VLC_FOURCC('f','l','6','4'): /* 64-bit Floating Point */
+ case VLC_CODEC_FL32: /* 32-bit Floating Point */
+ case VLC_CODEC_FL64: /* 64-bit Floating Point */
case VLC_FOURCC('i','n','2','4'): /* 24-bit Interger */
case VLC_FOURCC('i','n','3','2'): /* 32-bit Integer */
case 0x0011: /* DVI IMA */
case 0x6D730002: /* Microsoft ADPCM-ACM */
case 0x6D730011: /* DVI Intel IMAADPCM-ACM */
+#ifdef LOADER
+ p_dec->p_sys = NULL;
+ p_dec->pf_decode_audio = DecodeAudio;
+ p_dec->fmt_out.i_cat = AUDIO_ES;
+ return VLC_SUCCESS;
+#else
+ return OpenAudio( p_dec );
+#endif
- p_fifo->pf_run = RunDecoderAudio;
- return VLC_SUCCESS;
default:
return VLC_EGENERIC;
}
}
-/****************************************************************************
- ****************************************************************************
- **
- ** audio part
- **
- ****************************************************************************
- ****************************************************************************/
-static int InitThreadAudio ( adec_thread_t * );
-static void DecodeThreadAudio ( adec_thread_t * );
-static void EndThreadAudio ( adec_thread_t * );
-static int QTAudioInit ( adec_thread_t * );
-
-static int RunDecoderAudio( decoder_fifo_t *p_fifo )
+static vlc_mutex_t qt_mutex = VLC_STATIC_MUTEX;
+
+/*****************************************************************************
+ * Close:
+ *****************************************************************************/
+static void Close( vlc_object_t *p_this )
{
- adec_thread_t *p_dec;
- vlc_bool_t b_error;
+ decoder_t *p_dec = (decoder_t*)p_this;
+ decoder_sys_t *p_sys = p_dec->p_sys;
- p_dec = malloc( sizeof( adec_thread_t ) );
- if( !p_dec )
- {
- msg_Err( p_fifo, "out of memory" );
- DecoderError( p_fifo );
- return VLC_EGENERIC;
- }
- p_dec->p_fifo = p_fifo;
+ /* get lock, avoid segfault */
+ vlc_mutex_lock( &qt_mutex );
- if( InitThreadAudio( p_dec ) != 0 )
+ if( p_dec->fmt_out.i_cat == AUDIO_ES )
{
- DecoderError( p_fifo );
- return VLC_EGENERIC;
- }
+ int i_error;
+ unsigned long ConvertedFrames=0;
+ unsigned long ConvertedBytes=0;
- while( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error )
- {
- DecodeThreadAudio( p_dec );
- }
+ i_error = p_sys->SoundConverterEndConversion( p_sys->myConverter, NULL,
+ &ConvertedFrames,
+ &ConvertedBytes );
+ msg_Dbg( p_dec, "SoundConverterEndConversion => %d", i_error );
+ i_error = p_sys->SoundConverterClose( p_sys->myConverter );
+ msg_Dbg( p_dec, "SoundConverterClose => %d", i_error );
- if( ( b_error = p_dec->p_fifo->b_error ) )
- {
- DecoderError( p_dec->p_fifo );
+ free( p_sys->p_buffer );
}
-
- EndThreadAudio( p_dec );
- if( b_error )
+ else if( p_dec->fmt_out.i_cat == VIDEO_ES )
{
- return VLC_EGENERIC;
+ free( p_sys->plane );
}
- return VLC_SUCCESS;
+#ifndef __APPLE__
+ FreeLibrary( p_sys->qtml );
+ FreeLibrary( p_sys->qts );
+ msg_Dbg( p_dec, "FreeLibrary ok." );
+#else
+ ExitMovies();
+#endif
+
+#if 0
+ /* Segfault */
+#ifdef LOADER
+ Restore_LDT_Keeper( p_sys->ldt_fs );
+ msg_Dbg( p_dec, "Restore_LDT_Keeper" );
+#endif
+#endif
+
+ vlc_mutex_unlock( &qt_mutex );
+
+ free( p_sys );
}
-static int InitThreadAudio( adec_thread_t *p_dec )
+/*****************************************************************************
+ * OpenAudio:
+ *****************************************************************************/
+static int OpenAudio( decoder_t *p_dec )
{
- vlc_value_t lockval;
+ decoder_sys_t *p_sys;
+
int i_error;
char fcc[4];
unsigned long WantedBufferSize;
unsigned long InputBufferSize = 0;
unsigned long OutputBufferSize = 0;
- WAVEFORMATEX *p_wf;
+ /* get lock, avoid segfault */
+ vlc_mutex_lock( &qt_mutex );
- if( !( p_wf = (WAVEFORMATEX*)p_dec->p_fifo->p_waveformatex ) )
- {
- msg_Err( p_dec->p_fifo, "missing WAVEFORMATEX");
- return VLC_EGENERIC;
- }
- memcpy( fcc, &p_dec->p_fifo->i_fourcc, 4 );
+ p_sys = calloc( 1, sizeof( decoder_sys_t ) );
+ p_dec->p_sys = p_sys;
+ p_dec->pf_decode_audio = DecodeAudio;
- /* get lock, avoid segfault */
- var_Get( p_dec->p_fifo->p_libvlc, "qt_mutex", &lockval );
- vlc_mutex_lock( lockval.p_address );
+ if( p_dec->fmt_in.i_original_fourcc )
+ memcpy( fcc, &p_dec->fmt_in.i_original_fourcc, 4 );
+ else
+ memcpy( fcc, &p_dec->fmt_in.i_codec, 4 );
-#ifdef SYS_DARWIN
+#ifdef __APPLE__
EnterMovies();
#endif
- if( QTAudioInit( p_dec ) != VLC_SUCCESS )
+ if( QTAudioInit( p_dec ) )
{
- msg_Err( p_dec->p_fifo, "cannot initialize QT");
+ msg_Err( p_dec, "cannot initialize QT");
goto exit_error;
}
-#ifndef SYS_DARWIN
- if( ( i_error = p_dec->InitializeQTML( 6 + 16 ) ) )
+#ifndef __APPLE__
+ if( ( i_error = p_sys->InitializeQTML( 6 + 16 ) ) )
{
- msg_Dbg( p_dec->p_fifo, "error while InitializeQTML = %d", i_error );
+ msg_Dbg( p_dec, "error on InitializeQTML = %d", i_error );
goto exit_error;
}
#endif
/* input format settings */
- p_dec->InputFormatInfo.flags = 0;
- p_dec->InputFormatInfo.sampleCount = 0;
- p_dec->InputFormatInfo.buffer = NULL;
- p_dec->InputFormatInfo.reserved = 0;
- p_dec->InputFormatInfo.numChannels = p_wf->nChannels;
- p_dec->InputFormatInfo.sampleSize = p_wf->wBitsPerSample;
- p_dec->InputFormatInfo.sampleRate = p_wf->nSamplesPerSec;
- p_dec->InputFormatInfo.format = FCC( fcc[0], fcc[1], fcc[2], fcc[3] );
+ 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] );
/* output format settings */
- p_dec->OutputFormatInfo.flags = 0;
- p_dec->OutputFormatInfo.sampleCount = 0;
- p_dec->OutputFormatInfo.buffer = NULL;
- p_dec->OutputFormatInfo.reserved = 0;
- p_dec->OutputFormatInfo.numChannels = p_wf->nChannels;
- p_dec->OutputFormatInfo.sampleSize = 16;
- p_dec->OutputFormatInfo.sampleRate = p_wf->nSamplesPerSec;
- p_dec->OutputFormatInfo.format = FCC( 'N', 'O', 'N', 'E' );
-
-#ifdef SYS_DARWIN
-/* on OS X QT is not threadsafe */
- vlc_mutex_lock( &p_dec->p_fifo->p_vlc->quicktime_lock );
-#endif
-
- i_error = p_dec->SoundConverterOpen( &p_dec->InputFormatInfo,
- &p_dec->OutputFormatInfo,
- &p_dec->myConverter );
+ 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 );
if( i_error )
{
- msg_Err( p_dec->p_fifo,
- "error while SoundConverterOpen = %d", i_error );
+ msg_Err( p_dec, "error on SoundConverterOpen = %d", i_error );
goto exit_error;
}
(void *)true );
#endif
- if( p_wf->cbSize > 36 + 8 )
+ if( p_dec->fmt_in.i_extra > 36 + 8 )
{
- i_error =
- p_dec->SoundConverterSetInfo( p_dec->myConverter,
- FCC( 'w', 'a', 'v', 'e' ),
- ((uint8_t*)&p_wf[1]) + 36 + 8 );
- msg_Dbg( p_dec->p_fifo,
- "error while SoundConverterSetInfo = %d", i_error );
+ i_error = p_sys->SoundConverterSetInfo( p_sys->myConverter,
+ FCC( 'w', 'a', 'v', 'e' ),
+ ((uint8_t*)p_dec->fmt_in.p_extra) + 36 + 8 );
+
+ msg_Dbg( p_dec, "error on SoundConverterSetInfo = %d", i_error );
}
- WantedBufferSize = p_dec->OutputFormatInfo.numChannels *
- p_dec->OutputFormatInfo.sampleRate * 2;
- p_dec->FramesToGet = 0;
+ WantedBufferSize = p_sys->OutputFormatInfo.numChannels *
+ p_sys->OutputFormatInfo.sampleRate * 2;
+ p_sys->FramesToGet = 0;
- i_error = p_dec->SoundConverterGetBufferSizes( p_dec->myConverter,
- WantedBufferSize, &p_dec->FramesToGet,
- &InputBufferSize, &OutputBufferSize );
+ i_error = p_sys->SoundConverterGetBufferSizes( p_sys->myConverter,
+ WantedBufferSize,
+ &p_sys->FramesToGet,
+ &InputBufferSize,
+ &OutputBufferSize );
- msg_Dbg( p_dec->p_fifo, "WantedBufferSize=%li InputBufferSize=%li "
- "OutputBufferSize=%li FramesToGet=%li", WantedBufferSize,
- InputBufferSize, OutputBufferSize, p_dec->FramesToGet );
+ msg_Dbg( p_dec, "WantedBufferSize=%li InputBufferSize=%li "
+ "OutputBufferSize=%li FramesToGet=%li",
+ WantedBufferSize, InputBufferSize, OutputBufferSize,
+ p_sys->FramesToGet );
- p_dec->InFrameSize = (InputBufferSize + p_dec->FramesToGet - 1 ) /
- p_dec->FramesToGet;
- p_dec->OutFrameSize = OutputBufferSize / p_dec->FramesToGet;
+ p_sys->InFrameSize = (InputBufferSize + p_sys->FramesToGet - 1 ) /
+ p_sys->FramesToGet;
+ p_sys->OutFrameSize = OutputBufferSize / p_sys->FramesToGet;
- msg_Dbg( p_dec->p_fifo, "frame size %d -> %d",
- p_dec->InFrameSize, p_dec->OutFrameSize );
+ msg_Dbg( p_dec, "frame size %d -> %d",
+ p_sys->InFrameSize, p_sys->OutFrameSize );
- i_error = p_dec->SoundConverterBeginConversion( p_dec->myConverter );
- if( i_error )
+ if( (i_error = p_sys->SoundConverterBeginConversion(p_sys->myConverter)) )
{
- msg_Err( p_dec->p_fifo,
- "error while SoundConverterBeginConversion = %d", i_error );
+ msg_Err( p_dec,
+ "error on SoundConverterBeginConversion = %d", i_error );
goto exit_error;
}
-#ifdef SYS_DARWIN
- vlc_mutex_unlock( &p_dec->p_fifo->p_vlc->quicktime_lock );
-#endif
- p_dec->output_format.i_format = AOUT_FMT_S16_NE;
- p_dec->output_format.i_rate = p_wf->nSamplesPerSec;
- p_dec->output_format.i_physical_channels =
- p_dec->output_format.i_original_channels =
- pi_channels_maps[p_wf->nChannels];
- aout_DateInit( &p_dec->date, p_dec->output_format.i_rate );
- p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo,
- &p_dec->p_aout,
- &p_dec->output_format );
- if( !p_dec->p_aout_input )
- {
- msg_Err( p_dec->p_fifo, "cannot create aout" );
+ es_format_Init( &p_dec->fmt_out, AUDIO_ES, VLC_CODEC_S16N );
+ 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];
+
+ date_Init( &p_sys->date, p_dec->fmt_out.audio.i_rate, 1 );
+
+ 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_dec->i_buffer = 0;
- p_dec->i_buffer_size = 100*1000;
- p_dec->p_buffer = malloc( p_dec->i_buffer_size );
+ p_sys->i_out = 0;
+ p_sys->i_out_frames = 0;
- vlc_mutex_unlock( lockval.p_address );
+ vlc_mutex_unlock( &qt_mutex );
return VLC_SUCCESS;
exit_error:
+
#ifdef LOADER
- Restore_LDT_Keeper( p_dec->ldt_fs );
+ Restore_LDT_Keeper( p_sys->ldt_fs );
#endif
- vlc_mutex_unlock( lockval.p_address );
+ vlc_mutex_unlock( &qt_mutex );
+
+ free( p_sys );
return VLC_EGENERIC;
}
-static void DecodeThreadAudio( adec_thread_t *p_dec )
+/*****************************************************************************
+ * DecodeAudio:
+ *****************************************************************************/
+static aout_buffer_t *DecodeAudio( decoder_t *p_dec, block_t **pp_block )
{
- pes_packet_t *p_pes;
- vlc_value_t lockval;
- int i_error;
+ decoder_sys_t *p_sys = p_dec->p_sys;
- var_Get( p_dec->p_fifo->p_libvlc, "qt_mutex", &lockval );
+ block_t *p_block;
+ int i_error;
- input_ExtractPES( p_dec->p_fifo, &p_pes );
- if( !p_pes )
+#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 )
{
- msg_Err( p_dec->p_fifo, "cannot get PES" );
- p_dec->p_fifo->b_error = 1;
- return;
+ if( OpenAudio( p_dec ) )
+ {
+ /* Fatal */
+ p_dec->b_error = true;
+ return NULL;
+ }
+
+ p_sys = p_dec->p_sys;
}
+#endif
- p_dec->pts = p_pes->i_pts;
+ if( pp_block == NULL || *pp_block == NULL )
+ {
+ return NULL;
+ }
+ p_block = *pp_block;
+
+ if( p_sys->i_out_frames > 0 && p_sys->i_out >= p_sys->i_out_frames )
+ {
+ /* Ask new data */
+ p_sys->i_out = 0;
+ p_sys->i_out_frames = 0;
+
+ *pp_block = NULL;
+ return NULL;
+ }
- if( p_pes->i_pes_size > 0 && p_pes->i_pts > mdate() )
+ if( p_sys->i_out_frames <= 0 )
{
+ p_sys->pts = p_block->i_pts;
- if( p_dec->i_buffer_size < p_dec->i_buffer + p_pes->i_pes_size )
+ mtime_t i_display_date = 0;
+ if( !(p_block->i_flags & BLOCK_FLAG_PREROLL) )
+ i_display_date = decoder_GetDisplayDate( p_dec, p_block->i_pts );
+
+ if( i_display_date > 0 && i_display_date < mdate() )
{
- p_dec->i_buffer_size = p_dec->i_buffer + p_pes->i_pes_size + 1024;
- p_dec->p_buffer = realloc( p_dec->p_buffer,
- p_dec->i_buffer_size );
+ block_Release( p_block );
+ *pp_block = NULL;
+ return NULL;
}
- GetPESData( &p_dec->p_buffer[p_dec->i_buffer],
- p_dec->i_buffer_size - p_dec->i_buffer, p_pes );
- p_dec->i_buffer += p_pes->i_pes_size;
+ /* 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 = xrealloc( 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;
- if( p_dec->i_buffer > p_dec->InFrameSize )
+ if( p_sys->i_buffer > p_sys->InFrameSize )
{
- int i_frames = p_dec->i_buffer / p_dec->InFrameSize;
- long i_out_frames, i_out_bytes;
- /* enough data */
+ int i_frames = p_sys->i_buffer / p_sys->InFrameSize;
+ unsigned long i_out_frames, i_out_bytes;
+ vlc_mutex_lock( &qt_mutex );
- vlc_mutex_lock( lockval.p_address );
- i_error = p_dec->SoundConverterConvertBuffer( p_dec->myConverter,
- p_dec->p_buffer,
+ i_error = p_sys->SoundConverterConvertBuffer( p_sys->myConverter,
+ p_sys->p_buffer,
i_frames,
- p_dec->buffer_out,
+ p_sys->out_buffer,
&i_out_frames,
&i_out_bytes );
- vlc_mutex_unlock( lockval.p_address );
+ vlc_mutex_unlock( &qt_mutex );
/*
- msg_Dbg( p_dec->p_fifo,
- "decoded %d frames -> %ld frames (error=%d)",
+ msg_Dbg( p_dec, "decoded %d frames -> %ld frames (error=%d)",
i_frames, i_out_frames, i_error );
- msg_Dbg( p_dec->p_fifo, "decoded %ld frames = %ld bytes",
+ msg_Dbg( p_dec, "decoded %ld frames = %ld bytes",
i_out_frames, i_out_bytes );
*/
- p_dec->i_buffer -= i_frames * p_dec->InFrameSize;
- if( p_dec->i_buffer > 0 )
+ 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 > VLC_TS_INVALID &&
+ p_sys->pts != date_Get( &p_sys->date ) )
+ {
+ date_Set( &p_sys->date, p_sys->pts );
+ }
+ else if( !date_Get( &p_sys->date ) )
{
- memmove( &p_dec->p_buffer[0],
- &p_dec->p_buffer[i_frames * p_dec->InFrameSize],
- p_dec->i_buffer );
+ return NULL;
}
if( !i_error && i_out_frames > 0 )
{
- aout_buffer_t *p_aout_buffer;
- uint8_t *p_buff = p_dec->buffer_out;
-
- /*msg_Dbg( p_dec->p_fifo, "pts=%lld date=%lld dateget=%lld",
- p_dec->pts, mdate(), aout_DateGet( &p_dec->date ) );*/
-
- if( p_dec->pts != 0 &&
- p_dec->pts != aout_DateGet( &p_dec->date ) )
- {
- aout_DateSet( &p_dec->date, p_dec->pts );
- }
- else if( !aout_DateGet( &p_dec->date ) )
- {
- input_DeletePES( p_dec->p_fifo->p_packets_mgt, p_pes );
- return;
- }
-
- while( i_out_frames > 0 )
- {
- int i_frames;
-
- i_frames = __MIN( i_out_frames, 1000 );
- p_aout_buffer = aout_DecNewBuffer( p_dec->p_aout,
- p_dec->p_aout_input,
- i_frames );
- if( !p_aout_buffer )
- {
- msg_Err( p_dec->p_fifo, "cannot get aout buffer" );
- p_dec->p_fifo->b_error = 1;
- return;
- }
- p_aout_buffer->start_date = aout_DateGet( &p_dec->date );
- p_aout_buffer->end_date = aout_DateIncrement( &p_dec->date,
- i_frames );
-
- memcpy( p_aout_buffer->p_buffer,
- p_buff,
- p_aout_buffer->i_nb_bytes );
-
- /*
- msg_Dbg( p_dec->p_fifo,
- "==> start=%lld end=%lld date=%lld",
- p_aout_buffer->start_date,
- p_aout_buffer->end_date, mdate() );
- */
-
- aout_DecPlay( p_dec->p_aout, p_dec->p_aout_input,
- p_aout_buffer );
-
- /*
- msg_Dbg( p_dec->p_fifo, "s1=%d s2=%d", i_framesperchannels,
- p_aout_buffer->i_nb_samples );
-
- msg_Dbg( p_dec->p_fifo, "i_nb_bytes=%d i_nb_samples*4=%d",
- p_aout_buffer->i_nb_bytes,
- p_aout_buffer->i_nb_samples * 4 );
- */
-
- p_buff += i_frames * 4;
- i_out_frames -= i_frames;
- }
+ /* we have others samples */
+ p_sys->i_out_frames = i_out_frames;
+ p_sys->i_out = 0;
}
}
}
- input_DeletePES( p_dec->p_fifo->p_packets_mgt, p_pes );
-}
-
-static void EndThreadAudio( adec_thread_t *p_dec )
-{
- vlc_value_t lockval;
- int i_error;
- unsigned long ConvertedFrames=0;
- unsigned long ConvertedBytes=0;
-
- /* get lock, avoid segfault */
- var_Get( p_dec->p_fifo->p_libvlc, "qt_mutex", &lockval );
- vlc_mutex_lock( lockval.p_address );
-
- i_error = p_dec->SoundConverterEndConversion( p_dec->myConverter, NULL,
- &ConvertedFrames,
- &ConvertedBytes );
- msg_Dbg( p_dec->p_fifo, "SoundConverterEndConversion => %d", i_error );
-
- i_error = p_dec->SoundConverterClose( p_dec->myConverter );
- msg_Dbg( p_dec->p_fifo, "SoundConverterClose => %d", i_error );
-
-#ifndef SYS_DARWIN
- FreeLibrary( p_dec->qtml );
- msg_Dbg( p_dec->p_fifo, "FreeLibrary ok." );
-#endif
- vlc_mutex_unlock( lockval.p_address );
-
-#ifdef LOADER
- Restore_LDT_Keeper( p_dec->ldt_fs );
- msg_Dbg( p_dec->p_fifo, "Restore_LDT_Keeper" );
-#endif
-#ifdef SYS_DARWIN
- ExitMovies();
-#endif
- aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
-}
-
-static int QTAudioInit( adec_thread_t *p_dec )
-{
-
-#ifdef SYS_DARWIN
- p_dec->SoundConverterOpen = (void*)SoundConverterOpen;
- p_dec->SoundConverterClose = (void*)SoundConverterClose;
- p_dec->SoundConverterSetInfo = (void*)SoundConverterSetInfo;
- p_dec->SoundConverterGetBufferSizes = (void*)SoundConverterGetBufferSizes;
- p_dec->SoundConverterConvertBuffer = (void*)SoundConverterConvertBuffer;
- p_dec->SoundConverterBeginConversion= (void*)SoundConverterBeginConversion;
- p_dec->SoundConverterEndConversion = (void*)SoundConverterEndConversion;
-#else
-
-#ifdef LOADER
- p_dec->ldt_fs = Setup_LDT_Keeper();
-#endif /* LOADER */
-
- p_dec->qtml = LoadLibraryA( "qtmlClient.dll" );
- if( p_dec->qtml == NULL )
+ if( p_sys->i_out < p_sys->i_out_frames )
{
- msg_Dbg( p_dec->p_fifo, "failed loading qtmlClient.dll" );
- return VLC_EGENERIC;
- }
-
- p_dec->InitializeQTML =
- (void *)GetProcAddress( p_dec->qtml, "InitializeQTML" );
- if( p_dec->InitializeQTML == NULL )
- {
- msg_Dbg( p_dec->p_fifo, "failed geting proc address InitializeQTML" );
- return VLC_EGENERIC;
- }
-
- p_dec->SoundConverterOpen =
- (void *)GetProcAddress( p_dec->qtml, "SoundConverterOpen" );
- if( p_dec->SoundConverterOpen == NULL )
- {
- msg_Dbg( p_dec->p_fifo,
- "failed getting proc address SoundConverterOpen");
- return VLC_EGENERIC;
- }
-
- p_dec->SoundConverterClose =
- (void *)GetProcAddress( p_dec->qtml, "SoundConverterClose" );
- if( p_dec->SoundConverterClose == NULL )
- {
- msg_Dbg( p_dec->p_fifo,
- "failed getting proc address SoundConverterClose");
- return VLC_EGENERIC;
- }
-
- p_dec->TerminateQTML =
- (void *)GetProcAddress( p_dec->qtml, "TerminateQTML" );
- if( p_dec->TerminateQTML == NULL )
- {
- msg_Dbg( p_dec->p_fifo, "failed getting proc address TerminateQTML");
- return VLC_EGENERIC;
- }
-
- p_dec->SoundConverterSetInfo =
- (void *)GetProcAddress( p_dec->qtml, "SoundConverterSetInfo" );
- if( p_dec->SoundConverterSetInfo == NULL )
- {
- msg_Dbg( p_dec->p_fifo,
- "failed getting proc address SoundConverterSetInfo");
- return VLC_EGENERIC;
- }
+ aout_buffer_t *p_out;
+ int i_frames = __MIN( p_sys->i_out_frames - p_sys->i_out, 1000 );
- p_dec->SoundConverterGetBufferSizes =
- (void *)GetProcAddress( p_dec->qtml, "SoundConverterGetBufferSizes" );
- if( p_dec->SoundConverterGetBufferSizes == NULL )
- {
- msg_Dbg( p_dec->p_fifo,
- "failed getting proc address SoundConverterGetBufferSizes");
- return VLC_EGENERIC;
- }
+ p_out = decoder_NewAudioBuffer( p_dec, i_frames );
- p_dec->SoundConverterConvertBuffer =
- (void *)GetProcAddress( p_dec->qtml, "SoundConverterConvertBuffer" );
- if( p_dec->SoundConverterConvertBuffer == NULL )
- {
- msg_Dbg( p_dec->p_fifo,
- "failed getting proc address SoundConverterConvertBuffer" );
- return VLC_EGENERIC;
- }
+ if( p_out )
+ {
+ p_out->i_pts = date_Get( &p_sys->date );
+ p_out->i_length = date_Increment( &p_sys->date, i_frames )
+ - p_out->i_pts;
- p_dec->SoundConverterEndConversion =
- (void *)GetProcAddress( p_dec->qtml, "SoundConverterEndConversion" );
- if( p_dec->SoundConverterEndConversion == NULL )
- {
- msg_Dbg( p_dec->p_fifo,
- "failed getting proc address SoundConverterEndConversion" );
- return VLC_EGENERIC;
- }
+ memcpy( p_out->p_buffer,
+ &p_sys->out_buffer[2 * p_sys->i_out * p_dec->fmt_out.audio.i_channels],
+ p_out->i_buffer );
- p_dec->SoundConverterBeginConversion =
- (void *)GetProcAddress( p_dec->qtml, "SoundConverterBeginConversion");
- if( p_dec->SoundConverterBeginConversion == NULL )
- {
- msg_Dbg( p_dec->p_fifo,
- "failed getting proc address SoundConverterBeginConversion" );
- return VLC_EGENERIC;
+ p_sys->i_out += i_frames;
+ }
+ return p_out;
}
- msg_Dbg( p_dec->p_fifo,
- "Standard init done you may now call supported functions" );
-#endif /* else SYS_DARWIN */
-
- return VLC_SUCCESS;
+ return NULL;
}
-/****************************************************************************
- ****************************************************************************
- **
- ** video part
- **
- ****************************************************************************
- ****************************************************************************/
-
-#ifdef WIN32
-static int RunDecoderVideo( decoder_fifo_t *p_fifo ){ return VLC_EGENERIC; }
-
-#else
-static int InitThreadVideo ( vdec_thread_t * );
-static void DecodeThreadVideo ( vdec_thread_t * );
-static void EndThreadVideo ( vdec_thread_t * );
-
-static int RunDecoderVideo( decoder_fifo_t *p_fifo )
+/*****************************************************************************
+ * OpenVideo:
+ *****************************************************************************/
+static int OpenVideo( decoder_t *p_dec )
{
- vdec_thread_t *p_dec;
- vlc_bool_t b_error;
-
- p_dec = malloc( sizeof( vdec_thread_t ) );
- if( !p_dec )
- {
- msg_Err( p_fifo, "out of memory" );
- DecoderError( p_fifo );
- return VLC_EGENERIC;
- }
- p_dec->p_fifo = p_fifo;
-
- if( InitThreadVideo( p_dec ) != 0 )
- {
- DecoderError( p_fifo );
- return VLC_EGENERIC;
- }
-
- while( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error )
- {
- DecodeThreadVideo( p_dec );
- }
-
-
- if( ( b_error = p_dec->p_fifo->b_error ) )
- {
- DecoderError( p_dec->p_fifo );
- }
-
- EndThreadVideo( p_dec );
- if( b_error )
- {
- return VLC_EGENERIC;
- }
-
- return VLC_SUCCESS;
-}
+#ifndef WIN32
+ decoder_sys_t *p_sys = malloc( sizeof( decoder_sys_t ) );
+ if( !p_sys )
+ return VLC_ENOMEM;
-/*
- * InitThreadVideo: load and init library
- *
- */
-static int InitThreadVideo( vdec_thread_t *p_dec )
-{
- vlc_value_t lockval;
long i_result;
ComponentDescription desc;
Component prev;
CodecInfo cinfo; /* for ImageCodecGetCodecInfo() */
ImageDescription *id;
- BITMAPINFOHEADER *p_bih;
- int i_vide;
- uint8_t *p_vide;
char fcc[4];
+ int i_vide = p_dec->fmt_in.i_extra;
+ uint8_t *p_vide = p_dec->fmt_in.p_extra;
- if( !( p_bih = (BITMAPINFOHEADER*)p_dec->p_fifo->p_bitmapinfoheader ) )
- {
- msg_Err( p_dec->p_fifo, "missing BITMAPINFOHEADER !!" );
- return VLC_EGENERIC;
- }
- i_vide = p_bih->biSize - sizeof( BITMAPINFOHEADER );
- p_vide = (uint8_t*)&p_bih[1];
- if( i_vide <= 0 || p_vide == NULL )
+ p_dec->p_sys = p_sys;
+ p_dec->pf_decode_video = DecodeVideo;
+ p_sys->i_late = 0;
+
+ if( i_vide <= 0 )
{
- msg_Err( p_dec->p_fifo, "invalid BITMAPINFOHEADER !!" );
+ msg_Err( p_dec, "missing extra info" );
+ free( p_sys );
return VLC_EGENERIC;
}
- memcpy( fcc, &p_dec->p_fifo->i_fourcc, 4 );
- msg_Dbg( p_dec->p_fifo, "quicktime_video %4.4s %dx%d", fcc,
- p_bih->biWidth, p_bih->biHeight );
+
+ if( p_dec->fmt_in.i_original_fourcc )
+ memcpy( fcc, &p_dec->fmt_in.i_original_fourcc, 4 );
+ else
+ 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 );
/* get lock, avoid segfault */
- var_Get( p_dec->p_fifo->p_libvlc, "qt_mutex", &lockval );
- vlc_mutex_lock( lockval.p_address );
-#ifdef SYS_DARWIN
- EnterMovies();
-#else
-#ifdef LOADER
- p_dec->ldt_fs = Setup_LDT_Keeper();
-#endif /* LOADER */
- msg_Dbg( p_dec->p_fifo, "trying to load `qtmlClient.dll'" );
- if( !( p_dec->qtml = LoadLibraryA("qtmlClient.dll") ) )
- {
- msg_Err( p_dec->p_fifo, "cannot load qtmlClient.dll");
- goto exit_error;
- }
+ vlc_mutex_lock( &qt_mutex );
- msg_Dbg( p_dec->p_fifo, "qtmlClient.dll loaded" );
+#ifdef __APPLE__
+ EnterMovies();
+#endif
- /* (void*) to shut up gcc */
- p_dec->InitializeQTML = (void*)InitializeQTML;
-#endif /* SYS_DARWIN */
- p_dec->FindNextComponent = (void*)FindNextComponent;
- p_dec->OpenComponent = (void*)OpenComponent;
- p_dec->ImageCodecInitialize = (void*)ImageCodecInitialize;
- p_dec->ImageCodecGetCodecInfo = (void*)ImageCodecGetCodecInfo;
- p_dec->ImageCodecPreDecompress = (void*)ImageCodecPreDecompress;
- p_dec->ImageCodecBandDecompress = (void*)ImageCodecBandDecompress;
- p_dec->GetGWorldPixMap = (void*)GetGWorldPixMap;
- p_dec->QTNewGWorldFromPtr = (void*)QTNewGWorldFromPtr;
- p_dec->NewHandleClear = (void*)NewHandleClear;
-
-#ifndef SYS_DARWIN
- /* some sanity check */
- if( !p_dec->InitializeQTML ||
- !p_dec->FindNextComponent ||
- !p_dec->OpenComponent ||
- !p_dec->ImageCodecBandDecompress )
+ if( QTVideoInit( p_dec ) )
{
- msg_Err( p_dec->p_fifo, "error getting qtmlClient.dll symbols");
+ msg_Err( p_dec, "cannot initialize QT");
goto exit_error;
}
- if( ( i_result = p_dec->InitializeQTML( 6 + 16 ) ) )
+#ifndef __APPLE__
+ if( ( i_result = p_sys->InitializeQTML( 6 + 16 ) ) )
{
- msg_Dbg( p_dec->p_fifo, "error while InitializeQTML = %d", i_result );
+ msg_Dbg( p_dec, "error on InitializeQTML = %d", (int)i_result );
goto exit_error;
}
#endif
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
- if( !( prev = p_dec->FindNextComponent( NULL, &desc ) ) )
+ if( !( prev = p_sys->FindNextComponent( NULL, &desc ) ) )
{
- msg_Err( p_dec->p_fifo, "cannot find requested component" );
+ msg_Err( p_dec, "cannot find requested component" );
goto exit_error;
}
- msg_Dbg( p_dec->p_fifo, "component id=0x%p", prev );
+ msg_Dbg( p_dec, "component id=0x%p", prev );
- p_dec->ci = p_dec->OpenComponent( prev );
- msg_Dbg( p_dec->p_fifo, "component instance p=0x%p", p_dec->ci );
+ p_sys->ci = p_sys->OpenComponent( prev );
+ msg_Dbg( p_dec, "component instance p=0x%p", p_sys->ci );
memset( &icap, 0, sizeof( ImageSubCodecDecompressCapabilities ) );
- cres = p_dec->ImageCodecInitialize( p_dec->ci, &icap );
-/* msg_Dbg( p_dec->p_fifo, "ImageCodecInitialize->%p size=%d (%d)\n",cres,icap.recordSize,icap.decompressRecordSize); */
-
+ cres = p_sys->ImageCodecInitialize( p_sys->ci, &icap );
+ msg_Dbg( p_dec, "ImageCodecInitialize->0x%X size=%d (%d)",
+ (int)cres, (int)icap.recordSize, (int)icap.decompressRecordSize);
memset( &cinfo, 0, sizeof( CodecInfo ) );
- cres = p_dec->ImageCodecGetCodecInfo( p_dec->ci, &cinfo );
- msg_Dbg( p_dec->p_fifo,
- "Flags: compr: 0x%lx decomp: 0x%lx format: 0x%lx\n",
- cinfo.compressFlags, cinfo.decompressFlags, cinfo.formatFlags );
- msg_Dbg( p_dec->p_fifo, "quicktime_video: Codec name: %.*s\n",
+ cres = p_sys->ImageCodecGetCodecInfo( p_sys->ci, &cinfo );
+ msg_Dbg( p_dec,
+ "Flags: compr: 0x%x decomp: 0x%x format: 0x%x",
+ (unsigned int)cinfo.compressFlags,
+ (unsigned int)cinfo.decompressFlags,
+ (unsigned int)cinfo.formatFlags );
+ msg_Dbg( p_dec, "quicktime_video: Codec name: %.*s",
((unsigned char*)&cinfo.typeName)[0],
((unsigned char*)&cinfo.typeName)+1 );
/* make a yuy2 gworld */
- p_dec->OutBufferRect.top = 0;
- p_dec->OutBufferRect.left = 0;
- p_dec->OutBufferRect.right = p_bih->biWidth;
- p_dec->OutBufferRect.bottom = p_bih->biHeight;
+ 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;
/* codec data FIXME use codec not SVQ3 */
- msg_Dbg( p_dec->p_fifo, "vide = %d", i_vide );
+ 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 );
memcpy( ((char*)&id->clutID) + 2, p_vide + 70, i_vide - 70 );
}
- msg_Dbg( p_dec->p_fifo, "idSize=%ld ver=%d rev=%d vendor=%ld tempQ=%d "
- "spaQ=%d w=%d h=%d dpi=%d%d dataSize=%d frameCount=%d clutID=%d",
- id->idSize, id->version, id->revisionLevel, id->vendor,
+ 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",
+ (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_dec->framedescHandle =
- (ImageDescriptionHandle) p_dec->NewHandleClear( id->idSize );
- memcpy( *p_dec->framedescHandle, id, id->idSize );
+ p_sys->framedescHandle = (ImageDescriptionHandle) NewHandleClear( id->idSize );
+ memcpy( *p_sys->framedescHandle, id, id->idSize );
- p_dec->plane = malloc( p_bih->biWidth * p_bih->biHeight * 3 );
+ if( p_dec->fmt_in.video.i_width != 0 && p_dec->fmt_in.video.i_height != 0)
+ 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_dec->QTNewGWorldFromPtr( &p_dec->OutBufferGWorld,
+ i_result = p_sys->QTNewGWorldFromPtr( &p_sys->OutBufferGWorld,
/*pixel format of new GWorld==YUY2 */
kYUVSPixelFormat,
/* we should benchmark if yvu9 is
* faster for svq3, too */
- &p_dec->OutBufferRect,
+ &p_sys->OutBufferRect,
0, 0, 0,
- p_dec->plane,
- p_bih->biWidth * 2 );
+ p_sys->plane,
+ p_dec->fmt_in.video.i_width * 2 );
- msg_Dbg( p_dec->p_fifo, "NewGWorldFromPtr returned:%ld\n",
+ msg_Dbg( p_dec, "NewGWorldFromPtr returned:%ld",
65536 - ( i_result&0xffff ) );
- memset( &p_dec->decpar, 0, sizeof( CodecDecompressParams ) );
- p_dec->decpar.imageDescription = p_dec->framedescHandle;
- p_dec->decpar.startLine = 0;
- p_dec->decpar.stopLine = ( **p_dec->framedescHandle ).height;
- p_dec->decpar.frameNumber = 1;
- p_dec->decpar.matrixFlags = 0;
- p_dec->decpar.matrixType = 0;
- p_dec->decpar.matrix = 0;
- p_dec->decpar.capabilities = &p_dec->codeccap;
- p_dec->decpar.accuracy = codecNormalQuality;
- p_dec->decpar.srcRect = p_dec->OutBufferRect;
- p_dec->decpar.transferMode = srcCopy;
- p_dec->decpar.dstPixMap = **p_dec->GetGWorldPixMap( p_dec->OutBufferGWorld );/*destPixmap; */
-
- cres = p_dec->ImageCodecPreDecompress( p_dec->ci, &p_dec->decpar );
- msg_Dbg( p_dec->p_fifo,
- "quicktime_video: ImageCodecPreDecompress cres=0x%X\n",
+ 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",
(int)cres );
- p_dec->p_vout = vout_Request( p_dec->p_fifo, NULL,
- p_bih->biWidth, p_bih->biHeight,
- VLC_FOURCC( 'Y', 'U', 'Y', '2' ),
- VOUT_ASPECT_FACTOR * p_bih->biWidth /
- p_bih->biHeight );
+ es_format_Init( &p_dec->fmt_out, VIDEO_ES, VLC_CODEC_YUYV);
+ 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_sar_num = 1;
+ p_dec->fmt_out.video.i_sar_den = 1;
- if( !p_dec->p_vout )
- {
- msg_Err( p_dec->p_fifo, "cannot get a vout" );
- goto exit_error;
- }
-
- p_dec->i_buffer = 1000*1000;
- p_dec->p_buffer = malloc( p_dec->i_buffer );
-
- vlc_mutex_unlock( lockval.p_address );
+ vlc_mutex_unlock( &qt_mutex );
return VLC_SUCCESS;
exit_error:
#ifdef LOADER
- Restore_LDT_Keeper( p_dec->ldt_fs );
+ Restore_LDT_Keeper( p_sys->ldt_fs );
#endif
- vlc_mutex_unlock( lockval.p_address );
- return VLC_EGENERIC;
+ vlc_mutex_unlock( &qt_mutex );
+
+#else
+ VLC_UNUSED( p_dec );
+#endif /* !WIN32 */
+ return VLC_EGENERIC;
}
-static void DecodeThreadVideo( vdec_thread_t *p_dec )
+#ifndef WIN32
+/*****************************************************************************
+ * DecodeVideo:
+ *****************************************************************************/
+static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
{
- BITMAPINFOHEADER *p_bih =
- (BITMAPINFOHEADER*)p_dec->p_fifo->p_bitmapinfoheader;
+ decoder_sys_t *p_sys = p_dec->p_sys;
+ block_t *p_block;
+ picture_t *p_pic;
+ mtime_t i_pts;
- pes_packet_t *p_pes;
- vlc_value_t lockval;
- picture_t *p_pic;
ComponentResult cres;
- var_Get( p_dec->p_fifo->p_libvlc, "qt_mutex", &lockval );
-
- input_ExtractPES( p_dec->p_fifo, &p_pes );
- if( !p_pes )
+#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 )
{
- msg_Err( p_dec->p_fifo, "cannot get PES" );
- p_dec->p_fifo->b_error = 1;
- return;
+ if( OpenVideo( p_dec ) )
+ {
+ /* Fatal */
+ p_dec->b_error = true;
+ return NULL;
+ }
+ p_sys = p_dec->p_sys;
}
+#endif
- if( p_pes->i_pes_size > p_dec->i_buffer )
+ if( pp_block == NULL || *pp_block == NULL )
{
- p_dec->i_buffer = 3 * p_pes->i_pes_size / 2;
- free( p_dec->p_buffer );
- p_dec->p_buffer = malloc( p_dec->i_buffer );
+ return NULL;
}
+ p_block = *pp_block;
+ *pp_block = NULL;
+
+ i_pts = p_block->i_pts > VLC_TS_INVALID ? p_block->i_pts : p_block->i_dts;
+
+ mtime_t i_display_date = 0;
+ if( !(p_block->i_flags & BLOCK_FLAG_PREROLL) )
+ i_display_date = decoder_GetDisplayDate( p_dec, i_pts );
- if( p_pes->i_pes_size > 0 && p_pes->i_pts > mdate() )
+ if( i_display_date > 0 && i_display_date < mdate() )
{
- GetPESData( p_dec->p_buffer, p_dec->i_buffer, p_pes );
+ p_sys->i_late++;
+ }
+ else
+ {
+ p_sys->i_late = 0;
+ }
+#ifndef NDEBUG
+ msg_Dbg( p_dec, "bufsize: %d", (int)p_block->i_buffer);
+#endif
- while( !(p_pic = vout_CreatePicture( p_dec->p_vout, 0, 0, 0 ) ) )
- {
- if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error )
- {
- break;
- }
- msleep( VOUT_OUTMEM_SLEEP );
- }
+ if( p_sys->i_late > 10 )
+ {
+ msg_Dbg( p_dec, "late buffer dropped (%"PRId64")", i_pts );
+ block_Release( p_block );
+ return NULL;
+ }
+
+ vlc_mutex_lock( &qt_mutex );
- p_dec->decpar.data = p_dec->p_buffer;
- p_dec->decpar.bufferSize = p_pes->i_pes_size;
- (**p_dec->framedescHandle).dataSize = p_pes->i_pes_size;
+ if( ( p_pic = decoder_NewPicture( p_dec ) ) )
+ {
+ p_sys->decpar.data = (Ptr)p_block->p_buffer;
+ p_sys->decpar.bufferSize = p_block->i_buffer;
+ (**p_sys->framedescHandle).dataSize = p_block->i_buffer;
- vlc_mutex_lock( lockval.p_address );
- cres = p_dec->ImageCodecBandDecompress( p_dec->ci, &p_dec->decpar );
- vlc_mutex_unlock( lockval.p_address );
+ cres = p_sys->ImageCodecBandDecompress( p_sys->ci, &p_sys->decpar );
- ++p_dec->decpar.frameNumber;
+ ++p_sys->decpar.frameNumber;
if( cres &0xFFFF )
{
- msg_Dbg( p_dec->p_fifo, "quicktime_video: ImageCodecBandDecompress"
- " cres=0x%X (-0x%X) %d :(\n",
+ msg_Dbg( p_dec, "quicktime_video: ImageCodecBandDecompress"
+ " cres=0x%X (-0x%X) %d :(",
(int)cres,(int)-cres, (int)cres );
}
- memcpy( p_pic->p[0].p_pixels,
- p_dec->plane,
- p_bih->biWidth * p_bih->biHeight * 2 );
-
- vout_DatePicture( p_dec->p_vout, p_pic, p_pes->i_pts );
- vout_DisplayPicture( p_dec->p_vout, p_pic );
+ memcpy( p_pic->p[0].p_pixels, p_sys->plane,
+ p_dec->fmt_in.video.i_width * p_dec->fmt_in.video.i_height * 2 );
+ p_pic->date = i_pts;
}
+
+ vlc_mutex_unlock( &qt_mutex );
- input_DeletePES( p_dec->p_fifo->p_packets_mgt, p_pes );
+ block_Release( p_block );
+ return p_pic;
}
+#endif /* !WIN32 */
-static void EndThreadVideo( vdec_thread_t *p_dec )
+/*****************************************************************************
+ * QTAudioInit:
+ *****************************************************************************/
+static int QTAudioInit( decoder_t *p_dec )
{
- msg_Dbg( p_dec->p_fifo, "QuickTime library video decoder closing" );
- free( p_dec->plane );
- vout_Request( p_dec->p_fifo, p_dec->p_vout, 0, 0, 0, 0 );
+ decoder_sys_t *p_sys = p_dec->p_sys;
+
+#ifdef __APPLE__
+ 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
-#ifndef SYS_DARWIN
- FreeLibrary( p_dec->qtml );
- msg_Dbg( p_dec->p_fifo, "FreeLibrary ok." );
-#endif
+#ifdef LOADER
+ p_sys->ldt_fs = Setup_LDT_Keeper();
+#endif /* LOADER */
+
+ p_sys->qts = LoadLibraryA( "QuickTime.qts" );
+ if( p_sys->qts == NULL )
+ {
+ msg_Dbg( p_dec, "failed loading QuickTime.qts" );
+ return VLC_EGENERIC;
+ }
+ 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 )
+ {
+ msg_Err( p_dec, "failed getting proc address InitializeQTML" );
+ 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 )
+ {
+ msg_Err( p_dec, "failed getting proc address" );
+ return VLC_EGENERIC;
+ }
+
+ msg_Dbg( p_dec, "standard init done" );
+#endif /* else __APPLE__ */
+
+ return VLC_SUCCESS;
+}
+
+#ifndef WIN32
+/*****************************************************************************
+ * QTVideoInit:
+ *****************************************************************************/
+static int QTVideoInit( decoder_t *p_dec )
+{
+ decoder_sys_t *p_sys = p_dec->p_sys;
+
+#ifdef __APPLE__
+ 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
- Restore_LDT_Keeper( p_dec->ldt_fs );
- msg_Dbg( p_dec->p_fifo, "Restore_LDT_Keeper" );
-#endif
-#ifdef SYS_DARWIN
- ExitMovies();
-#endif
+ p_sys->ldt_fs = Setup_LDT_Keeper();
+#endif /* LOADER */
+ p_sys->qts = LoadLibraryA( "QuickTime.qts" );
+ if( p_sys->qts == NULL )
+ {
+ msg_Dbg( p_dec, "failed loading QuickTime.qts" );
+ return VLC_EGENERIC;
+ }
+ msg_Dbg( p_dec, "QuickTime.qts loaded" );
+ 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 )
+ {
+ msg_Dbg( p_dec, "failed getting proc address InitializeQTML" );
+ 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 )
+ {
+ msg_Err( p_dec, "failed getting proc address" );
+ return VLC_EGENERIC;
+ }
+#endif /* __APPLE__ */
+
+ return VLC_SUCCESS;
}
-#endif
+#endif /* !WIN32 */