]> git.sesse.net Git - vlc/blob - src/audio_output/aout_spdif.c
-moved warning message to debug message in spdif pass-through plugin
[vlc] / src / audio_output / aout_spdif.c
1 /*****************************************************************************
2  * aout_spdif: ac3 passthrough output
3  *****************************************************************************
4  * Copyright (C) 2001 VideoLAN
5  * $Id: aout_spdif.c,v 1.18 2001/11/14 03:38:11 stef Exp $
6  *
7  * Authors: Michel Kaempf <maxx@via.ecp.fr>
8  *          Stéphane Borel <stef@via.ecp.fr>
9  *
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.
14  * 
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.
19  *
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  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include "defs.h"
29
30 #include <stdio.h>                                           /* "intf_msg.h" */
31 #include <stdlib.h>                            /* calloc(), malloc(), free() */
32 #include <string.h>                                              /* memset() */
33
34 #include "config.h"
35 #include "common.h"
36 #include "threads.h"
37 #include "mtime.h"                             /* mtime_t, mdate(), msleep() */
38
39 #include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
40
41 #include "audio_output.h"
42 #include "aout_common.h"
43
44 /*****************************************************************************
45  * aout_SpdifThread: audio output thread that sends raw spdif data
46  *                   to an external decoder
47  *****************************************************************************
48  * This output thread is quite specific as it can only handle one fifo now.
49  *
50  * Note: spdif can demux up to 8 ac3 streams, and can even take
51  * care of time stamps (cf ac3 spec) but I'm not sure all decoders
52  * implement it.
53  *****************************************************************************/
54 void aout_SpdifThread( aout_thread_t * p_aout )
55 {
56   int         i_fifo;
57   mtime_t     m_frame_time = 0;
58   mtime_t     m_play;
59   mtime_t     m_old = 0;
60
61
62   intf_DbgMsg( "aout debug: starting spdif output loop" );
63
64   while( !p_aout->b_die )
65   {
66     for( i_fifo = 0 ; i_fifo < AOUT_MAX_FIFOS ; i_fifo++ )
67     {
68       /* the loop read each fifo so that we can change the stream
69        * on the fly but mulitplexing is not handled yet so
70        * the sound will be broken is more than one fifo has data */ 
71       /* TODO: write the muliplexer :) */
72       if( p_aout->fifo[i_fifo].i_type == AOUT_ADEC_SPDIF_FIFO )
73       {
74         vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
75         if( p_aout->fifo[i_fifo].b_die )
76         {
77           vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
78
79           vlc_mutex_lock( &p_aout->fifos_lock );
80           aout_FreeFifo( &p_aout->fifo[i_fifo] );
81           vlc_mutex_unlock( &p_aout->fifos_lock );
82         }
83         else if( !AOUT_FIFO_ISEMPTY( p_aout->fifo[i_fifo] ) )
84         {
85           /* Copy data from fifo to buffer to release the lock earlier */
86           memcpy( p_aout->buffer,
87                   (byte_t *)p_aout->fifo[i_fifo].buffer
88                           + p_aout->fifo[i_fifo].l_start_frame
89                           * SPDIF_FRAME_SIZE,
90                   SPDIF_FRAME_SIZE );
91
92           m_play = p_aout->fifo[i_fifo].date[p_aout->fifo[i_fifo].
93                        l_start_frame];
94
95           p_aout->fifo[i_fifo].l_start_frame =
96               (p_aout->fifo[i_fifo].l_start_frame + 1 )
97               & AOUT_FIFO_SIZE;
98
99           /* Compute the theorical duration of an ac3 frame */
100           m_frame_time = 1000000 * AC3_FRAME_SIZE
101                                  / p_aout->fifo[i_fifo].l_rate;
102
103           vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
104
105           /* play spdif frame to the external decoder 
106            * the kernel driver will sleep until the
107            * dsp buffer is empty enough to accept the data */
108           if( m_play > ( mdate() - m_frame_time ) )
109           {
110             /* check continuity */
111             if( (m_play - m_old) != m_frame_time )
112             {
113               intf_DbgMsg( "aout debug: malformed frame ? (%lld)",
114                                m_play - m_old );
115               mwait( m_play - m_frame_time );
116             }
117             else
118             {
119               mwait( m_play - 2 * m_frame_time );
120             }
121             m_old = m_play;
122
123             p_aout->pf_play( p_aout,
124                              (byte_t *)p_aout->buffer,
125                              SPDIF_FRAME_SIZE );
126           }
127           else
128           {
129             intf_DbgMsg( "aout debug: late spdif frame" );
130           }
131         }
132         else
133         {
134           vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
135           msleep( m_frame_time );
136           intf_WarnMsg( 3, "aout warning: empty spdif fifo" );
137         }
138       }
139     }
140   }
141
142   intf_DbgMsg( "aout debug: exiting spdif loop" );
143   vlc_mutex_lock( &p_aout->fifos_lock );
144
145   for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
146   {
147     aout_FreeFifo( &p_aout->fifo[i_fifo] );
148   }
149
150   vlc_mutex_unlock( &p_aout->fifos_lock );
151
152   return;
153 }
154