@ -87,6 +87,7 @@ static int vmd_read_header(AVFormatContext *s,
int64_t current_video_pts = 0 , current_audio_pts = 0 ;
unsigned char chunk [ BYTES_PER_FRAME_RECORD ] ;
int num , den ;
int sound_buffers ;
/* fetch the main header, including the 2 header length bytes */
url_fseek ( pb , 0 , SEEK_SET ) ;
@ -146,13 +147,14 @@ static int vmd_read_header(AVFormatContext *s,
raw_frame_table = NULL ;
vmd - > frame_table = NULL ;
sound_buffers = LE_16 ( & vmd - > vmd_header [ 808 ] ) ;
raw_frame_table_size = vmd - > frame_count * 6 ;
raw_frame_table = av_malloc ( raw_frame_table_size ) ;
if ( vmd - > frame_count * vmd - > frames_per_block > = UINT_MAX / sizeof ( vmd_frame_t ) ) {
av_log ( s , AV_LOG_ERROR , " vmd->frame_count * vmd->frames_per_block too large \n " ) ;
return - 1 ;
}
vmd - > frame_table = av_malloc ( vmd - > frame_count * vmd - > frames_per_block * sizeof ( vmd_frame_t ) ) ;
vmd - > frame_table = av_malloc ( ( vmd - > frame_count * vmd - > frames_per_block + sound_buffers ) * sizeof ( vmd_frame_t ) ) ;
if ( ! raw_frame_table | | ! vmd - > frame_table ) {
av_free ( raw_frame_table ) ;
av_free ( vmd - > frame_table ) ;
@ -182,14 +184,43 @@ static int vmd_read_header(AVFormatContext *s,
continue ;
switch ( type ) {
case 1 : /* Audio Chunk */
/* first audio chunk contains several audio buffers */
if ( current_audio_pts ) {
vmd - > frame_table [ total_frames ] . frame_offset = current_offset ;
vmd - > frame_table [ total_frames ] . stream_index = vmd - > audio_stream_index ;
vmd - > frame_table [ total_frames ] . frame_size = size ;
memcpy ( vmd - > frame_table [ total_frames ] . frame_record , chunk , BYTES_PER_FRAME_RECORD ) ;
vmd - > frame_table [ total_frames ] . pts = current_audio_pts ;
total_frames + + ;
/* first audio chunk contains several audio buffers */
current_audio_pts + = ( current_audio_pts = = 0 ) ? LE_16 ( & vmd - > vmd_header [ 808 ] ) * pts_inc : pts_inc ;
current_audio_pts + = pts_inc ;
} else {
uint32_t flags ;
int k ;
int noff ;
int64_t pos ;
pos = url_ftell ( pb ) ;
url_fseek ( pb , current_offset , SEEK_SET ) ;
flags = get_le32 ( pb ) ;
noff = 4 ;
url_fseek ( pb , pos , SEEK_SET ) ;
av_log ( s , AV_LOG_DEBUG , " Sound mapping = %08X (%i bufs) \n " , flags , sound_buffers ) ;
for ( k = 0 ; k < sound_buffers - 1 ; k + + ) {
if ( flags & 1 ) { /* silent block */
vmd - > frame_table [ total_frames ] . frame_size = 0 ;
} else {
vmd - > frame_table [ total_frames ] . frame_size = st - > codec - > block_align + ( st - > codec - > block_align & 1 ) ;
}
noff + = vmd - > frame_table [ total_frames ] . frame_size ;
vmd - > frame_table [ total_frames ] . frame_offset = current_offset + noff ;
vmd - > frame_table [ total_frames ] . stream_index = vmd - > audio_stream_index ;
memcpy ( vmd - > frame_table [ total_frames ] . frame_record , chunk , BYTES_PER_FRAME_RECORD ) ;
vmd - > frame_table [ total_frames ] . pts = current_audio_pts ;
total_frames + + ;
current_audio_pts + = pts_inc ;
flags > > = 1 ;
}
}
break ;
case 2 : /* Video Chunk */
vmd - > frame_table [ total_frames ] . frame_offset = current_offset ;