X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fvideo_parser%2Fvpar_headers.c;h=779cfa9eaaf48b13be02ffd6c5012345900585be;hb=a70f8bb371466209770c4c3bcdb7137b94acef66;hp=b7eb6eb29bb0924aea8bb173f55436f0a10974e5;hpb=82c006196cb112d4f694e1d526964f30cd6c15ca;p=vlc diff --git a/src/video_parser/vpar_headers.c b/src/video_parser/vpar_headers.c index b7eb6eb29b..779cfa9eaa 100644 --- a/src/video_parser/vpar_headers.c +++ b/src/video_parser/vpar_headers.c @@ -1,51 +1,64 @@ /***************************************************************************** * vpar_headers.c : headers parsing - * (c)1999 VideoLAN + ***************************************************************************** + * Copyright (C) 1999, 2000 VideoLAN + * $Id: vpar_headers.c,v 1.83 2001/05/01 04:18:18 sam Exp $ + * + * Authors: Christophe Massiot + * Stéphane Borel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************/ /***************************************************************************** * Preamble *****************************************************************************/ -#include -#include -#include -#include -#include -#include +#include "defs.h" + +#include /* free() */ +#include /* memcpy(), memset() */ #include "config.h" #include "common.h" +#include "threads.h" #include "mtime.h" -#include "vlc_thread.h" #include "intf_msg.h" -#include "debug.h" /* ?? temporaire, requis par netlist.h */ -#include "input.h" -#include "input_netlist.h" -#include "decoder_fifo.h" +#include "stream_control.h" +#include "input_ext-dec.h" + #include "video.h" #include "video_output.h" -#include "vdec_idct.h" #include "video_decoder.h" #include "vdec_motion.h" +#include "../video_decoder/vdec_idct.h" #include "vpar_blocks.h" -#include "vpar_headers.h" -#include "vpar_synchro.h" -#include "video_parser.h" -#include "video_fifo.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" -/* - * Function pointer - */ -typedef void (*f_picture_data_t)( vpar_thread_t*, int ); +#include "main.h" /* XXX REMOVE THIS */ /* * Local prototypes */ -static __inline__ void NextStartCode( vpar_thread_t * p_vpar ); +static __inline__ void NextStartCode( bit_stream_t * ); static void SequenceHeader( vpar_thread_t * p_vpar ); static void GroupHeader( vpar_thread_t * p_vpar ); static void PictureHeader( vpar_thread_t * p_vpar ); @@ -65,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, @@ -76,26 +88,12 @@ int pi_default_intra_quant[] = 26, 27, 29, 32, 35, 40, 48, 58, 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, @@ -106,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 @@ -153,7 +138,9 @@ static void __inline__ ReferenceUpdate( vpar_thread_t * p_vpar, if( i_coding_type != B_CODING_TYPE ) { if( p_vpar->sequence.p_forward != NULL ) + { vout_UnlinkPicture( p_vpar->p_vout, p_vpar->sequence.p_forward ); + } if( p_vpar->sequence.p_backward != NULL ) { vout_DatePicture( p_vpar->p_vout, p_vpar->sequence.p_backward, @@ -162,13 +149,20 @@ static void __inline__ ReferenceUpdate( vpar_thread_t * p_vpar, p_vpar->sequence.p_forward = p_vpar->sequence.p_backward; p_vpar->sequence.p_backward = p_newref; if( p_newref != NULL ) + { vout_LinkPicture( p_vpar->p_vout, p_newref ); + } + } + else if( p_newref != NULL ) + { + /* Put date immediately. */ + vout_DatePicture( p_vpar->p_vout, p_newref, vpar_SynchroDate(p_vpar) ); } } /***************************************************************************** * ReferenceReplace : Replace the last reference pointer when we destroy - * a picture + * a picture *****************************************************************************/ static void __inline__ ReferenceReplace( vpar_thread_t * p_vpar, int i_coding_type, @@ -177,35 +171,40 @@ static void __inline__ ReferenceReplace( vpar_thread_t * p_vpar, if( i_coding_type != B_CODING_TYPE ) { if( p_vpar->sequence.p_backward != NULL ) + { vout_UnlinkPicture( p_vpar->p_vout, p_vpar->sequence.p_backward ); + } p_vpar->sequence.p_backward = p_newref; if( p_newref != NULL ) + { vout_LinkPicture( p_vpar->p_vout, p_newref ); + } } } /***************************************************************************** * 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()\n"); - p_vpar->b_error = 1; + intf_ErrMsg( "vpar error: allocation error in LoadMatrix()" ); + p_vpar->p_fifo->b_error = 1; return; } p_matrix->b_allocated = 1; } - + 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 ); } @@ -219,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 ) { @@ -227,7 +226,7 @@ static __inline__ void LinkMatrix( quant_matrix_t * p_matrix, int * pi_array ) free( p_matrix->pi_matrix ); p_matrix->b_allocated = 0; } - + p_matrix->pi_matrix = pi_array; } @@ -240,11 +239,13 @@ static __inline__ void LinkMatrix( quant_matrix_t * p_matrix, int * pi_array ) *****************************************************************************/ int vpar_NextSequenceHeader( vpar_thread_t * p_vpar ) { - while( !p_vpar->b_die ) + while( !p_vpar->p_fifo->b_die ) { - NextStartCode( p_vpar ); + NextStartCode( &p_vpar->bit_stream ); if( ShowBits( &p_vpar->bit_stream, 32 ) == SEQUENCE_HEADER_CODE ) + { return 0; + } RemoveBits( &p_vpar->bit_stream, 8 ); } return 1; @@ -255,12 +256,15 @@ int vpar_NextSequenceHeader( vpar_thread_t * p_vpar ) *****************************************************************************/ int vpar_ParseHeader( vpar_thread_t * p_vpar ) { - while( !p_vpar->b_die ) + while( !p_vpar->p_fifo->b_die ) { - NextStartCode( p_vpar ); + NextStartCode( &p_vpar->bit_stream ); switch( GetBits32( &p_vpar->bit_stream ) ) { case SEQUENCE_HEADER_CODE: +#ifdef STATS + p_vpar->c_sequences++; +#endif SequenceHeader( p_vpar ); return 0; break; @@ -276,11 +280,12 @@ int vpar_ParseHeader( vpar_thread_t * p_vpar ) break; case SEQUENCE_END_CODE: - intf_DbgMsg("vpar debug: sequence end code received\n"); + intf_DbgMsg("vpar debug: sequence end code received"); return 1; break; default: + break; } } @@ -296,37 +301,37 @@ int vpar_ParseHeader( vpar_thread_t * p_vpar ) *****************************************************************************/ static void SequenceHeader( vpar_thread_t * p_vpar ) { -#define RESERVED -1 - static float r_frame_rate_table[16] = +#define RESERVED -1 + static int i_frame_rate_table[16] = { - 0.0, - ((23.0*1000.0)/1001.0), - 24.0, - 25.0, - ((30.0*1000.0)/1001.0), - 30.0, - 50.0, - ((60.0*1000.0)/1001.0), - 60.0, + 0, + 23 * 1000, + 24 * 1001, + 25 * 1001, + 30 * 1000, + 30 * 1001, + 50 * 1001, + 60 * 1000, + 60 * 1001, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED }; #undef RESERVED int i_height_save, i_width_save; - + i_height_save = p_vpar->sequence.i_height; i_width_save = p_vpar->sequence.i_width; p_vpar->sequence.i_width = GetBits( &p_vpar->bit_stream, 12 ); p_vpar->sequence.i_height = GetBits( &p_vpar->bit_stream, 12 ); p_vpar->sequence.i_aspect_ratio = GetBits( &p_vpar->bit_stream, 4 ); - p_vpar->sequence.r_frame_rate = - r_frame_rate_table[ GetBits( &p_vpar->bit_stream, 4 ) ]; + p_vpar->sequence.i_frame_rate = + i_frame_rate_table[ GetBits( &p_vpar->bit_stream, 4 ) ]; /* We don't need bit_rate_value, marker_bit, vbv_buffer_size, * constrained_parameters_flag */ RemoveBits( &p_vpar->bit_stream, 30 ); - + /* * Quantization matrices */ @@ -337,19 +342,21 @@ 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 * matrices for luminance and chrominance. */ LinkMatrix( &p_vpar->sequence.chroma_intra_quant, @@ -360,14 +367,14 @@ static void SequenceHeader( vpar_thread_t * p_vpar ) /* * Sequence Extension */ - NextStartCode( p_vpar ); + NextStartCode( &p_vpar->bit_stream ); if( ShowBits( &p_vpar->bit_stream, 32 ) == EXTENSION_START_CODE ) { int i_dummy; /* Turn the MPEG2 flag on */ p_vpar->sequence.b_mpeg2 = 1; - + /* Parse sequence_extension */ RemoveBits32( &p_vpar->bit_stream ); /* extension_start_code_identifier, profile_and_level_indication */ @@ -376,12 +383,13 @@ 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 ); /* frame_rate_extension_d */ - p_vpar->sequence.r_frame_rate *= (i_dummy + 1) + p_vpar->sequence.i_frame_rate *= (i_dummy + 1) / (GetBits( &p_vpar->bit_stream, 5 ) + 1); } else @@ -436,12 +444,19 @@ static void SequenceHeader( vpar_thread_t * p_vpar ) if( p_vpar->sequence.i_width != i_width_save || p_vpar->sequence.i_height != i_height_save ) { - /* What do we do in case of a size change ??? */ + /* FIXME: What do we do in case of a size change ?? */ } #endif /* 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 ); + } } /***************************************************************************** @@ -459,51 +474,35 @@ static void GroupHeader( vpar_thread_t * p_vpar ) *****************************************************************************/ static void PictureHeader( vpar_thread_t * p_vpar ) { - /* Table of optimized PictureData functions. */ - static f_picture_data_t ppf_picture_data[4][4] = - { - { - NULL, NULL, NULL, NULL - }, - { - /* TOP_FIELD */ -#if (VPAR_OPTIM_LEVEL > 1) - NULL, vpar_PictureData2I420TZ, vpar_PictureData2P420TZ, - vpar_PictureData2B420TZ -#else - NULL, vpar_PictureDataGENERIC, vpar_PictureDataGENERIC, - vpar_PictureDataGENERIC -#endif - }, - { - /* BOTTOM_FIELD */ -#if (VPAR_OPTIM_LEVEL > 1) - NULL, vpar_PictureData2I420BZ, vpar_PictureData2P420BZ, - vpar_PictureData2B420BZ -#else - NULL, vpar_PictureDataGENERIC, vpar_PictureDataGENERIC, - vpar_PictureDataGENERIC -#endif - }, - { - /* FRAME_PICTURE */ -#if (VPAR_OPTIM_LEVEL > 0) - NULL, vpar_PictureData2I420F0, vpar_PictureData2P420F0, - vpar_PictureData2B420F0 -#else - NULL, vpar_PictureDataGENERIC, vpar_PictureDataGENERIC, - vpar_PictureDataGENERIC -#endif - } - }; - int i_structure; int i_mb_base; boolean_t b_parsable; #ifdef VDEC_SMP 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 */ @@ -526,17 +525,17 @@ static void PictureHeader( vpar_thread_t * p_vpar ) RemoveBits( &p_vpar->bit_stream, 8 ); } - /* + /* * Picture Coding Extension */ - NextStartCode( p_vpar ); + NextStartCode( &p_vpar->bit_stream ); if( ShowBits( &p_vpar->bit_stream, 32 ) == EXTENSION_START_CODE ) { /* Parse picture_coding_extension */ RemoveBits32( &p_vpar->bit_stream ); /* extension_start_code_identifier */ RemoveBits( &p_vpar->bit_stream, 4 ); - + p_vpar->picture.ppi_f_code[0][0] = GetBits( &p_vpar->bit_stream, 4 ); p_vpar->picture.ppi_f_code[0][1] = GetBits( &p_vpar->bit_stream, 4 ); p_vpar->picture.ppi_f_code[1][0] = GetBits( &p_vpar->bit_stream, 4 ); @@ -551,12 +550,10 @@ 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 ) ) { @@ -570,15 +567,20 @@ 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 + p_vpar->pc_pictures[p_vpar->picture.i_coding_type]++; +#endif + if( p_vpar->picture.i_current_structure && (i_structure == FRAME_STRUCTURE || i_structure == p_vpar->picture.i_current_structure) ) @@ -599,10 +601,10 @@ static void PictureHeader( vpar_thread_t * p_vpar ) #endif vout_DestroyPicture( p_vpar->p_vout, p_vpar->picture.p_picture ); } - + p_vpar->picture.i_current_structure = 0; - intf_DbgMsg("vpar debug: odd number of field picture.\n"); + intf_WarnMsg( 2, "Odd number of field pictures." ); } /* Do we have the reference pictures ? */ @@ -613,15 +615,43 @@ static void PictureHeader( vpar_thread_t * p_vpar ) (p_vpar->sequence.p_forward == NULL || p_vpar->sequence.p_backward == NULL))); - if( b_parsable ) + if( p_vpar->picture.i_current_structure ) { - if( p_vpar->picture.i_current_structure ) + /* Second field of a frame. We will decode it if, and only if we + * have decoded the first field. */ + if( b_parsable ) { - /* Second field of a frame. We will decode it if, and only if we - * have decoded the first field. */ b_parsable = (p_vpar->picture.p_picture != NULL); } + } + 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, + i_repeat_field ); + + if( b_parsable ) { /* Does synchro say we have enough time to decode it ? */ b_parsable = vpar_SynchroChoose( p_vpar, @@ -633,19 +663,38 @@ static void PictureHeader( vpar_thread_t * p_vpar ) { /* Update the reference pointers. */ ReferenceUpdate( p_vpar, p_vpar->picture.i_coding_type, NULL ); - - /* Warn Synchro we have trashed a picture. */ - vpar_SynchroTrash( p_vpar, p_vpar->picture.i_coding_type, i_structure ); /* Update context. */ if( i_structure != FRAME_STRUCTURE ) - p_vpar->picture.i_current_structure = i_structure; + { + if( (p_vpar->picture.i_current_structure | i_structure) + == FRAME_STRUCTURE ) + { + p_vpar->picture.i_current_structure = 0; + } + else + { + /* The frame is complete. */ + p_vpar->picture.i_current_structure = i_structure; + + vpar_SynchroTrash( p_vpar, p_vpar->picture.i_coding_type, i_structure ); + } + } + else + { + /* Warn Synchro we have trashed a picture. */ + vpar_SynchroTrash( p_vpar, p_vpar->picture.i_coding_type, i_structure ); + } p_vpar->picture.p_picture = NULL; return; } /* OK, now we are sure we will decode the picture. */ +#ifdef STATS + p_vpar->pc_decoded_pictures[p_vpar->picture.i_coding_type]++; +#endif + #define P_picture p_vpar->picture.p_picture p_vpar->picture.b_error = 0; p_vpar->picture.b_frame_structure = (i_structure == FRAME_STRUCTURE); @@ -654,13 +703,13 @@ 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 */ 99+p_vpar->sequence.i_chroma_format, p_vpar->sequence.i_width, p_vpar->sequence.i_height ) ) == NULL ) { - intf_DbgMsg("vpar debug: allocation error in vout_CreatePicture, delaying\n"); - if( p_vpar->b_die || p_vpar->b_error ) + intf_DbgMsg("vpar debug: allocation error in vout_CreatePicture, delaying"); + if( p_vpar->p_fifo->b_die || p_vpar->p_fifo->b_error ) { return; } @@ -669,12 +718,6 @@ static void PictureHeader( vpar_thread_t * p_vpar ) /* Initialize values. */ vpar_SynchroDecode( p_vpar, p_vpar->picture.i_coding_type, i_structure ); - if( p_vpar->picture.i_coding_type == B_CODING_TYPE ) - { - /* Put date immediately. */ - vout_DatePicture( p_vpar->p_vout, P_picture, - vpar_SynchroDate( p_vpar ) ); - } P_picture->i_aspect_ratio = p_vpar->sequence.i_aspect_ratio; P_picture->i_matrix_coefficients = p_vpar->sequence.i_matrix_coefficients; p_vpar->picture.i_l_stride = ( p_vpar->sequence.i_width @@ -683,19 +726,19 @@ 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 -/* FIXME ! remove asap */ +/* FIXME ! remove asap ?? */ //memset( P_picture->p_data, 0, (p_vpar->sequence.i_mb_size*384)); /* Update the reference pointers. */ ReferenceUpdate( p_vpar, p_vpar->picture.i_coding_type, P_picture ); #ifdef VDEC_SMP - /* Link referenced pictures for the decoder - * They are unlinked in vpar_ReleaseMacroblock() & vpar_DestroyMacroblock() */ + /* Link referenced pictures for the decoder + * 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 ) { @@ -704,7 +747,7 @@ static void PictureHeader( vpar_thread_t * p_vpar ) if( p_vpar->picture.i_coding_type == B_CODING_TYPE ) { vout_LinkPicture( p_vpar->p_vout, p_vpar->sequence.p_backward ); - } + } #endif } p_vpar->picture.i_current_structure |= i_structure; @@ -727,22 +770,70 @@ static void PictureHeader( vpar_thread_t * p_vpar ) /* Extension and User data. */ ExtensionAndUserData( p_vpar ); - /* Picture data (ISO/IEC 13818-2 6.2.3.7). */ - if( p_vpar->sequence.i_chroma_format != CHROMA_420 - || !p_vpar->sequence.b_mpeg2 || p_vpar->sequence.i_height > 2800 - || p_vpar->sequence.i_scalable_mode == SC_DP ) + /* 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 ) { - /* Weird stream. Use the slower generic function. */ - vpar_PictureDataGENERIC( p_vpar, i_mb_base ); + 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 { - /* Try to find an optimized function. */ - ppf_picture_data[p_vpar->picture.i_structure] - [p_vpar->picture.i_coding_type]( p_vpar, i_mb_base ); +#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->b_die || p_vpar->b_error ) + if( p_vpar->p_fifo->b_die || p_vpar->p_fifo->b_error ) { return; } @@ -750,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++ ) { @@ -758,8 +848,13 @@ static void PictureHeader( vpar_thread_t * p_vpar ) } #endif +#ifdef STATS + p_vpar->pc_malformed_pictures[p_vpar->picture.i_coding_type]++; +#endif + if( P_picture->i_deccount != 1 ) { + vpar_SynchroEnd( p_vpar, 1 ); vout_DestroyPicture( p_vpar->p_vout, P_picture ); } @@ -772,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++ ) @@ -798,9 +892,9 @@ static void PictureHeader( vpar_thread_t * p_vpar ) *****************************************************************************/ static void ExtensionAndUserData( vpar_thread_t * p_vpar ) { - while( !p_vpar->b_die ) + while( !p_vpar->p_fifo->b_die ) { - NextStartCode( p_vpar ); + NextStartCode( &p_vpar->bit_stream ); switch( ShowBits( &p_vpar->bit_stream, 32 ) ) { case EXTENSION_START_CODE: @@ -829,6 +923,7 @@ static void ExtensionAndUserData( vpar_thread_t * p_vpar ) CopyrightExtension( p_vpar ); break; default: + break; } break; @@ -880,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 ) ) { @@ -891,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 ) ) {