* 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 <massiot@via.ecp.fr>
* Stéphane Borel <stef@via.ecp.fr>
/*****************************************************************************
* Preamble
*****************************************************************************/
-#include "defs.h"
-
#include <stdlib.h> /* free() */
#include <string.h> /* memcpy(), memset() */
-#include "common.h"
-#include "intf_msg.h"
-#include "threads.h"
-#include "mtime.h"
+#include <videolan/vlc.h>
#include "video.h"
#include "video_output.h"
#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 );
/*****************************************************************************
* 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 )
{
* 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 )
{
/*****************************************************************************
* 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;
/*****************************************************************************
* 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 )
{
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.
*/
*****************************************************************************/
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;
};
#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 ) ];
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) ?
/* 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 );
}
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 )
{
{
/* 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 );
(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 )
{
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,