X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=plugins%2Fmpeg_vdec%2Fvpar_headers.c;h=9516fdb41e77fb383111266e70c9e28d1ea8d5a8;hb=ac5c557fc6320a89f6d3d0265537a14c88df4c18;hp=f694f6763ae13847a522fe7505df15b2b52687c7;hpb=003c2ab30097c1406da51290eccab8863dfe5101;p=vlc diff --git a/plugins/mpeg_vdec/vpar_headers.c b/plugins/mpeg_vdec/vpar_headers.c index f694f6763a..9516fdb41e 100644 --- a/plugins/mpeg_vdec/vpar_headers.c +++ b/plugins/mpeg_vdec/vpar_headers.c @@ -2,7 +2,7 @@ * vpar_headers.c : headers parsing ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: vpar_headers.c,v 1.4 2001/12/10 04:53:11 sam Exp $ + * $Id: vpar_headers.c,v 1.20 2002/05/18 17:47:47 sam Exp $ * * Authors: Christophe Massiot * Stéphane Borel @@ -25,15 +25,10 @@ /***************************************************************************** * Preamble *****************************************************************************/ -#include "defs.h" - #include /* free() */ #include /* memcpy(), memset() */ -#include "common.h" -#include "intf_msg.h" -#include "threads.h" -#include "mtime.h" +#include #include "video.h" #include "video_output.h" @@ -46,12 +41,10 @@ #include "video_parser.h" #include "video_decoder.h" -#include "modules_export.h" - /* * Local prototypes */ -static __inline__ void NextStartCode( bit_stream_t * ); +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 ); @@ -124,9 +117,9 @@ u8 pi_scan[2][64] ATTR_ALIGN(16) = /***************************************************************************** * ReferenceUpdate : Update the reference pointers when we have a new picture *****************************************************************************/ -static void __inline__ ReferenceUpdate( vpar_thread_t * p_vpar, - int i_coding_type, - picture_t * p_newref ) +static void inline ReferenceUpdate( vpar_thread_t * p_vpar, + int i_coding_type, + picture_t * p_newref ) { if( i_coding_type != B_CODING_TYPE ) { @@ -157,9 +150,8 @@ static void __inline__ ReferenceUpdate( vpar_thread_t * p_vpar, * ReferenceReplace : Replace the last reference pointer when we destroy * a picture *****************************************************************************/ -static void __inline__ ReferenceReplace( vpar_thread_t * p_vpar, - int i_coding_type, - picture_t * p_newref ) +static void inline ReferenceReplace( vpar_thread_t * p_vpar, int i_coding_type, + picture_t * p_newref ) { if( i_coding_type != B_CODING_TYPE ) { @@ -178,8 +170,8 @@ 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; @@ -205,7 +197,7 @@ static __inline__ void LoadMatrix( vpar_thread_t * p_vpar, /***************************************************************************** * LinkMatrix : Link a quantization matrix to another *****************************************************************************/ -static __inline__ void LinkMatrix( quant_matrix_t * p_matrix, u8 * pi_array ) +static inline void LinkMatrix( quant_matrix_t * p_matrix, u8 * pi_array ) { if( p_matrix->b_allocated ) { @@ -217,6 +209,28 @@ static __inline__ void LinkMatrix( quant_matrix_t * p_matrix, u8 * pi_array ) p_matrix->pi_matrix = pi_array; } +/***************************************************************************** + * ChromaToFourCC: Return a FourCC value used by the video output. + *****************************************************************************/ +static inline u64 ChromaToFourCC( int i_chroma ) +{ + switch( i_chroma ) + { + case CHROMA_420: + return FOURCC_I420; + + case CHROMA_422: + return FOURCC_I422; + + case CHROMA_444: + return FOURCC_I444; + + default: + /* This can't happen */ + return 0xdeadbeef; + } +} + /* * Exported functions. */ @@ -243,36 +257,35 @@ int vpar_NextSequenceHeader( vpar_thread_t * p_vpar ) *****************************************************************************/ int vpar_ParseHeader( vpar_thread_t * p_vpar ) { - while( !p_vpar->p_fifo->b_die ) + NextStartCode( &p_vpar->bit_stream ); + switch( GetBits32( &p_vpar->bit_stream ) ) { - NextStartCode( &p_vpar->bit_stream ); - switch( GetBits32( &p_vpar->bit_stream ) ) - { - case SEQUENCE_HEADER_CODE: - p_vpar->c_sequences++; + case SEQUENCE_HEADER_CODE: + p_vpar->c_sequences++; + SequenceHeader( p_vpar ); + return 0; + break; - SequenceHeader( p_vpar ); - return 0; - break; + case GROUP_START_CODE: + GroupHeader( p_vpar ); + return 0; + break; - case GROUP_START_CODE: - GroupHeader( p_vpar ); - return 0; - break; + case PICTURE_START_CODE: + PictureHeader( p_vpar ); + return 0; + break; - case PICTURE_START_CODE: - PictureHeader( p_vpar ); - return 0; - break; + case SEQUENCE_END_CODE: + intf_WarnMsg(3, "vpar warning: sequence end code received"); - case SEQUENCE_END_CODE: - intf_DbgMsg("vpar debug: sequence end code received"); - return 1; - break; + ReferenceUpdate( p_vpar, I_CODING_TYPE, NULL ); - default: - break; - } + return 1; + break; + + default: + break; } return 0; @@ -303,14 +316,14 @@ static void SequenceHeader( vpar_thread_t * p_vpar ) }; #undef RESERVED - int i_height_save, i_width_save; + int i_height_save, i_width_save, i_aspect; 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 ); + i_aspect = GetBits( &p_vpar->bit_stream, 4 ); p_vpar->sequence.i_frame_rate = i_frame_rate_table[ GetBits( &p_vpar->bit_stream, 4 ) ]; @@ -381,12 +394,64 @@ static void SequenceHeader( vpar_thread_t * p_vpar ) else { /* It's an MPEG-1 stream. Put adequate parameters. */ + int i_xyratio; + static int pi_mpeg1ratio[15] = { + 10000, 10000, 6735, 7031, 7615, 8055, 8437, 8935, + 9157, 9815, 10255, 10695, 10950, 11575, 12015 + }; + + if( i_aspect > 1 ) + { + i_xyratio = p_vpar->sequence.i_height * + pi_mpeg1ratio[i_aspect] / p_vpar->sequence.i_width; + if( 7450 < i_xyratio && i_xyratio < 7550 ) + { + i_aspect = 2; + } + else if( 5575 < i_xyratio && i_xyratio < 5675 ) + { + i_aspect = 3; + } + else if( 4475 < i_xyratio && i_xyratio < 4575 ) + { + i_aspect = 4; + } + } p_vpar->sequence.b_mpeg2 = 0; p_vpar->sequence.b_progressive = 1; p_vpar->sequence.i_chroma_format = CHROMA_420; } + /* check whether the input gives a particular aspect ratio */ + if( p_vpar->p_config->p_demux_data + && ( *(int*)(p_vpar->p_config->p_demux_data) & 0x7 ) ) + { + i_aspect = *(int*)(p_vpar->p_config->p_demux_data); + } + + /* Store calculated aspect ratio */ + switch( i_aspect ) + { + case AR_3_4_PICTURE: + p_vpar->sequence.i_aspect = VOUT_ASPECT_FACTOR * 4 / 3; + break; + + case AR_16_9_PICTURE: + p_vpar->sequence.i_aspect = VOUT_ASPECT_FACTOR * 16 / 9; + break; + + case AR_221_1_PICTURE: + p_vpar->sequence.i_aspect = VOUT_ASPECT_FACTOR * 221 / 100; + break; + + case AR_SQUARE_PICTURE: + default: + p_vpar->sequence.i_aspect = VOUT_ASPECT_FACTOR + * p_vpar->sequence.i_width / p_vpar->sequence.i_height; + break; + } + /* Update sizes */ p_vpar->sequence.i_mb_width = (p_vpar->sequence.i_width + 15) / 16; p_vpar->sequence.i_mb_height = (p_vpar->sequence.b_progressive) ? @@ -433,35 +498,58 @@ static void SequenceHeader( vpar_thread_t * p_vpar ) /* Spawn a video output if there is none */ vlc_mutex_lock( &p_vout_bank->lock ); + if( p_vout_bank->i_count != 0 ) + { + /* Take the first video output FIXME: take the best one */ + p_vpar->p_vout = p_vout_bank->pp_vout[ 0 ]; + + if( p_vpar->p_vout->render.i_width != p_vpar->sequence.i_width + || p_vpar->p_vout->render.i_height != p_vpar->sequence.i_height + || p_vpar->p_vout->render.i_chroma != ChromaToFourCC( p_vpar->sequence.i_chroma_format ) + || p_vpar->p_vout->render.i_aspect != p_vpar->sequence.i_aspect ) + { + p_vout_bank->pp_vout[ 0 ] = NULL; + p_vout_bank->i_count--; + vlc_mutex_unlock( &p_vout_bank->lock ); + vout_DestroyThread( p_vpar->p_vout, NULL ); + vlc_mutex_lock( &p_vout_bank->lock ); + + /* XXX: race condition here if p_vout_bank->i_count was updated */ + if( p_vout_bank->i_count ) + { + vlc_mutex_unlock( &p_vout_bank->lock ); + intf_ErrMsg( "vpar error: can't open vout, aborting" ); + p_vpar->p_fifo->b_error = 1; + return; + } + } + } + if( p_vout_bank->i_count == 0 ) { intf_WarnMsg( 1, "vpar: no vout present, spawning one" ); - p_vpar->p_vout = - vout_CreateThread( NULL, p_vpar->sequence.i_width, - p_vpar->sequence.i_height, - 99 + p_vpar->sequence.i_chroma_format, - p_vpar->sequence.i_aspect_ratio ); + vlc_mutex_unlock( &p_vout_bank->lock ); + + p_vpar->p_vout = vout_CreateThread( + NULL, p_vpar->sequence.i_width, + p_vpar->sequence.i_height, + ChromaToFourCC( p_vpar->sequence.i_chroma_format ), + p_vpar->sequence.i_aspect ); /* Everything failed */ if( p_vpar->p_vout == NULL ) { intf_ErrMsg( "vpar error: can't open vout, aborting" ); - vlc_mutex_unlock( &p_vout_bank->lock ); - p_vpar->p_fifo->b_error = 1; - /* XXX ! XXX ! XXX ! what to do here ? */ return; } + vlc_mutex_lock( &p_vout_bank->lock ); + p_vout_bank->pp_vout[ p_vout_bank->i_count ] = p_vpar->p_vout; p_vout_bank->i_count++; } - else - { - /* Take the first video output FIXME: take the best one */ - p_vpar->p_vout = p_vout_bank->pp_vout[ 0 ]; - } vlc_mutex_unlock( &p_vout_bank->lock ); } @@ -484,6 +572,10 @@ static void PictureHeader( vpar_thread_t * p_vpar ) int i_structure, i_previous_coding_type; boolean_t b_parsable = 0; + /* Retrieve the PTS. */ + CurrentPTS( &p_vpar->bit_stream, &p_vpar->sequence.next_pts, + &p_vpar->sequence.next_dts ); + /* Recover in case of stream discontinuity. */ if( p_vpar->sequence.b_expect_discontinuity ) { @@ -738,26 +830,21 @@ 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, - p_vpar->sequence.i_width, - p_vpar->sequence.i_height, - /* XXX */ 99 + p_vpar->sequence.i_chroma_format, - p_vpar->sequence.i_aspect_ratio ) ) - == NULL ) + p_vpar->picture.b_progressive, + p_vpar->picture.b_top_field_first, + p_vpar->picture.b_repeat_first_field ) ) + == NULL ) { - intf_DbgMsg("vpar debug: vout_CreatePicture failed, delaying"); if( p_vpar->p_fifo->b_die || p_vpar->p_fifo->b_error ) { return; } - msleep( VPAR_OUTMEM_SLEEP ); + msleep( VOUT_OUTMEM_SLEEP ); } /* Initialize values. */ vpar_SynchroDecode( p_vpar, p_vpar->picture.i_coding_type, i_structure ); - 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_field_width = ( p_vpar->sequence.i_width - << ( 1 - p_vpar->picture.b_frame_structure ) ); /* Update the reference pointers. */ ReferenceUpdate( p_vpar, p_vpar->picture.i_coding_type, P_picture ); @@ -770,6 +857,13 @@ static void PictureHeader( vpar_thread_t * p_vpar ) (i_structure != p_vpar->picture.i_current_structure); p_vpar->picture.b_current_field = (i_structure == BOTTOM_FIELD ); + p_vpar->picture.i_lum_stride = p_vpar->picture.p_picture->Y_PITCH + << ( 1 - p_vpar->picture.b_frame_structure ); + p_vpar->picture.i_chrom_stride = p_vpar->picture.p_picture->U_PITCH + << ( 1 - p_vpar->picture.b_frame_structure ); + /* We suppose the pitch is the same for U and V planes. */ + p_vpar->picture.i_field_width = p_vpar->sequence.i_width + << ( 1 - p_vpar->picture.b_frame_structure ); if( !p_vpar->p_config->p_stream_ctrl->b_grayscale ) { @@ -1015,17 +1109,6 @@ static void QuantMatrixExtension( vpar_thread_t * p_vpar ) LoadMatrix( p_vpar, &p_vpar->sequence.chroma_nonintra_quant ); } else - { - /* Link the chrominance intra matrix to the luminance one. */ - LinkMatrix( &p_vpar->sequence.chroma_intra_quant, - p_vpar->sequence.intra_quant.pi_matrix ); - } - if( GetBits( &p_vpar->bit_stream, 1 ) ) - { - /* Load non_intra_quantiser_matrix for chrominance. */ - LoadMatrix( p_vpar, &p_vpar->sequence.chroma_nonintra_quant ); - } - else { /* Link the chrominance nonintra matrix to the luminance one. */ LinkMatrix( &p_vpar->sequence.chroma_nonintra_quant,