Commit 10b03bcb authored by Sam Hocevar's avatar Sam Hocevar

  OS X fixes:

  * Applied Eugenio's fix to the DVDioctl driver. I didn't test it, but
    it should not hang the kernel anymore.

  * Ported most dvd_ioctl.c functions to the DVDioctl driver: ReportAgid,
    ReportChallenge, ReportKey1, ReportASF, InvalidateAgid, SendChallenge,
    SendKey2. They should comply with the "Mt. Fuji Commands for Multimedia
    Devices" paper.

    Last remaining problem: ReadCopyright and ReadKey. The version of
 Darwin I have here only has reportKey() and sendKey() functions in
 the IODVDBlockStorageDevice class (pages 413 and 449 of the Mt. Fuji
 paper), but we also need the READ_STRUCTURE (page 357) which I couldn't
 find anywhere in the kernel headers. Either I missed it, or we'll have
 to wait for Apple to implement it (or maybe we can emulate this command
 with some other IOKit commands).
parent 32335766
......@@ -73,11 +73,11 @@ AC3_DECODER = src/ac3_decoder/ac3_decoder_thread.o \
src/ac3_decoder/ac3_rematrix.o \
src/ac3_decoder/ac3_imdct.o
AC3_SPDIF = src/ac3_spdif/ac3_spdif.o \
src/ac3_spdif/ac3_iec958.o
AC3_SPDIF = src/ac3_spdif/ac3_spdif.o \
src/ac3_spdif/ac3_iec958.o
LPCM_DECODER = src/lpcm_decoder/lpcm_decoder_thread.o \
src/lpcm_decoder/lpcm_decoder.o
src/lpcm_decoder/lpcm_decoder.o
AUDIO_DECODER = src/audio_decoder/audio_decoder.o \
src/audio_decoder/adec_generic.o \
......@@ -107,7 +107,7 @@ C_OBJ = $(INTERFACE) \
$(VIDEO_OUTPUT) \
$(AUDIO_OUTPUT) \
$(AC3_DECODER) \
$(AC3_SPDIF) \
$(AC3_SPDIF) \
$(LPCM_DECODER) \
$(AUDIO_DECODER) \
$(SPU_DECODER) \
......
......@@ -3,7 +3,7 @@
*****************************************************************************
* Copyright (C) 1998-2000 Apple Computer, Inc. All rights reserved.
* Copyright (C) 2001 VideoLAN
* $Id: DVDioctl.cpp,v 1.5 2001/04/17 14:39:51 sam Exp $
* $Id: DVDioctl.cpp,v 1.6 2001/05/25 04:23:37 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -29,9 +29,6 @@
* it is still in use
*****************************************************************************/
//XXX: uncomment to activate the key exchange ioctls - may hang the machine
//#define ACTIVATE_DANGEROUS_IOCTL 1
/*****************************************************************************
* Preamble
*****************************************************************************/
......@@ -453,7 +450,12 @@ static void DVDStrategy( buf_t * bp )
static int DVDBlockIoctl( dev_t dev, u_long cmd, caddr_t addr, int flags,
struct proc *p )
{
dvdioctl_data_t * p_data = (dvdioctl_data_t *)addr;
dvdioctl_data_t *p_data = (dvdioctl_data_t *)addr;
IOMemoryDescriptor *p_mem;
p_mem = IOMemoryDescriptor::withAddress( p_data->p_buffer,
p_data->i_size,
kIODirectionOutIn );
switch( cmd )
{
......@@ -468,19 +470,14 @@ static int DVDBlockIoctl( dev_t dev, u_long cmd, caddr_t addr, int flags,
case IODVD_SEND_KEY:
log( LOG_INFO, "DVD ioctl: send key to `%s', "
"buf %d, format %d, class %d, agid %d\n",
"buf %d, class %d, lba N/A, agid %d, format %d\n",
p_drive->getDeviceTypeName(),
(int)p_data->p_buffer, p_data->i_keyformat,
p_data->i_keyclass, p_data->i_agid );
(int)p_data->p_buffer, p_data->i_keyclass,
p_data->i_agid, p_data->i_keyformat );
#ifdef ACTIVATE_DANGEROUS_IOCTL
return p_drive->sendKey( (IOMemoryDescriptor *)p_data->p_buffer,
(DVDKeyClass)p_data->i_keyclass,
return p_drive->sendKey( p_mem, (DVDKeyClass)p_data->i_keyclass,
p_data->i_agid,
(DVDKeyFormat)p_data->i_keyformat );
#else
return -1;
#endif
case IODVD_REPORT_KEY:
......@@ -490,14 +487,9 @@ static int DVDBlockIoctl( dev_t dev, u_long cmd, caddr_t addr, int flags,
(int)p_data->p_buffer, p_data->i_keyclass, p_data->i_lba,
p_data->i_agid, p_data->i_keyformat );
#ifdef ACTIVATE_DANGEROUS_IOCTL
return p_drive->reportKey( (IOMemoryDescriptor *)p_data->p_buffer,
(DVDKeyClass)p_data->i_keyclass,
return p_drive->reportKey( p_mem, (DVDKeyClass)p_data->i_keyclass,
p_data->i_lba, p_data->i_agid,
(DVDKeyFormat)p_data->i_keyformat );
#else
return -1;
#endif
default:
......
......@@ -2,7 +2,7 @@
* DVDioctl.h: Linux-like DVD driver for Darwin and MacOS X
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: DVDioctl.h,v 1.2 2001/04/04 02:49:18 sam Exp $
* $Id: DVDioctl.h,v 1.3 2001/05/25 04:23:37 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -51,9 +51,11 @@ typedef struct dvdioctl_data
void *p_buffer;
#if defined(KERNEL)
UInt32 i_size;
UInt32 i_lba;
UInt8 i_agid;
#else
u32 i_size;
u32 i_lba;
u8 i_agid;
#endif
......
......@@ -2,7 +2,7 @@
* dvd_ioctl.c: DVD ioctl replacement function
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_ioctl.c,v 1.11 2001/05/02 20:01:44 sam Exp $
* $Id: dvd_ioctl.c,v 1.12 2001/05/25 04:23:37 sam Exp $
*
* Authors: Markus Kuespert <ltlBeBoy@beosmail.com>
* Samuel Hocevar <sam@zoy.org>
......@@ -59,14 +59,29 @@
#include "dvd_ioctl.h"
/*****************************************************************************
* Local prototypes - BeOS specific
* Local prototypes, BeOS specific
*****************************************************************************/
#if defined( SYS_BEOS )
static void BeInitRDC ( raw_device_command *, void *, int, int );
static void BeInitRDC ( raw_device_command *, int );
#define INIT_RDC( TYPE, SIZE ) \
raw_device_command rdc; \
u8 p_buffer[ (SIZE) ]; \
BeInitRDC( &rdc, p_buffer, (TYPE), (SIZE) );
rdc.data = (char *)p_buffer; \
rdc.data_length = (SIZE); \
BeInitRDC( &rdc, (TYPE) );
#endif
/*****************************************************************************
* Local prototypes, Darwin specific
*****************************************************************************/
#if defined( SYS_DARWIN1_3 )
#define INIT_DVDIOCTL( SIZE ) \
dvdioctl_data_t dvdioctl; \
u8 p_buffer[ (SIZE) ]; \
dvdioctl.p_buffer = p_buffer; \
dvdioctl.i_size = (SIZE); \
dvdioctl.i_keyclass = kCSS_CSS2_CPRM; \
memset( p_buffer, 0, (SIZE) );
#endif
/*****************************************************************************
......@@ -108,9 +123,9 @@ int ioctl_ReadCopyright( int i_fd, int i_layer, int *pi_copyright )
#elif defined( SYS_DARWIN1_3 )
intf_ErrMsg( "css error: DVD ioctls not fully functional yet" );
intf_ErrMsg( "css error: assuming disc is encrypted" );
intf_ErrMsg( "css error: assuming disc is unencrypted" );
*pi_copyright = 0;
*pi_copyright = 1;
i_ret = 0;
......@@ -176,6 +191,14 @@ int ioctl_ReadKey( int i_fd, int *pi_agid, u8 *p_key )
memcpy( p_key, p_buffer + 4, 2048 );
#elif defined( SYS_DARWIN1_3 )
intf_ErrMsg( "css error: DVD ioctls not fully functional yet" );
intf_ErrMsg( "css error: sending an empty key" );
i_ret = 0;
memset( p_key, 0x00, 2048 );
#else
/* DVD ioctls unavailable - do as if the ioctl failed */
i_ret = -1;
......@@ -214,12 +237,23 @@ int ioctl_ReportAgid( int i_fd, int *pi_agid )
#elif defined( SYS_BEOS )
INIT_RDC( GPCMD_REPORT_KEY, 8 );
rdc.command[ 10 ] = 0x00 | (*pi_agid << 6);
rdc.command[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
*pi_agid = p_buffer[ 7 ] >> 6;
#elif defined( SYS_DARWIN1_3 )
INIT_DVDIOCTL( 8 );
dvdioctl.i_keyformat = kCSSAGID;
dvdioctl.i_agid = *pi_agid;
dvdioctl.i_lba = 0;
i_ret = ioctl( i_fd, IODVD_REPORT_KEY, &dvdioctl );
*pi_asf = p_buffer[ 7 ] >> 6;
#else
/* DVD ioctls unavailable - do as if the ioctl failed */
i_ret = -1;
......@@ -258,12 +292,23 @@ int ioctl_ReportChallenge( int i_fd, int *pi_agid, u8 *p_challenge )
#elif defined( SYS_BEOS )
INIT_RDC( GPCMD_REPORT_KEY, 16 );
rdc.command[ 10 ] = 0x01 | (*pi_agid << 6);
rdc.command[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
memcpy( p_challenge, p_buffer + 4, 12 );
#elif defined( SYS_DARWIN1_3 )
INIT_DVDIOCTL( 16 );
dvdioctl.i_keyformat = kChallengeKey;
dvdioctl.i_agid = *pi_agid;
dvdioctl.i_lba = 0;
i_ret = ioctl( i_fd, IODVD_REPORT_KEY, &dvdioctl );
memcpy( p_challenge, p_buffer + 4, 12 );
#else
/* DVD ioctls unavailable - do as if the ioctl failed */
i_ret = -1;
......@@ -304,23 +349,20 @@ int ioctl_ReportASF( int i_fd, int *pi_agid, int *pi_asf )
#elif defined( SYS_BEOS )
INIT_RDC( GPCMD_REPORT_KEY, 8 );
rdc.command[ 10 ] = 0x05 | (*pi_agid << 6);
rdc.command[ 10 ] = DVD_REPORT_ASF | (*pi_agid << 6);
i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
*pi_asf = p_buffer[ 7 ] & 1;
#elif defined( SYS_DARWIN1_3 )
dvdioctl_data_t data;
u8 p_buffer[ 8 ];
INIT_DVDIOCTL( 8 );
data.p_buffer = p_buffer;
data.i_lba = 0;
data.i_agid = *pi_agid;
data.i_keyclass = kCSS_CSS2_CPRM;
data.i_keyformat = kASF;
dvdioctl.i_keyformat = kASF;
dvdioctl.i_agid = *pi_agid;
dvdioctl.i_lba = 0;
i_ret = ioctl( i_fd, IODVD_REPORT_KEY, &data );
i_ret = ioctl( i_fd, IODVD_REPORT_KEY, &dvdioctl );
*pi_asf = p_buffer[ 7 ] & 1;
......@@ -362,12 +404,22 @@ int ioctl_ReportKey1( int i_fd, int *pi_agid, u8 *p_key )
#elif defined( SYS_BEOS )
INIT_RDC( GPCMD_REPORT_KEY, 12 );
rdc.command[ 10 ] = 0x02 | (*pi_agid << 6);
rdc.command[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
memcpy( p_key, p_buffer + 4, 8 );
#elif defined( SYS_DARWIN1_3 )
INIT_DVDIOCTL( 12 );
dvdioctl.i_keyformat = kKey1;
dvdioctl.i_agid = *pi_agid;
i_ret = ioctl( i_fd, IODVD_SEND_KEY, &dvdioctl );
memcpy( p_key, p_buffer + 4, 8 );
#else
/* DVD ioctls unavailable - do as if the ioctl failed */
i_ret = -1;
......@@ -406,10 +458,18 @@ int ioctl_InvalidateAgid( int i_fd, int *pi_agid )
#elif defined( SYS_BEOS )
INIT_RDC( GPCMD_REPORT_KEY, 0 );
rdc.command[ 10 ] = 0x3f | (*pi_agid << 6);
rdc.command[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6);
i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
#elif defined( SYS_DARWIN1_3 )
INIT_DVDIOCTL( 0 );
dvdioctl.i_keyformat = kInvalidateAGID;
dvdioctl.i_agid = *pi_agid;
i_ret = ioctl( i_fd, IODVD_SEND_KEY, &dvdioctl );
#else
/* DVD ioctls unavailable - do as if the ioctl failed */
i_ret = -1;
......@@ -446,13 +506,24 @@ int ioctl_SendChallenge( int i_fd, int *pi_agid, u8 *p_challenge )
#elif defined( SYS_BEOS )
INIT_RDC( GPCMD_SEND_KEY, 16 );
rdc.command[ 10 ] = 0x01 | (*pi_agid << 6);
rdc.command[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
p_buffer[ 1 ] = 0xe;
memcpy( p_buffer + 4, p_challenge, 12 );
return ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
#elif defined( SYS_DARWIN1_3 )
INIT_DVDIOCTL( 16 );
dvdioctl.i_keyformat = kChallengeKey;
dvdioctl.i_agid = *pi_agid;
p_buffer[ 1 ] = 0xe;
memcpy( p_buffer + 4, p_challenge, 12 );
return ioctl( i_fd, IODVD_SEND_KEY, &dvdioctl );
#else
/* DVD ioctls unavailable - do as if the ioctl failed */
return -1;
......@@ -488,13 +559,24 @@ int ioctl_SendKey2( int i_fd, int *pi_agid, u8 *p_key )
#elif defined( SYS_BEOS )
INIT_RDC( GPCMD_SEND_KEY, 12 );
rdc.command[ 10 ] = 0x3 | (*pi_agid << 6);
rdc.command[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
p_buffer[ 1 ] = 0xa;
memcpy( p_buffer + 4, p_key, 8 );
return ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
#elif defined( SYS_DARWIN1_3 )
INIT_DVDIOCTL( 12 );
dvdioctl.i_keyformat = kKey2;
dvdioctl.i_agid = *pi_agid;
p_buffer[ 1 ] = 0xa;
memcpy( p_buffer + 4, p_key, 8 );
return ioctl( i_fd, IODVD_SEND_KEY, &dvdioctl );
#else
/* DVD ioctls unavailable - do as if the ioctl failed */
return -1;
......@@ -511,11 +593,10 @@ int ioctl_SendKey2( int i_fd, int *pi_agid, u8 *p_key )
* This function initializes a BeOS raw device command structure for future
* use, either a read command or a write command.
*****************************************************************************/
static void BeInitRDC( raw_device_command *p_rdc,
void *p_buffer, int i_type, int i_len )
static void BeInitRDC( raw_device_command *p_rdc, int i_type )
{
memset( p_rdc, 0, sizeof( raw_device_command ) );
memset( p_buffer, 0, i_len );
memset( p_rdc->data, 0, p_rdc->data_length );
switch( i_type )
{
......@@ -531,13 +612,10 @@ static void BeInitRDC( raw_device_command *p_rdc,
p_rdc->command[ 0 ] = i_type;
p_rdc->command[ 8 ] = (i_len >> 8) & 0xff;
p_rdc->command[ 9 ] = i_len & 0xff;
p_rdc->command[ 8 ] = (p_rdc->data_length >> 8) & 0xff;
p_rdc->command[ 9 ] = p_rdc->data_length & 0xff;
p_rdc->command_length = 12;
p_rdc->data = (char *)p_buffer;
p_rdc->data_length = i_len;
p_rdc->sense_data = NULL;
p_rdc->sense_data_length = 0;
......
......@@ -2,7 +2,7 @@
* aout_esd.c : Esound functions library
*****************************************************************************
* Copyright (C) 2000 VideoLAN
* $Id: aout_esd.c,v 1.11 2001/03/21 13:42:33 sam Exp $
* $Id: aout_esd.c,v 1.12 2001/05/25 04:23:37 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -141,9 +141,13 @@ static int aout_Open( aout_thread_t *p_aout )
p_aout->p_sys->esd_format = (i_bits | i_mode | i_func) & (~ESD_MASK_CHAN);
if( p_aout->i_channels == 1 )
{
p_aout->p_sys->esd_format |= ESD_MONO;
}
else
{
p_aout->p_sys->esd_format |= ESD_STEREO;
}
/* open a socket for playing a stream
* and try to open /dev/dsp if there's no EsounD */
......@@ -157,6 +161,10 @@ static int aout_Open( aout_thread_t *p_aout )
return( -1 );
}
intf_ErrMsg( "aout error: you are using the Esound plugin. There is no way yet to get the\n"
" driver latency because esd_get_latency() hangs, so expect a one\n"
" second delay with sound. Type `esdctl off' to disable esd." );
return( 0 );
}
......@@ -184,25 +192,31 @@ static long aout_GetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
*****************************************************************************/
static void aout_Play( aout_thread_t *p_aout, byte_t *buffer, int i_size )
{
int amount;
int i_amount;
if (p_aout->p_sys->esd_format & ESD_STEREO)
{
if (p_aout->p_sys->esd_format & ESD_BITS16)
amount = (44100 * (ESD_BUF_SIZE + 64)) / p_aout->l_rate;
{
i_amount = (44100 * (ESD_BUF_SIZE + 64)) / p_aout->l_rate;
}
else
amount = (44100 * (ESD_BUF_SIZE + 128)) / p_aout->l_rate;
{
i_amount = (44100 * (ESD_BUF_SIZE + 128)) / p_aout->l_rate;
}
}
else
{
if (p_aout->p_sys->esd_format & ESD_BITS16)
amount = (2 * 44100 * (ESD_BUF_SIZE + 128)) / p_aout->l_rate;
{
i_amount = (2 * 44100 * (ESD_BUF_SIZE + 128)) / p_aout->l_rate;
}
else
amount = (2 * 44100 * (ESD_BUF_SIZE + 256)) / p_aout->l_rate;
{
i_amount = (2 * 44100 * (ESD_BUF_SIZE + 256)) / p_aout->l_rate;
}
}
intf_DbgMsg( "aout: latency is %i", amount );
write( p_aout->i_fd, buffer, i_size );
}
......
......@@ -2,7 +2,7 @@
* audio_output.c : audio output thread
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: audio_output.c,v 1.60 2001/05/06 04:32:02 sam Exp $
* $Id: audio_output.c,v 1.61 2001/05/25 04:23:37 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
*
......@@ -188,9 +188,9 @@ aout_thread_t *aout_CreateThread( int *pi_status )
*****************************************************************************/
static int aout_SpawnThread( aout_thread_t * p_aout )
{
int i_fifo;
long l_bytes;
void * aout_thread = NULL;
int i_fifo;
long l_bytes;
void (* pf_aout_thread)( aout_thread_t * ) = NULL;
/* We want the audio output thread to live */
p_aout->b_die = 0;
......@@ -212,7 +212,7 @@ static int aout_SpawnThread( aout_thread_t * p_aout )
p_aout->l_units = (long)( ((s64)p_aout->l_rate * AOUT_BUFFER_DURATION) / 1000000 );
p_aout->l_msleep = (long)( ((s64)p_aout->l_units * 1000000) / (s64)p_aout->l_rate );
/* Make aout_thread point to the right thread function, and compute the
/* Make pf_aout_thread point to the right thread function, and compute the
* byte size of the audio output buffer */
switch ( p_aout->i_channels )
{
......@@ -223,32 +223,33 @@ static int aout_SpawnThread( aout_thread_t * p_aout )
case AOUT_FMT_U8:
intf_WarnMsg( 2, "aout info: unsigned 8 bits mono thread" );
l_bytes = 1 * sizeof(u8) * p_aout->l_units;
aout_thread = (void *)aout_U8MonoThread;
pf_aout_thread = aout_U8MonoThread;
break;
case AOUT_FMT_S8:
intf_WarnMsg( 2, "aout info: signed 8 bits mono thread" );
l_bytes = 1 * sizeof(s8) * p_aout->l_units;
aout_thread = (void *)aout_S8MonoThread;
pf_aout_thread = aout_S8MonoThread;
break;
case AOUT_FMT_U16_LE:
case AOUT_FMT_U16_BE:
intf_WarnMsg( 2, "aout info: unsigned 16 bits mono thread" );
l_bytes = 1 * sizeof(u16) * p_aout->l_units;
aout_thread = (void *)aout_U16MonoThread;
pf_aout_thread = aout_U16MonoThread;
break;
case AOUT_FMT_S16_LE:
case AOUT_FMT_S16_BE:
intf_WarnMsg( 2, "aout info: signed 16 bits mono thread" );
l_bytes = 1 * sizeof(s16) * p_aout->l_units;
aout_thread = (void *)aout_S16MonoThread;
pf_aout_thread = aout_S16MonoThread;
break;
case AOUT_FMT_AC3:
intf_WarnMsg( 2, "aout info: ac3 pass-through thread" );
l_bytes = 0;
aout_thread = (void *)aout_SpdifThread;
pf_aout_thread = aout_SpdifThread;
break;
default:
......@@ -265,27 +266,27 @@ static int aout_SpawnThread( aout_thread_t * p_aout )
case AOUT_FMT_U8:
intf_WarnMsg( 2, "aout info: unsigned 8 bits stereo thread" );
l_bytes = 2 * sizeof(u8) * p_aout->l_units;
aout_thread = (void *)aout_U8StereoThread;
pf_aout_thread = aout_U8StereoThread;
break;
case AOUT_FMT_S8:
intf_WarnMsg( 2, "aout info: signed 8 bits stereo thread" );
l_bytes = 2 * sizeof(s8) * p_aout->l_units;
aout_thread = (void *)aout_S8StereoThread;
pf_aout_thread = aout_S8StereoThread;
break;
case AOUT_FMT_U16_LE:
case AOUT_FMT_U16_BE:
intf_WarnMsg( 2, "aout info: unsigned 16 bits stereo thread" );
l_bytes = 2 * sizeof(u16) * p_aout->l_units;
aout_thread = (void *)aout_U16StereoThread;
pf_aout_thread = aout_U16StereoThread;
break;
case AOUT_FMT_S16_LE:
case AOUT_FMT_S16_BE:
intf_WarnMsg( 2, "aout info: signed 16 bits stereo thread" );
l_bytes = 2 * sizeof(s16) * p_aout->l_units;
aout_thread = (void *)aout_S16StereoThread;
pf_aout_thread = aout_S16StereoThread;
break;
default:
intf_ErrMsg( "aout error: unknown audio output format %i",
......@@ -323,7 +324,7 @@ static int aout_SpawnThread( aout_thread_t * p_aout )
/* Launch the thread */
if ( vlc_thread_create( &p_aout->thread_id, "audio output",
(vlc_thread_func_t)aout_thread, p_aout ) )
(vlc_thread_func_t)pf_aout_thread, p_aout ) )
{
intf_ErrMsg( "aout error: cannot spawn audio output thread" );
free( p_aout->buffer );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment