|  |  | @@ -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; | 
		
	
	
		
			
				|  |  | 
 |