]> git.sesse.net Git - vlc/blob - src/spu_decoder/spu_decoder.c
* audio_output/audio_output.c :
[vlc] / src / spu_decoder / spu_decoder.c
1 /*******************************************************************************
2  * spu_decoder.c : spu decoder thread
3  * (c)2000 VideoLAN
4  *******************************************************************************/
5
6 /* repompĂ© sur video_decoder.c
7  * ?? passer en terminate/destroy avec les signaux supplĂ©mentaires */
8
9 /*******************************************************************************
10  * Preamble
11  *******************************************************************************/
12 //#include "vlc.h"
13
14 #include <errno.h>
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <unistd.h>
18 #include <string.h>
19 #include <sys/uio.h>
20
21 #include "config.h"
22 #include "common.h"
23 #include "mtime.h"
24 #include "vlc_thread.h"
25
26 #include "intf_msg.h"
27 #include "debug.h"                    /* ?? temporaire, requis par netlist.h */
28
29 #include "input.h"
30 #include "input_netlist.h"
31 #include "decoder_fifo.h"
32
33 #include "spu_decoder.h"
34
35 /*
36  * Local prototypes
37  */
38 static int      InitThread          ( spudec_thread_t *p_spudec );
39 static void     RunThread           ( spudec_thread_t *p_spudec );
40 static void     ErrorThread         ( spudec_thread_t *p_spudec );
41 static void     EndThread           ( spudec_thread_t *p_spudec );
42
43 /******************************************************************************
44  * spudec_CreateThread: create a spu decoder thread
45  ******************************************************************************/
46 spudec_thread_t * spudec_CreateThread( input_thread_t * p_input )
47 {
48     spudec_thread_t *     p_spudec;
49
50     intf_DbgMsg("spudec debug: creating spu decoder thread\n");
51
52     /* Allocate the memory needed to store the thread's structure */
53     if ( (p_spudec = (spudec_thread_t *)malloc( sizeof(spudec_thread_t) )) == NULL )
54     {
55         intf_ErrMsg("spudec error: not enough memory for spudec_CreateThread() to create the new thread\n");
56         return( NULL );
57     }
58
59     /*
60      * Initialize the thread properties
61      */
62     p_spudec->b_die = 0;
63     p_spudec->b_error = 0;
64
65     /*
66      * Initialize the input properties
67      */
68     /* Initialize the decoder fifo's data lock and conditional variable and set
69      * its buffer as empty */
70     vlc_mutex_init( &p_spudec->fifo.data_lock );
71     vlc_cond_init( &p_spudec->fifo.data_wait );
72     p_spudec->fifo.i_start = 0;
73     p_spudec->fifo.i_end = 0;
74
75     /* Spawn the spu decoder thread */
76     if ( vlc_thread_create(&p_spudec->thread_id, "spu decoder",
77          (vlc_thread_func_t)RunThread, (void *)p_spudec) )
78     {
79         intf_ErrMsg("spudec error: can't spawn spu decoder thread\n");
80         free( p_spudec );
81         return( NULL );
82     }
83
84     intf_DbgMsg("spudec debug: spu decoder thread (%p) created\n", p_spudec);
85     return( p_spudec );
86 }
87
88 /*******************************************************************************
89  * spudec_DestroyThread: destroy a spu decoder thread
90  *******************************************************************************
91  * Destroy and terminate thread. This function will return 0 if the thread could
92  * be destroyed, and non 0 else. The last case probably means that the thread
93  * was still active, and another try may succeed.
94  *******************************************************************************/
95 void spudec_DestroyThread( spudec_thread_t *p_spudec )
96 {
97     intf_DbgMsg("spudec debug: requesting termination of spu decoder thread %p\n", p_spudec);
98 //    fprintf(stderr, "spudec debug: requesting termination of spu decoder thread %p\n", p_spudec);
99
100     /* Ask thread to kill itself */
101     p_spudec->b_die = 1;
102
103     /* Warn the decoder that we're quitting */
104     vlc_cond_signal( &p_spudec->fifo.data_wait );
105
106     /* Waiting for the decoder thread to exit */
107     /* Remove this as soon as the "status" flag is implemented */
108     vlc_thread_join( p_spudec->thread_id );
109 }
110
111 /* following functions are local */
112
113 /*******************************************************************************
114  * InitThread: initialize spu decoder thread
115  *******************************************************************************
116  * This function is called from RunThread and performs the second step of the
117  * initialization. It returns 0 on success. Note that the thread's flag are not
118  * modified inside this function.
119  *******************************************************************************/
120 static int InitThread( spudec_thread_t *p_spudec )
121 {
122     intf_DbgMsg("spudec debug: initializing spu decoder thread %p\n", p_spudec);
123
124     /* Our first job is to initialize the bit stream structure with the
125      * beginning of the input stream */
126     vlc_mutex_lock( &p_spudec->fifo.data_lock );
127     while ( DECODER_FIFO_ISEMPTY(p_spudec->fifo) && !p_spudec->b_die )
128     {
129         vlc_cond_wait( &p_spudec->fifo.data_wait, &p_spudec->fifo.data_lock );
130     }
131
132     if( p_spudec->b_die )
133     {
134         vlc_mutex_unlock( &p_spudec->fifo.data_lock );
135         return( 0 );
136     }
137     
138     p_spudec->bit_stream.p_ts = DECODER_FIFO_START( p_spudec->fifo )->p_first_ts;
139     p_spudec->bit_stream.i_byte = p_spudec->bit_stream.p_ts->i_payload_start;
140     vlc_mutex_unlock( &p_spudec->fifo.data_lock );
141                         
142     /* Mark thread as running and return */
143     intf_DbgMsg("spudec debug: InitThread(%p) succeeded\n", p_spudec);    
144     return( 0 );    
145 }
146
147 /*******************************************************************************
148  * RunThread: spu decoder thread
149  *******************************************************************************
150  * spu decoder thread. This function does only return when the thread is
151  * terminated. 
152  *******************************************************************************/
153 static void RunThread( spudec_thread_t *p_spudec )
154 {
155     intf_DbgMsg("spudec debug: running spu decoder thread (%p) (pid == %i)\n",
156                 p_spudec, getpid());
157
158     /* 
159      * Initialize thread and free configuration 
160      */
161     p_spudec->b_error = InitThread( p_spudec );
162     if( p_spudec->b_error )
163     {
164         return;
165     }
166     p_spudec->b_run = 1;
167
168     /*
169      * Main loop - it is not executed if an error occured during
170      * initialization
171      */
172     while( (!p_spudec->b_die) && (!p_spudec->b_error) )
173     {
174
175
176 //        fprintf(stderr, "I'm in the spu decoder main loop !\n");
177         sleep(1);
178     } 
179
180     /*
181      * Error loop
182      */
183     if( p_spudec->b_error )
184     {
185         ErrorThread( p_spudec );        
186     }
187
188     /* End of thread */
189     EndThread( p_spudec );
190     p_spudec->b_run = 0;
191 }
192
193 /*******************************************************************************
194  * ErrorThread: RunThread() error loop
195  *******************************************************************************
196  * This function is called when an error occured during thread main's loop. The
197  * thread can still receive feed, but must be ready to terminate as soon as
198  * possible.
199  *******************************************************************************/
200 static void ErrorThread( spudec_thread_t *p_spudec )
201 {
202     /* Wait until a `die' order */
203     while( !p_spudec->b_die )
204     {
205         // foo();
206     }
207 }
208
209 /*******************************************************************************
210  * EndThread: thread destruction
211  *******************************************************************************
212  * This function is called when the thread ends after a sucessfull 
213  * initialization.
214  *******************************************************************************/
215 static void EndThread( spudec_thread_t *p_spudec )
216 {
217     intf_DbgMsg("spudec debug: EndThread(%p)\n", p_spudec);
218 }
219