* Introduce 'spdb' the big endian variant of 'spdi' output. This will be needed for the encoded audio output on the PowerMac G5. Only A52 is supported so far. DTS support will follow later. (As well as the actual OSX output changes)

This commit is contained in:
Derk-Jan Hartman 2005-12-01 14:12:16 +00:00
parent a644825aa9
commit b8840f72ca
3 changed files with 90 additions and 25 deletions

View File

@ -41,14 +41,17 @@
# define AOUT_FMT_S16_NE VLC_FOURCC('s','1','6','b')
# define AOUT_FMT_U16_NE VLC_FOURCC('u','1','6','b')
# define AOUT_FMT_S24_NE VLC_FOURCC('s','2','4','b')
# define AOUT_FMT_SPDIF_NE VLC_FOURCC('s','p','d','b')
#else
# define AOUT_FMT_S16_NE VLC_FOURCC('s','1','6','l')
# define AOUT_FMT_U16_NE VLC_FOURCC('u','1','6','l')
# define AOUT_FMT_S24_NE VLC_FOURCC('s','2','4','l')
# define AOUT_FMT_SPDIF_NE VLC_FOURCC('s','p','d','i')
#endif
#define AOUT_FMT_NON_LINEAR( p_format ) \
( ((p_format)->i_format == VLC_FOURCC('s','p','d','i')) \
|| ((p_format)->i_format == VLC_FOURCC('s','p','d','b')) \
|| ((p_format)->i_format == VLC_FOURCC('a','5','2',' ')) \
|| ((p_format)->i_format == VLC_FOURCC('d','t','s',' ')) )

View File

