mirror of https://code.videolan.org/videolan/vlc
* 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:
parent
a644825aa9
commit
b8840f72ca
|
@ -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',' ')) )
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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'):
|
||||
|
|
Loading…
Reference in New Issue