From 8f312ab4a6d711582882a587cbbff5d9a9f5e0a3 Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Fri, 11 May 2012 21:50:46 +0200 Subject: [PATCH] Added support for vprp chunk in AVI demuxer. It is an OpenDML extension that contains the aspect ratio (it closes #6777). --- modules/demux/avi/avi.c | 12 ++++++++++++ modules/demux/avi/libavi.c | 33 +++++++++++++++++++++++++++++++++ modules/demux/avi/libavi.h | 28 ++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) diff --git a/modules/demux/avi/avi.c b/modules/demux/avi/avi.c index d5927ce19c..dbc98bf626 100644 --- a/modules/demux/avi/avi.c +++ b/modules/demux/avi/avi.c @@ -464,6 +464,7 @@ static int Open( vlc_object_t * p_this ) break; case( AVIFOURCC_vids ): + { tk->i_cat = VIDEO_ES; tk->i_codec = AVI_FourccGetCodec( VIDEO_ES, p_vids->p_bih->biCompression ); @@ -530,6 +531,16 @@ static int Open( vlc_object_t * p_this ) fmt.video.i_bits_per_pixel = p_vids->p_bih->biBitCount; fmt.video.i_frame_rate = tk->i_rate; fmt.video.i_frame_rate_base = tk->i_scale; + avi_chunk_vprp_t *p_vprp = AVI_ChunkFind( p_strl, AVIFOURCC_vprp, 0 ); + if( p_vprp ) + { + uint32_t i_frame_aspect_ratio = p_vprp->i_frame_aspect_ratio; + if( p_vprp->i_video_format_token >= 1 && + p_vprp->i_video_format_token <= 4 ) + i_frame_aspect_ratio = 0x00040003; + fmt.video.i_sar_num = ((i_frame_aspect_ratio >> 16) & 0xffff) * fmt.video.i_height; + fmt.video.i_sar_den = ((i_frame_aspect_ratio >> 0) & 0xffff) * fmt.video.i_width; + } fmt.i_extra = __MAX( p_vids->p_bih->biSize - sizeof( VLC_BITMAPINFOHEADER ), p_vids->i_chunk_size - sizeof(VLC_BITMAPINFOHEADER) ); @@ -576,6 +587,7 @@ static int Open( vlc_object_t * p_this ) } } break; + } case( AVIFOURCC_txts): msg_Dbg( p_demux, "stream[%d] subtitle attachment", i ); diff --git a/modules/demux/avi/libavi.c b/modules/demux/avi/libavi.c index e289212823..2a39131371 100644 --- a/modules/demux/avi/libavi.c +++ b/modules/demux/avi/libavi.c @@ -576,7 +576,39 @@ static void AVI_ChunkFree_indx( avi_chunk_t *p_chk ) FREENULL( p_indx->idx.super ); } +static int AVI_ChunkRead_vprp( stream_t *s, avi_chunk_t *p_chk ) +{ + avi_chunk_vprp_t *p_vprp = (avi_chunk_vprp_t*)p_chk; + + AVI_READCHUNK_ENTER; + + AVI_READ4BYTES( p_vprp->i_video_format_token ); + AVI_READ4BYTES( p_vprp->i_video_standard ); + AVI_READ4BYTES( p_vprp->i_vertical_refresh ); + AVI_READ4BYTES( p_vprp->i_h_total_in_t ); + AVI_READ4BYTES( p_vprp->i_v_total_in_lines ); + AVI_READ4BYTES( p_vprp->i_frame_aspect_ratio ); + AVI_READ4BYTES( p_vprp->i_frame_width_in_pixels ); + AVI_READ4BYTES( p_vprp->i_frame_height_in_pixels ); + AVI_READ4BYTES( p_vprp->i_nb_fields_per_frame ); + for( unsigned i = 0; i < __MIN( p_vprp->i_nb_fields_per_frame, 2 ); i++ ) + { + AVI_READ4BYTES( p_vprp->field_info[i].i_compressed_bm_height ); + AVI_READ4BYTES( p_vprp->field_info[i].i_compressed_bm_width ); + AVI_READ4BYTES( p_vprp->field_info[i].i_valid_bm_height ); + AVI_READ4BYTES( p_vprp->field_info[i].i_valid_bm_width ); + AVI_READ4BYTES( p_vprp->field_info[i].i_valid_bm_x_offset ); + AVI_READ4BYTES( p_vprp->field_info[i].i_valid_bm_y_offset ); + AVI_READ4BYTES( p_vprp->field_info[i].i_video_x_offset_in_t ); + AVI_READ4BYTES( p_vprp->field_info[i].i_video_y_valid_start_line ); + } +#ifdef AVI_DEBUG + msg_Dbg( (vlc_object_t*)s, "vprp: format:%d standard:%d", + p_vprp->i_video_format_token, p_vprp->i_video_standard ); +#endif + AVI_READCHUNK_EXIT( VLC_SUCCESS ); +} static const struct { @@ -674,6 +706,7 @@ static const struct { AVIFOURCC_strd, AVI_ChunkRead_strd, AVI_ChunkFree_strd }, { AVIFOURCC_idx1, AVI_ChunkRead_idx1, AVI_ChunkFree_idx1 }, { AVIFOURCC_indx, AVI_ChunkRead_indx, AVI_ChunkFree_indx }, + { AVIFOURCC_vprp, AVI_ChunkRead_vprp, AVI_ChunkFree_nothing }, { AVIFOURCC_JUNK, AVI_ChunkRead_nothing, AVI_ChunkFree_nothing }, { AVIFOURCC_IARL, AVI_ChunkRead_strz, AVI_ChunkFree_strz }, diff --git a/modules/demux/avi/libavi.h b/modules/demux/avi/libavi.h index 96df03dcfc..14a930e4c2 100644 --- a/modules/demux/avi/libavi.h +++ b/modules/demux/avi/libavi.h @@ -145,6 +145,32 @@ typedef struct avi_chunk_strd_s uint8_t *p_data; } avi_chunk_strd_t; +typedef struct avi_chunk_vprp_s +{ + AVI_CHUNK_COMMON + uint32_t i_video_format_token; + uint32_t i_video_standard; + uint32_t i_vertical_refresh; + uint32_t i_h_total_in_t; + uint32_t i_v_total_in_lines; + uint32_t i_frame_aspect_ratio; + uint32_t i_frame_width_in_pixels; + uint32_t i_frame_height_in_pixels; + uint32_t i_nb_fields_per_frame; + struct + { + uint32_t i_compressed_bm_height; + uint32_t i_compressed_bm_width; + uint32_t i_valid_bm_height; + uint32_t i_valid_bm_width; + uint32_t i_valid_bm_x_offset; + uint32_t i_valid_bm_y_offset; + uint32_t i_video_x_offset_in_t; + uint32_t i_video_y_valid_start_line; + } field_info[2]; + +} avi_chunk_vprp_t; + #define AVI_INDEX_OF_INDEXES 0x00 #define AVI_INDEX_OF_CHUNKS 0x01 @@ -206,6 +232,7 @@ typedef union avi_chunk_u avi_chunk_strh_t strh; avi_chunk_strf_t strf; avi_chunk_strd_t strd; + avi_chunk_vprp_t vprp; avi_chunk_indx_t indx; avi_chunk_STRING_t strz; } avi_chunk_t; @@ -258,6 +285,7 @@ void AVI_ChunkFreeRoot( stream_t *, avi_chunk_t *p_chk ); #define AVIFOURCC_strd VLC_FOURCC('s','t','r','d') #define AVIFOURCC_strn VLC_FOURCC('s','t','r','n') #define AVIFOURCC_indx VLC_FOURCC('i','n','d','x') +#define AVIFOURCC_vprp VLC_FOURCC('v','p','r','p') #define AVIFOURCC_rec VLC_FOURCC('r','e','c',' ') #define AVIFOURCC_auds VLC_FOURCC('a','u','d','s') -- 2.39.2