@ -44,6 +44,54 @@ static int Create ( vlc_object_t * );
static void DoWork ( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
aout_buffer_t * );
struct frmsize_s
{
uint16_t bit_rate;
uint16_t frm_size[3];
};
static const struct frmsize_s frmsizecod_tbl[64] =
{
{ 32 ,{64 ,69 ,96 } },
{ 32 ,{64 ,70 ,96 } },
{ 40 ,{80 ,87 ,120 } },
{ 40 ,{80 ,88 ,120 } },
{ 48 ,{96 ,104 ,144 } },
{ 48 ,{96 ,105 ,144 } },
{ 56 ,{112 ,121 ,168 } },
{ 56 ,{112 ,122 ,168 } },
{ 64 ,{128 ,139 ,192 } },
{ 64 ,{128 ,140 ,192 } },
{ 80 ,{160 ,174 ,240 } },
{ 80 ,{160 ,175 ,240 } },
{ 96 ,{192 ,208 ,288 } },
{ 96 ,{192 ,209 ,288 } },
{ 112 ,{224 ,243 ,336 } },
{ 112 ,{224 ,244 ,336 } },
{ 128 ,{256 ,278 ,384 } },
{ 128 ,{256 ,279 ,384 } },
{ 160 ,{320 ,348 ,480 } },
{ 160 ,{320 ,349 ,480 } },
{ 192 ,{384 ,417 ,576 } },
{ 192 ,{384 ,418 ,576 } },
{ 224 ,{448 ,487 ,672 } },
{ 224 ,{448 ,488 ,672 } },
{ 256 ,{512 ,557 ,768 } },
{ 256 ,{512 ,558 ,768 } },
{ 320 ,{640 ,696 ,960 } },
{ 320 ,{640 ,697 ,960 } },
{ 384 ,{768 ,835 ,1152 } },
{ 384 ,{768 ,836 ,1152 } },
{ 448 ,{896 ,975 ,1344 } },
{ 448 ,{896 ,976 ,1344 } },
{ 512 ,{1024 ,1114 ,1536 } },
{ 512 ,{1024 ,1115 ,1536 } },
{ 576 ,{1152 ,1253 ,1728 } },
{ 576 ,{1152 ,1254 ,1728 } },
{ 640 ,{1280 ,1393 ,1920 } },
{ 640 ,{1280 ,1394 ,1920 } }
};
/*****************************************************************************
* Module descriptor
*****************************************************************************/
@ -63,6 +111,7 @@ static int Create( vlc_object_t *p_this )
aout_filter_t * p_filter = (aout_filter_t *)p_this;
if ( p_filter->input.i_format != VLC_FOURCC('a','5','2',' ')
|| p_filter->output.i_format != VLC_FOURCC('s','p','d','b')
|| p_filter->output.i_format != VLC_FOURCC('s','p','d','i') )
{
return -1;
@ -80,43 +129,55 @@ static int Create( vlc_object_t *p_this )
static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
{
/* It is not entirely clear which endianness the AC3 stream should have.
* I have been told endianness does not matter, AC3 can be both endian.
* But then, I could not get it to work on Mac OS X and a JVC RX-6000R
* decoder without using little endian. So right now, I convert to little
* endian.
/* AC3 is natively big endian. Most SPDIF devices have the native endianness of
* the computersystem. On MAc OS X however, little endian devices are also common.
*/
static const uint8_t p_sync[6] = { 0x72, 0xF8, 0x1F, 0x4E, 0x01, 0x00 };
uint32_t syncword, crc1, fscod, frmsizecod, bsid, bsmod, frame_size;
static const uint8_t p_sync_le[6] = { 0x72, 0xF8, 0x1F, 0x4E, 0x01, 0x00 };
static const uint8_t p_sync_be[6] = { 0xF8, 0x72, 0x4E, 0x1F, 0x00, 0x01 };
#ifndef HAVE_SWAB
byte_t * p_tmp;
uint16_t i;
#endif
uint16_t i_length = p_in_buf->i_nb_bytes;
uint8_t * pi_length;
byte_t * p_in = p_in_buf->p_buffer;
byte_t * p_out = p_out_buf->p_buffer;
/* AC3 header decode */
syncword = p_in[0] | (p_in[1] << 8);
crc1 = p_in[2] | (p_in[3] << 8);
fscod = (p_in[4] >> 6) & 0x3;
frmsizecod = p_in[4] & 0x3f;
bsid = (p_in[5] >> 3) & 0x1f;
bsmod = p_in[5] & 0x7;
frame_size = frmsizecod_tbl[frmsizecod].frm_size[fscod];
/* Copy the S/PDIF headers. */
memcpy( p_out, p_sync, 6 );
pi_length = (p_out + 6);
*pi_length = (i_length * 8) & 0xff;
*(pi_length + 1) = (i_length * 8) >> 8;
#ifdef HAVE_SWAB
swab( p_in, p_out + 8, i_length );
#else
p_tmp = p_out + 8;
for ( i = i_length / 2 ; i-- ; )
if( p_filter->output.i_format == VLC_FOURCC('s','p','d','b') )
{
p_tmp[0] = p_in[1];
p_tmp[1] = p_in[0];
p_tmp += 2; p_in += 2;
p_filter->p_vlc->pf_memcpy( p_out, p_sync_be, 6 );
p_out[4] = bsmod;
p_out[6] = ((frame_size ) >> 4) & 0xff;
p_out[7] = (frame_size << 4) & 0xff;
p_filter->p_vlc->pf_memcpy( &p_out[8], p_in, frame_size * 2 );
}
else
{
memcpy( p_out, p_sync_le, 6 );
p_out[5] = bsmod;
p_out[6] = (frame_size << 4) & 0xff;
p_out[7] = ((frame_size ) >> 4) & 0xff;
#ifdef HAVE_SWAB
swab( p_in, &p_out[8], frame_size * 2 );
#else
p_tmp = &p_out[8];
for( i = frame_size; i-- ; )
{
p_tmp[0] = p_in[1];
p_tmp[1] = p_in[0];
p_tmp += 2; p_in += 2;
}
#endif
p_filter->p_vlc->pf_memset( p_out + 8 + i_length, 0,
AOUT_SPDIF_SIZE - i_length - 8 );
}
p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
p_out_buf->i_nb_bytes = AOUT_SPDIF_SIZE;

View File

@ -142,6 +142,7 @@ void aout_FormatPrepare( audio_sample_format_t * p_format )
break;
case VLC_FOURCC('s','p','d','i'):
case VLC_FOURCC('s','p','d','b'): /* Big endian spdif output */
case VLC_FOURCC('a','5','2',' '):
case VLC_FOURCC('d','t','s',' '):
case VLC_FOURCC('m','p','g','a'):