1 /*****************************************************************************
2 * aout_spdif: ac3 passthrough output
3 *****************************************************************************
4 * Copyright (C) 2001 VideoLAN
5 * $Id: aout_spdif.c,v 1.6 2001/05/19 00:39:30 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 *****************************************************************************/
30 #include <stdio.h> /* "intf_msg.h" */
31 #include <stdlib.h> /* calloc(), malloc(), free() */
32 #include <string.h> /* memset() */
37 #include "mtime.h" /* mtime_t, mdate(), msleep() */
39 #include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
41 #include "audio_output.h"
42 #include "aout_common.h"
44 #define BLANK_FRAME_MAX 1000
46 /*****************************************************************************
47 * aout_SpdifThread: audio output thread that sends raw spdif data
48 * to an external decoder
49 *****************************************************************************
50 * This output thread is quite specific as it can only handle one fifo now.
52 * Note: spdif can demux up to 8 ac3 streams, and can even take
53 * care of time stamps (cf ac3 spec).
54 *****************************************************************************/
55 void aout_SpdifThread( aout_thread_t * p_aout )
57 u8 pi_spdif_blank [9] =
58 { 0x72, 0xf8, 0x1f, 0x4e, 0x01, 0x00, 0x08, 0x00, 0x77 };
59 u8 pi_blank[SPDIF_FRAME_SIZE];
64 /* get a blank frame ready */
65 memset( pi_blank, 0, sizeof(pi_blank) );
66 memcpy( pi_blank, pi_spdif_blank, sizeof(pi_spdif_blank) );
68 intf_WarnMsg( 3, "aout info: starting spdif output loop" );
70 /* variable used to compute the nnumber of blank frames since the
71 * last significant frame */
74 while( !p_aout->b_die )
76 /* we leave some time for aout fifo to fill and not to stress
77 * the external decoder too much */
80 /* variable to check that we send data to the decoder
81 * once per loop at least */
84 /* FIXME: find a way to hnadle the locks here */
85 for( i_fifo = 0 ; i_fifo < AOUT_MAX_FIFOS ; i_fifo++ )
87 /* the loop read each fifo so that we can change the stream
88 * on the fly but mulitplexing is not handled yet so
89 * the sound will be broken is more than one fifo has data */
90 /* TODO: write the muliplexer :) */
91 if( p_aout->fifo[i_fifo].i_type == AOUT_ADEC_SPDIF_FIFO )
93 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
94 if( p_aout->fifo[i_fifo].b_die )
96 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
97 aout_FreeFifo( &p_aout->fifo[i_fifo] );
99 else if( !AOUT_FIFO_ISEMPTY( p_aout->fifo[i_fifo] ) )
101 // vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
102 //fprintf(stderr, "delay %lld\n",p_aout->fifo[i_fifo].date[p_aout->fifo[i_fifo].l_start_frame] -mdate() );
104 /* play spdif frame to the external decoder */
105 p_aout->pf_play( p_aout,
106 p_aout->fifo[i_fifo].buffer +
107 p_aout->fifo[i_fifo].l_start_frame*
109 p_aout->fifo[i_fifo].l_frame_size );
111 // vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
112 p_aout->fifo[i_fifo].l_start_frame =
113 (p_aout->fifo[i_fifo].l_start_frame + 1 )
115 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
122 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
128 /* insert blank frame for stream continuity to
129 * the external decoder */
130 p_aout->pf_play( p_aout, pi_blank, SPDIF_FRAME_SIZE );
132 /* we kill the output if we don't have any stream */
133 if( ++i_blank > BLANK_FRAME_MAX )
140 intf_WarnMsg( 3, "aout info: exiting spdif loop" );