X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fvideo_parser%2Fvpar_headers.c;h=779cfa9eaaf48b13be02ffd6c5012345900585be;hb=a70f8bb371466209770c4c3bcdb7137b94acef66;hp=949f61eacf711d8e51af8fa65f13f88282c3d7f8;hpb=555bac08482b060ca32ec0f5b7e5c2e879a5dc0b;p=vlc diff --git a/src/video_parser/vpar_headers.c b/src/video_parser/vpar_headers.c index 949f61eacf..779cfa9eaa 100644 --- a/src/video_parser/vpar_headers.c +++ b/src/video_parser/vpar_headers.c @@ -2,7 +2,7 @@ * vpar_headers.c : headers parsing ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: vpar_headers.c,v 1.64 2000/12/29 10:52:40 massiot Exp $ + * $Id: vpar_headers.c,v 1.83 2001/05/01 04:18:18 sam Exp $ * * Authors: Christophe Massiot * Stéphane Borel @@ -28,14 +28,12 @@ #include "defs.h" #include /* free() */ -#include /* on BSD, uio.h needs types.h */ -#include /* "input.h" */ +#include /* memcpy(), memset() */ #include "config.h" #include "common.h" #include "threads.h" #include "mtime.h" -#include "plugins.h" #include "intf_msg.h" @@ -45,16 +43,18 @@ #include "video.h" #include "video_output.h" +#include "video_decoder.h" +#include "vdec_motion.h" #include "../video_decoder/vdec_idct.h" -#include "../video_decoder/video_decoder.h" -#include "../video_decoder/vdec_motion.h" -#include "../video_decoder/vpar_blocks.h" +#include "vpar_blocks.h" #include "../video_decoder/vpar_headers.h" #include "../video_decoder/vpar_synchro.h" #include "../video_decoder/video_parser.h" #include "../video_decoder/video_fifo.h" +#include "main.h" /* XXX REMOVE THIS */ + /* * Local prototypes */ @@ -78,8 +78,7 @@ static void CopyrightExtension( vpar_thread_t * p_vpar ); /***************************************************************************** * pi_default_intra_quant : default quantization matrix *****************************************************************************/ -#ifndef VDEC_DFT -int pi_default_intra_quant[] = +u8 pi_default_intra_quant[] = { 8, 16, 19, 22, 26, 27, 29, 34, 16, 16, 22, 24, 27, 29, 34, 37, @@ -90,25 +89,11 @@ int pi_default_intra_quant[] = 26, 27, 29, 34, 38, 46, 56, 69, 27, 29, 35, 38, 46, 56, 69, 83 }; -#else -int pi_default_intra_quant[] = -{ - 2048, 5681, 6355, 6623, 6656, 5431, 4018, 2401, - 5681, 7880, 10207, 10021, 9587, 8091, 6534, 3625, - 6355, 10207, 11363, 10619, 9700, 8935, 6155, 3507, - 6623, 9186, 10226, 9557, 8730, 8041, 6028, 3322, - 5632, 9232, 9031, 8730, 8192, 7040, 5542, 3390, - 5230, 7533, 7621, 7568, 7040, 6321, 5225, 3219, - 3602, 5189, 5250, 5539, 5265, 5007, 4199, 2638, - 1907, 2841, 3230, 3156, 3249, 3108, 2638, 1617 -}; -#endif /***************************************************************************** * pi_default_nonintra_quant : default quantization matrix *****************************************************************************/ -#ifndef VDEC_DFT -int pi_default_nonintra_quant[] = +u8 pi_default_nonintra_quant[] = { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, @@ -119,19 +104,6 @@ int pi_default_nonintra_quant[] = 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 }; -#else -int pi_default_nonintra_quanit[] = -{ - 4096, 5680, 5344, 4816, 4096, 3216, 2224, 1136, - 5680, 7888, 7424, 6688, 5680, 4464, 3072, 1568, - 5344, 7424, 6992, 6288, 5344, 4208, 2896, 1472, - 4816, 6688, 6288, 5664, 4816, 3792, 2608, 1328, - 4096, 5680, 5344, 4816, 4096, 3216, 2224, 1136, - 3216, 4464, 4208, 3792, 3216, 2528, 1744, 880, - 2224, 3072, 2896, 2608, 2224, 1744, 1200, 608, - 1136, 1568, 1472, 1328, 1136, 880, 608, 304 -}; -#endif /***************************************************************************** * pi_scan : zig-zag and alternate scan patterns @@ -213,14 +185,15 @@ static void __inline__ ReferenceReplace( vpar_thread_t * p_vpar, /***************************************************************************** * LoadMatrix : Load a quantization matrix *****************************************************************************/ -static __inline__ void LoadMatrix( vpar_thread_t * p_vpar, quant_matrix_t * p_matrix ) +static __inline__ void LoadMatrix( vpar_thread_t * p_vpar, + quant_matrix_t * p_matrix ) { int i_dummy; if( !p_matrix->b_allocated ) { /* Allocate a piece of memory to load the matrix. */ - if( (p_matrix->pi_matrix = (int *)malloc( 64*sizeof(int) )) == NULL ) + if( (p_matrix->pi_matrix = (u8 *)malloc( 64*sizeof(u8) )) == NULL ) { intf_ErrMsg( "vpar error: allocation error in LoadMatrix()" ); p_vpar->p_fifo->b_error = 1; @@ -231,7 +204,7 @@ static __inline__ void LoadMatrix( vpar_thread_t * p_vpar, quant_matrix_t * p_ma for( i_dummy = 0; i_dummy < 64; i_dummy++ ) { - p_matrix->pi_matrix[pi_scan[SCAN_ZIGZAG][i_dummy]] + p_matrix->pi_matrix[p_vpar->ppi_scan[SCAN_ZIGZAG][i_dummy]] = GetBits( &p_vpar->bit_stream, 8 ); } @@ -245,7 +218,7 @@ static __inline__ void LoadMatrix( vpar_thread_t * p_vpar, quant_matrix_t * p_ma /***************************************************************************** * LinkMatrix : Link a quantization matrix to another *****************************************************************************/ -static __inline__ void LinkMatrix( quant_matrix_t * p_matrix, int * pi_array ) +static __inline__ void LinkMatrix( quant_matrix_t * p_matrix, u8 * pi_array ) { if( p_matrix->b_allocated ) { @@ -312,6 +285,7 @@ int vpar_ParseHeader( vpar_thread_t * p_vpar ) break; default: + break; } } @@ -368,17 +342,19 @@ static void SequenceHeader( vpar_thread_t * p_vpar ) else { /* Use default matrix. */ - LinkMatrix( &p_vpar->sequence.intra_quant, pi_default_intra_quant ); + LinkMatrix( &p_vpar->sequence.intra_quant, + p_vpar->pi_default_intra_quant ); } - if( GetBits( &p_vpar->bit_stream, 1 ) ) /* load_non_intra_quantizer_matrix */ + if( GetBits(&p_vpar->bit_stream, 1) ) /* load_non_intra_quantizer_matrix */ { LoadMatrix( p_vpar, &p_vpar->sequence.nonintra_quant ); } else { /* Use default matrix. */ - LinkMatrix( &p_vpar->sequence.nonintra_quant, pi_default_nonintra_quant ); + LinkMatrix( &p_vpar->sequence.nonintra_quant, + p_vpar->pi_default_nonintra_quant ); } /* Unless later overwritten by a matrix extension, we have the same @@ -407,7 +383,8 @@ static void SequenceHeader( vpar_thread_t * p_vpar ) p_vpar->sequence.i_chroma_format = GetBits( &p_vpar->bit_stream, 2 ); p_vpar->sequence.i_width |= GetBits( &p_vpar->bit_stream, 2 ) << 12; p_vpar->sequence.i_height |= GetBits( &p_vpar->bit_stream, 2 ) << 12; - /* bit_rate_extension, marker_bit, vbv_buffer_size_extension, low_delay */ + /* bit_rate_extension, marker_bit, vbv_buffer_size_extension, + * low_delay */ RemoveBits( &p_vpar->bit_stream, 22 ); /* frame_rate_extension_n */ i_dummy = GetBits( &p_vpar->bit_stream, 2 ); @@ -473,6 +450,13 @@ static void SequenceHeader( vpar_thread_t * p_vpar ) /* Extension and User data */ ExtensionAndUserData( p_vpar ); + + /* XXX: The vout request and fifo opening will eventually be here */ + if( p_main->p_vout == NULL ) + { + intf_Msg( "vpar: no vout present, spawning one" ); + p_main->p_vout = p_vpar->p_vout = vout_CreateThread( NULL ); + } } /***************************************************************************** @@ -497,6 +481,28 @@ static void PictureHeader( vpar_thread_t * p_vpar ) int i_mb; #endif + /* Recover in case of stream discontinuity. */ + if( p_vpar->sequence.b_expect_discontinuity ) + { + ReferenceUpdate( p_vpar, I_CODING_TYPE, NULL ); + ReferenceUpdate( p_vpar, I_CODING_TYPE, NULL ); + if( p_vpar->picture.p_picture != NULL ) + { +#ifdef VDEC_SMP + int i_mb; + + for( i_mb = 0; p_vpar->picture.pp_mb[i_mb] != NULL; i_mb++ ) + { + vpar_DestroyMacroblock( &p_vpar->vfifo, + p_vpar->picture.pp_mb[i_mb] ); + } +#endif + vout_DestroyPicture( p_vpar->p_vout, p_vpar->picture.p_picture ); + } + p_vpar->sequence.b_expect_discontinuity = 0; + } + + /* Parse the picture header. */ RemoveBits( &p_vpar->bit_stream, 10 ); /* temporal_reference */ p_vpar->picture.i_coding_type = GetBits( &p_vpar->bit_stream, 3 ); RemoveBits( &p_vpar->bit_stream, 16 ); /* vbv_delay */ @@ -544,11 +550,9 @@ static void PictureHeader( vpar_thread_t * p_vpar ) p_vpar->picture.b_intra_vlc_format = GetBits( &p_vpar->bit_stream, 1 ); p_vpar->picture.b_alternate_scan = GetBits( &p_vpar->bit_stream, 1 ); p_vpar->picture.b_repeat_first_field = GetBits( &p_vpar->bit_stream, 1 ); - /* repeat_first_field (ISO/IEC 13818-2 6.3.10 is necessary to know - * the length of the picture_display_extension structure. - * chroma_420_type (obsolete) */ + /* chroma_420_type (obsolete) */ RemoveBits( &p_vpar->bit_stream, 1 ); - p_vpar->picture.b_progressive_frame = GetBits( &p_vpar->bit_stream, 1 ); + p_vpar->picture.b_progressive = GetBits( &p_vpar->bit_stream, 1 ); /* composite_display_flag */ if( GetBits( &p_vpar->bit_stream, 1 ) ) @@ -563,13 +567,14 @@ static void PictureHeader( vpar_thread_t * p_vpar ) /* MPEG-1 compatibility flags */ p_vpar->picture.i_intra_dc_precision = 0; /* 8 bits */ i_structure = FRAME_STRUCTURE; + p_vpar->picture.b_top_field_first = 0; p_vpar->picture.b_frame_pred_frame_dct = 1; p_vpar->picture.b_concealment_mv = 0; p_vpar->picture.b_q_scale_type = 0; p_vpar->picture.b_intra_vlc_format = 0; p_vpar->picture.b_alternate_scan = 0; /* zigzag */ p_vpar->picture.b_repeat_first_field = 0; - p_vpar->picture.b_progressive_frame = 1; + p_vpar->picture.b_progressive = 1; } #ifdef STATS @@ -599,7 +604,7 @@ static void PictureHeader( vpar_thread_t * p_vpar ) p_vpar->picture.i_current_structure = 0; - intf_DbgMsg("vpar debug: odd number of field picture."); + intf_WarnMsg( 2, "Odd number of field pictures." ); } /* Do we have the reference pictures ? */ @@ -621,8 +626,30 @@ static void PictureHeader( vpar_thread_t * p_vpar ) } else { + int i_repeat_field; + + /* Compute the number of times the frame will be emitted by the + * decoder (number of half-periods). */ + if( p_vpar->sequence.b_progressive ) + { + i_repeat_field = (1 + p_vpar->picture.b_repeat_first_field + + p_vpar->picture.b_top_field_first) * 2; + } + else + { + if( p_vpar->picture.b_progressive ) + { + i_repeat_field = 2 + p_vpar->picture.b_repeat_first_field; + } + else + { + i_repeat_field = 2; + } + } + /* Warn synchro we have a new picture (updates pictures index). */ - vpar_SynchroNewPicture( p_vpar, p_vpar->picture.i_coding_type ); + vpar_SynchroNewPicture( p_vpar, p_vpar->picture.i_coding_type, + i_repeat_field ); if( b_parsable ) { @@ -676,7 +703,7 @@ static void PictureHeader( vpar_thread_t * p_vpar ) { /* This is a new frame. Get a structure from the video_output. */ while( ( P_picture = vout_CreatePicture( p_vpar->p_vout, - 99+p_vpar->sequence.i_chroma_format, /*XXX??*/ + /* XXX */ 99+p_vpar->sequence.i_chroma_format, p_vpar->sequence.i_width, p_vpar->sequence.i_height ) ) == NULL ) @@ -699,7 +726,6 @@ static void PictureHeader( vpar_thread_t * p_vpar ) << ( 1 - p_vpar->picture.b_frame_structure )); P_picture->i_deccount = p_vpar->sequence.i_mb_size; - vlc_mutex_init( &p_vpar->picture.p_picture->lock_deccount ); #ifdef VDEC_SMP memset( p_vpar->picture.pp_mb, 0, MAX_MB*sizeof(macroblock_t *) ); #endif @@ -711,7 +737,8 @@ static void PictureHeader( vpar_thread_t * p_vpar ) #ifdef VDEC_SMP /* Link referenced pictures for the decoder - * They are unlinked in vpar_ReleaseMacroblock() & vpar_DestroyMacroblock() */ + * They are unlinked in vpar_ReleaseMacroblock() & + * vpar_DestroyMacroblock() */ if( p_vpar->picture.i_coding_type == P_CODING_TYPE || p_vpar->picture.i_coding_type == B_CODING_TYPE ) { @@ -743,7 +770,68 @@ static void PictureHeader( vpar_thread_t * p_vpar ) /* Extension and User data. */ ExtensionAndUserData( p_vpar ); - vpar_PictureData( p_vpar, i_mb_base ); + /* This is an MP@ML decoder, please note that neither of the following + * assertions can be true : + * p_vpar->sequence.i_chroma_format != CHROMA_420 + * p_vpar->sequence.i_height > 2800 + * p_vpar->sequence.i_scalable_mode == SC_DP + * Be cautious if you try to use the decoder for other profiles and + * levels. + */ + if( p_vpar->sequence.b_mpeg2 ) + { + static f_picture_data_t ppf_picture_data[4][4] = + { + { + NULL, NULL, NULL, NULL + }, + { + /* TOP_FIELD */ +#if (VPAR_OPTIM_LEVEL > 1) + NULL, vpar_PictureData2IT, vpar_PictureData2PT, + vpar_PictureData2BT +#else + NULL, vpar_PictureDataGENERIC, vpar_PictureDataGENERIC, + vpar_PictureDataGENERIC +#endif + }, + { + /* BOTTOM_FIELD */ +#if (VPAR_OPTIM_LEVEL > 1) + NULL, vpar_PictureData2IB, vpar_PictureData2PB, + vpar_PictureData2BB +#else + NULL, vpar_PictureDataGENERIC, vpar_PictureDataGENERIC, + vpar_PictureDataGENERIC +#endif + }, + { + /* FRAME_PICTURE */ +#if (VPAR_OPTIM_LEVEL > 0) + NULL, vpar_PictureData2IF, vpar_PictureData2PF, + vpar_PictureData2BF +#else + NULL, vpar_PictureDataGENERIC, vpar_PictureDataGENERIC, + vpar_PictureDataGENERIC +#endif + } + }; + + ppf_picture_data[p_vpar->picture.i_structure] + [p_vpar->picture.i_coding_type]( p_vpar, i_mb_base ); + } + else + { +#if (VPAR_OPTIM_LEVEL > 0) + static f_picture_data_t pf_picture_data[5] = + { NULL, vpar_PictureData1I, vpar_PictureData1P, vpar_PictureData1B, + vpar_PictureData1D }; + + pf_picture_data[p_vpar->picture.i_coding_type]( p_vpar, i_mb_base ); +#else + vpar_PictureDataGENERIC( p_vpar, i_mb_base ); +#endif + } if( p_vpar->p_fifo->b_die || p_vpar->p_fifo->b_error ) { @@ -753,7 +841,6 @@ static void PictureHeader( vpar_thread_t * p_vpar ) if( p_vpar->picture.b_error ) { /* Trash picture. */ -//fprintf(stderr, "Image trashee\n"); #ifdef VDEC_SMP for( i_mb = 1; p_vpar->picture.pp_mb[i_mb] != NULL; i_mb++ ) { @@ -780,7 +867,6 @@ static void PictureHeader( vpar_thread_t * p_vpar ) } else if( p_vpar->picture.i_current_structure == FRAME_STRUCTURE ) { -//fprintf(stderr, "Image parsee (%d)\n", p_vpar->picture.i_coding_type); /* Frame completely parsed. */ #ifdef VDEC_SMP for( i_mb = 1; p_vpar->picture.pp_mb[i_mb] != NULL; i_mb++ ) @@ -837,6 +923,7 @@ static void ExtensionAndUserData( vpar_thread_t * p_vpar ) CopyrightExtension( p_vpar ); break; default: + break; } break; @@ -888,7 +975,7 @@ static void QuantMatrixExtension( vpar_thread_t * p_vpar ) { /* Use the default matrix. */ LinkMatrix( &p_vpar->sequence.intra_quant, - pi_default_intra_quant ); + p_vpar->pi_default_intra_quant ); } if( GetBits( &p_vpar->bit_stream, 1 ) ) { @@ -899,7 +986,7 @@ static void QuantMatrixExtension( vpar_thread_t * p_vpar ) { /* Use the default matrix. */ LinkMatrix( &p_vpar->sequence.nonintra_quant, - pi_default_nonintra_quant ); + p_vpar->pi_default_nonintra_quant ); } if( GetBits( &p_vpar->bit_stream, 1 ) ) {