static int AVI_ChunkRead_strd( stream_t *s, avi_chunk_t *p_chk ) { AVI_READCHUNK_ENTER; p_chk->strd.p_data = malloc( p_chk->common.i_chunk_size ); memcpy( p_chk->strd.p_data, p_buff + 8, p_chk->common.i_chunk_size ); AVI_READCHUNK_EXIT( VLC_SUCCESS ); }
static int AVI_ChunkRead_strz( stream_t *s, avi_chunk_t *p_chk ) { int i_index; avi_chunk_STRING_t *p_strz = (avi_chunk_STRING_t*)p_chk; AVI_READCHUNK_ENTER; for( i_index = 0;; i_index++) { if( !AVI_strz_type[i_index].i_fourcc || AVI_strz_type[i_index].i_fourcc == p_strz->i_chunk_fourcc ) { break; } } p_strz->p_type = strdup( AVI_strz_type[i_index].psz_type ); p_strz->p_str = malloc( i_read + 1); if( p_strz->i_chunk_size ) { memcpy( p_strz->p_str, p_read, i_read ); } p_strz->p_str[i_read] = 0; #ifdef AVI_DEBUG msg_Dbg( (vlc_object_t*)s, "%4.4s: %s : %s", (char*)&p_strz->i_chunk_fourcc, p_strz->p_type, p_strz->p_str); #endif AVI_READCHUNK_EXIT( VLC_SUCCESS ); }
static int AVI_ChunkRead_idx1( stream_t *s, avi_chunk_t *p_chk ) { unsigned int i_count, i_index; AVI_READCHUNK_ENTER; i_count = __MIN( (int64_t)p_chk->common.i_chunk_size, i_read ) / 16; p_chk->idx1.i_entry_count = i_count; p_chk->idx1.i_entry_max = i_count; if( i_count > 0 ) { p_chk->idx1.entry = calloc( i_count, sizeof( idx1_entry_t ) ); for( i_index = 0; i_index < i_count ; i_index++ ) { AVI_READFOURCC( p_chk->idx1.entry[i_index].i_fourcc ); AVI_READ4BYTES( p_chk->idx1.entry[i_index].i_flags ); AVI_READ4BYTES( p_chk->idx1.entry[i_index].i_pos ); AVI_READ4BYTES( p_chk->idx1.entry[i_index].i_length ); } } else { p_chk->idx1.entry = NULL; } #ifdef AVI_DEBUG msg_Dbg( (vlc_object_t*)s, "idx1: index entry:%d", i_count ); #endif AVI_READCHUNK_EXIT( VLC_SUCCESS ); }
static int AVI_ChunkRead_strh( stream_t *s, avi_chunk_t *p_chk ) { AVI_READCHUNK_ENTER; AVI_READFOURCC( p_chk->strh.i_type ); AVI_READFOURCC( p_chk->strh.i_handler ); AVI_READ4BYTES( p_chk->strh.i_flags ); AVI_READ4BYTES( p_chk->strh.i_reserved1 ); AVI_READ4BYTES( p_chk->strh.i_initialframes ); AVI_READ4BYTES( p_chk->strh.i_scale ); AVI_READ4BYTES( p_chk->strh.i_rate ); AVI_READ4BYTES( p_chk->strh.i_start ); AVI_READ4BYTES( p_chk->strh.i_length ); AVI_READ4BYTES( p_chk->strh.i_suggestedbuffersize ); AVI_READ4BYTES( p_chk->strh.i_quality ); AVI_READ4BYTES( p_chk->strh.i_samplesize ); #ifdef AVI_DEBUG msg_Dbg( (vlc_object_t*)s, "strh: type:%4.4s handler:0x%8.8x samplesize:%d %.2ffps", (char*)&p_chk->strh.i_type, p_chk->strh.i_handler, p_chk->strh.i_samplesize, ( p_chk->strh.i_scale ? (float)p_chk->strh.i_rate / (float)p_chk->strh.i_scale : -1) ); #endif AVI_READCHUNK_EXIT( VLC_SUCCESS ); }
static int AVI_ChunkRead_avih( stream_t *s, avi_chunk_t *p_chk ) { AVI_READCHUNK_ENTER; p_chk->common.i_chunk_fourcc = AVIFOURCC_avih; AVI_READ4BYTES( p_chk->avih.i_microsecperframe); AVI_READ4BYTES( p_chk->avih.i_maxbytespersec ); AVI_READ4BYTES( p_chk->avih.i_reserved1 ); AVI_READ4BYTES( p_chk->avih.i_flags ); AVI_READ4BYTES( p_chk->avih.i_totalframes ); AVI_READ4BYTES( p_chk->avih.i_initialframes ); AVI_READ4BYTES( p_chk->avih.i_streams ); AVI_READ4BYTES( p_chk->avih.i_suggestedbuffersize ); AVI_READ4BYTES( p_chk->avih.i_width ); AVI_READ4BYTES( p_chk->avih.i_height ); AVI_READ4BYTES( p_chk->avih.i_scale ); AVI_READ4BYTES( p_chk->avih.i_rate ); AVI_READ4BYTES( p_chk->avih.i_start ); AVI_READ4BYTES( p_chk->avih.i_length ); #ifdef AVI_DEBUG msg_Dbg( (vlc_object_t*)s, "avih: streams:%d flags:%s%s%s%s %dx%d", p_chk->avih.i_streams, p_chk->avih.i_flags&AVIF_HASINDEX?" HAS_INDEX":"", p_chk->avih.i_flags&AVIF_MUSTUSEINDEX?" MUST_USE_INDEX":"", p_chk->avih.i_flags&AVIF_ISINTERLEAVED?" IS_INTERLEAVED":"", p_chk->avih.i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"", p_chk->avih.i_width, p_chk->avih.i_height ); #endif AVI_READCHUNK_EXIT( VLC_SUCCESS ); }
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 int AVI_ChunkRead_strd( stream_t *s, avi_chunk_t *p_chk ) { if ( p_chk->common.i_chunk_size == 0 ) { msg_Dbg( (vlc_object_t*)s, "Zero sized pre-JUNK section met" ); return AVI_STRD_ZERO_CHUNK; } AVI_READCHUNK_ENTER; p_chk->strd.p_data = xmalloc( p_chk->common.i_chunk_size ); memcpy( p_chk->strd.p_data, p_buff + 8, p_chk->common.i_chunk_size ); AVI_READCHUNK_EXIT( VLC_SUCCESS ); }
static int AVI_ChunkRead_dmlh( stream_t *s, avi_chunk_t *p_chk ) { avi_chunk_dmlh_t *p_dmlh = (avi_chunk_dmlh_t*)p_chk; AVI_READCHUNK_ENTER; AVI_READ4BYTES( p_dmlh->dwTotalFrames ); #ifdef AVI_DEBUG msg_Dbg( (vlc_object_t*)s, "dmlh: dwTotalFrames %d", p_dmlh->dwTotalFrames ); #endif AVI_READCHUNK_EXIT( VLC_SUCCESS ); }
static int AVI_ChunkRead_indx( stream_t *s, avi_chunk_t *p_chk ) { unsigned int i_count, i; int32_t i_dummy; avi_chunk_indx_t *p_indx = (avi_chunk_indx_t*)p_chk; AVI_READCHUNK_ENTER; AVI_READ2BYTES( p_indx->i_longsperentry ); AVI_READ1BYTE ( p_indx->i_indexsubtype ); AVI_READ1BYTE ( p_indx->i_indextype ); AVI_READ4BYTES( p_indx->i_entriesinuse ); AVI_READ4BYTES( p_indx->i_id ); p_indx->idx.std = NULL; p_indx->idx.field = NULL; p_indx->idx.super = NULL; if( p_indx->i_indextype == AVI_INDEX_OF_CHUNKS && p_indx->i_indexsubtype == 0 ) { AVI_READ8BYTES( p_indx->i_baseoffset ); AVI_READ4BYTES( i_dummy ); i_count = __MIN( p_indx->i_entriesinuse, i_read / 8 ); p_indx->i_entriesinuse = i_count; p_indx->idx.std = calloc( i_count, sizeof( indx_std_entry_t ) ); for( i = 0; i < i_count; i++ ) { AVI_READ4BYTES( p_indx->idx.std[i].i_offset ); AVI_READ4BYTES( p_indx->idx.std[i].i_size ); } } else if( p_indx->i_indextype == AVI_INDEX_OF_CHUNKS && p_indx->i_indexsubtype == AVI_INDEX_2FIELD ) { AVI_READ8BYTES( p_indx->i_baseoffset ); AVI_READ4BYTES( i_dummy ); i_count = __MIN( p_indx->i_entriesinuse, i_read / 12 ); p_indx->i_entriesinuse = i_count; p_indx->idx.field = calloc( i_count, sizeof( indx_field_entry_t ) ); for( i = 0; i < i_count; i++ ) { AVI_READ4BYTES( p_indx->idx.field[i].i_offset ); AVI_READ4BYTES( p_indx->idx.field[i].i_size ); AVI_READ4BYTES( p_indx->idx.field[i].i_offsetfield2 ); } } else if( p_indx->i_indextype == AVI_INDEX_OF_INDEXES ) { p_indx->i_baseoffset = 0; AVI_READ4BYTES( i_dummy ); AVI_READ4BYTES( i_dummy ); AVI_READ4BYTES( i_dummy ); i_count = __MIN( p_indx->i_entriesinuse, i_read / 16 ); p_indx->i_entriesinuse = i_count; p_indx->idx.super = calloc( i_count, sizeof( indx_super_entry_t ) ); for( i = 0; i < i_count; i++ ) { AVI_READ8BYTES( p_indx->idx.super[i].i_offset ); AVI_READ4BYTES( p_indx->idx.super[i].i_size ); AVI_READ4BYTES( p_indx->idx.super[i].i_duration ); } } else { msg_Warn( (vlc_object_t*)s, "unknow type/subtype index" ); } #ifdef AVI_DEBUG msg_Dbg( (vlc_object_t*)s, "indx: type=%d subtype=%d entry=%d", p_indx->i_indextype, p_indx->i_indexsubtype, p_indx->i_entriesinuse ); #endif AVI_READCHUNK_EXIT( VLC_SUCCESS ); }
static int AVI_ChunkRead_strf( stream_t *s, avi_chunk_t *p_chk ) { avi_chunk_t *p_strh; AVI_READCHUNK_ENTER; if( p_chk->common.p_father == NULL ) { msg_Err( (vlc_object_t*)s, "malformed avi file" ); AVI_READCHUNK_EXIT( VLC_EGENERIC ); } if( !( p_strh = AVI_ChunkFind( p_chk->common.p_father, AVIFOURCC_strh, 0 ) ) ) { msg_Err( (vlc_object_t*)s, "malformed avi file" ); AVI_READCHUNK_EXIT( VLC_EGENERIC ); } switch( p_strh->strh.i_type ) { case( AVIFOURCC_auds ): p_chk->strf.auds.i_cat = AUDIO_ES; p_chk->strf.auds.p_wf = malloc( __MAX( p_chk->common.i_chunk_size, sizeof( WAVEFORMATEX ) ) ); AVI_READ2BYTES( p_chk->strf.auds.p_wf->wFormatTag ); AVI_READ2BYTES( p_chk->strf.auds.p_wf->nChannels ); AVI_READ4BYTES( p_chk->strf.auds.p_wf->nSamplesPerSec ); AVI_READ4BYTES( p_chk->strf.auds.p_wf->nAvgBytesPerSec ); AVI_READ2BYTES( p_chk->strf.auds.p_wf->nBlockAlign ); AVI_READ2BYTES( p_chk->strf.auds.p_wf->wBitsPerSample ); if( p_chk->strf.auds.p_wf->wFormatTag != WAVE_FORMAT_PCM && p_chk->common.i_chunk_size > sizeof( WAVEFORMATEX ) ) { AVI_READ2BYTES( p_chk->strf.auds.p_wf->cbSize ); /* prevent segfault */ if( p_chk->strf.auds.p_wf->cbSize > p_chk->common.i_chunk_size - sizeof( WAVEFORMATEX ) ) { p_chk->strf.auds.p_wf->cbSize = p_chk->common.i_chunk_size - sizeof( WAVEFORMATEX ); } if( p_chk->strf.auds.p_wf->wFormatTag == WAVE_FORMAT_EXTENSIBLE ) { /* Found an extensible header atm almost nothing uses that. */ msg_Warn( (vlc_object_t*)s, "WAVE_FORMAT_EXTENSIBLE or " "vorbis audio dectected: not supported" ); } } else { p_chk->strf.auds.p_wf->cbSize = 0; } if( p_chk->strf.auds.p_wf->cbSize > 0 ) { memcpy( &p_chk->strf.auds.p_wf[1] , p_buff + 8 + sizeof( WAVEFORMATEX ), /* 8=fourrc+size */ p_chk->strf.auds.p_wf->cbSize ); } #ifdef AVI_DEBUG msg_Dbg( (vlc_object_t*)s, "strf: audio:0x%4.4x channels:%d %dHz %dbits/sample %dkb/s", p_chk->strf.auds.p_wf->wFormatTag, p_chk->strf.auds.p_wf->nChannels, p_chk->strf.auds.p_wf->nSamplesPerSec, p_chk->strf.auds.p_wf->wBitsPerSample, p_chk->strf.auds.p_wf->nAvgBytesPerSec * 8 / 1024 ); #endif break; case( AVIFOURCC_vids ): p_strh->strh.i_samplesize = 0; /* XXX for ffmpeg avi file */ p_chk->strf.vids.i_cat = VIDEO_ES; p_chk->strf.vids.p_bih = malloc( p_chk->common.i_chunk_size ); AVI_READ4BYTES( p_chk->strf.vids.p_bih->biSize ); AVI_READ4BYTES( p_chk->strf.vids.p_bih->biWidth ); AVI_READ4BYTES( p_chk->strf.vids.p_bih->biHeight ); AVI_READ2BYTES( p_chk->strf.vids.p_bih->biPlanes ); AVI_READ2BYTES( p_chk->strf.vids.p_bih->biBitCount ); AVI_READFOURCC( p_chk->strf.vids.p_bih->biCompression ); AVI_READ4BYTES( p_chk->strf.vids.p_bih->biSizeImage ); AVI_READ4BYTES( p_chk->strf.vids.p_bih->biXPelsPerMeter ); AVI_READ4BYTES( p_chk->strf.vids.p_bih->biYPelsPerMeter ); AVI_READ4BYTES( p_chk->strf.vids.p_bih->biClrUsed ); AVI_READ4BYTES( p_chk->strf.vids.p_bih->biClrImportant ); if( p_chk->strf.vids.p_bih->biSize > p_chk->common.i_chunk_size ) { p_chk->strf.vids.p_bih->biSize = p_chk->common.i_chunk_size; } if( p_chk->common.i_chunk_size - sizeof(BITMAPINFOHEADER) > 0 ) { memcpy( &p_chk->strf.vids.p_bih[1], p_buff + 8 + sizeof(BITMAPINFOHEADER), /* 8=fourrc+size */ p_chk->common.i_chunk_size -sizeof(BITMAPINFOHEADER) ); } #ifdef AVI_DEBUG msg_Dbg( (vlc_object_t*)s, "strf: video:%4.4s %"PRIu32"x%"PRIu32" planes:%d %dbpp", (char*)&p_chk->strf.vids.p_bih->biCompression, (uint32_t)p_chk->strf.vids.p_bih->biWidth, (uint32_t)p_chk->strf.vids.p_bih->biHeight, p_chk->strf.vids.p_bih->biPlanes, p_chk->strf.vids.p_bih->biBitCount ); #endif break; default: msg_Warn( (vlc_object_t*)s, "unknown stream type" ); p_chk->strf.common.i_cat = UNKNOWN_ES; break; } AVI_READCHUNK_EXIT( VLC_SUCCESS ); }
static int AVI_ChunkRead_strf( stream_t *s, avi_chunk_t *p_chk ) { avi_chunk_t *p_strh; AVI_READCHUNK_ENTER; if( p_chk->common.p_father == NULL ) { msg_Err( (vlc_object_t*)s, "malformed avi file" ); AVI_READCHUNK_EXIT( VLC_EGENERIC ); } if( !( p_strh = AVI_ChunkFind( p_chk->common.p_father, AVIFOURCC_strh, 0 ) ) ) { msg_Err( (vlc_object_t*)s, "malformed avi file" ); AVI_READCHUNK_EXIT( VLC_EGENERIC ); } switch( p_strh->strh.i_type ) { case( AVIFOURCC_auds ): p_chk->strf.auds.i_cat = AUDIO_ES; p_chk->strf.auds.p_wf = xmalloc( __MAX( p_chk->common.i_chunk_size, sizeof( WAVEFORMATEX ) ) ); if ( !p_chk->strf.auds.p_wf ) { AVI_READCHUNK_EXIT( VLC_ENOMEM ); } AVI_READ2BYTES( p_chk->strf.auds.p_wf->wFormatTag ); AVI_READ2BYTES( p_chk->strf.auds.p_wf->nChannels ); AVI_READ4BYTES( p_chk->strf.auds.p_wf->nSamplesPerSec ); AVI_READ4BYTES( p_chk->strf.auds.p_wf->nAvgBytesPerSec ); AVI_READ2BYTES( p_chk->strf.auds.p_wf->nBlockAlign ); AVI_READ2BYTES( p_chk->strf.auds.p_wf->wBitsPerSample ); if( p_chk->strf.auds.p_wf->wFormatTag != WAVE_FORMAT_PCM && p_chk->common.i_chunk_size > sizeof( WAVEFORMATEX ) ) { AVI_READ2BYTES( p_chk->strf.auds.p_wf->cbSize ); /* prevent segfault */ if( p_chk->strf.auds.p_wf->cbSize > p_chk->common.i_chunk_size - sizeof( WAVEFORMATEX ) ) { p_chk->strf.auds.p_wf->cbSize = p_chk->common.i_chunk_size - sizeof( WAVEFORMATEX ); } if( p_chk->strf.auds.p_wf->wFormatTag == WAVE_FORMAT_EXTENSIBLE ) { msg_Dbg( s, "Extended header found" ); } } else { p_chk->strf.auds.p_wf->cbSize = 0; } if( p_chk->strf.auds.p_wf->cbSize > 0 ) { memcpy( &p_chk->strf.auds.p_wf[1] , p_buff + 8 + sizeof( WAVEFORMATEX ), /* 8=fourcc+size */ p_chk->strf.auds.p_wf->cbSize ); } #ifdef AVI_DEBUG msg_Dbg( (vlc_object_t*)s, "strf: audio:0x%4.4x channels:%d %dHz %dbits/sample %dkb/s", p_chk->strf.auds.p_wf->wFormatTag, p_chk->strf.auds.p_wf->nChannels, p_chk->strf.auds.p_wf->nSamplesPerSec, p_chk->strf.auds.p_wf->wBitsPerSample, p_chk->strf.auds.p_wf->nAvgBytesPerSec * 8 / 1024 ); #endif break; case( AVIFOURCC_vids ): p_strh->strh.i_samplesize = 0; /* XXX for ffmpeg avi file */ p_chk->strf.vids.i_cat = VIDEO_ES; p_chk->strf.vids.p_bih = xmalloc( __MAX( p_chk->common.i_chunk_size, sizeof( *p_chk->strf.vids.p_bih ) ) ); if ( !p_chk->strf.vids.p_bih ) { AVI_READCHUNK_EXIT( VLC_ENOMEM ); } AVI_READ4BYTES( p_chk->strf.vids.p_bih->biSize ); AVI_READ4BYTES( p_chk->strf.vids.p_bih->biWidth ); AVI_READ4BYTES( p_chk->strf.vids.p_bih->biHeight ); AVI_READ2BYTES( p_chk->strf.vids.p_bih->biPlanes ); AVI_READ2BYTES( p_chk->strf.vids.p_bih->biBitCount ); AVI_READFOURCC( p_chk->strf.vids.p_bih->biCompression ); AVI_READ4BYTES( p_chk->strf.vids.p_bih->biSizeImage ); AVI_READ4BYTES( p_chk->strf.vids.p_bih->biXPelsPerMeter ); AVI_READ4BYTES( p_chk->strf.vids.p_bih->biYPelsPerMeter ); AVI_READ4BYTES( p_chk->strf.vids.p_bih->biClrUsed ); AVI_READ4BYTES( p_chk->strf.vids.p_bih->biClrImportant ); if( p_chk->strf.vids.p_bih->biSize > p_chk->common.i_chunk_size ) { p_chk->strf.vids.p_bih->biSize = p_chk->common.i_chunk_size; } if ( p_chk->common.i_chunk_size > sizeof(VLC_BITMAPINFOHEADER) ) { uint64_t i_extrasize = p_chk->common.i_chunk_size - sizeof(VLC_BITMAPINFOHEADER); /* There's a color palette appended, set up VLC_BITMAPINFO */ memcpy( &p_chk->strf.vids.p_bih[1], p_buff + 8 + sizeof(VLC_BITMAPINFOHEADER), /* 8=fourrc+size */ i_extrasize ); if ( !p_chk->strf.vids.p_bih->biClrUsed ) p_chk->strf.vids.p_bih->biClrUsed = (1 << p_chk->strf.vids.p_bih->biBitCount); if( i_extrasize / sizeof(uint32_t) > UINT32_MAX ) p_chk->strf.vids.p_bih->biClrUsed = UINT32_MAX; else { p_chk->strf.vids.p_bih->biClrUsed = __MIN( i_extrasize / sizeof(uint32_t), p_chk->strf.vids.p_bih->biClrUsed ); } /* stay within VLC's limits */ p_chk->strf.vids.p_bih->biClrUsed = __MIN( VIDEO_PALETTE_COLORS_MAX, p_chk->strf.vids.p_bih->biClrUsed ); } else p_chk->strf.vids.p_bih->biClrUsed = 0; #ifdef AVI_DEBUG msg_Dbg( (vlc_object_t*)s, "strf: video:%4.4s %"PRIu32"x%"PRIu32" planes:%d %dbpp", (char*)&p_chk->strf.vids.p_bih->biCompression, (uint32_t)p_chk->strf.vids.p_bih->biWidth, (uint32_t)p_chk->strf.vids.p_bih->biHeight, p_chk->strf.vids.p_bih->biPlanes, p_chk->strf.vids.p_bih->biBitCount ); #endif break; case AVIFOURCC_iavs: case AVIFOURCC_ivas: p_chk->strf.common.i_cat = UNKNOWN_ES; break; case( AVIFOURCC_txts ): p_chk->strf.common.i_cat = SPU_ES; break; default: msg_Warn( (vlc_object_t*)s, "unknown stream type: %4.4s", (char*)&p_strh->strh.i_type ); p_chk->strf.common.i_cat = UNKNOWN_ES; break; } AVI_READCHUNK_EXIT( VLC_SUCCESS ); }