1 /*****************************************************************************
2 * vpar_headers.c : headers parsing
4 *****************************************************************************/
6 /* ?? passer en terminate/destroy avec les signaux supplémentaires */
8 /*****************************************************************************
10 *****************************************************************************/
18 #include <X11/extensions/XShm.h>
23 #include "vlc_thread.h"
26 #include "debug.h" /* ?? temporaire, requis par netlist.h */
29 #include "input_netlist.h"
30 #include "decoder_fifo.h"
32 #include "video_output.h"
33 #include "video_parser.h"
35 #include "undec_picture.h"
36 #include "video_fifo.h"
37 #include "video_decoder.h"
43 /*****************************************************************************
44 * vpar_NextSequenceHeader : Find the next sequence header
45 *****************************************************************************/
46 void vpar_NextSequenceHeader( vpar_thread_t * p_vpar )
48 while( !p_vpar->b_die )
50 NextStartCode( p_vpar );
51 if( ShowBits( &p_vpar->bit_stream, 32 ) == SEQUENCE_START_CODE )
56 /*****************************************************************************
57 * vpar_ParseHeader : Parse the next header
58 *****************************************************************************/
59 int vpar_ParseHeader( vpar_thread_t * p_vpar )
61 while( !p_vpar->b_die )
63 NextStartCode( p_vpar );
64 switch( GetBits32( &p_vpar->bit_stream ) )
66 case SEQUENCE_HEADER_CODE:
67 SequenceHeader( p_vpar );
71 case GROUP_START_CODE:
72 GroupHeader( p_vpar );
76 case PICTURE_START_CODE:
77 PictureHeader( p_vpar );
81 case SEQUENCE_END_CODE:
93 * Following functions are local
96 /*****************************************************************************
97 * NextStartCode : Find the next start code
98 *****************************************************************************/
99 static __inline__ void NextStartCode( vpar_thread_t * p_vpar )
101 /* Re-align the buffer to an 8-bit boundary */
102 DumpBits( &p_vpar->bit_stream, p_vpar->bit_stream.fifo.i_available & 7 );
104 while( ShowBits( &p_vpar->bit_stream, 24 ) != 0x01L && !p_vpar->b_die )
106 DumpBits( &p_vpar->bit_stream, 8 );
110 /*****************************************************************************
111 * SequenceHeader : Parse the next sequence header
112 *****************************************************************************/
114 static double d_frame_rate_table[16] =
117 ((23.0*1000.0)/1001.0),
120 ((30.0*1000.0)/1001.0),
123 ((60.0*1000.0)/1001.0),
135 static void SequenceHeader( vpar_thread_t * p_vpar )
137 int i_height_save, i_width_save;
139 i_height_save = p_vpar->sequence.i_height;
140 i_width_save = p_vpar->sequence.i_width;
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 ) );
148 /* We don't need bit_rate_value, marker_bit, vbv_buffer_size,
149 * constrained_parameters_flag */
150 DumpBits( p_vpar->bit_stream, 30 );
153 * Quantization matrices
155 if( GetBits( p_vpar->bit_stream, 1 ) ) /* load_intra_quantizer_matrix */
157 LoadMatrix( p_vpar, &p_vpar->sequence.intra_quant );
161 /* Use default matrix. */
162 LinkMatrix( &p_vpar->sequence.intra_quant, pi_default_intra_quant );
165 if( GetBits( p_vpar->bit_stream, 1 ) ) /* load_non_intra_quantizer_matrix */
167 LoadMatrix( p_vpar, &p_vpar->sequence.nonintra_quant );
171 /* Use default matrix. */
172 LinkMatrix( &p_vpar->sequence.nonintra_quant, pi_default_nonintra_quant );
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 );
185 if( ShowBits( p_vpar->bit_stream, 32 ) == EXTENSION_START_CODE )
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);
205 /* Extension and User data */
206 ExtensionAndUserData( p_vpar );
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;
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);
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 )
227 pel_lookup_table * p_fr, p_fl;
229 static int pi_chroma_size[4] = {0, 2, 1, 0}
230 #define Sequence p_vpar->sequence
232 /* The size of the pictures has changed. Probably a new sequence.
233 * We must recalculate the lookup matrices. */
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 )
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 );
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] );
261 if( !Sequence.p_frame_lum_lookup || !Sequence.p_field_lum_lookup
262 || !Sequence.p_frame_chroma_lookup
263 || !Sequence.p_field_chroma_lookup )
265 intf_DbgMsg("vpar error: not enough memory for lookup tables");
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;
275 for( i_y = 0; i_y < Sequence.i_height; i_y++ )
277 int i_mb_y, i_b_y, i_pos_y;
279 i_b_y = (i_y & 15) >> 3;
282 for( i_x = 0; i_x < Sequence.i_width; i_x++ )
284 int i_mb_x, i_b_x, i_pos_x;
286 i_b_x = (i_x & 15) >> 3;
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;
294 i_fr += Sequence.i_width;
295 i_fl += Sequence.i_width << 1;
296 if( i_fl == Sequence.i_width*Sequence.i_height )
298 i_fl = Sequence.i_width;
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;
307 switch( p_vpar->i_chroma_format )
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 );
319 for( i_y = 0; i_y < Sequence.i_height; i_y++ )
321 int i_mb_y, i_b_y, i_pos_y;
323 i_b_y = (i_y & 15) >> 3;
326 for( i_x = 0; i_x < (Sequence.i_width >> 1); i_x++ )
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
335 + i_pos_y*8 + i_pos_x;
337 i_fr += Sequence.i_width >> 1;
338 i_fl += Sequence.i_width;
339 if( i_fl == (Sequence.i_width*Sequence.i_height >> 1) )
341 i_fl = (Sequence.i_width >> 1);
346 for( i_y = 0; i_y < (Sequence.i_height >> 1); i_y++ )
352 for( i_x = 0; i_x < (Sequence.i_width >> 1); i_x++ )
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;
362 i_fr += Sequence.i_width >> 1;
363 i_fl += Sequence.i_width;
364 if( i_fl == (Sequence.i_width*Sequence.i_height >> 2) )
366 i_fl = Sequence.i_width >> 1;
371 /* Link the new lookup tables so that they don't get freed all
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 );
381 /*****************************************************************************
382 * GroupHeader : Parse the next group of pictures header
383 *****************************************************************************/
384 static void GroupHeader( vpar_thread_t * p_vpar )
386 /* Nothing to do, we don't care */
387 DumpBits( &p_vpar->bit_stream, 27 );
388 ExtensionAndUserData( p_vpar );
391 /*****************************************************************************
392 * PictureHeader : Parse the next picture header
393 *****************************************************************************/
394 static void PictureHeader( vpar_thread_t * p_vpar )
398 undec_picture_t * p_undec_p;
400 DumpBits( &p_vpar->bit_stream, 10 ); /* temporal_reference */
401 i_coding_type = GetBits( &p_vpar->bit_stream, 3 );
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)) )
409 /* The picture cannot be decoded because we lack one of the
410 * reference frames */
412 /* Update the reference pointers */
413 ReferenceUpdate( p_vpar, i_coding_type, NULL );
415 /* Warn Synchro we have trashed a picture */
416 vpar_SynchroTrash( p_vpar, i_coding_type );
421 if( !(i_pts = vpar_SynchroChoose( p_vpar, i_coding_type )) )
423 /* Synchro has decided not to decode the picture */
425 /* Update the reference pointers */
426 ReferenceUpdate( p_vpar, i_coding_type, NULL );
431 /* OK, now we are sure we will decode the picture. Get a structure. */
432 p_undec_p = vpar_NewPicture( &p_vpar->vfifo );
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 );
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;
449 /*****************************************************************************
450 * ReferenceUpdate : Update the reference pointers when we have a new picture
451 *****************************************************************************/
452 static void __inline__ ReferenceUpdate( vpar_thread_t * p_vpar,
454 picture_t * p_newref )
456 if( i_coding_type != B_CODING_TYPE )
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;
465 /*****************************************************************************
466 * ExtensionAndUserData : Parse the extension_and_user_data structure
467 *****************************************************************************/
468 static void ExtensionAndUserData( vpar_thread_t * p_vpar )
470 /* Nothing to do, we don't care. */
471 DumpBits( &p_vpar->bit_stream, 27 );
472 ExtensionAndUserData( p_vpar );
475 /*****************************************************************************
476 * LoadMatrix : Load a quantization matrix
477 *****************************************************************************/
478 static void LoadMatrix( vpar_thread_t * p_vpar, quant_matrix_t * p_matrix )
482 if( !p_matrix->b_allocated )
484 /* Allocate a piece of memory to load the matrix. */
485 p_matrix->pi_matrix = (int *)malloc( 64*sizeof(int) );
486 p_matrix->b_allocated = TRUE;
489 for( i_dummy = 0; i_dummy < 64; i_dummy++ )
491 p_matrix->pi_matrix[pi_scan[SCAN_ZIGZAG][i_dummy]]
492 = GetBits( p_vpar->bit_stream, 8 );
496 /* Discrete Fourier Transform requires the quantization matrices to
497 * be normalized before using them. */
498 vdec_NormQuantMatrix( p_matrix->pi_matrix );
502 /*****************************************************************************
503 * LinkMatrix : Link a quantization matrix to another
504 *****************************************************************************/
505 static void LinkMatrix( quant_matrix_t * p_matrix, int * pi_array )
509 if( p_matrix->b_allocated )
511 /* Deallocate the piece of memory. */
512 free( p_matrix->pi_matrix );
513 p_matrix->b_allocated = FALSE;
516 p_matrix->pi_matrix = pi_array;