1 /*****************************************************************************
2 * aout_spdif.c: AC3 passthrough output
3 *****************************************************************************
4 * Copyright (C) 2001 VideoLAN
5 * $Id: aout_spdif.c,v 1.28 2002/05/18 08:50:54 stef Exp $
7 * Authors: Michel Kaempf <maxx@via.ecp.fr>
8 * Stéphane Borel <stef@via.ecp.fr>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
28 #include <stdio.h> /* "intf_msg.h" */
29 #include <stdlib.h> /* calloc(), malloc(), free() */
30 #include <string.h> /* memset() */
32 #include <videolan/vlc.h>
38 #include "audio_output.h"
39 #include "aout_spdif.h"
41 /****************************************************************************
42 * iec958_build_burst: builds an iec958/spdif frame
43 ****************************************************************************/
44 void iec958_build_burst( u8 * p_buf, aout_fifo_t * p_fifo )
46 const u8 p_sync[6] = { 0x72, 0xF8, 0x1F, 0x4E, 0x01, 0x00 };
47 int i_length = p_fifo->i_frame_size;
49 /* Skip the first byte if i_length is odd */
50 u16 * p_in = (u16 *)( p_fifo->buffer + ( i_length & 0x1 ) );
51 u16 * p_out = (u16 *)p_buf;
54 /* Add the spdif headers */
55 memcpy( p_buf, p_sync, 6 );
56 p_buf[6] = ( i_length * 8 ) & 0xFF;
57 p_buf[7] = ( ( i_length * 8 ) >> 8 ) & 0xFF;
60 swab( p_fifo->buffer + p_fifo->i_start_frame * i_length,
61 p_buf + 8, i_length );
63 /* i_length should be even */
68 *p_out = ( (*p_in & 0x00ff) << 16 ) | ( (*p_in & 0xff00) >> 16 );
75 /* Add zeroes to complete the spdif frame,
76 * they will be ignored by the decoder */
77 memset( p_buf + 8 + i_length, 0, SPDIF_FRAME_SIZE - 8 - i_length );
81 /*****************************************************************************
82 * aout_SpdifThread: audio output thread that sends raw spdif data
83 * to an external decoder
84 *****************************************************************************
85 * This output thread is quite specific as it can only handle one fifo now.
87 * Note: spdif can demux up to 8 ac3 streams, and can even take
88 * care of time stamps (cf ac3 spec) but I'm not sure all decoders
90 *****************************************************************************/
91 void aout_SpdifThread( aout_thread_t * p_aout )
94 mtime_t m_frame_time = 0;
98 while( !p_aout->b_die )
101 /* Find spdif fifo */
102 while( ( p_aout->fifo[i_fifo].i_format != AOUT_FIFO_SPDIF ) &&
103 ( i_fifo < AOUT_MAX_FIFOS ) && !p_aout->b_die )
110 while( !p_aout->b_die &&
111 !p_aout->fifo[i_fifo].b_die )
113 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
114 if( !AOUT_FIFO_ISEMPTY( p_aout->fifo[i_fifo] ) )
116 /* Copy data from fifo to buffer to release the
118 iec958_build_burst( p_aout->buffer,
119 &p_aout->fifo[i_fifo] );
121 m_play = p_aout->fifo[i_fifo].date[p_aout->fifo[i_fifo].
124 p_aout->fifo[i_fifo].i_start_frame =
125 (p_aout->fifo[i_fifo].i_start_frame + 1 )
128 /* Compute the theorical duration of an ac3 frame */
129 m_frame_time = 1000000 * AC3_FRAME_SIZE
130 / p_aout->fifo[i_fifo].i_rate;
132 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
134 /* Play spdif frame to the external decoder
135 * the kernel driver will sleep until the
136 * dsp buffer is empty enough to accept the data */
137 if( m_play > ( mdate() - m_frame_time ) )
139 /* check continuity */
140 if( (m_play - m_old) != m_frame_time )
142 mwait( m_play - m_frame_time );
146 mwait( m_play - 2 * m_frame_time );
150 p_aout->pf_getbufinfo( p_aout, 0 );
152 p_aout->pf_play( p_aout, (byte_t *)p_aout->buffer,
158 intf_WarnMsg( 3, "aout warning: empty spdif fifo" );
159 while( AOUT_FIFO_ISEMPTY( p_aout->fifo[i_fifo] ) &&
161 !p_aout->fifo[i_fifo].b_die )
164 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
165 msleep( m_frame_time );
166 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
168 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
172 vlc_mutex_lock( &p_aout->fifos_lock );
173 aout_FreeFifo( &p_aout->fifo[i_fifo] );
174 vlc_mutex_unlock( &p_aout->fifos_lock );