| 87 | | /********************************************************************/ |
|---|
| | 86 | |
|---|
| | 87 | /***************************************************************************** |
|---|
| | 88 | * Some usefull functions to manipulate memory |
|---|
| | 89 | *****************************************************************************/ |
|---|
| | 90 | static u16 GetWLE( byte_t *p_buff ) |
|---|
| | 91 | { |
|---|
| | 92 | u16 i; |
|---|
| | 93 | i = (*p_buff) + ( *(p_buff + 1) <<8 ); |
|---|
| | 94 | return ( i ); |
|---|
| | 95 | } |
|---|
| | 96 | static u32 GetDWLE( byte_t *p_buff ) |
|---|
| | 97 | { |
|---|
| | 98 | u32 i; |
|---|
| | 99 | i = (*p_buff) + ( *(p_buff + 1) <<8 ) + |
|---|
| | 100 | ( *(p_buff + 2) <<16 ) + ( *(p_buff + 3) <<24 ); |
|---|
| | 101 | return ( i ); |
|---|
| | 102 | } |
|---|
| | 103 | static inline off_t __EVEN( off_t i ) |
|---|
| | 104 | { |
|---|
| | 105 | return( (i & 1) ? i+1 : i ); |
|---|
| | 106 | } |
|---|
| | 107 | |
|---|
| | 108 | |
|---|
| | 109 | /***************************************************************************** |
|---|
| | 110 | * Functions for parsing the headers in an avi file |
|---|
| | 111 | *****************************************************************************/ |
|---|
| | 112 | static void AVI_Parse_avih( MainAVIHeader_t *p_avih, byte_t *p_buff ) |
|---|
| | 113 | { |
|---|
| | 114 | p_avih->i_microsecperframe = GetDWLE( p_buff ); |
|---|
| | 115 | p_avih->i_maxbytespersec = GetDWLE( p_buff + 4); |
|---|
| | 116 | p_avih->i_reserved1 = GetDWLE( p_buff + 8); |
|---|
| | 117 | p_avih->i_flags = GetDWLE( p_buff + 12); |
|---|
| | 118 | p_avih->i_totalframes = GetDWLE( p_buff + 16); |
|---|
| | 119 | p_avih->i_initialframes = GetDWLE( p_buff + 20); |
|---|
| | 120 | p_avih->i_streams = GetDWLE( p_buff + 24); |
|---|
| | 121 | p_avih->i_suggestedbuffersize = GetDWLE( p_buff + 28); |
|---|
| | 122 | p_avih->i_width = GetDWLE( p_buff + 32 ); |
|---|
| | 123 | p_avih->i_height = GetDWLE( p_buff + 36 ); |
|---|
| | 124 | p_avih->i_scale = GetDWLE( p_buff + 40 ); |
|---|
| | 125 | p_avih->i_rate = GetDWLE( p_buff + 44 ); |
|---|
| | 126 | p_avih->i_start = GetDWLE( p_buff + 48); |
|---|
| | 127 | p_avih->i_length = GetDWLE( p_buff + 52); |
|---|
| | 128 | } |
|---|
| | 129 | static void AVI_Parse_Header( AVIStreamHeader_t *p_strh, byte_t *p_buff ) |
|---|
| | 130 | { |
|---|
| | 131 | p_strh->i_type = GetDWLE( p_buff ); |
|---|
| | 132 | p_strh->i_handler = GetDWLE( p_buff + 4 ); |
|---|
| | 133 | p_strh->i_flags = GetDWLE( p_buff + 8 ); |
|---|
| | 134 | p_strh->i_reserved1 = GetDWLE( p_buff + 12); |
|---|
| | 135 | p_strh->i_initialframes = GetDWLE( p_buff + 16); |
|---|
| | 136 | p_strh->i_scale = GetDWLE( p_buff + 20); |
|---|
| | 137 | p_strh->i_rate = GetDWLE( p_buff + 24); |
|---|
| | 138 | p_strh->i_start = GetDWLE( p_buff + 28); |
|---|
| | 139 | p_strh->i_length = GetDWLE( p_buff + 32); |
|---|
| | 140 | p_strh->i_suggestedbuffersize = GetDWLE( p_buff + 36); |
|---|
| | 141 | p_strh->i_quality = GetDWLE( p_buff + 40); |
|---|
| | 142 | p_strh->i_samplesize = GetDWLE( p_buff + 44); |
|---|
| | 143 | } |
|---|
| | 144 | static void AVI_Parse_BitMapInfoHeader( bitmapinfoheader_t *h, byte_t *p_data ) |
|---|
| | 145 | { |
|---|
| | 146 | h->i_size = GetDWLE( p_data ); |
|---|
| | 147 | h->i_width = GetDWLE( p_data + 4 ); |
|---|
| | 148 | h->i_height = GetDWLE( p_data + 8 ); |
|---|
| | 149 | h->i_planes = GetWLE( p_data + 12 ); |
|---|
| | 150 | h->i_bitcount = GetWLE( p_data + 14 ); |
|---|
| | 151 | h->i_compression = GetDWLE( p_data + 16 ); |
|---|
| | 152 | h->i_sizeimage = GetDWLE( p_data + 20 ); |
|---|
| | 153 | h->i_xpelspermeter = GetDWLE( p_data + 24 ); |
|---|
| | 154 | h->i_ypelspermeter = GetDWLE( p_data + 28 ); |
|---|
| | 155 | h->i_clrused = GetDWLE( p_data + 32 ); |
|---|
| | 156 | h->i_clrimportant = GetDWLE( p_data + 36 ); |
|---|
| | 157 | } |
|---|
| | 158 | static void AVI_Parse_WaveFormatEx( waveformatex_t *h, byte_t *p_data ) |
|---|
| | 159 | { |
|---|
| | 160 | h->i_formattag = GetWLE( p_data ); |
|---|
| | 161 | h->i_channels = GetWLE( p_data + 2 ); |
|---|
| | 162 | h->i_samplespersec = GetDWLE( p_data + 4 ); |
|---|
| | 163 | h->i_avgbytespersec= GetDWLE( p_data + 8 ); |
|---|
| | 164 | h->i_blockalign = GetWLE( p_data + 12 ); |
|---|
| | 165 | h->i_bitspersample = GetWLE( p_data + 14 ); |
|---|
| | 166 | h->i_size = GetWLE( p_data + 16 ); |
|---|
| | 167 | } |
|---|
| | 168 | |
|---|
| | 169 | |
|---|
| | 170 | |
|---|
| | 171 | static inline int __AVI_GetESTypeFromTwoCC( u16 i_type ) |
|---|
| | 172 | { |
|---|
| | 173 | switch( i_type ) |
|---|
| | 174 | { |
|---|
| | 175 | case( TWOCC_wb ): |
|---|
| | 176 | return( AUDIO_ES ); |
|---|
| | 177 | case( TWOCC_dc ): |
|---|
| | 178 | case( TWOCC_db ): |
|---|
| | 179 | return( VIDEO_ES ); |
|---|
| | 180 | } |
|---|
| | 181 | return( UNKNOWN_ES ); |
|---|
| | 182 | } |
|---|
| | 183 | |
|---|
| | 184 | static int AVI_AudioGetType( u32 i_type ) |
|---|
| | 185 | { |
|---|
| | 186 | switch( i_type ) |
|---|
| | 187 | { |
|---|
| | 188 | /* case( WAVE_FORMAT_PCM ): |
|---|
| | 189 | return( WAVE_AUDIO_ES ); */ |
|---|
| | 190 | case( WAVE_FORMAT_AC3 ): |
|---|
| | 191 | return( AC3_AUDIO_ES ); |
|---|
| | 192 | case( WAVE_FORMAT_MPEG): |
|---|
| | 193 | case( WAVE_FORMAT_MPEGLAYER3): |
|---|
| | 194 | return( MPEG2_AUDIO_ES ); /* 2 for mpeg-2 layer 1 2 ou 3 */ |
|---|
| | 195 | default: |
|---|
| | 196 | return( 0 ); |
|---|
| | 197 | } |
|---|
| | 198 | } |
|---|
| | 199 | static int AVI_VideoGetType( u32 i_type ) |
|---|
| | 200 | { |
|---|
| | 201 | switch( i_type ) |
|---|
| | 202 | { |
|---|
| | 203 | case( FOURCC_DIV1 ): /* FIXME it is for msmpeg4v1 or old mpeg4 ?? */ |
|---|
| | 204 | case( FOURCC_div1 ): |
|---|
| | 205 | case( FOURCC_MPG4 ): |
|---|
| | 206 | case( FOURCC_mpg4 ): |
|---|
| | 207 | return( MSMPEG4v1_VIDEO_ES ); |
|---|
| | 208 | |
|---|
| | 209 | case( FOURCC_DIV2 ): |
|---|
| | 210 | case( FOURCC_div2 ): |
|---|
| | 211 | case( FOURCC_MP42 ): |
|---|
| | 212 | case( FOURCC_mp42 ): |
|---|
| | 213 | return( MSMPEG4v2_VIDEO_ES ); |
|---|
| | 214 | |
|---|
| | 215 | case( FOURCC_MPG3 ): |
|---|
| | 216 | case( FOURCC_mpg3 ): |
|---|
| | 217 | case( FOURCC_div3 ): |
|---|
| | 218 | case( FOURCC_MP43 ): |
|---|
| | 219 | case( FOURCC_mp43 ): |
|---|
| | 220 | case( FOURCC_DIV3 ): |
|---|
| | 221 | case( FOURCC_DIV4 ): |
|---|
| | 222 | case( FOURCC_div4 ): |
|---|
| | 223 | case( FOURCC_DIV5 ): |
|---|
| | 224 | case( FOURCC_div5 ): |
|---|
| | 225 | case( FOURCC_DIV6 ): |
|---|
| | 226 | case( FOURCC_div6 ): |
|---|
| | 227 | case( FOURCC_AP41 ): |
|---|
| | 228 | case( FOURCC_3IV1 ): |
|---|
| | 229 | return( MSMPEG4v3_VIDEO_ES ); |
|---|
| | 230 | |
|---|
| | 231 | |
|---|
| | 232 | case( FOURCC_DIVX ): |
|---|
| | 233 | case( FOURCC_divx ): |
|---|
| | 234 | case( FOURCC_MP4S ): |
|---|
| | 235 | case( FOURCC_mp4s ): |
|---|
| | 236 | case( FOURCC_M4S2 ): |
|---|
| | 237 | case( FOURCC_m4s2 ): |
|---|
| | 238 | case( FOURCC_xvid ): |
|---|
| | 239 | case( FOURCC_XVID ): |
|---|
| | 240 | case( FOURCC_XviD ): |
|---|
| | 241 | case( FOURCC_DX50 ): |
|---|
| | 242 | case( FOURCC_mp4v ): |
|---|
| | 243 | case( FOURCC_4 ): |
|---|
| | 244 | return( MPEG4_VIDEO_ES ); |
|---|
| | 245 | |
|---|
| | 246 | default: |
|---|
| | 247 | return( 0 ); |
|---|
| | 248 | } |
|---|
| | 249 | } |
|---|
| | 250 | /***************************************************************************** |
|---|
| | 251 | * Data and functions to manipulate pes buffer |
|---|
| | 252 | *****************************************************************************/ |
|---|
| | 253 | #define BUFFER_MAXTOTALSIZE 512*1024 /* 1/2 Mo */ |
|---|
| | 254 | #define BUFFER_MAXSPESSIZE 1024*200 |
|---|
| | 255 | static void AVI_PESBuffer_Add( input_buffers_t *p_method_data, |
|---|
| | 256 | AVIStreamInfo_t *p_info, |
|---|
| | 257 | pes_packet_t *p_pes, |
|---|
| | 258 | int i_posc, |
|---|
| | 259 | int i_posb ) |
|---|
| | 260 | { |
|---|
| | 261 | AVIESBuffer_t *p_buffer_pes; |
|---|
| | 262 | |
|---|
| | 263 | if( p_info->i_pes_totalsize > BUFFER_MAXTOTALSIZE ) |
|---|
| | 264 | { |
|---|
| | 265 | input_DeletePES( p_method_data, p_pes ); |
|---|
| | 266 | return; |
|---|
| | 267 | } |
|---|
| | 268 | |
|---|
| | 269 | if( !( p_buffer_pes = malloc( sizeof( AVIESBuffer_t ) ) ) ) |
|---|
| | 270 | { |
|---|
| | 271 | input_DeletePES( p_method_data, p_pes ); |
|---|
| | 272 | return; |
|---|
| | 273 | } |
|---|
| | 274 | p_buffer_pes->p_next = NULL; |
|---|
| | 275 | p_buffer_pes->p_pes = p_pes; |
|---|
| | 276 | p_buffer_pes->i_posc = i_posc; |
|---|
| | 277 | p_buffer_pes->i_posb = i_posb; |
|---|
| | 278 | |
|---|
| | 279 | if( p_info->p_pes_last ) |
|---|
| | 280 | { |
|---|
| | 281 | p_info->p_pes_last->p_next = p_buffer_pes; |
|---|
| | 282 | } |
|---|
| | 283 | p_info->p_pes_last = p_buffer_pes; |
|---|
| | 284 | if( !p_info->p_pes_first ) |
|---|
| | 285 | { |
|---|
| | 286 | p_info->p_pes_first = p_buffer_pes; |
|---|
| | 287 | } |
|---|
| | 288 | p_info->i_pes_count++; |
|---|
| | 289 | p_info->i_pes_totalsize += p_pes->i_pes_size; |
|---|
| | 290 | } |
|---|
| | 291 | static pes_packet_t *AVI_PESBuffer_Get( AVIStreamInfo_t *p_info ) |
|---|
| | 292 | { |
|---|
| | 293 | AVIESBuffer_t *p_buffer_pes; |
|---|
| | 294 | pes_packet_t *p_pes; |
|---|
| | 295 | if( p_info->p_pes_first ) |
|---|
| | 296 | { |
|---|
| | 297 | p_buffer_pes = p_info->p_pes_first; |
|---|
| | 298 | p_info->p_pes_first = p_buffer_pes->p_next; |
|---|
| | 299 | if( !p_info->p_pes_first ) |
|---|
| | 300 | { |
|---|
| | 301 | p_info->p_pes_last = NULL; |
|---|
| | 302 | } |
|---|
| | 303 | p_pes = p_buffer_pes->p_pes; |
|---|
| | 304 | |
|---|
| | 305 | free( p_buffer_pes ); |
|---|
| | 306 | p_info->i_pes_count--; |
|---|
| | 307 | p_info->i_pes_totalsize -= p_pes->i_pes_size; |
|---|
| | 308 | return( p_pes ); |
|---|
| | 309 | } |
|---|
| | 310 | else |
|---|
| | 311 | { |
|---|
| | 312 | return( NULL ); |
|---|
| | 313 | } |
|---|
| | 314 | } |
|---|
| | 315 | static int AVI_PESBuffer_Drop( input_buffers_t *p_method_data, |
|---|
| | 316 | AVIStreamInfo_t *p_info ) |
|---|
| | 317 | { |
|---|
| | 318 | pes_packet_t *p_pes = AVI_PESBuffer_Get( p_info ); |
|---|
| | 319 | if( p_pes ) |
|---|
| | 320 | { |
|---|
| | 321 | input_DeletePES( p_method_data, p_pes ); |
|---|
| | 322 | return( 1 ); |
|---|
| | 323 | } |
|---|
| | 324 | else |
|---|
| | 325 | { |
|---|
| | 326 | return( 0 ); |
|---|
| | 327 | } |
|---|
| | 328 | } |
|---|
| | 329 | static void AVI_PESBuffer_Flush( input_buffers_t *p_method_data, |
|---|
| | 330 | AVIStreamInfo_t *p_info ) |
|---|
| | 331 | { |
|---|
| | 332 | while( p_info->p_pes_first ) |
|---|
| | 333 | { |
|---|
| | 334 | AVI_PESBuffer_Drop( p_method_data, p_info ); |
|---|
| | 335 | } |
|---|
| | 336 | } |
|---|
| | 337 | |
|---|
| | 338 | |
|---|
| | 339 | |
|---|
| | 340 | |
|---|
| | 341 | |
|---|
| | 342 | |
|---|
| | 343 | |
|---|
| 121 | | static void __AVI_Parse_avih( MainAVIHeader_t *p_avih, byte_t *p_buff ) |
|---|
| 122 | | { |
|---|
| 123 | | p_avih->i_microsecperframe = __GetDoubleWordLittleEndianFromBuff( p_buff ); |
|---|
| 124 | | p_avih->i_maxbytespersec = __GetDoubleWordLittleEndianFromBuff( p_buff + 4); |
|---|
| 125 | | p_avih->i_reserved1 = __GetDoubleWordLittleEndianFromBuff( p_buff + 8); |
|---|
| 126 | | p_avih->i_flags = __GetDoubleWordLittleEndianFromBuff( p_buff + 12); |
|---|
| 127 | | p_avih->i_totalframes = __GetDoubleWordLittleEndianFromBuff( p_buff + 16); |
|---|
| 128 | | p_avih->i_initialframes = __GetDoubleWordLittleEndianFromBuff( p_buff + 20); |
|---|
| 129 | | p_avih->i_streams = __GetDoubleWordLittleEndianFromBuff( p_buff + 24); |
|---|
| 130 | | p_avih->i_suggestedbuffersize = |
|---|
| 131 | | __GetDoubleWordLittleEndianFromBuff( p_buff + 28); |
|---|
| 132 | | p_avih->i_width = __GetDoubleWordLittleEndianFromBuff( p_buff + 32 ); |
|---|
| 133 | | p_avih->i_height = __GetDoubleWordLittleEndianFromBuff( p_buff + 36 ); |
|---|
| 134 | | p_avih->i_scale = __GetDoubleWordLittleEndianFromBuff( p_buff + 40 ); |
|---|
| 135 | | p_avih->i_rate = __GetDoubleWordLittleEndianFromBuff( p_buff + 44 ); |
|---|
| 136 | | p_avih->i_start = __GetDoubleWordLittleEndianFromBuff( p_buff + 48); |
|---|
| 137 | | p_avih->i_length = __GetDoubleWordLittleEndianFromBuff( p_buff + 52); |
|---|
| 138 | | } |
|---|
| 139 | | |
|---|
| 140 | | static void __AVI_Parse_Header( AVIStreamHeader_t *p_strh, byte_t *p_buff ) |
|---|
| 141 | | { |
|---|
| 142 | | p_strh->i_type = __GetDoubleWordLittleEndianFromBuff( p_buff ); |
|---|
| 143 | | p_strh->i_handler = __GetDoubleWordLittleEndianFromBuff( p_buff + 4 ); |
|---|
| 144 | | p_strh->i_flags = __GetDoubleWordLittleEndianFromBuff( p_buff + 8 ); |
|---|
| 145 | | p_strh->i_reserved1 = __GetDoubleWordLittleEndianFromBuff( p_buff + 12); |
|---|
| 146 | | p_strh->i_initialframes = __GetDoubleWordLittleEndianFromBuff( p_buff + 16); |
|---|
| 147 | | p_strh->i_scale = __GetDoubleWordLittleEndianFromBuff( p_buff + 20); |
|---|
| 148 | | p_strh->i_rate = __GetDoubleWordLittleEndianFromBuff( p_buff + 24); |
|---|
| 149 | | p_strh->i_start = __GetDoubleWordLittleEndianFromBuff( p_buff + 28); |
|---|
| 150 | | p_strh->i_length = __GetDoubleWordLittleEndianFromBuff( p_buff + 32); |
|---|
| 151 | | p_strh->i_suggestedbuffersize = |
|---|
| 152 | | __GetDoubleWordLittleEndianFromBuff( p_buff + 36); |
|---|
| 153 | | p_strh->i_quality = __GetDoubleWordLittleEndianFromBuff( p_buff + 40); |
|---|
| 154 | | p_strh->i_samplesize = __GetDoubleWordLittleEndianFromBuff( p_buff + 44); |
|---|
| 155 | | } |
|---|
| 156 | | |
|---|
| 157 | | int avi_ParseBitMapInfoHeader( bitmapinfoheader_t *h, byte_t *p_data ) |
|---|
| 158 | | { |
|---|
| 159 | | h->i_size = __GetDoubleWordLittleEndianFromBuff( p_data ); |
|---|
| 160 | | h->i_width = __GetDoubleWordLittleEndianFromBuff( p_data + 4 ); |
|---|
| 161 | | h->i_height = __GetDoubleWordLittleEndianFromBuff( p_data + 8 ); |
|---|
| 162 | | h->i_planes = __GetWordLittleEndianFromBuff( p_data + 12 ); |
|---|
| 163 | | h->i_bitcount = __GetWordLittleEndianFromBuff( p_data + 14 ); |
|---|
| 164 | | h->i_compression = __GetDoubleWordLittleEndianFromBuff( p_data + 16 ); |
|---|
| 165 | | h->i_sizeimage = __GetDoubleWordLittleEndianFromBuff( p_data + 20 ); |
|---|
| 166 | | h->i_xpelspermeter = __GetDoubleWordLittleEndianFromBuff( p_data + 24 ); |
|---|
| 167 | | h->i_ypelspermeter = __GetDoubleWordLittleEndianFromBuff( p_data + 28 ); |
|---|
| 168 | | h->i_clrused = __GetDoubleWordLittleEndianFromBuff( p_data + 32 ); |
|---|
| 169 | | h->i_clrimportant = __GetDoubleWordLittleEndianFromBuff( p_data + 36 ); |
|---|
| 170 | | return( 0 ); |
|---|
| 171 | | } |
|---|
| 172 | | |
|---|
| 173 | | int avi_ParseWaveFormatEx( waveformatex_t *h, byte_t *p_data ) |
|---|
| 174 | | { |
|---|
| 175 | | h->i_formattag = __GetWordLittleEndianFromBuff( p_data ); |
|---|
| 176 | | h->i_channels = __GetWordLittleEndianFromBuff( p_data + 2 ); |
|---|
| 177 | | h->i_samplespersec = __GetDoubleWordLittleEndianFromBuff( p_data + 4 ); |
|---|
| 178 | | h->i_avgbytespersec= __GetDoubleWordLittleEndianFromBuff( p_data + 8 ); |
|---|
| 179 | | h->i_blockalign = __GetWordLittleEndianFromBuff( p_data + 12 ); |
|---|
| 180 | | h->i_bitspersample = __GetWordLittleEndianFromBuff( p_data + 14 ); |
|---|
| 181 | | h->i_size = __GetWordLittleEndianFromBuff( p_data + 16 ); |
|---|
| 182 | | return( 0 ); |
|---|
| 183 | | } |
|---|
| 184 | | |
|---|
| 185 | | static inline int __AVIGetESTypeFromTwoCC( u16 i_type ) |
|---|
| 186 | | { |
|---|
| 187 | | switch( i_type ) |
|---|
| 188 | | { |
|---|
| 189 | | case( TWOCC_wb ): |
|---|
| 190 | | return( AUDIO_ES ); |
|---|
| 191 | | case( TWOCC_dc ): |
|---|
| 192 | | case( TWOCC_db ): |
|---|
| 193 | | return( VIDEO_ES ); |
|---|
| 194 | | } |
|---|
| 195 | | return( UNKNOWN_ES ); |
|---|
| 196 | | } |
|---|
| 197 | | |
|---|
| 198 | | |
|---|
| 199 | | static int __AVI_ParseStreamHeader( u32 i_id, int *i_number, u16 *i_type ) |
|---|
| | 378 | static void AVI_ParseStreamHeader( u32 i_id, int *i_number, int *i_type ) |
|---|
| 680 | | |
|---|
| 681 | | /* we verify that each stream have at least one entry or create it */ |
|---|
| 682 | | for( i = 0; i < p_avi_demux->i_streams ; i++ ) |
|---|
| 683 | | { |
|---|
| 684 | | AVIIndexEntry_t index; |
|---|
| 685 | | riffchunk_t *p_chunk; |
|---|
| 686 | | #define p_info p_avi_demux->pp_info[i] |
|---|
| 687 | | if( p_info->p_index == NULL ) |
|---|
| 688 | | { |
|---|
| 689 | | RIFF_GoToChunk( p_input, p_avi_demux->p_movi ); |
|---|
| 690 | | if( RIFF_DescendChunk(p_input) != 0 ) { continue; } |
|---|
| 691 | | p_chunk = NULL; |
|---|
| 692 | | switch( p_info->i_cat ) |
|---|
| 693 | | { |
|---|
| 694 | | case( AUDIO_ES ): |
|---|
| 695 | | if( RIFF_FindChunk( p_input, |
|---|
| 696 | | VLC_FOURCC('0'+i/10, '0'+i%10,'w','b' ), |
|---|
| 697 | | p_movi ) == 0) |
|---|
| 698 | | { |
|---|
| 699 | | p_chunk = RIFF_ReadChunk( p_input ); |
|---|
| 700 | | } |
|---|
| 701 | | break; |
|---|
| 702 | | |
|---|
| 703 | | case( VIDEO_ES ): |
|---|
| 704 | | if( (RIFF_FindChunk( p_input, |
|---|
| 705 | | VLC_FOURCC('0'+i/10, '0'+i%10,'d','c' ), |
|---|
| 706 | | p_movi ) == 0) ) |
|---|
| 707 | | { |
|---|
| 708 | | p_chunk = RIFF_ReadChunk( p_input ); |
|---|
| 709 | | } |
|---|
| 710 | | else |
|---|
| 711 | | { |
|---|
| 712 | | RIFF_GoToChunk( p_input, p_avi_demux->p_movi ); |
|---|
| 713 | | if( RIFF_DescendChunk(p_input) != 0 ) { continue; } |
|---|
| 714 | | if( (RIFF_FindChunk( p_input, |
|---|
| 715 | | VLC_FOURCC('0'+i/10, '0'+i%10,'d','b' ), |
|---|
| 716 | | p_movi ) == 0) ) |
|---|
| 717 | | { |
|---|
| 718 | | p_chunk = RIFF_ReadChunk( p_input ); |
|---|
| 719 | | } |
|---|
| 720 | | } |
|---|
| 721 | | break; |
|---|
| 722 | | } |
|---|
| 723 | | if( p_chunk != NULL ) |
|---|
| 724 | | { |
|---|
| 725 | | index.i_id = p_chunk->i_id; |
|---|
| 726 | | index.i_flags = AVIIF_KEYFRAME; |
|---|
| 727 | | index.i_pos = p_chunk->i_pos; |
|---|
| 728 | | index.i_length = p_chunk->i_size; |
|---|
| 729 | | __AVI_AddEntryIndex( p_info, &index ); |
|---|
| 730 | | msg_Dbg( p_input, "add index entry (%4.4s) (%d)", |
|---|
| 731 | | (char*)&p_chunk->i_id, i ); |
|---|
| 732 | | |
|---|
| 733 | | } |
|---|
| 734 | | } |
|---|
| 735 | | #undef p_info |
|---|
| 736 | | } |
|---|
| 737 | | |
|---|
| 738 | | /* to make sure to go the begining because unless demux will see a seek */ |
|---|
| 739 | | RIFF_GoToChunk( p_input, p_avi_demux->p_movi ); |
|---|
| 740 | | if( RIFF_DescendChunk( p_input ) != 0 ) |
|---|
| 741 | | { |
|---|
| 742 | | __AVIFreeDemuxData( p_input ); |
|---|
| 743 | | msg_Err( p_input, "cannot go in (\"movi\")" ); |
|---|
| 744 | | return( -1 ); |
|---|
| 745 | | } |
|---|
| 858 | | |
|---|
| 859 | | static int __AVI_NextIndexEntry( input_thread_t *p_input, |
|---|
| 860 | | AVIStreamInfo_t *p_info ) |
|---|
| 861 | | { |
|---|
| 862 | | AVIIndexEntry_t index; |
|---|
| 863 | | riffchunk_t *p_chunk; |
|---|
| 864 | | AVIStreamInfo_t *p_info_tmp; |
|---|
| 865 | | int i; |
|---|
| 866 | | int i_idxposc; |
|---|
| 867 | | int b_inc = 0; |
|---|
| 868 | | demux_data_avi_file_t *p_avi_demux = |
|---|
| 869 | | (demux_data_avi_file_t*)p_input->p_demux_data; |
|---|
| 870 | | |
|---|
| 871 | | p_info->i_idxposc++; |
|---|
| 872 | | |
|---|
| 873 | | if( p_info->i_idxposc < p_info->i_idxnb ) |
|---|
| 874 | | { |
|---|
| 875 | | return( 0 ); |
|---|
| 876 | | } |
|---|
| 877 | | if( p_info->i_idxposc > p_info->i_idxnb ) |
|---|
| 878 | | { |
|---|
| 879 | | return( -1 ); |
|---|
| 880 | | } |
|---|
| 881 | | p_info->i_idxposc--; |
|---|
| 882 | | |
|---|
| 883 | | /* create entry on the fly */ |
|---|
| 884 | | /* search for the more advance stream and parse from it for all streams*/ |
|---|
| 885 | | p_info_tmp = p_info; |
|---|
| 886 | | for( i = 0; i < p_avi_demux->i_streams; i++ ) |
|---|
| 887 | | { |
|---|
| 888 | | #define p_info_i p_avi_demux->pp_info[i] |
|---|
| 889 | | if( ( p_info_i->p_index ) |
|---|
| 890 | | && ( p_info_i->p_index[p_info_i->i_idxnb - 1].i_pos > |
|---|
| 891 | | p_info_tmp->p_index[p_info_tmp->i_idxnb - 1].i_pos ) ) |
|---|
| 892 | | { |
|---|
| 893 | | p_info_tmp = p_info_i; |
|---|
| 894 | | } |
|---|
| 895 | | #undef p_info_i |
|---|
| 896 | | } |
|---|
| 897 | | |
|---|
| 898 | | /* go to last defined entry */ |
|---|
| 899 | | i_idxposc = p_info_tmp->i_idxposc; /* save p_info_tmp->i_idxposc */ |
|---|
| 900 | | p_info_tmp->i_idxposc = p_info_tmp->i_idxnb - 1; |
|---|
| 901 | | __AVI_SeekToChunk( p_input, p_info_tmp ); |
|---|
| 902 | | p_info_tmp->i_idxposc = i_idxposc; |
|---|
| 903 | | |
|---|
| 904 | | if( RIFF_NextChunk( p_input, p_avi_demux->p_movi ) != 0 ) |
|---|
| 905 | | { |
|---|
| 906 | | p_info->i_idxposc++; |
|---|
| 907 | | return( -1 ); |
|---|
| 908 | | } |
|---|
| 909 | | |
|---|
| 910 | | /* save idxpos of p_info */ |
|---|
| 911 | | /* now parse for all stream and stop when reach next chunk for p_info */ |
|---|
| 912 | | for( i = 0; (i < 15)||(!b_inc); i++) |
|---|
| 913 | | { |
|---|
| 914 | | int i_number; |
|---|
| 915 | | u16 i_type; |
|---|
| 916 | | if( (p_chunk = RIFF_ReadChunk( p_input )) == NULL ) |
|---|
| 917 | | { |
|---|
| 918 | | p_info->i_idxposc++; |
|---|
| 919 | | return( b_inc == 1 ? 0 : -1 ); |
|---|
| 920 | | } |
|---|
| 921 | | |
|---|
| 922 | | index.i_id = p_chunk->i_id; |
|---|
| 923 | | index.i_flags = AVIIF_KEYFRAME; |
|---|
| 924 | | index.i_pos = p_chunk->i_pos; |
|---|
| 925 | | index.i_length = p_chunk->i_size; |
|---|
| 926 | | RIFF_DeleteChunk( p_input, p_chunk ); |
|---|
| 927 | | #define p_info_i p_avi_demux->pp_info[i_number] |
|---|
| 928 | | if( (__AVI_ParseStreamHeader( index.i_id, &i_number, &i_type ) == 0) |
|---|
| 929 | | &&( i_number < p_avi_demux->i_streams ) |
|---|
| 930 | | &&( p_info_i->p_index ) |
|---|
| 931 | | &&( p_info_i->p_index[p_info_i->i_idxnb - 1].i_pos + |
|---|
| 932 | | p_info_i->p_index[p_info_i->i_idxnb - 1].i_length + 8<= |
|---|
| 933 | | index.i_pos ) |
|---|
| 934 | | &&( __AVIGetESTypeFromTwoCC( i_type ) == p_info_i->i_cat ) ) |
|---|
| 935 | | { |
|---|
| 936 | | __AVI_AddEntryIndex( p_info_i, &index ); |
|---|
| 937 | | if( (p_info_i == p_info)&&(!b_inc) ) |
|---|
| 938 | | { |
|---|
| 939 | | b_inc = 1; |
|---|
| 940 | | } |
|---|
| 941 | | } |
|---|
| 942 | | #undef p_info_i |
|---|
| 943 | | if( RIFF_NextChunk( p_input, p_avi_demux->p_movi ) != 0 ) |
|---|
| 944 | | { |
|---|
| 945 | | p_info->i_idxposc++; |
|---|
| 946 | | return( b_inc == 1 ? 0 : -1 ); |
|---|
| 947 | | } |
|---|
| 948 | | |
|---|
| 949 | | } |
|---|
| 950 | | |
|---|
| 951 | | p_info->i_idxposc++; |
|---|
| 952 | | return( 0 ); |
|---|
| 953 | | } |
|---|
| 954 | | |
|---|