]> git.sesse.net Git - vlc/blob - src/video_parser/vpar_synchro.c
. correction d'un bug dans l'interface framebuffer
[vlc] / src / video_parser / vpar_synchro.c
1 /*****************************************************************************
2  * vpar_motion.c : motion vectors parsing
3  * (c)1999 VideoLAN
4  *****************************************************************************/
5
6 /*****************************************************************************
7  * Preamble
8  *****************************************************************************/
9 #include <errno.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <unistd.h>
13 #include <string.h>
14 #include <sys/uio.h>
15
16 #include "config.h"
17 #include "common.h"
18 #include "mtime.h"
19 #include "vlc_thread.h"
20
21 #include "intf_msg.h"
22 #include "debug.h"                    /* ?? temporaire, requis par netlist.h */
23
24 #include "input.h"
25 #include "input_netlist.h"
26 #include "decoder_fifo.h"
27 #include "video.h"
28 #include "video_output.h"
29
30 #include "vdec_idct.h"
31 #include "video_decoder.h"
32 #include "vdec_motion.h"
33
34 #include "vpar_blocks.h"
35 #include "vpar_headers.h"
36 #include "vpar_synchro.h"
37 #include "video_parser.h"
38 #include "video_fifo.h"
39
40 #define MAX_COUNT 3
41
42 /*
43  * Local prototypes
44  */
45
46 /*****************************************************************************
47  * vpar_SynchroUpdateTab : Update a mean table in the synchro structure
48  *****************************************************************************/
49 float vpar_SynchroUpdateTab( video_synchro_tab_t * tab, int count )
50 {
51         
52     tab->mean = ( tab->mean + MAX_COUNT * count ) / ( MAX_COUNT + 1 );
53     tab->deviation = ( tab->deviation + MAX_COUNT * abs (tab->mean - count) )
54                         / ( MAX_COUNT + 1 );
55
56     return tab->deviation;
57 }
58
59 /*****************************************************************************
60  * vpar_SynchroUpdateStructures : Update the synchro structures
61  *****************************************************************************/
62 void vpar_SynchroUpdateStructures( vpar_thread_t * p_vpar,
63                                    int i_coding_type )
64 {
65     float candidate_deviation;
66     float optimal_deviation;
67     float predict;
68     mtime_t i_current_pts;
69     decoder_fifo_t * decoder_fifo;
70
71     /* interpolate the current PTS */
72     decoder_fifo = p_vpar->bit_stream.p_decoder_fifo;
73     /* see if the current image has a pts - if not, interpolate */
74     if( i_current_pts = decoder_fifo->buffer[decoder_fifo->i_start]->i_pts )
75     {
76         p_vpar->synchro.i_images_since_pts = 1;
77     }
78     else
79     {
80         i_current_pts = p_vpar->synchro.i_last_pts
81                         + (1000000 / p_vpar->synchro.theorical_fps);
82         p_vpar->synchro.i_images_since_pts++;
83     }
84     p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_stop].i_pts = i_current_pts;
85     p_vpar->synchro.i_last_pts = i_current_pts;
86
87         
88     /* update structures */
89     switch(i_coding_type)
90     {
91         case P_CODING_TYPE:
92
93             p_vpar->synchro.current_p_count++;
94             break;
95
96         case B_CODING_TYPE:
97             p_vpar->synchro.current_b_count++;
98             break;
99
100         case I_CODING_TYPE:
101
102             /* update information about images we can decode */
103             if ( p_vpar->synchro.i_last_i_pts )
104             {
105                 p_vpar->synchro.theorical_fps = 1000000 * (1 + p_vpar->synchro.current_b_count + p_vpar->synchro.current_p_count) / (i_current_pts - p_vpar->synchro.i_last_i_pts);
106             }
107             p_vpar->synchro.i_last_i_pts = i_current_pts;
108
109
110             /* update all the structures for P images */
111
112             /* period == 1 */
113             optimal_deviation = vpar_SynchroUpdateTab(
114                             &p_vpar->synchro.tab_p[0],
115                             p_vpar->synchro.current_p_count);
116             predict = p_vpar->synchro.tab_p[0].mean;
117
118             /* period == 2 */
119             candidate_deviation = vpar_SynchroUpdateTab(
120                             &p_vpar->synchro.tab_p[1 + (p_vpar->synchro.modulo & 0x1)],
121                             p_vpar->synchro.current_p_count);
122             if (candidate_deviation < optimal_deviation)
123             {
124                 optimal_deviation = candidate_deviation;
125                 predict = p_vpar->synchro.tab_p[1 + (p_vpar->synchro.modulo & 0x1)].mean;
126             }
127
128             /* period == 3 */
129             candidate_deviation = vpar_SynchroUpdateTab(
130                             &p_vpar->synchro.tab_p[3 + (p_vpar->synchro.modulo % 3)],
131                             p_vpar->synchro.current_p_count);
132             if (candidate_deviation < optimal_deviation)
133             {
134                 optimal_deviation = candidate_deviation;
135                 predict = p_vpar->synchro.tab_p[1 + (p_vpar->synchro.modulo % 3)].mean;
136             }
137
138             p_vpar->synchro.p_count_predict = predict;
139             p_vpar->synchro.current_p_count = 0;
140
141
142             /* update all the structures for B images */
143
144             /* period == 1 */
145             optimal_deviation = vpar_SynchroUpdateTab(
146                             &p_vpar->synchro.tab_b[0],
147                             p_vpar->synchro.current_b_count);
148             predict = p_vpar->synchro.tab_b[0].mean;
149
150             /* period == 2 */
151             candidate_deviation = vpar_SynchroUpdateTab(
152                             &p_vpar->synchro.tab_b[1 + (p_vpar->synchro.modulo & 0x1)],
153                             p_vpar->synchro.current_b_count);
154             if (candidate_deviation < optimal_deviation)
155             {
156                 optimal_deviation = candidate_deviation;
157                 predict = p_vpar->synchro.tab_b[1 + (p_vpar->synchro.modulo & 0x1)].mean;
158             }
159
160             /* period == 3 */
161             candidate_deviation = vpar_SynchroUpdateTab(
162                             &p_vpar->synchro.tab_b[3 + (p_vpar->synchro.modulo % 3)],
163                             p_vpar->synchro.current_b_count);
164             if (candidate_deviation < optimal_deviation)
165             {
166                 optimal_deviation = candidate_deviation;
167                 predict = p_vpar->synchro.tab_b[1 + (p_vpar->synchro.modulo % 3)].mean;
168             }
169
170             p_vpar->synchro.b_count_predict = predict;
171             p_vpar->synchro.current_b_count = 0;
172             
173             break;
174     }
175
176     p_vpar->synchro.modulo++;
177
178 }
179
180 /*****************************************************************************
181  * vpar_SynchroChoose : Decide whether we will decode a picture or not
182  *****************************************************************************/
183 boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type,
184                               int i_structure )
185 {
186
187     if( p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_start].i_decode_date + ((p_vpar->synchro.i_fifo_stop - p_vpar->synchro.i_fifo_start) & 0xf) * p_vpar->synchro.i_mean_decode_time > mdate() )
188     {
189         //fprintf( stderr, "chooser : we are à la bourre !\n");
190         return( i_coding_type == I_CODING_TYPE );
191     }
192
193     return( i_coding_type == I_CODING_TYPE || (i_coding_type == P_CODING_TYPE));
194
195 }
196
197 /*****************************************************************************
198  * vpar_SynchroTrash : Update timers when we trash a picture
199  *****************************************************************************/
200 void vpar_SynchroTrash( vpar_thread_t * p_vpar, int i_coding_type,
201                         int i_structure )
202 {
203     vpar_SynchroUpdateStructures (p_vpar, i_coding_type);
204
205 }
206
207 /*****************************************************************************
208  * vpar_SynchroDecode : Update timers when we decide to decode a picture
209  *****************************************************************************/
210 void vpar_SynchroDecode( vpar_thread_t * p_vpar, int i_coding_type,
211                             int i_structure )
212 {
213     vpar_SynchroUpdateStructures (p_vpar, i_coding_type);
214
215     p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_stop].i_decode_date = mdate();
216     p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_stop].i_image_type
217         = i_coding_type;
218     p_vpar->synchro.i_fifo_stop = (p_vpar->synchro.i_fifo_stop + 1) & 0xf;
219
220 }
221
222 /*****************************************************************************
223  * vpar_SynchroEnd : Called when the image is totally decoded
224  *****************************************************************************/
225 void vpar_SynchroEnd( vpar_thread_t * p_vpar )
226 {
227     mtime_t i_decode_time;
228
229     i_decode_time = (mdate() -
230             p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_start].i_decode_date)
231         / (p_vpar->synchro.i_fifo_stop - p_vpar->synchro.i_fifo_start & 0x0f);
232
233     p_vpar->synchro.i_mean_decode_time =
234         ( 3 * p_vpar->synchro.i_mean_decode_time + i_decode_time ) / 4;
235
236     p_vpar->synchro.i_fifo_start = (p_vpar->synchro.i_fifo_start + 1) & 0xf;
237 }
238
239 /*****************************************************************************
240  * vpar_SynchroDate : When an image has been decoded, ask for its date
241  *****************************************************************************/
242 mtime_t vpar_SynchroDate( vpar_thread_t * p_vpar )
243 {
244     decoder_fifo_t * fifo;
245     mtime_t i_displaydate;
246     mtime_t i_delay;
247
248     i_displaydate =
249         p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_start].i_decode_date;
250     /* this value should be removed */
251     i_displaydate += 500000;
252     i_delay = i_displaydate - mdate();
253     
254     //fprintf(stderr, "displaying type %i with delay %lli)\n", p_vpar->synchro.fifo[p_vpar->synchro.i_fifo_start].i_image_type, i_delay);
255
256     return i_displaydate;
257 }
258