]> git.sesse.net Git - vlc/blob - src/video_parser/vpar_headers.c
suite du parseur.
[vlc] / src / video_parser / vpar_headers.c
1 /*****************************************************************************
2  * vpar_headers.c : headers parsing
3  * (c)1999 VideoLAN
4  *****************************************************************************/
5
6 /* ?? passer en terminate/destroy avec les signaux supplémentaires */
7
8 /*****************************************************************************
9  * Preamble
10  *****************************************************************************/
11 #include <errno.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <unistd.h>
15 #include <string.h>
16 #include <sys/uio.h>
17 #include <X11/Xlib.h>
18 #include <X11/extensions/XShm.h>
19
20 #include "config.h"
21 #include "common.h"
22 #include "mtime.h"
23 #include "vlc_thread.h"
24
25 #include "intf_msg.h"
26 #include "debug.h"                    /* ?? temporaire, requis par netlist.h */
27
28 #include "input.h"
29 #include "input_netlist.h"
30 #include "decoder_fifo.h"
31 #include "video.h"
32 #include "video_output.h"
33 #include "video_parser.h"
34
35 #include "undec_picture.h"
36 #include "video_fifo.h"
37 #include "video_decoder.h"
38
39 /*
40  * Local prototypes
41  */
42
43 /*****************************************************************************
44  * vpar_NextSequenceHeader : Find the next sequence header
45  *****************************************************************************/
46 void vpar_NextSequenceHeader( vpar_thread_t * p_vpar )
47 {
48     while( !p_vpar->b_die )
49     {
50         NextStartCode( p_vpar );
51         if( ShowBits( &p_vpar->bit_stream, 32 ) == SEQUENCE_START_CODE )
52             return;
53     }
54 }
55
56 /*****************************************************************************
57  * vpar_ParseHeader : Parse the next header
58  *****************************************************************************/
59 int vpar_ParseHeader( vpar_thread_t * p_vpar )
60 {
61     while( !p_vpar->b_die )
62     {
63         NextStartCode( p_vpar );
64         switch( GetBits32( &p_vpar->bit_stream ) )
65         {
66         case SEQUENCE_HEADER_CODE:
67             SequenceHeader( p_vpar );
68             return 0;
69             break;
70
71         case GROUP_START_CODE:
72             GroupHeader( p_vpar );
73             return 0;
74             break;
75
76         case PICTURE_START_CODE:
77             PictureHeader( p_vpar );
78             return 0;
79             break;
80
81         case SEQUENCE_END_CODE:
82             return 1;
83             break;
84
85         default:
86         }
87     }
88
89     return 0;
90 }
91
92 /*
93  * Following functions are local
94  */
95
96 /*****************************************************************************
97  * NextStartCode : Find the next start code
98  *****************************************************************************/
99 static __inline__ void NextStartCode( vpar_thread_t * p_vpar )
100 {
101     /* Re-align the buffer to an 8-bit boundary */
102     DumpBits( &p_vpar->bit_stream, p_vpar->bit_stream.fifo.i_available & 7 );
103
104     while( ShowBits( &p_vpar->bit_stream, 24 ) != 0x01L && !p_vpar->b_die )
105     {
106         DumpBits( &p_vpar->bit_stream, 8 );
107     }
108 }
109
110 /*****************************************************************************
111  * SequenceHeader : Parse the next sequence header
112  *****************************************************************************/
113 #define RESERVED    -1 
114 static double d_frame_rate_table[16] =
115 {
116   0.0,
117   ((23.0*1000.0)/1001.0),
118   24.0,
119   25.0,
120   ((30.0*1000.0)/1001.0),
121   30.0,
122   50.0,
123   ((60.0*1000.0)/1001.0),
124   60.0,
125  
126   RESERVED,
127   RESERVED,
128   RESERVED,
129   RESERVED,
130   RESERVED,
131   RESERVED,
132   RESERVED
133 };
134
135 static void SequenceHeader( vpar_thread_t * p_vpar )
136 {
137     int i_height_save, i_width_save;
138     
139     i_height_save = p_vpar->sequence.i_height;
140     i_width_save = p_vpar->sequence.i_width;
141
142     p_vpar->sequence.i_height = ntohl( GetBits( p_vpar->bit_stream, 12 ) );
143     p_vpar->sequence.i_width = ntohl( GetBits( p_vpar->bit_stream, 12 ) );
144     p_vpar->sequence.i_ratio = GetBits( p_vpar->bit_stream, 4 );
145     p_vpar->sequence.d_frame_rate =
146             d_frame_rate_table( GetBits( p_vpar->bit_stream, 4 ) );
147
148     /* We don't need bit_rate_value, marker_bit, vbv_buffer_size,
149      * constrained_parameters_flag */
150     DumpBits( p_vpar->bit_stream, 30 );
151     
152     /*
153      * Quantization matrices
154      */
155     if( GetBits( p_vpar->bit_stream, 1 ) ) /* load_intra_quantizer_matrix */
156     {
157         LoadMatrix( p_vpar, &p_vpar->sequence.intra_quant );
158     }
159     else
160     {
161         /* Use default matrix. */
162         LinkMatrix( &p_vpar->sequence.intra_quant, pi_default_intra_quant );
163     }
164     
165     if( GetBits( p_vpar->bit_stream, 1 ) ) /* load_non_intra_quantizer_matrix */
166     {
167         LoadMatrix( p_vpar, &p_vpar->sequence.nonintra_quant );
168     }
169     else
170     {
171         /* Use default matrix. */
172         LinkMatrix( &p_vpar->sequence.nonintra_quant, pi_default_nonintra_quant );
173     }
174     
175     /* Unless later overwritten by a matrix extension, we have the same
176      * matrices for luminance and chrominance. */
177     LinkMatrix( &p_vpar->sequence.chroma_intra_quant,
178                 p_vpar->sequence.intra_quant.pi_matrix );
179     LinkMatrix( &p_vpar->sequence.chroma_nonintra_quant,
180                 p_vpar->sequence.nonintra_quant.pi_matrix );
181
182     /*
183      * Sequence Extension
184      */
185     if( ShowBits( p_vpar->bit_stream, 32 ) == EXTENSION_START_CODE )
186     {
187         int             i_dummy;
188     
189         /* Parse sequence_extension */
190         DumpBits32( &p_vpar->bit_stream );
191         /* extension_start_code_identifier, profile_and_level_indication */
192         DumpBits( &p_vpar->bit_stream, 12 );
193         p_vpar->sequence.b_progressive = GetBits( &p_vpar->bit_stream, 1 );
194         p_vpar->sequence.i_chroma_format = GetBits( &p_vpar->bit_stream, 2 );
195         p_vpar->sequence.i_width |= GetBits( &p_vpar->bit_stream, 2 ) << 12;
196         p_vpar->sequence.i_height |= GetBits( &p_vpar->bit_stream, 2 ) << 12;
197         /* bit_rate_extension, marker_bit, vbv_buffer_size_extension, low_delay */
198         DumpBits( &p_vpar->bit_stream, 22 );
199         /* frame_rate_extension_n */
200         i_dummy = GetBits( &p_vpar->bit_stream, 2 );
201         /* frame_rate_extension_d */
202         p_vpar->sequence.d_frame_rate *= (i_dummy + 1)
203                                   / (GetBits( &p_vpar->bit_stream, 5 ) + 1);
204
205         /* Extension and User data */
206         ExtensionAndUserData( p_vpar );
207     }
208     else
209     {
210         /* It's an MPEG-1 stream. Put adequate parameters. */
211         p_vpar->sequence.b_progressive = 1;
212         p_vpar->i_chroma_format = CHROMA_420;
213     }
214
215     p_vpar->sequence.i_mb_width = (p_vpar->sequence.i_width + 15) / 16;
216     p_vpar->sequence.i_mb_height = (p_vpar->sequence.b_progressive) ?
217                                    (p_vpar->sequence.i_height + 15) / 16 :
218                                    2 * (p_vpar->sequence.i_height + 31) / 32;
219     p_vpar->sequence.i_width = (p_vpar->sequence.i_mb_width * 16);
220     p_vpar->sequence.i_height = (p_vpar->sequence.i_mb_height * 16);
221
222     if(    p_vpar->sequence.i_width != i_width_save
223         || p_vpar->sequence.i_height != i_height_save
224         || p_vpar->sequence.p_frame_lum_lookup == NULL )
225     {
226         int                 i_x, i_y;
227         pel_lookup_table *  p_fr, p_fl;
228         int                 i_fr, i_fl;
229         static int          pi_chroma_size[4] = {0, 2, 1, 0}
230 #define Sequence p_vpar->sequence
231
232         /* The size of the pictures has changed. Probably a new sequence.
233          * We must recalculate the lookup matrices. */
234
235         /* First unlink the previous lookup matrices so that they can
236          * be freed in the future. */
237         if( Sequence.p_frame_lum_lookup != NULL )
238         {
239             UNLINK_LOOKUP( Sequence.p_frame_lum_lookup );
240             UNLINK_LOOKUP( Sequence.p_field_lum_lookup );
241             UNLINK_LOOKUP( Sequence.p_frame_chroma_lookup );
242             UNLINK_LOOKUP( Sequence.p_field_chroma_lookup );
243         }
244
245         /* Allocate the new lookup tables. */
246         Sequence.p_frame_lum_lookup
247             = (pel_lookup_table_t *)malloc( sizeof( pel_lookup_table_t ) *
248                         Sequence.i_width * Sequence.i_height );
249         Sequence.p_field_lum_lookup
250             = (pel_lookup_table_t *)malloc( sizeof( pel_lookup_table_t ) *
251                         Sequence.i_width * Sequence.i_height );
252         Sequence.p_frame_chroma_lookup
253             = (pel_lookup_table_t *)malloc( sizeof( pel_lookup_table_t ) *
254                         Sequence.i_width * Sequence.i_height
255                          >> pi_chroma_size[Sequence.i_chroma_format] );
256         Sequence.p_field_chroma_lookup
257             = (pel_lookup_table_t *)malloc( sizeof( pel_lookup_table_t ) *
258                         Sequence.i_width * Sequence.i_height
259                          >> pi_chroma_size[Sequence.i_chroma_format] );
260
261         if( !Sequence.p_frame_lum_lookup || !Sequence.p_field_lum_lookup
262             || !Sequence.p_frame_chroma_lookup
263             || !Sequence.p_field_chroma_lookup )
264         {
265             intf_DbgMsg("vpar error: not enough memory for lookup tables");
266             p_vpar->b_error = 1;
267             return;
268         }
269
270         /* Fill in the luminance lookup tables */
271         p_fr = &Sequence.p_frame_lum_lookup->pi_pel;
272         p_fl = &Sequence.p_field_lum_lookup->pi_pel;
273         i_fr = i_fl = 0;
274
275         for( i_y = 0; i_y < Sequence.i_height; i_y++ )
276         {
277             int i_mb_y, i_b_y, i_pos_y;
278             i_mb_y = i_y >> 4;
279             i_b_y = (i_y & 15) >> 3;
280             i_pos_y = (i_y & 7);
281
282             for( i_x = 0; i_x < Sequence.i_width; i_x++ )
283             {
284                 int i_mb_x, i_b_x, i_pos_x;
285                 i_mb_x = i_x >> 4;
286                 i_b_x = (i_x & 15) >> 3;
287                 i_pos_x = (i_x & 7);
288
289                 p_fl[i_fr + i_x] = p_fr[i_fr + i_x]
290                                  = (i_mb_y*Sequence.i_mb_width + i_mb_y)*256
291                                         + ((i_b_y << 1) + i_b_x)*64
292                                         + i_pos_y*8 + i_pos_x;
293             }
294             i_fr += Sequence.i_width;
295             i_fl += Sequence.i_width << 1;
296             if( i_fl == Sequence.i_width*Sequence.i_height )
297             {
298                 i_fl = Sequence.i_width;
299             }
300         }
301         
302         /* Fill in the chrominance lookup tables */
303         p_fr = &Sequence.p_frame_chroma_lookup->pi_pel;
304         p_fl = &Sequence.p_field_chroma_lookup->pi_pel;
305         i_fr = i_fl = 0;
306
307         switch( p_vpar->i_chroma_format )
308         {
309         case CHROMA_444:
310             /* That's the same as luminance */
311             memcopy( &Sequence.p_frame_croma_lookup->pi_pel,
312                      &Sequence.p_frame_lum_lookup->pi_pel,
313                      sizeof(PEL_P)*Sequence.i_height*Sequence.i_width );
314             memcopy( &Sequence.p_field_croma_lookup->pi_pel,
315                      &Sequence.p_field_lum_lookup->pi_pel,
316                      sizeof(PEL_P)*Sequence.i_height*Sequence.i_width );
317
318         case CHROMA_422:
319             for( i_y = 0; i_y < Sequence.i_height; i_y++ )
320             {
321                 int i_mb_y, i_b_y, i_pos_y;
322                 i_mb_y = i_y >> 4;
323                 i_b_y = (i_y & 15) >> 3;
324                 i_pos_y = (i_y & 7);
325     
326                 for( i_x = 0; i_x < (Sequence.i_width >> 1); i_x++ )
327                 {
328                     int i_mb_x, i_pos_x;
329                     i_mb_x = i_x >> 3;
330                     i_pos_x = (i_x & 7);
331     
332                     p_fl[i_fr + i_x] = p_fr[i_fr + i_x]
333                                      = (i_mb_y*Sequence.i_mb_width + i_mb_y)*128
334                                             + i_b_y*64
335                                             + i_pos_y*8 + i_pos_x;
336                 }
337                 i_fr += Sequence.i_width >> 1;
338                 i_fl += Sequence.i_width;
339                 if( i_fl == (Sequence.i_width*Sequence.i_height >> 1) )
340                 {
341                     i_fl = (Sequence.i_width >> 1);
342                 }
343             }
344
345         case CHROMA_420:
346             for( i_y = 0; i_y < (Sequence.i_height >> 1); i_y++ )
347             {
348                 int i_mb_y, i_pos_y;
349                 i_mb_y = i_y >> 3;
350                 i_pos_y = (i_y & 7);
351     
352                 for( i_x = 0; i_x < (Sequence.i_width >> 1); i_x++ )
353                 {
354                     int i_mb_x, i_pos_x;
355                     i_mb_x = i_x >> 3;
356                     i_pos_x = (i_x & 7);
357     
358                     p_fl[i_fr + i_x] = p_fr[i_fr + i_x]
359                                      = (i_mb_y*Sequence.i_mb_width + i_mb_y)*64
360                                             + i_pos_y*8 + i_pos_x;
361                 }
362                 i_fr += Sequence.i_width >> 1;
363                 i_fl += Sequence.i_width;
364                 if( i_fl == (Sequence.i_width*Sequence.i_height >> 2) )
365                 {
366                     i_fl = Sequence.i_width >> 1;
367                 }
368             }
369         } /* switch */
370         
371         /* Link the new lookup tables so that they don't get freed all
372          * the time. */
373         LINK_LOOKUP( Sequence.p_frame_lum_lookup );
374         LINK_LOOKUP( Sequence.p_field_lum_lookup );
375         LINK_LOOKUP( Sequence.p_frame_chroma_lookup );
376         LINK_LOOKUP( Sequence.p_field_chroma_lookup );
377 #undef Sequence
378     }
379 }
380
381 /*****************************************************************************
382  * GroupHeader : Parse the next group of pictures header
383  *****************************************************************************/
384 static void GroupHeader( vpar_thread_t * p_vpar )
385 {
386     /* Nothing to do, we don't care. */
387     DumpBits( &p_vpar->bit_stream, 27 );
388     ExtensionAndUserData( p_vpar );
389 }
390
391 /*****************************************************************************
392  * PictureHeader : Parse the next picture header
393  *****************************************************************************/
394 static void PictureHeader( vpar_thread_t * p_vpar )
395 {
396     int                 i_coding_type;
397     mtime_t             i_pts;
398     undec_picture_t *   p_undec_p;
399     
400     DumpBits( &p_vpar->bit_stream, 10 ); /* temporal_reference */
401     i_coding_type = GetBits( &p_vpar->bit_stream, 3 );
402     
403     if( ((i_coding_type == P_CODING_TYPE) &&
404          (p_vpar->sequence.p_forward == NULL)) ||
405         ((i_coding_type == B_CODING_TYPE) &&
406          (p_vpar->sequence.p_forward == NULL ||
407           p_vpar->sequence.p_backward == NULL)) )
408     {
409         /* The picture cannot be decoded because we lack one of the
410          * reference frames */
411         
412         /* Update the reference pointers */
413         ReferenceUpdate( p_vpar, i_coding_type, NULL );
414         
415         /* Warn Synchro we have trashed a picture */
416         vpar_SynchroTrash( p_vpar, i_coding_type );
417
418         return;
419     }
420
421     if( !(i_pts = vpar_SynchroChoose( p_vpar, i_coding_type )) )
422     {
423         /* Synchro has decided not to decode the picture */
424         
425         /* Update the reference pointers */
426         ReferenceUpdate( p_vpar, i_coding_type, NULL );
427         
428         return;
429     }
430
431     /* OK, now we are sure we will decode the picture. Get a structure. */
432     p_undec_p = vpar_NewPicture( &p_vpar->vfifo );
433     
434     /* Request a buffer from the video_output. */
435     p_undec_p->p_picture = vout_CreatePicture( p_vpar->p_vout,
436                                                SPLITTED_YUV_PICTURE,
437                                                p_vpar->sequence.i_width,
438                                                p_vpar->sequence.i_height,
439                                                p_vpar->sequence.i_chroma_format );
440
441     /* Initialize values */
442     p_undec_p->i_coding_type = i_conding_type;
443     p_undec_p->b_mpeg2 = p_vpar->sequence.b_mpeg2;
444     p_undec_p->i_mb_height = p_vpar->sequence.i_mb_height;
445     p_undec_p->i_mb_width = p_vpar->sequence.i_mb_width;
446     p_undec_p->i_pts = i_pts;
447 }
448
449 /*****************************************************************************
450  * ReferenceUpdate : Update the reference pointers when we have a new picture
451  *****************************************************************************/
452 static void __inline__ ReferenceUpdate( vpar_thread_t * p_vpar,
453                                         int i_coding_type,
454                                         picture_t * p_newref )
455 {
456     if( i_coding_type != B_CODING_TYPE )
457     {
458         /* The P picture would have become the new p_backward reference. */
459         vout_UnlinkPicture( p_vpar->p_vout, p_vpar->sequence.p_forward );
460         p_vpar->sequence.p_forward = p_vpar->sequence.p_backward;
461         p_vpar->sequence.p_backward = p_newref;
462     }
463 }
464
465 /*****************************************************************************
466  * ExtensionAndUserData : Parse the extension_and_user_data structure
467  *****************************************************************************/
468 static void ExtensionAndUserData( vpar_thread_t * p_vpar )
469 {
470     while( !p_vpar->b_die )
471     {
472         NextStartCode( p_vpar );
473         switch( ShowBits( &p_vpar->bit_stream, 32 ) )
474         {
475         case EXTENSION_START_CODE:
476             DumpBits32( &p_vpar->bit_stream );
477             switch( GetBits( &p_vpar->bit_stream, 4 ) )
478             {
479             case SEQUENCE_DISPLAY_EXTENSION_ID:
480                 SequenceDisplayExtension( p_vpar );
481                 break;
482             case QUANT_MATRIX_EXTENSION_ID:
483                 QuantMatrixExtension( p_vpar );
484                 break;
485             case SEQUENCE_SCALABLE_EXTENSION_ID:
486                 SequenceScalableExtension( p_vpar );
487                 break;
488             case PICTURE_DISPLAY_EXTENSION_ID:
489                 PictureDisplayExtension( p_vpar );
490                 break;
491             case PICTURE_SPATIAL_SCALABLE_EXTENSION_ID:
492                 PictureSpatialScalableExtension( p_vpar );
493                 break;
494             case PICTURE_TEMPORAL_SCALABLE_EXTENSION_ID:
495                 PictureTemporalScalableExtension( p_vpar );
496                 break;
497             case COPYRIGHT_EXTENSION_ID:
498                 CopyrightExtension( p_vpar );
499                 break;
500             default:
501             }
502             break;
503
504         case USER_DATA_START_CODE:
505             DumpBits32( &p_vpar->bit_stream );
506             /* Wait for the next start code */
507             break;
508
509         default:
510             return;
511         }
512     }
513 }
514
515 /*****************************************************************************
516  * SequenceDisplayExtension : Parse the sequence_display_extension structure
517  *****************************************************************************/
518 static void SequenceDisplayExtension( vpar_thread_t * p_vpar )
519 {
520
521 }
522
523 /*****************************************************************************
524  * LoadMatrix : Load a quantization matrix
525  *****************************************************************************/
526 static void LoadMatrix( vpar_thread_t * p_vpar, quant_matrix_t * p_matrix )
527 {
528     int i_dummy;
529     
530     if( !p_matrix->b_allocated )
531     {
532         /* Allocate a piece of memory to load the matrix. */
533         p_matrix->pi_matrix = (int *)malloc( 64*sizeof(int) );
534         p_matrix->b_allocated = TRUE;
535     }
536     
537     for( i_dummy = 0; i_dummy < 64; i_dummy++ )
538     {
539         p_matrix->pi_matrix[pi_scan[SCAN_ZIGZAG][i_dummy]]
540              = GetBits( p_vpar->bit_stream, 8 );
541     }
542
543 #ifdef FOURIER_IDCT
544     /* Discrete Fourier Transform requires the quantization matrices to
545      * be normalized before using them. */
546     vdec_NormQuantMatrix( p_matrix->pi_matrix );
547 #endif
548 }
549
550 /*****************************************************************************
551  * LinkMatrix : Link a quantization matrix to another
552  *****************************************************************************/
553 static void LinkMatrix( quant_matrix_t * p_matrix, int * pi_array )
554 {
555     int i_dummy;
556     
557     if( p_matrix->b_allocated )
558     {
559         /* Deallocate the piece of memory. */
560         free( p_matrix->pi_matrix );
561         p_matrix->b_allocated = FALSE;
562     }
563     
564     p_matrix->pi_matrix = pi_array;
565 }
566