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
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2000 Apple Computer, Inc. All rights reserved. * Copyright (C) 1998-2000 Apple Computer, Inc. All rights reserved.
* Copyright (C) 2001 VideoLAN * 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> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -29,9 +29,6 @@ ...@@ -29,9 +29,6 @@
* it is still in use * it is still in use
*****************************************************************************/ *****************************************************************************/
//XXX: uncomment to activate the key exchange ioctls - may hang the machine
//#define ACTIVATE_DANGEROUS_IOCTL 1
/***************************************************************************** /*****************************************************************************
* Preamble * Preamble
*****************************************************************************/ *****************************************************************************/
...@@ -453,7 +450,12 @@ static void DVDStrategy( buf_t * bp ) ...@@ -453,7 +450,12 @@ static void DVDStrategy( buf_t * bp )
static int DVDBlockIoctl( dev_t dev, u_long cmd, caddr_t addr, int flags, static int DVDBlockIoctl( dev_t dev, u_long cmd, caddr_t addr, int flags,
struct proc *p ) 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 ) switch( cmd )
{ {
...@@ -468,19 +470,14 @@ static int DVDBlockIoctl( dev_t dev, u_long cmd, caddr_t addr, int flags, ...@@ -468,19 +470,14 @@ static int DVDBlockIoctl( dev_t dev, u_long cmd, caddr_t addr, int flags,
case IODVD_SEND_KEY: case IODVD_SEND_KEY:
log( LOG_INFO, "DVD ioctl: send key to `%s', " 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(), p_drive->getDeviceTypeName(),
(int)p_data->p_buffer, p_data->i_keyformat, (int)p_data->p_buffer, p_data->i_keyclass,
p_data->i_keyclass, p_data->i_agid ); p_data->i_agid, p_data->i_keyformat );
#ifdef ACTIVATE_DANGEROUS_IOCTL return p_drive->sendKey( p_mem, (DVDKeyClass)p_data->i_keyclass,
return p_drive->sendKey( (IOMemoryDescriptor *)p_data->p_buffer,
(DVDKeyClass)p_data->i_keyclass,
p_data->i_agid, p_data->i_agid,
(DVDKeyFormat)p_data->i_keyformat ); (DVDKeyFormat)p_data->i_keyformat );
#else
return -1;
#endif
case IODVD_REPORT_KEY: case IODVD_REPORT_KEY:
...@@ -490,14 +487,9 @@ static int DVDBlockIoctl( dev_t dev, u_long cmd, caddr_t addr, int flags, ...@@ -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, (int)p_data->p_buffer, p_data->i_keyclass, p_data->i_lba,
p_data->i_agid, p_data->i_keyformat ); p_data->i_agid, p_data->i_keyformat );
#ifdef ACTIVATE_DANGEROUS_IOCTL return p_drive->reportKey( p_mem, (DVDKeyClass)p_data->i_keyclass,
return p_drive->reportKey( (IOMemoryDescriptor *)p_data->p_buffer,
(DVDKeyClass)p_data->i_keyclass,
p_data->i_lba, p_data->i_agid, p_data->i_lba, p_data->i_agid,
(DVDKeyFormat)p_data->i_keyformat ); (DVDKeyFormat)p_data->i_keyformat );
#else
return -1;
#endif
default: default:
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* DVDioctl.h: Linux-like DVD driver for Darwin and MacOS X * DVDioctl.h: Linux-like DVD driver for Darwin and MacOS X
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * 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> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -51,9 +51,11 @@ typedef struct dvdioctl_data ...@@ -51,9 +51,11 @@ typedef struct dvdioctl_data
void *p_buffer; void *p_buffer;
#if defined(KERNEL) #if defined(KERNEL)
UInt32 i_size;
UInt32 i_lba; UInt32 i_lba;
UInt8 i_agid; UInt8 i_agid;
#else #else
u32 i_size;
u32 i_lba; u32 i_lba;
u8 i_agid; u8 i_agid;
#endif #endif
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* dvd_ioctl.c: DVD ioctl replacement function * dvd_ioctl.c: DVD ioctl replacement function
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * Authors: Markus Kuespert <ltlBeBoy@beosmail.com>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -59,14 +59,29 @@ ...@@ -59,14 +59,29 @@
#include "dvd_ioctl.h" #include "dvd_ioctl.h"
/***************************************************************************** /*****************************************************************************
* Local prototypes - BeOS specific * Local prototypes, BeOS specific
*****************************************************************************/ *****************************************************************************/
#if defined( SYS_BEOS ) #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 ) \ #define INIT_RDC( TYPE, SIZE ) \
raw_device_command rdc; \ raw_device_command rdc; \
u8 p_buffer[ (SIZE) ]; \ 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 #endif
/***************************************************************************** /*****************************************************************************
...@@ -108,9 +123,9 @@ int ioctl_ReadCopyright( int i_fd, int i_layer, int *pi_copyright ) ...@@ -108,9 +123,9 @@ int ioctl_ReadCopyright( int i_fd, int i_layer, int *pi_copyright )
#elif defined( SYS_DARWIN1_3 ) #elif defined( SYS_DARWIN1_3 )
intf_ErrMsg( "css error: DVD ioctls not fully functional yet" ); 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 = 1;
*pi_copyright = 0;
i_ret = 0; i_ret = 0;
...@@ -176,6 +191,14 @@ int ioctl_ReadKey( int i_fd, int *pi_agid, u8 *p_key ) ...@@ -176,6 +191,14 @@ int ioctl_ReadKey( int i_fd, int *pi_agid, u8 *p_key )
memcpy( p_key, p_buffer + 4, 2048 ); 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 #else
/* DVD ioctls unavailable - do as if the ioctl failed */ /* DVD ioctls unavailable - do as if the ioctl failed */
i_ret = -1; i_ret = -1;
...@@ -214,12 +237,23 @@ int ioctl_ReportAgid( int i_fd, int *pi_agid ) ...@@ -214,12 +237,23 @@ int ioctl_ReportAgid( int i_fd, int *pi_agid )
#elif defined( SYS_BEOS ) #elif defined( SYS_BEOS )
INIT_RDC( GPCMD_REPORT_KEY, 8 ); 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) ); i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
*pi_agid = p_buffer[ 7 ] >> 6; *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 #else
/* DVD ioctls unavailable - do as if the ioctl failed */ /* DVD ioctls unavailable - do as if the ioctl failed */
i_ret = -1; i_ret = -1;
...@@ -258,12 +292,23 @@ int ioctl_ReportChallenge( int i_fd, int *pi_agid, u8 *p_challenge ) ...@@ -258,12 +292,23 @@ int ioctl_ReportChallenge( int i_fd, int *pi_agid, u8 *p_challenge )
#elif defined( SYS_BEOS ) #elif defined( SYS_BEOS )
INIT_RDC( GPCMD_REPORT_KEY, 16 ); 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) ); i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
memcpy( p_challenge, p_buffer + 4, 12 ); 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 #else
/* DVD ioctls unavailable - do as if the ioctl failed */ /* DVD ioctls unavailable - do as if the ioctl failed */
i_ret = -1; i_ret = -1;
...@@ -304,23 +349,20 @@ int ioctl_ReportASF( int i_fd, int *pi_agid, int *pi_asf ) ...@@ -304,23 +349,20 @@ int ioctl_ReportASF( int i_fd, int *pi_agid, int *pi_asf )
#elif defined( SYS_BEOS ) #elif defined( SYS_BEOS )
INIT_RDC( GPCMD_REPORT_KEY, 8 ); 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) ); i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
*pi_asf = p_buffer[ 7 ] & 1; *pi_asf = p_buffer[ 7 ] & 1;
#elif defined( SYS_DARWIN1_3 ) #elif defined( SYS_DARWIN1_3 )
dvdioctl_data_t data; INIT_DVDIOCTL( 8 );
u8 p_buffer[ 8 ];
data.p_buffer = p_buffer; dvdioctl.i_keyformat = kASF;
data.i_lba = 0; dvdioctl.i_agid = *pi_agid;
data.i_agid = *pi_agid; dvdioctl.i_lba = 0;
data.i_keyclass = kCSS_CSS2_CPRM;
data.i_keyformat = kASF;
i_ret = ioctl( i_fd, IODVD_REPORT_KEY, &data ); i_ret = ioctl( i_fd, IODVD_REPORT_KEY, &dvdioctl );
*pi_asf = p_buffer[ 7 ] & 1; *pi_asf = p_buffer[ 7 ] & 1;
...@@ -362,12 +404,22 @@ int ioctl_ReportKey1( int i_fd, int *pi_agid, u8 *p_key ) ...@@ -362,12 +404,22 @@ int ioctl_ReportKey1( int i_fd, int *pi_agid, u8 *p_key )
#elif defined( SYS_BEOS ) #elif defined( SYS_BEOS )
INIT_RDC( GPCMD_REPORT_KEY, 12 ); 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) ); i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
memcpy( p_key, p_buffer + 4, 8 ); 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 #else
/* DVD ioctls unavailable - do as if the ioctl failed */ /* DVD ioctls unavailable - do as if the ioctl failed */
i_ret = -1; i_ret = -1;
...@@ -406,10 +458,18 @@ int ioctl_InvalidateAgid( int i_fd, int *pi_agid ) ...@@ -406,10 +458,18 @@ int ioctl_InvalidateAgid( int i_fd, int *pi_agid )
#elif defined( SYS_BEOS ) #elif defined( SYS_BEOS )
INIT_RDC( GPCMD_REPORT_KEY, 0 ); 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) ); 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 #else
/* DVD ioctls unavailable - do as if the ioctl failed */ /* DVD ioctls unavailable - do as if the ioctl failed */
i_ret = -1; i_ret = -1;
...@@ -446,13 +506,24 @@ int ioctl_SendChallenge( int i_fd, int *pi_agid, u8 *p_challenge ) ...@@ -446,13 +506,24 @@ int ioctl_SendChallenge( int i_fd, int *pi_agid, u8 *p_challenge )
#elif defined( SYS_BEOS ) #elif defined( SYS_BEOS )
INIT_RDC( GPCMD_SEND_KEY, 16 ); 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; p_buffer[ 1 ] = 0xe;
memcpy( p_buffer + 4, p_challenge, 12 ); memcpy( p_buffer + 4, p_challenge, 12 );
return ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) ); 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 #else
/* DVD ioctls unavailable - do as if the ioctl failed */ /* DVD ioctls unavailable - do as if the ioctl failed */
return -1; return -1;
...@@ -488,13 +559,24 @@ int ioctl_SendKey2( int i_fd, int *pi_agid, u8 *p_key ) ...@@ -488,13 +559,24 @@ int ioctl_SendKey2( int i_fd, int *pi_agid, u8 *p_key )
#elif defined( SYS_BEOS ) #elif defined( SYS_BEOS )
INIT_RDC( GPCMD_SEND_KEY, 12 ); 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; p_buffer[ 1 ] = 0xa;
memcpy( p_buffer + 4, p_key, 8 ); memcpy( p_buffer + 4, p_key, 8 );
return ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) ); 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 #else
/* DVD ioctls unavailable - do as if the ioctl failed */ /* DVD ioctls unavailable - do as if the ioctl failed */
return -1; return -1;
...@@ -511,11 +593,10 @@ int ioctl_SendKey2( int i_fd, int *pi_agid, u8 *p_key ) ...@@ -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 * This function initializes a BeOS raw device command structure for future
* use, either a read command or a write command. * use, either a read command or a write command.
*****************************************************************************/ *****************************************************************************/
static void BeInitRDC( raw_device_command *p_rdc, static void BeInitRDC( raw_device_command *p_rdc, int i_type )
void *p_buffer, int i_type, int i_len )
{ {
memset( p_rdc, 0, sizeof( raw_device_command ) ); 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 ) switch( i_type )
{ {
...@@ -531,13 +612,10 @@ static void BeInitRDC( raw_device_command *p_rdc, ...@@ -531,13 +612,10 @@ static void BeInitRDC( raw_device_command *p_rdc,
p_rdc->command[ 0 ] = i_type; p_rdc->command[ 0 ] = i_type;
p_rdc->command[ 8 ] = (i_len >> 8) & 0xff; p_rdc->command[ 8 ] = (p_rdc->data_length >> 8) & 0xff;
p_rdc->command[ 9 ] = i_len & 0xff; p_rdc->command[ 9 ] = p_rdc->data_length & 0xff;
p_rdc->command_length = 12; 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 = NULL;
p_rdc->sense_data_length = 0; p_rdc->sense_data_length = 0;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* aout_esd.c : Esound functions library * aout_esd.c : Esound functions library
***************************************************************************** *****************************************************************************
* Copyright (C) 2000 VideoLAN * 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> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -141,9 +141,13 @@ static int aout_Open( aout_thread_t *p_aout ) ...@@ -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); p_aout->p_sys->esd_format = (i_bits | i_mode | i_func) & (~ESD_MASK_CHAN);
if( p_aout->i_channels == 1 ) if( p_aout->i_channels == 1 )
{
p_aout->p_sys->esd_format |= ESD_MONO; p_aout->p_sys->esd_format |= ESD_MONO;
}
else else
{
p_aout->p_sys->esd_format |= ESD_STEREO; p_aout->p_sys->esd_format |= ESD_STEREO;
}
/* open a socket for playing a stream /* open a socket for playing a stream
* and try to open /dev/dsp if there's no EsounD */ * and try to open /dev/dsp if there's no EsounD */
...@@ -157,6 +161,10 @@ static int aout_Open( aout_thread_t *p_aout ) ...@@ -157,6 +161,10 @@ static int aout_Open( aout_thread_t *p_aout )
return( -1 ); 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 ); return( 0 );
} }
...@@ -184,24 +192,30 @@ static long aout_GetBufInfo( aout_thread_t *p_aout, long l_buffer_limit ) ...@@ -184,24 +192,30 @@ 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 ) 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_STEREO)
{ {
if (p_aout->p_sys->esd_format & ESD_BITS16) 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 else
amount = (44100 * (ESD_BUF_SIZE + 128)) / p_aout->l_rate; {
i_amount = (44100 * (ESD_BUF_SIZE + 128)) / p_aout->l_rate;
}
} }
else else
{ {
if (p_aout->p_sys->esd_format & ESD_BITS16) 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 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 ); write( p_aout->i_fd, buffer, i_size );
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* audio_output.c : audio output thread * audio_output.c : audio output thread
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN * 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> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* *
...@@ -190,7 +190,7 @@ static int aout_SpawnThread( aout_thread_t * p_aout ) ...@@ -190,7 +190,7 @@ static int aout_SpawnThread( aout_thread_t * p_aout )
{ {
int i_fifo; int i_fifo;
long l_bytes; long l_bytes;
void * aout_thread = NULL; void (* pf_aout_thread)( aout_thread_t * ) = NULL;
/* We want the audio output thread to live */ /* We want the audio output thread to live */
p_aout->b_die = 0; p_aout->b_die = 0;
...@@ -212,7 +212,7 @@ static int aout_SpawnThread( aout_thread_t * p_aout ) ...@@ -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_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 ); 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 */ * byte size of the audio output buffer */
switch ( p_aout->i_channels ) switch ( p_aout->i_channels )
{ {
...@@ -223,32 +223,33 @@ static int aout_SpawnThread( aout_thread_t * p_aout ) ...@@ -223,32 +223,33 @@ static int aout_SpawnThread( aout_thread_t * p_aout )
case AOUT_FMT_U8: case AOUT_FMT_U8:
intf_WarnMsg( 2, "aout info: unsigned 8 bits mono thread" ); intf_WarnMsg( 2, "aout info: unsigned 8 bits mono thread" );
l_bytes = 1 * sizeof(u8) * p_aout->l_units; l_bytes = 1 * sizeof(u8) * p_aout->l_units;
aout_thread = (void *)aout_U8MonoThread; pf_aout_thread = aout_U8MonoThread;
break; break;
case AOUT_FMT_S8: case AOUT_FMT_S8:
intf_WarnMsg( 2, "aout info: signed 8 bits mono thread" ); intf_WarnMsg( 2, "aout info: signed 8 bits mono thread" );
l_bytes = 1 * sizeof(s8) * p_aout->l_units; l_bytes = 1 * sizeof(s8) * p_aout->l_units;
aout_thread = (void *)aout_S8MonoThread; pf_aout_thread = aout_S8MonoThread;
break; break;
case AOUT_FMT_U16_LE: case AOUT_FMT_U16_LE:
case AOUT_FMT_U16_BE: case AOUT_FMT_U16_BE:
intf_WarnMsg( 2, "aout info: unsigned 16 bits mono thread" ); intf_WarnMsg( 2, "aout info: unsigned 16 bits mono thread" );
l_bytes = 1 * sizeof(u16) * p_aout->l_units; l_bytes = 1 * sizeof(u16) * p_aout->l_units;
aout_thread = (void *)aout_U16MonoThread; pf_aout_thread = aout_U16MonoThread;
break; break;
case AOUT_FMT_S16_LE: case AOUT_FMT_S16_LE:
case AOUT_FMT_S16_BE: case AOUT_FMT_S16_BE:
intf_WarnMsg( 2, "aout info: signed 16 bits mono thread" ); intf_WarnMsg( 2, "aout info: signed 16 bits mono thread" );
l_bytes = 1 * sizeof(s16) * p_aout->l_units; l_bytes = 1 * sizeof(s16) * p_aout->l_units;
aout_thread = (void *)aout_S16MonoThread; pf_aout_thread = aout_S16MonoThread;
break; break;
case AOUT_FMT_AC3: case AOUT_FMT_AC3:
intf_WarnMsg( 2, "aout info: ac3 pass-through thread" ); intf_WarnMsg( 2, "aout info: ac3 pass-through thread" );
l_bytes = 0; l_bytes = 0;
aout_thread = (void *)aout_SpdifThread; pf_aout_thread = aout_SpdifThread;
break; break;
default: default:
...@@ -265,27 +266,27 @@ static int aout_SpawnThread( aout_thread_t * p_aout ) ...@@ -265,27 +266,27 @@ static int aout_SpawnThread( aout_thread_t * p_aout )
case AOUT_FMT_U8: case AOUT_FMT_U8:
intf_WarnMsg( 2, "aout info: unsigned 8 bits stereo thread" ); intf_WarnMsg( 2, "aout info: unsigned 8 bits stereo thread" );
l_bytes = 2 * sizeof(u8) * p_aout->l_units; l_bytes = 2 * sizeof(u8) * p_aout->l_units;
aout_thread = (void *)aout_U8StereoThread; pf_aout_thread = aout_U8StereoThread;
break; break;
case AOUT_FMT_S8: case AOUT_FMT_S8:
intf_WarnMsg( 2, "aout info: signed 8 bits stereo thread" ); intf_WarnMsg( 2, "aout info: signed 8 bits stereo thread" );
l_bytes = 2 * sizeof(s8) * p_aout->l_units; l_bytes = 2 * sizeof(s8) * p_aout->l_units;
aout_thread = (void *)aout_S8StereoThread; pf_aout_thread = aout_S8StereoThread;
break; break;
case AOUT_FMT_U16_LE: case AOUT_FMT_U16_LE:
case AOUT_FMT_U16_BE: case AOUT_FMT_U16_BE:
intf_WarnMsg( 2, "aout info: unsigned 16 bits stereo thread" ); intf_WarnMsg( 2, "aout info: unsigned 16 bits stereo thread" );
l_bytes = 2 * sizeof(u16) * p_aout->l_units; l_bytes = 2 * sizeof(u16) * p_aout->l_units;
aout_thread = (void *)aout_U16StereoThread; pf_aout_thread = aout_U16StereoThread;
break; break;
case AOUT_FMT_S16_LE: case AOUT_FMT_S16_LE:
case AOUT_FMT_S16_BE: case AOUT_FMT_S16_BE:
intf_WarnMsg( 2, "aout info: signed 16 bits stereo thread" ); intf_WarnMsg( 2, "aout info: signed 16 bits stereo thread" );
l_bytes = 2 * sizeof(s16) * p_aout->l_units; l_bytes = 2 * sizeof(s16) * p_aout->l_units;
aout_thread = (void *)aout_S16StereoThread; pf_aout_thread = aout_S16StereoThread;
break; break;
default: default:
intf_ErrMsg( "aout error: unknown audio output format %i", intf_ErrMsg( "aout error: unknown audio output format %i",
...@@ -323,7 +324,7 @@ static int aout_SpawnThread( aout_thread_t * p_aout ) ...@@ -323,7 +324,7 @@ static int aout_SpawnThread( aout_thread_t * p_aout )
/* Launch the thread */ /* Launch the thread */
if ( vlc_thread_create( &p_aout->thread_id, "audio output", 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" ); intf_ErrMsg( "aout error: cannot spawn audio output thread" );
free( p_aout->buffer ); 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