1 /*****************************************************************************
2 * avi.c : AVI file Stream input module for vlc
3 *****************************************************************************
4 * Copyright (C) 2001 VideoLAN
5 * $Id: avi.c,v 1.6 2002/10/15 00:55:07 fenrir Exp $
6 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
21 *****************************************************************************/
23 /*****************************************************************************
25 *****************************************************************************/
26 #include <stdlib.h> /* malloc(), free() */
27 #include <string.h> /* strdup() */
29 #include <sys/types.h>
32 #include <vlc/input.h>
36 #include "libioRIFF.h"
40 /*****************************************************************************
42 *****************************************************************************/
43 static int AVIInit ( vlc_object_t * );
44 static void __AVIEnd ( vlc_object_t * );
45 static int AVISeek ( input_thread_t *, mtime_t, int );
46 static int AVIDemux_Seekable ( input_thread_t * );
47 static int AVIDemux_UnSeekable( input_thread_t *p_input );
49 #define AVIEnd(a) __AVIEnd(VLC_OBJECT(a))
51 /*****************************************************************************
53 *****************************************************************************/
55 add_category_hint( "demuxer", NULL );
56 add_bool( "avi-interleaved", 0, NULL,
57 "force interleaved method",
58 "force interleaved method" );
59 add_bool( "avi-index", 0, NULL,
60 "force index creation",
61 "force index creation" );
63 set_description( "avi demuxer" );
64 set_capability( "demux", 160 );
65 set_callbacks( AVIInit, __AVIEnd );
68 /*****************************************************************************
69 * Some usefull functions to manipulate memory
70 *****************************************************************************/
71 static int __AVI_GetDataInPES( input_thread_t *, pes_packet_t **, int, int );
73 static u16 GetWLE( byte_t *p_buff )
75 return( p_buff[0] + ( p_buff[1] << 8 ) );
77 static u32 GetDWLE( byte_t *p_buff )
79 return( p_buff[0] + ( p_buff[1] << 8 ) +
80 ( p_buff[2] << 16 ) + ( p_buff[3] << 24 ) );
82 static u32 GetDWBE( byte_t *p_buff )
84 return( p_buff[3] + ( p_buff[2] << 8 ) +
85 ( p_buff[1] << 16 ) + ( p_buff[0] << 24 ) );
87 static vlc_fourcc_t GetFOURCC( byte_t *p_buff )
89 return( VLC_FOURCC( p_buff[0], p_buff[1], p_buff[2], p_buff[3] ) );
92 static inline off_t __EVEN( off_t i )
94 return( (i & 1) ? i+1 : i );
97 #define __ABS( x ) ( (x) < 0 ? (-(x)) : (x) )
99 /* Test if it seems that it's a key frame */
100 static int AVI_GetKeyFlag( vlc_fourcc_t i_fourcc, u8 *p_byte )
106 startcode: 0x00000100 32bits
108 piture type 0(I),1(P) 2bits
110 if( GetDWBE( p_byte ) != 0x00000100 )
112 /* it's not an msmpegv1 stream, strange...*/
113 return( AVIIF_KEYFRAME );
117 return( p_byte[4]&0x06 ? 0 : AVIIF_KEYFRAME);
120 case FOURCC_DIV3: // wmv1 also
122 picture type 0(I),1(P) 2bits
124 return( p_byte[0]&0xC0 ? 0 : AVIIF_KEYFRAME );
126 /* we should find first occurence of 0x000001b6 (32bits)
127 startcode: 0x000001b6 32bits
128 piture type 0(I),1(P) 2bits
130 if( GetDWBE( p_byte ) != 0x000001b6 )
132 /* not true , need to find the first VOP header */
133 return( AVIIF_KEYFRAME );
137 return( p_byte[4]&0xC0 ? 0 : AVIIF_KEYFRAME );
140 /* I can't do it, so said yes */
141 return( AVIIF_KEYFRAME );
145 vlc_fourcc_t AVI_FourccGetCodec( int i_cat, vlc_fourcc_t i_codec )
152 case( WAVE_FORMAT_PCM ):
153 return( VLC_FOURCC( 'a', 'r', 'a', 'w' ) );
154 case( WAVE_FORMAT_MPEG ):
155 case( WAVE_FORMAT_MPEGLAYER3 ):
156 return( VLC_FOURCC( 'm', 'p', 'g', 'a' ) );
157 case( WAVE_FORMAT_A52 ):
158 return( VLC_FOURCC( 'a', '5', '2', ' ' ) );
159 case( WAVE_FORMAT_WMA1 ):
160 return( VLC_FOURCC( 'w', 'm', 'a', '1' ) );
161 case( WAVE_FORMAT_WMA2 ):
162 return( VLC_FOURCC( 'w', 'm', 'a', '2' ) );
164 return( VLC_FOURCC( 'm', 's',
165 ( i_codec >> 8 )&0xff,
169 // XXX DIV1 <- msmpeg4v1, DIV2 <- msmpeg4v2, DIV3 <- msmpeg4v3, mp4v for mpeg4
176 return( FOURCC_DIV1 );
183 return( FOURCC_DIV2 );
196 return( FOURCC_DIV3 );
209 return( FOURCC_mp4v );
212 return( VLC_FOURCC( 'u', 'n', 'd', 'f' ) );
215 /*****************************************************************************
216 * Data and functions to manipulate pes buffer
217 *****************************************************************************/
218 #define BUFFER_MAXTOTALSIZE 500*1024 /* 1/2 Mo */
219 #define BUFFER_MAXSPESSIZE 200*1024
220 static int AVI_PESBuffer_IsFull( AVIStreamInfo_t *p_info )
222 return( p_info->i_pes_totalsize > BUFFER_MAXTOTALSIZE ? 1 : 0);
224 static void AVI_PESBuffer_Add( input_buffers_t *p_method_data,
225 AVIStreamInfo_t *p_info,
230 AVIESBuffer_t *p_buffer_pes;
232 if( p_info->i_pes_totalsize > BUFFER_MAXTOTALSIZE )
234 input_DeletePES( p_method_data, p_pes );
238 if( !( p_buffer_pes = malloc( sizeof( AVIESBuffer_t ) ) ) )
240 input_DeletePES( p_method_data, p_pes );
243 p_buffer_pes->p_next = NULL;
244 p_buffer_pes->p_pes = p_pes;
245 p_buffer_pes->i_posc = i_posc;
246 p_buffer_pes->i_posb = i_posb;
248 if( p_info->p_pes_last )
250 p_info->p_pes_last->p_next = p_buffer_pes;
252 p_info->p_pes_last = p_buffer_pes;
253 if( !p_info->p_pes_first )
255 p_info->p_pes_first = p_buffer_pes;
257 p_info->i_pes_count++;
258 p_info->i_pes_totalsize += p_pes->i_pes_size;
260 static pes_packet_t *AVI_PESBuffer_Get( AVIStreamInfo_t *p_info )
262 AVIESBuffer_t *p_buffer_pes;
264 if( p_info->p_pes_first )
266 p_buffer_pes = p_info->p_pes_first;
267 p_info->p_pes_first = p_buffer_pes->p_next;
268 if( !p_info->p_pes_first )
270 p_info->p_pes_last = NULL;
272 p_pes = p_buffer_pes->p_pes;
274 free( p_buffer_pes );
275 p_info->i_pes_count--;
276 p_info->i_pes_totalsize -= p_pes->i_pes_size;
284 static int AVI_PESBuffer_Drop( input_buffers_t *p_method_data,
285 AVIStreamInfo_t *p_info )
287 pes_packet_t *p_pes = AVI_PESBuffer_Get( p_info );
290 input_DeletePES( p_method_data, p_pes );
298 static void AVI_PESBuffer_Flush( input_buffers_t *p_method_data,
299 AVIStreamInfo_t *p_info )
301 while( p_info->p_pes_first )
303 AVI_PESBuffer_Drop( p_method_data, p_info );
307 static void AVI_ParseStreamHeader( u32 i_id, int *pi_number, int *pi_type )
309 #define SET_PTR( p, v ) if( p ) *(p) = (v);
311 /* XXX i_id have to be read using MKFOURCC and NOT VLC_FOURCC */
312 c1 = ( i_id ) & 0xFF;
313 c2 = ( i_id >> 8 ) & 0xFF;
315 if( c1 < '0' || c1 > '9' || c2 < '0' || c2 > '9' )
317 SET_PTR( pi_number, 100); /* > max stream number */
318 SET_PTR( pi_type, UNKNOWN_ES);
322 SET_PTR( pi_number, (c1 - '0') * 10 + (c2 - '0' ) );
323 switch( ( i_id >> 16 ) & 0xFFFF )
326 SET_PTR( pi_type, AUDIO_ES );
330 SET_PTR( pi_type, VIDEO_ES);
333 SET_PTR( pi_type, UNKNOWN_ES );
340 typedef struct avi_packet_s
345 u32 i_type; // only for AVIFOURCC_LIST
346 u8 i_peek[8]; //first 8 bytes
352 static int AVI_PacketGetHeader( input_thread_t *p_input, avi_packet_t *p_pk )
356 if( input_Peek( p_input, &p_peek, 16 ) < 16 )
360 p_pk->i_fourcc = GetDWLE( p_peek );
361 p_pk->i_size = GetDWLE( p_peek + 4 );
362 p_pk->i_pos = AVI_TellAbsolute( p_input );
363 if( p_pk->i_fourcc == AVIFOURCC_LIST )
365 p_pk->i_type = GetDWLE( p_peek + 8 );
372 memcpy( p_pk->i_peek, p_peek + 8, 8 );
374 AVI_ParseStreamHeader( p_pk->i_fourcc, &p_pk->i_stream, &p_pk->i_cat );
378 static int AVI_PacketNext( input_thread_t *p_input )
382 if( !AVI_PacketGetHeader( p_input, &avi_ck ) )
386 if( avi_ck.i_fourcc == AVIFOURCC_LIST && avi_ck.i_type == AVIFOURCC_rec )
388 return( AVI_SkipBytes( p_input, 12 ) );
392 return( AVI_SkipBytes( p_input, __EVEN( avi_ck.i_size ) + 8 ));
395 static int AVI_PacketRead( input_thread_t *p_input,
397 pes_packet_t **pp_pes )
400 if( __AVI_GetDataInPES( p_input, pp_pes, p_pk->i_size + 8, 1)
405 (*pp_pes)->p_first->p_payload_start += 8;
406 (*pp_pes)->i_pes_size -= 8;
410 static int AVI_PacketSearch( input_thread_t *p_input )
412 demux_sys_t *p_avi = p_input->p_demux_data;
417 if( !AVI_SkipBytes( p_input, 1 ) )
421 AVI_PacketGetHeader( p_input, &avi_pk );
422 if( avi_pk.i_stream < p_avi->i_streams &&
423 ( avi_pk.i_cat == AUDIO_ES || avi_pk.i_cat == VIDEO_ES ) )
427 switch( avi_pk.i_fourcc )
438 static void __AVI_AddEntryIndex( AVIStreamInfo_t *p_info,
439 AVIIndexEntry_t *p_index)
441 if( p_info->p_index == NULL )
443 p_info->i_idxmax = 16384;
445 if( !( p_info->p_index = calloc( p_info->i_idxmax,
446 sizeof( AVIIndexEntry_t ) ) ) )
451 if( p_info->i_idxnb >= p_info->i_idxmax )
453 p_info->i_idxmax += 16384;
454 if( !( p_info->p_index = realloc( (void*)p_info->p_index,
456 sizeof( AVIIndexEntry_t ) ) ) )
461 /* calculate cumulate length */
462 if( p_info->i_idxnb > 0 )
464 p_index->i_lengthtotal =
465 p_info->p_index[p_info->i_idxnb - 1].i_length +
466 p_info->p_index[p_info->i_idxnb - 1].i_lengthtotal;
470 p_index->i_lengthtotal = 0;
473 p_info->p_index[p_info->i_idxnb] = *p_index;
477 static void AVI_IndexLoad( input_thread_t *p_input )
479 demux_sys_t *p_avi = p_input->p_demux_data;
481 avi_chunk_list_t *p_riff;
482 avi_chunk_list_t *p_movi;
483 avi_chunk_idx1_t *p_idx1;
489 p_riff = (avi_chunk_list_t*)AVI_ChunkFind( &p_avi->ck_root,
492 p_idx1 = (avi_chunk_idx1_t*)AVI_ChunkFind( p_riff, AVIFOURCC_idx1, 0);
493 p_movi = (avi_chunk_list_t*)AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0);
497 msg_Warn( p_input, "cannot find idx1 chunk, no index defined" );
500 for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
502 p_avi->pp_info[i_stream]->i_idxnb = 0;
503 p_avi->pp_info[i_stream]->i_idxmax = 0;
504 p_avi->pp_info[i_stream]->p_index = NULL;
506 /* *** calculate offset *** */
507 if( p_idx1->i_entry_count > 0 &&
508 p_idx1->entry[0].i_pos < p_movi->i_chunk_pos )
510 i_offset = p_movi->i_chunk_pos + 8;
517 for( i_index = 0; i_index < p_idx1->i_entry_count; i_index++ )
521 AVI_ParseStreamHeader( p_idx1->entry[i_index].i_fourcc,
524 if( i_stream < p_avi->i_streams &&
525 i_cat == p_avi->pp_info[i_stream]->i_cat )
527 AVIIndexEntry_t index;
528 index.i_id = p_idx1->entry[i_index].i_fourcc;
529 index.i_flags = p_idx1->entry[i_index].i_flags&(~AVIIF_FIXKEYFRAME);
530 index.i_pos = p_idx1->entry[i_index].i_pos + i_offset;
531 index.i_length = p_idx1->entry[i_index].i_length;
532 __AVI_AddEntryIndex( p_avi->pp_info[i_stream],
536 for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
539 "stream[%d] creating %d index entries",
541 p_avi->pp_info[i_stream]->i_idxnb );
546 static void AVI_IndexCreate( input_thread_t *p_input )
548 demux_sys_t *p_avi = p_input->p_demux_data;
550 avi_chunk_list_t *p_riff;
551 avi_chunk_list_t *p_movi;
556 p_riff = (avi_chunk_list_t*)AVI_ChunkFind( &p_avi->ck_root,
558 p_movi = (avi_chunk_list_t*)AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0);
562 msg_Err( p_input, "cannot find p_movi" );
566 for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
568 p_avi->pp_info[i_stream]->i_idxnb = 0;
569 p_avi->pp_info[i_stream]->i_idxmax = 0;
570 p_avi->pp_info[i_stream]->p_index = NULL;
572 i_movi_end = __MIN( p_movi->i_chunk_pos + p_movi->i_chunk_size,
573 p_input->stream.p_selected_area->i_size );
575 AVI_SeekAbsolute( p_input, p_movi->i_chunk_pos + 12);
576 msg_Warn( p_input, "creating index from LIST-movi, will take time !" );
581 if( !AVI_PacketGetHeader( p_input, &pk ) )
585 if( pk.i_stream < p_avi->i_streams &&
586 pk.i_cat == p_avi->pp_info[pk.i_stream]->i_cat )
588 AVIIndexEntry_t index;
589 index.i_id = pk.i_fourcc;
591 AVI_GetKeyFlag(p_avi->pp_info[pk.i_stream]->i_codec, pk.i_peek);
592 index.i_pos = pk.i_pos;
593 index.i_length = pk.i_size;
594 __AVI_AddEntryIndex( p_avi->pp_info[pk.i_stream],
599 switch( pk.i_fourcc )
607 msg_Warn( p_input, "need resync, probably broken avi" );
608 if( !AVI_PacketSearch( p_input ) )
610 msg_Warn( p_input, "lost sync, abord index creation" );
615 if( pk.i_pos + pk.i_size >= i_movi_end ||
616 !AVI_PacketNext( p_input ) )
623 for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
626 "stream[%d] creating %d index entries",
628 p_avi->pp_info[i_stream]->i_idxnb );
633 /*****************************************************************************
635 *****************************************************************************/
636 static int AVI_StreamStart ( input_thread_t *, demux_sys_t *, int );
637 static int AVI_StreamSeek ( input_thread_t *, demux_sys_t *, int, mtime_t );
638 static void AVI_StreamStop ( input_thread_t *, demux_sys_t *, int );
640 static int AVI_StreamStart( input_thread_t *p_input,
641 demux_sys_t *p_avi, int i_stream )
643 #define p_stream p_avi->pp_info[i_stream]
644 if( !p_stream->p_es )
646 msg_Warn( p_input, "stream[%d] unselectable", i_stream );
649 if( p_stream->i_activated )
651 msg_Warn( p_input, "stream[%d] already selected", i_stream );
655 if( !p_stream->p_es->p_decoder_fifo )
657 vlc_mutex_lock( &p_input->stream.stream_lock );
658 input_SelectES( p_input, p_stream->p_es );
659 vlc_mutex_unlock( &p_input->stream.stream_lock );
661 p_stream->i_activated = p_stream->p_es->p_decoder_fifo ? 1 : 0;
663 AVI_StreamSeek( p_input, p_avi, i_stream, p_avi->i_time );
665 return( p_stream->i_activated );
669 static void AVI_StreamStop( input_thread_t *p_input,
670 demux_sys_t *p_avi, int i_stream )
672 #define p_stream p_avi->pp_info[i_stream]
674 if( !p_stream->i_activated )
676 msg_Warn( p_input, "stream[%d] already unselected", i_stream );
680 // AVI_PESBuffer_Flush( p_input->p_method_data, p_stream );
682 if( p_stream->p_es->p_decoder_fifo )
684 vlc_mutex_lock( &p_input->stream.stream_lock );
685 input_UnselectES( p_input, p_stream->p_es );
686 vlc_mutex_unlock( &p_input->stream.stream_lock );
690 p_stream->i_activated = 0;
695 /****************************************************************************
696 * AVI_MovieGetLength give max streams length in second
697 ****************************************************************************/
698 static mtime_t AVI_MovieGetLength( input_thread_t *p_input, demux_sys_t *p_avi )
704 for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
706 #define p_stream p_avi->pp_info[i_stream]
708 /* fix length for each stream */
709 if( p_stream->i_idxnb < 1 || !p_stream->p_index )
714 if( p_stream->i_samplesize )
717 (mtime_t)( p_stream->p_index[p_stream->i_idxnb-1].i_lengthtotal +
718 p_stream->p_index[p_stream->i_idxnb-1].i_length ) /
719 (mtime_t)p_stream->i_scale /
720 (mtime_t)p_stream->i_rate /
721 (mtime_t)p_stream->i_samplesize;
725 i_length = (mtime_t)p_stream->i_idxnb *
726 (mtime_t)p_stream->i_scale /
727 (mtime_t)p_stream->i_rate;
731 "stream[%d] length:%lld (based on index)",
734 i_maxlength = __MAX( i_maxlength, i_length );
738 return( i_maxlength );
741 /*****************************************************************************
742 * AVIEnd: frees unused data
743 *****************************************************************************/
744 static void __AVIEnd ( vlc_object_t * p_this )
746 input_thread_t * p_input = (input_thread_t *)p_this;
748 demux_sys_t *p_avi = p_input->p_demux_data ;
751 RIFF_DeleteChunk( p_input, p_avi->p_movi );
754 for( i = 0; i < p_avi->i_streams; i++ )
756 if( p_avi->pp_info[i] )
758 if( p_avi->pp_info[i]->p_index )
760 free( p_avi->pp_info[i]->p_index );
761 AVI_PESBuffer_Flush( p_input->p_method_data,
764 free( p_avi->pp_info[i] );
767 free( p_avi->pp_info );
769 AVI_ChunkFreeRoot( p_input, &p_avi->ck_root );
772 /*****************************************************************************
773 * AVIInit: check file and initializes AVI structures
774 *****************************************************************************/
775 static int AVIInit( vlc_object_t * p_this )
777 input_thread_t * p_input = (input_thread_t *)p_this;
779 avi_chunk_list_t *p_riff = (avi_chunk_list_t*)&ck_riff;
780 avi_chunk_list_t *p_hdrl, *p_movi;
782 avi_chunk_list_t *p_INFO;
783 avi_chunk_strz_t *p_name;
785 avi_chunk_avih_t *p_avih;
787 es_descriptor_t *p_es = NULL; /* avoid warning */
790 p_input->pf_demux = AVIDemux_Seekable;
791 if( !AVI_TestFile( p_input ) )
793 msg_Warn( p_input, "avi module discarded (invalid headr)" );
797 /* Initialize access plug-in structures. */
798 if( p_input->i_mtu == 0 )
801 p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE;
804 if( !( p_input->p_demux_data =
805 p_avi = malloc( sizeof(demux_sys_t) ) ) )
807 msg_Err( p_input, "out of memory" );
810 memset( p_avi, 0, sizeof( demux_sys_t ) );
813 p_avi->i_rate = DEFAULT_RATE;
814 p_avi->b_seekable = ( ( p_input->stream.b_seekable )
815 &&( p_input->stream.i_method == INPUT_METHOD_FILE ) );
816 /* *** for unseekable stream, automaticaly use AVIDemux_interleaved *** */
817 if( !p_avi->b_seekable || config_GetInt( p_input, "avi-interleaved" ) )
819 p_input->pf_demux = AVIDemux_UnSeekable;
822 if( !AVI_ChunkReadRoot( p_input, &p_avi->ck_root, p_avi->b_seekable ) )
824 msg_Err( p_input, "avi module discarded (invalid file)" );
827 AVI_ChunkDumpDebug( p_input, &p_avi->ck_root );
830 p_riff = (avi_chunk_list_t*)AVI_ChunkFind( &p_avi->ck_root,
832 p_hdrl = (avi_chunk_list_t*)AVI_ChunkFind( p_riff,
834 p_movi = (avi_chunk_list_t*)AVI_ChunkFind( p_riff,
837 p_INFO = (avi_chunk_list_t*)AVI_ChunkFind( p_riff,
839 p_name = (avi_chunk_strz_t*)AVI_ChunkFind( p_INFO,
847 if( !p_hdrl || !p_movi )
849 msg_Err( p_input, "avi module discarded (invalid file)" );
853 if( !( p_avih = (avi_chunk_avih_t*)AVI_ChunkFind( p_hdrl,
854 AVIFOURCC_avih, 0 ) ) )
856 msg_Err( p_input, "cannot find avih chunk" );
859 p_avi->i_streams = AVI_ChunkCount( p_hdrl, AVIFOURCC_strl );
860 if( p_avih->i_streams != p_avi->i_streams )
863 "found %d stream but %d are declared",
867 if( p_avi->i_streams == 0 )
870 msg_Err( p_input, "no stream defined!" );
874 /* create one program */
875 vlc_mutex_lock( &p_input->stream.stream_lock );
876 if( input_InitStream( p_input, 0 ) == -1)
878 vlc_mutex_unlock( &p_input->stream.stream_lock );
880 msg_Err( p_input, "cannot init stream" );
883 if( input_AddProgram( p_input, 0, 0) == NULL )
885 vlc_mutex_unlock( &p_input->stream.stream_lock );
887 msg_Err( p_input, "cannot add program" );
890 p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
891 vlc_mutex_unlock( &p_input->stream.stream_lock );
893 /* print informations on streams */
894 msg_Dbg( p_input, "AVIH: %d stream, flags %s%s%s%s ",
896 p_avih->i_flags&AVIF_HASINDEX?" HAS_INDEX":"",
897 p_avih->i_flags&AVIF_MUSTUSEINDEX?" MUST_USE_INDEX":"",
898 p_avih->i_flags&AVIF_ISINTERLEAVED?" IS_INTERLEAVED":"",
899 p_avih->i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"" );
901 /* now read info on each stream and create ES */
902 p_avi->pp_info = calloc( p_avi->i_streams,
903 sizeof( AVIStreamInfo_t* ) );
904 memset( p_avi->pp_info,
906 sizeof( AVIStreamInfo_t* ) * p_avi->i_streams );
908 for( i = 0 ; i < p_avi->i_streams; i++ )
910 avi_chunk_list_t *p_avi_strl;
911 avi_chunk_strh_t *p_avi_strh;
912 avi_chunk_strf_auds_t *p_avi_strf_auds;
913 avi_chunk_strf_vids_t *p_avi_strf_vids;
916 #define p_info p_avi->pp_info[i]
917 p_info = malloc( sizeof(AVIStreamInfo_t ) );
918 memset( p_info, 0, sizeof( AVIStreamInfo_t ) );
920 p_avi_strl = (avi_chunk_list_t*)AVI_ChunkFind( p_hdrl,
922 p_avi_strh = (avi_chunk_strh_t*)AVI_ChunkFind( p_avi_strl,
925 p_avi_strf_vids = AVI_ChunkFind( p_avi_strl, AVIFOURCC_strf, 0 );
927 if( !p_avi_strl || !p_avi_strh ||
928 ( !p_avi_strf_auds && !p_avi_strf_vids ) )
930 msg_Warn( p_input, "stream[%d] incomlete", i );
934 /* *** Init p_info *** */
935 p_info->i_rate = p_avi_strh->i_rate;
936 p_info->i_scale = p_avi_strh->i_scale;
937 p_info->i_samplesize = p_avi_strh->i_samplesize;
939 switch( p_avi_strh->i_type )
941 case( AVIFOURCC_auds ):
942 p_info->i_cat = AUDIO_ES;
944 AVI_FourccGetCodec( AUDIO_ES,
945 p_avi_strf_auds->i_formattag );
946 p_info->i_codec = p_info->i_fourcc;
947 i_init_size = p_avi_strf_auds->i_chunk_size;
948 p_init_data = p_avi_strf_auds->p_wfx;
949 msg_Dbg( p_input, "stream[%d] audio(0x%x) %d channels %dHz %dbits",
951 p_avi_strf_auds->i_formattag,
952 p_avi_strf_auds->i_channels,
953 p_avi_strf_auds->i_samplespersec,
954 p_avi_strf_auds->i_bitspersample );
957 case( AVIFOURCC_vids ):
958 p_info->i_cat = VIDEO_ES;
959 /* XXX quick hack for playing ffmpeg video, I don't know
960 who is doing something wrong */
961 p_info->i_samplesize = 0;
962 p_info->i_fourcc = p_avi_strf_vids->i_compression;
964 AVI_FourccGetCodec( VIDEO_ES, p_info->i_fourcc );
965 i_init_size = p_avi_strf_vids->i_chunk_size;
966 p_init_data = p_avi_strf_vids->p_bih;
967 msg_Dbg( p_input, "stream[%d] video(%4.4s) %dx%d %dbpp %ffps",
969 (char*)&p_avi_strf_vids->i_compression,
970 p_avi_strf_vids->i_width,
971 p_avi_strf_vids->i_height,
972 p_avi_strf_vids->i_bitcount,
973 (float)p_info->i_rate /
974 (float)p_info->i_scale );
977 msg_Err( p_input, "stream[%d] unknown type", i );
978 p_info->i_cat = UNKNOWN_ES;
983 p_info->i_activated = 0;
985 vlc_mutex_lock( &p_input->stream.stream_lock );
987 p_es = input_AddES( p_input,
988 p_input->stream.p_selected_program, 1+i,
990 vlc_mutex_unlock( &p_input->stream.stream_lock );
991 p_es->i_stream_id =i; /* XXX: i don't use it */
992 p_es->i_fourcc = p_info->i_fourcc;
993 p_es->i_cat = p_info->i_cat;
995 /* We copy strf for decoder in p_es->p_demux_data */
998 memcpy( p_es->p_demux_data,
1004 if( config_GetInt( p_input, "avi-index" ) )
1006 if( p_avi->b_seekable )
1008 AVI_IndexCreate( p_input );
1012 msg_Warn( p_input, "cannot create index (unseekable stream)" );
1013 AVI_IndexLoad( p_input );
1018 AVI_IndexLoad( p_input );
1021 /* *** movie length in sec *** */
1023 p_avi->i_length = (mtime_t)p_avih->i_totalframes *
1024 (mtime_t)p_avih->i_microsecperframe /
1028 p_avi->i_length = AVI_MovieGetLength( p_input, p_avi );
1029 if( p_avi->i_length < (mtime_t)p_avih->i_totalframes *
1030 (mtime_t)p_avih->i_microsecperframe /
1033 msg_Warn( p_input, "broken or missing index, 'seek' will be axproximative or will have strange behavour" );
1036 vlc_mutex_lock( &p_input->stream.stream_lock );
1037 if( p_avi->i_length )
1039 p_input->stream.i_mux_rate =
1040 p_input->stream.p_selected_area->i_size / 50 / p_avi->i_length;
1044 p_input->stream.i_mux_rate = 0;
1046 vlc_mutex_unlock( &p_input->stream.stream_lock );
1048 /* create a pseudo p_movi */
1049 p_avi->p_movi = malloc( sizeof( riffchunk_t ) );
1050 p_avi->p_movi->i_id = AVIFOURCC_LIST;
1051 p_avi->p_movi->i_type = AVIFOURCC_movi;
1052 p_avi->p_movi->i_size = p_movi->i_chunk_size;
1053 p_avi->p_movi->i_pos = p_movi->i_chunk_pos;
1054 p_avi->p_movi->p_data = NULL;
1057 for( i = 0; i < p_avi->i_streams; i++ )
1059 #define p_info p_avi->pp_info[i]
1060 switch( p_info->p_es->i_cat )
1064 if( (p_avi->p_info_video == NULL) )
1066 p_avi->p_info_video = p_info;
1067 /* TODO add test to see if a decoder has been found */
1068 AVI_StreamStart( p_input, p_avi, i );
1073 if( (p_avi->p_info_audio == NULL) )
1075 p_avi->p_info_audio = p_info;
1076 AVI_StreamStart( p_input, p_avi, i );
1085 /* we select the first audio and video ES */
1086 vlc_mutex_lock( &p_input->stream.stream_lock );
1087 if( !p_avi->p_info_video )
1089 msg_Warn( p_input, "no video stream found" );
1091 if( !p_avi->p_info_audio )
1093 msg_Warn( p_input, "no audio stream found!" );
1095 p_input->stream.p_selected_program->b_is_ok = 1;
1096 vlc_mutex_unlock( &p_input->stream.stream_lock );
1098 if( p_avi->b_seekable )
1100 AVI_ChunkGoto( p_input, p_movi );
1104 // already at begining of p_movi
1106 AVI_SkipBytes( p_input, 12 ); // enter in p_movi
1113 /*****************************************************************************
1114 * Function to convert pts to chunk or byte
1115 *****************************************************************************/
1117 static inline mtime_t AVI_PTSToChunk( AVIStreamInfo_t *p_info,
1120 return( (mtime_t)((s64)i_pts *
1121 (s64)p_info->i_rate /
1122 (s64)p_info->i_scale /
1125 static inline mtime_t AVI_PTSToByte( AVIStreamInfo_t *p_info,
1128 return( (mtime_t)((s64)i_pts *
1129 (s64)p_info->i_samplesize *
1130 (s64)p_info->i_rate /
1131 (s64)p_info->i_scale /
1135 static mtime_t AVI_GetPTS( AVIStreamInfo_t *p_info )
1138 if( p_info->i_samplesize )
1140 /* we need a valid entry we will emulate one */
1142 if( p_info->i_idxposc == p_info->i_idxnb )
1144 if( p_info->i_idxposc )
1146 /* use the last entry */
1147 i_len = p_info->p_index[p_info->i_idxnb - 1].i_lengthtotal
1148 + p_info->p_index[p_info->i_idxnb - 1].i_length
1149 + p_info->i_idxposb; /* should be 0 */
1153 i_len = p_info->i_idxposb;
1154 /* no valid entry use only offset*/
1159 i_len = p_info->p_index[p_info->i_idxposc].i_lengthtotal
1160 + p_info->i_idxposb;
1162 return( (mtime_t)( (s64)1000000 *
1164 (s64)p_info->i_scale /
1165 (s64)p_info->i_rate /
1166 (s64)p_info->i_samplesize ) );
1170 /* even if p_info->i_idxposc isn't valid, there isn't any problem */
1171 return( (mtime_t)( (s64)1000000 *
1172 (s64)(p_info->i_idxposc ) *
1173 (s64)p_info->i_scale /
1174 (s64)p_info->i_rate) );
1179 /*****************************************************************************
1180 * Functions to acces streams data
1181 * Uses it, because i plane to read unseekable stream
1182 * XXX NEVER set directly i_idxposc and i_idxposb unless you know what you do
1183 *****************************************************************************/
1185 /* FIXME FIXME change b_pad to number of bytes to skipp after reading */
1186 static int __AVI_GetDataInPES( input_thread_t *p_input,
1187 pes_packet_t **pp_pes,
1193 data_packet_t *p_data;
1196 if( !(*pp_pes = input_NewPES( p_input->p_method_data ) ) )
1204 p_data = input_NewPacket( p_input->p_method_data, 0 );
1205 (*pp_pes)->p_first = (*pp_pes)->p_last = p_data;
1206 (*pp_pes)->i_nb_data = 1;
1207 (*pp_pes)->i_pes_size = 0;
1211 if( ( i_size&1 )&&( b_pad ) )
1223 i_read = input_SplitBuffer(p_input, &p_data, __MIN( i_size -
1224 (*pp_pes)->i_pes_size, 1024 ) );
1227 return( (*pp_pes)->i_pes_size );
1229 if( !(*pp_pes)->p_first )
1231 (*pp_pes)->p_first =
1232 (*pp_pes)->p_last = p_data;
1233 (*pp_pes)->i_nb_data = 1;
1234 (*pp_pes)->i_pes_size = i_read;
1238 (*pp_pes)->p_last->p_next =
1239 (*pp_pes)->p_last = p_data;
1240 (*pp_pes)->i_nb_data++;
1241 (*pp_pes)->i_pes_size += i_read;
1243 } while( ((*pp_pes)->i_pes_size < i_size)&&( i_read ) );
1247 (*pp_pes)->i_pes_size--;
1248 (*pp_pes)->p_last->p_payload_end--;
1255 static int __AVI_SeekAndGetChunk( input_thread_t *p_input,
1256 AVIStreamInfo_t *p_info )
1258 pes_packet_t *p_pes;
1259 int i_length, i_ret;
1261 i_length = __MIN( p_info->p_index[p_info->i_idxposc].i_length
1262 - p_info->i_idxposb,
1263 BUFFER_MAXSPESSIZE );
1265 AVI_SeekAbsolute( p_input,
1266 (off_t)p_info->p_index[p_info->i_idxposc].i_pos +
1267 p_info->i_idxposb + 8);
1269 i_ret = __AVI_GetDataInPES( p_input, &p_pes, i_length , 0);
1271 if( i_ret != i_length )
1275 /* TODO test key frame if i_idxposb == 0*/
1276 AVI_PESBuffer_Add( p_input->p_method_data,
1280 p_info->i_idxposb );
1283 /* TODO check if it's correct (humm...) and optimisation ... */
1284 /* return 0 if we choose to get only the ck we want
1285 * 1 if index is invalid
1286 * 2 if there is a ck_other before ck_info and the last proced ck_info*/
1287 /* XXX XXX XXX avi file is some BIG shit, and sometime index give
1288 * a refenrence to the same chunk BUT with a different size ( usually 0 )
1291 static inline int __AVI_GetChunkMethod( input_thread_t *p_input,
1292 AVIStreamInfo_t *p_info,
1293 AVIStreamInfo_t *p_other )
1298 int i_info_pos_last;
1299 int i_other_pos_last;
1301 /*If we don't have a valid entry we need to parse from last
1302 defined chunk and it's the only way that we return 1*/
1303 if( p_info->i_idxposc >= p_info->i_idxnb )
1308 /* KNOW we have a valid entry for p_info */
1309 /* we return 0 if we haven't an valid entry for p_other */
1310 if( ( !p_other )||( p_other->i_idxposc >= p_other->i_idxnb ) )
1315 /* KNOW there are 2 streams with valid entry */
1317 /* we return 0 if for one of the two streams we will not read
1319 if( ( p_info->i_idxposb )||( p_other->i_idxposb ) )
1324 /* KNOW we have a valid entry for the 2 streams
1325 and for the 2 we want an aligned chunk (given by i_idxposc )*/
1326 /* if in stream, the next chunk is back than the one we
1327 have just read, it's useless to parse */
1328 i_info_pos = p_info->p_index[p_info->i_idxposc].i_pos;
1329 i_other_pos = p_other->p_index[p_other->i_idxposc].i_pos ;
1331 i_info_pos_last = p_info->i_idxposc ?
1332 p_info->p_index[p_info->i_idxposc - 1].i_pos : 0;
1333 i_other_pos_last = p_other->i_idxposc ?
1334 p_other->p_index[p_other->i_idxposc - 1].i_pos : 0 ;
1337 if( ( ( p_info->i_idxposc )&&( i_info_pos <= i_info_pos_last ) ) ||
1338 ( ( p_other->i_idxposc )&&( i_other_pos <= i_other_pos_last ) ) )
1343 /* KNOW for the 2 streams, the ck we want are after the last read
1344 or it's the first */
1346 /* if the first ck_other we want isn't between ck_info_last
1347 and ck_info, don't parse */
1348 /* TODO fix this, use also number in buffered PES */
1349 if( ( i_other_pos > i_info_pos) /* ck_other too far */
1350 ||( i_other_pos < i_info_pos_last ) ) /* it's too late for ck_other */
1355 /* we Know we will find ck_other, and before ck_info
1356 "if ck_info is too far" will be handle after */
1361 static inline int __AVI_ChooseSize( int l1, int l2 )
1363 /* XXX l2 is prefered if 0 otherwise min not equal to 0 */
1368 return( !l1 ? l2 : __MIN( l1,l2 ) );
1371 /* We know we will read chunk align */
1372 static int __AVI_GetAndPutChunkInBuffer( input_thread_t *p_input,
1373 AVIStreamInfo_t *p_info,
1378 pes_packet_t *p_pes;
1381 i_length = __MIN( i_size, BUFFER_MAXSPESSIZE );
1383 /* Skip chunk header */
1385 if( __AVI_GetDataInPES( p_input, &p_pes, i_length + 8,1 ) != i_length +8 )
1389 p_pes->p_first->p_payload_start += 8;
1390 p_pes->i_pes_size -= 8;
1392 i_size = GetDWLE( p_pes->p_first->p_demux_start + 4);
1394 AVI_PESBuffer_Add( p_input->p_method_data,
1399 /* skip unwanted bytes */
1400 if( i_length != i_size)
1402 msg_Err( p_input, "Chunk Size mismatch" );
1403 AVI_SeekAbsolute( p_input,
1404 __EVEN( AVI_TellAbsolute( p_input ) +
1405 i_size - i_length ) );
1410 /* XXX Don't use this function directly ! XXX */
1411 static int __AVI_GetChunk( input_thread_t *p_input,
1412 AVIStreamInfo_t *p_info,
1415 demux_sys_t *p_avi = p_input->p_demux_data;
1416 AVIStreamInfo_t *p_other;
1421 #define p_info_i p_avi->pp_info[i]
1422 while( p_info->p_pes_first )
1424 if( ( p_info->p_pes_first->i_posc == p_info->i_idxposc )
1425 &&( p_info->i_idxposb >= p_info->p_pes_first->i_posb )
1426 &&( p_info->i_idxposb < p_info->p_pes_first->i_posb +
1427 p_info->p_pes_first->p_pes->i_pes_size ) )
1430 return( 1 ); /* we have it in buffer */
1434 AVI_PESBuffer_Drop( p_input->p_method_data, p_info );
1437 /* up to now we handle only one audio and video streams at the same time */
1438 p_other = (p_info == p_avi->p_info_video ) ?
1439 p_avi->p_info_audio : p_avi->p_info_video ;
1441 i_method = __AVI_GetChunkMethod( p_input, p_info, p_other );
1445 /* get directly the good chunk */
1446 return( b_load ? __AVI_SeekAndGetChunk( p_input, p_info ) : 1 );
1449 * because invalid index
1450 * or will find ck_other before ck_info
1452 /* msg_Warn( p_input, "method %d", i_method ); */
1453 /* we will calculate the better position we have to reach */
1457 /* the position max we have already reached */
1458 /* FIXME this isn't the better because sometime will fail to
1459 put in buffer p_other since it could be too far */
1460 AVIStreamInfo_t *p_info_max = p_info;
1462 for( i = 0; i < p_avi->i_streams; i++ )
1464 if( p_info_i->i_idxnb )
1466 if( p_info_max->i_idxnb )
1468 if( p_info_i->p_index[p_info_i->i_idxnb -1 ].i_pos >
1469 p_info_max->p_index[p_info_max->i_idxnb -1 ].i_pos )
1471 p_info_max = p_info_i;
1476 p_info_max = p_info_i;
1480 if( p_info_max->i_idxnb )
1482 /* be carefull that size between index and ck can sometime be
1483 different without any error (and other time it's an error) */
1484 i_posmax = p_info_max->p_index[p_info_max->i_idxnb -1 ].i_pos;
1485 /* so choose this, and I know that we have already reach it */
1489 i_posmax = p_avi->p_movi->i_pos + 12;
1496 return( 1 ); /* all is ok */
1499 /* we know that the entry and the last one are valid for the 2 stream */
1500 /* and ck_other will come *before* index so go directly to it*/
1501 i_posmax = p_other->p_index[p_other->i_idxposc].i_pos;
1504 AVI_SeekAbsolute( p_input, i_posmax );
1505 /* the first chunk we will see is :
1506 * the last chunk that we have already seen for broken index
1507 * the first ck for other with good index */
1508 for( ; ; ) /* infinite parsing until the ck we want */
1513 /* Get the actual chunk in the stream */
1514 if( !(p_ck = RIFF_ReadChunk( p_input )) )
1518 /* msg_Dbg( p_input, "ck: %4.4s len %d", &p_ck->i_id, p_ck->i_size ); */
1519 /* special case for LIST-rec chunk */
1520 if( ( p_ck->i_id == AVIFOURCC_LIST )&&( p_ck->i_type == AVIFOURCC_rec ) )
1522 AVI_SkipBytes( p_input, 12 );
1523 // RIFF_DescendChunk( p_input );
1524 RIFF_DeleteChunk( p_input, p_ck );
1527 AVI_ParseStreamHeader( p_ck->i_id, &i, &i_type );
1528 /* littles checks but not too much if you want to read all file */
1529 if( i >= p_avi->i_streams )
1531 RIFF_DeleteChunk( p_input, p_ck );
1532 if( RIFF_NextChunk( p_input, p_avi->p_movi ) != 0 )
1541 /* have we found a new entry (not present in index)? */
1542 if( ( !p_info_i->i_idxnb )
1543 ||(p_info_i->p_index[p_info_i->i_idxnb-1].i_pos < p_ck->i_pos))
1545 AVIIndexEntry_t index;
1547 index.i_id = p_ck->i_id;
1548 index.i_flags = AVI_GetKeyFlag( p_info_i->i_codec,
1549 (u8*)&p_ck->i_8bytes);
1550 index.i_pos = p_ck->i_pos;
1551 index.i_length = p_ck->i_size;
1552 __AVI_AddEntryIndex( p_info_i, &index );
1556 /* TODO check if p_other is full and then if is possible
1557 go directly to the good chunk */
1558 if( ( p_info_i == p_other )
1559 &&( !AVI_PESBuffer_IsFull( p_other ) )
1560 &&( ( !p_other->p_pes_last )||
1561 ( p_other->p_pes_last->p_pes->i_pes_size !=
1562 BUFFER_MAXSPESSIZE ) ) )
1564 int i_ck = p_other->p_pes_last ?
1565 p_other->p_pes_last->i_posc + 1 : p_other->i_idxposc;
1566 i_size = __AVI_ChooseSize( p_ck->i_size,
1567 p_other->p_index[i_ck].i_length);
1569 if( p_other->p_index[i_ck].i_pos == p_ck->i_pos )
1571 if( !__AVI_GetAndPutChunkInBuffer( p_input, p_other,
1574 RIFF_DeleteChunk( p_input, p_ck );
1580 if( RIFF_NextChunk( p_input, p_avi->p_movi ) != 0 )
1582 RIFF_DeleteChunk( p_input, p_ck );
1589 RIFF_DeleteChunk( p_input, p_ck );
1592 if( ( p_info_i == p_info)
1593 &&( p_info->i_idxposc < p_info->i_idxnb ) )
1595 /* the first ck_info is ok otherwise it should be
1596 loaded without parsing */
1597 i_size = __AVI_ChooseSize( p_ck->i_size,
1598 p_info->p_index[p_info->i_idxposc].i_length);
1601 RIFF_DeleteChunk( p_input, p_ck );
1603 return( b_load ? __AVI_GetAndPutChunkInBuffer( p_input,
1606 p_info->i_idxposc ) : 1 );
1611 RIFF_DeleteChunk( p_input, p_ck );
1612 if( RIFF_NextChunk( p_input, p_avi->p_movi ) != 0 )
1625 /* be sure that i_ck will be a valid index entry */
1626 static int AVI_SetStreamChunk( input_thread_t *p_input,
1627 AVIStreamInfo_t *p_info,
1631 p_info->i_idxposc = i_ck;
1632 p_info->i_idxposb = 0;
1634 if( i_ck < p_info->i_idxnb )
1640 p_info->i_idxposc = p_info->i_idxnb - 1;
1643 p_info->i_idxposc++;
1644 if( !__AVI_GetChunk( p_input, p_info, 0 ) )
1648 } while( p_info->i_idxposc < i_ck );
1655 /* XXX FIXME up to now, we assume that all chunk are one after one */
1656 static int AVI_SetStreamBytes( input_thread_t *p_input,
1657 AVIStreamInfo_t *p_info,
1660 if( ( p_info->i_idxnb > 0 )
1661 &&( i_byte < p_info->p_index[p_info->i_idxnb - 1].i_lengthtotal +
1662 p_info->p_index[p_info->i_idxnb - 1].i_length ) )
1664 /* index is valid to find the ck */
1665 /* uses dichototmie to be fast enougth */
1666 int i_idxposc = __MIN( p_info->i_idxposc, p_info->i_idxnb - 1 );
1667 int i_idxmax = p_info->i_idxnb;
1671 if( p_info->p_index[i_idxposc].i_lengthtotal > i_byte )
1673 i_idxmax = i_idxposc ;
1674 i_idxposc = ( i_idxmin + i_idxposc ) / 2 ;
1678 if( p_info->p_index[i_idxposc].i_lengthtotal +
1679 p_info->p_index[i_idxposc].i_length <= i_byte)
1681 i_idxmin = i_idxposc ;
1682 i_idxposc = (i_idxmax + i_idxposc ) / 2 ;
1686 p_info->i_idxposc = i_idxposc;
1687 p_info->i_idxposb = i_byte -
1688 p_info->p_index[i_idxposc].i_lengthtotal;
1697 p_info->i_idxposc = p_info->i_idxnb - 1;
1698 p_info->i_idxposb = 0;
1701 p_info->i_idxposc++;
1702 if( !__AVI_GetChunk( p_input, p_info, 0 ) )
1706 } while( p_info->p_index[p_info->i_idxposc].i_lengthtotal +
1707 p_info->p_index[p_info->i_idxposc].i_length <= i_byte );
1709 p_info->i_idxposb = i_byte -
1710 p_info->p_index[p_info->i_idxposc].i_lengthtotal;
1715 static pes_packet_t *AVI_ReadStreamChunkInPES( input_thread_t *p_input,
1716 AVIStreamInfo_t *p_info )
1719 if( p_info->i_idxposc > p_info->i_idxnb )
1724 /* we want chunk (p_info->i_idxposc,0) */
1725 p_info->i_idxposb = 0;
1726 if( !__AVI_GetChunk( p_input, p_info, 1) )
1728 msg_Err( p_input, "Got one chunk : failed" );
1731 p_info->i_idxposc++;
1732 return( AVI_PESBuffer_Get( p_info ) );
1735 static pes_packet_t *AVI_ReadStreamBytesInPES( input_thread_t *p_input,
1736 AVIStreamInfo_t *p_info,
1739 pes_packet_t *p_pes;
1740 data_packet_t *p_data;
1745 if( !( p_pes = input_NewPES( p_input->p_method_data ) ) )
1749 if( !( p_data = input_NewPacket( p_input->p_method_data, i_byte ) ) )
1751 input_DeletePES( p_input->p_method_data, p_pes );
1756 p_pes->p_last = p_data;
1757 p_pes->i_nb_data = 1;
1758 p_pes->i_pes_size = i_byte;
1762 if( !__AVI_GetChunk( p_input, p_info, 1) )
1764 msg_Err( p_input, "Got one chunk : failed" );
1766 input_DeletePES( p_input->p_method_data, p_pes );
1770 i_read = __MIN( p_info->p_pes_first->p_pes->i_pes_size -
1771 ( p_info->i_idxposb - p_info->p_pes_first->i_posb ),
1773 /* FIXME FIXME FIXME follow all data packet */
1774 memcpy( p_data->p_payload_start + i_count,
1775 p_info->p_pes_first->p_pes->p_first->p_payload_start +
1776 p_info->i_idxposb - p_info->p_pes_first->i_posb,
1779 AVI_PESBuffer_Drop( p_input->p_method_data, p_info );
1783 p_info->i_idxposb += i_read;
1784 if( p_info->p_index[p_info->i_idxposc].i_length <= p_info->i_idxposb )
1786 p_info->i_idxposb -= p_info->p_index[p_info->i_idxposc].i_length;
1787 p_info->i_idxposc++;
1793 /*****************************************************************************
1794 * AVI_GetFrameInPES : get dpts length(µs) in pes from stream
1795 *****************************************************************************
1796 * Handle multiple pes, and set pts to the good value
1797 *****************************************************************************/
1798 static pes_packet_t *AVI_GetFrameInPES( input_thread_t *p_input,
1799 AVIStreamInfo_t *p_info,
1803 pes_packet_t *p_pes = NULL;
1804 pes_packet_t *p_pes_tmp = NULL;
1805 pes_packet_t *p_pes_first = NULL;
1813 if( !p_info->i_samplesize )
1815 int i_chunk = __MAX( AVI_PTSToChunk( p_info, i_dpts), 1 );
1817 for( i = 0; i < i_chunk; i++ )
1819 /* get pts while is valid */
1820 i_pts = AVI_GetPTS( p_info );
1822 p_pes_tmp = AVI_ReadStreamChunkInPES( p_input, p_info );
1826 return( p_pes_first );
1828 p_pes_tmp->i_pts = i_pts;
1831 p_pes_first = p_pes_tmp;
1835 p_pes->p_next = p_pes_tmp;
1839 return( p_pes_first );
1843 /* stream is byte based */
1844 int i_byte = AVI_PTSToByte( p_info, i_dpts);
1845 if( i_byte < 50 ) /* to avoid some problem with audio */
1849 i_pts = AVI_GetPTS( p_info ); /* ok even with broken index */
1850 p_pes = AVI_ReadStreamBytesInPES( p_input, p_info, i_byte);
1854 p_pes->i_pts = i_pts;
1859 /*****************************************************************************
1860 * AVI_DecodePES : send a pes to decoder
1861 *****************************************************************************
1862 * Handle multiple pes, and update pts to the good value
1863 *****************************************************************************/
1864 static inline void AVI_DecodePES( input_thread_t *p_input,
1865 AVIStreamInfo_t *p_info,
1866 pes_packet_t *p_pes )
1868 pes_packet_t *p_pes_next;
1869 /* input_decode want only one pes, but AVI_GetFrameInPES give
1870 multiple pes so send one by one */
1873 p_pes_next = p_pes->p_next;
1874 p_pes->p_next = NULL;
1875 p_pes->i_pts = input_ClockGetTS( p_input,
1876 p_input->stream.p_selected_program,
1877 p_pes->i_pts * 9/100);
1878 input_DecodePES( p_info->p_es->p_decoder_fifo, p_pes );
1884 static int AVI_StreamSeek( input_thread_t *p_input,
1889 #define p_stream p_avi->pp_info[i_stream]
1892 AVI_PESBuffer_Flush( p_input->p_method_data, p_stream );
1893 i_oldpts = AVI_GetPTS( p_stream );
1895 if( !p_stream->i_samplesize )
1897 AVI_SetStreamChunk( p_input,
1899 AVI_PTSToChunk( p_stream, i_date ) );
1900 /* search key frame */
1902 "old:%lld %s new %lld",
1904 i_oldpts > i_date ? ">" : "<",
1907 if( i_date < i_oldpts )
1909 while( p_stream->i_idxposc > 0 &&
1910 !( p_stream->p_index[p_stream->i_idxposc].i_flags &
1913 if( !AVI_SetStreamChunk( p_input,
1915 p_stream->i_idxposc - 1 ) )
1923 while( !( p_stream->p_index[p_stream->i_idxposc].i_flags &
1926 if( !AVI_SetStreamChunk( p_input,
1928 p_stream->i_idxposc + 1 ) )
1937 AVI_SetStreamBytes( p_input,
1939 AVI_PTSToByte( p_stream, i_date ) );
1945 /*****************************************************************************
1946 * AVISeek: goto to i_date or i_percent
1947 *****************************************************************************
1948 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
1949 *****************************************************************************/
1950 static int AVISeek ( input_thread_t *p_input,
1951 mtime_t i_date, int i_percent )
1954 demux_sys_t *p_avi = p_input->p_demux_data;
1957 "seek requested: %lld secondes %d%%",
1961 if( p_avi->b_seekable )
1963 if( !p_avi->i_length )
1966 AVIStreamInfo_t *p_stream;
1969 /* use i_percent to create a true i_date */
1971 "mmh, seeking without index at %d%%"
1972 " work only for interleaved file", i_percent );
1974 if( i_percent >= 100 )
1976 msg_Err( p_input, "cannot seek so far !" );
1979 i_percent = __MAX( i_percent, 0 );
1981 /* try to find chunk that is at i_percent or the file */
1982 i_pos = __MAX( i_percent *
1983 p_input->stream.p_selected_area->i_size / 100,
1984 p_avi->p_movi->i_pos );
1985 /* search first selected stream */
1986 for( i_index = 0,p_stream = NULL;
1987 i_index < p_avi->i_streams; i_stream++ )
1989 p_stream = p_avi->pp_info[i_index];
1990 if( p_stream->i_activated )
1995 if( !p_stream || !p_stream->p_index )
1997 msg_Err( p_input, "cannot find any selected stream" );
2001 p_stream->i_idxposc = __MAX( p_stream->i_idxposc - 1, 0 );
2002 while( ( i_pos < p_stream->p_index[p_stream->i_idxposc].i_pos )
2003 &&( p_stream->i_idxposc > 0 ) )
2005 /* search before i_idxposc */
2006 if( !AVI_SetStreamChunk( p_input,
2007 p_stream, p_stream->i_idxposc - 1 ) )
2009 msg_Err( p_input, "cannot seek" );
2013 while( i_pos >= p_stream->p_index[p_stream->i_idxposc].i_pos +
2014 p_stream->p_index[p_stream->i_idxposc].i_length + 8 )
2016 /* search after i_idxposc */
2017 if( !AVI_SetStreamChunk( p_input,
2018 p_stream, p_stream->i_idxposc + 1 ) )
2020 msg_Err( p_input, "cannot seek" );
2024 i_date = AVI_GetPTS( p_stream );
2025 /* TODO better support for i_samplesize != 0 */
2026 msg_Dbg( p_input, "estimate date %lld", i_date );
2029 #define p_stream p_avi->pp_info[i_stream]
2031 /* seek for chunk based streams */
2032 for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
2034 if( p_stream->i_activated && !p_stream->i_samplesize )
2035 // if( p_stream->i_activated )
2037 AVI_StreamSeek( p_input, p_avi, i_stream, i_date );
2038 p_avi->i_time = __MAX( AVI_GetPTS( p_stream ),
2045 i_date = p_avi->i_time;
2047 /* seek for bytes based streams */
2048 for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
2050 if( p_stream->i_activated && p_stream->i_samplesize )
2052 AVI_StreamSeek( p_input, p_avi, i_stream, i_date );
2053 // p_avi->i_time = __MAX( AVI_GetPTS( p_stream ), p_avi->i_time );
2056 msg_Dbg( p_input, "seek: %lld secondes", p_avi->i_time /1000000 );
2057 /* set true movie time */
2059 if( !p_avi->i_time )
2061 p_avi->i_time = i_date;
2068 msg_Err( p_input, "shouldn't yet be executed" );
2073 /*****************************************************************************
2074 * AVIDemux_Seekable: reads and demuxes data packets for stream seekable
2075 *****************************************************************************
2076 * AVIDemux: reads and demuxes data packets
2077 *****************************************************************************
2078 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
2079 * TODO add support for unstreable file, just read a chunk and send it
2080 * to the right decoder, very easy
2081 *****************************************************************************/
2083 static int AVIDemux_Seekable( input_thread_t *p_input )
2089 demux_sys_t *p_avi = p_input->p_demux_data;
2091 /* detect new selected/unselected streams */
2092 for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
2094 #define p_stream p_avi->pp_info[i_stream]
2095 if( p_stream->p_es )
2097 if( p_stream->p_es->p_decoder_fifo &&
2098 !p_stream->i_activated )
2100 AVI_StreamStart( p_input, p_avi, i_stream );
2103 if( !p_stream->p_es->p_decoder_fifo &&
2104 p_stream->i_activated )
2106 AVI_StreamStop( p_input, p_avi, i_stream );
2111 /* search new video and audio stream selected
2112 if current have been unselected*/
2113 if( ( !p_avi->p_info_video )
2114 || ( !p_avi->p_info_video->p_es->p_decoder_fifo ) )
2116 p_avi->p_info_video = NULL;
2117 for( i = 0; i < p_avi->i_streams; i++ )
2119 if( ( p_avi->pp_info[i]->i_cat == VIDEO_ES )
2120 &&( p_avi->pp_info[i]->p_es->p_decoder_fifo ) )
2122 p_avi->p_info_video = p_avi->pp_info[i];
2127 if( ( !p_avi->p_info_audio )
2128 ||( !p_avi->p_info_audio->p_es->p_decoder_fifo ) )
2130 p_avi->p_info_audio = NULL;
2131 for( i = 0; i < p_avi->i_streams; i++ )
2133 if( ( p_avi->pp_info[i]->i_cat == AUDIO_ES )
2134 &&( p_avi->pp_info[i]->p_es->p_decoder_fifo ) )
2136 p_avi->p_info_audio = p_avi->pp_info[i];
2142 if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT )
2146 /* first wait for empty buffer, arbitrary time FIXME */
2147 msleep( DEFAULT_PTS_DELAY );
2149 i_date = (mtime_t)1000000 *
2150 (mtime_t)p_avi->i_length *
2151 (mtime_t)AVI_TellAbsolute( p_input ) /
2152 (mtime_t)p_input->stream.p_selected_area->i_size;
2153 i_percent = 100 * AVI_TellAbsolute( p_input ) /
2154 p_input->stream.p_selected_area->i_size;
2155 AVISeek( p_input, i_date, i_percent);
2156 // input_ClockInit( p_input->stream.p_selected_program );
2158 /* wait for the good time */
2159 input_ClockManageRef( p_input,
2160 p_input->stream.p_selected_program,
2163 p_avi->i_pcr = p_avi->i_time * 9 / 100;
2164 p_avi->i_time += 100*1000; /* read 100ms */
2166 for( i_stream = 0, b_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
2168 #define p_stream p_avi->pp_info[i_stream]
2169 pes_packet_t *p_pes;
2171 if( !p_stream->p_es ||
2172 !p_stream->p_es->p_decoder_fifo )
2177 if( p_avi->i_time <= AVI_GetPTS( p_stream ) )
2179 msg_Warn( p_input, "skeeping stream %d", i_stream );
2183 p_pes = AVI_GetFrameInPES( p_input,
2185 p_avi->i_time - AVI_GetPTS( p_stream ) );
2188 AVI_DecodePES( p_input, p_stream, p_pes );
2195 return( b_stream ? 1 : 0 );
2200 /*****************************************************************************
2201 * AVIDemux_UnSeekable: reads and demuxes data packets for unseekable
2203 *****************************************************************************
2204 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
2205 *****************************************************************************/
2206 static int AVIDemux_UnSeekable( input_thread_t *p_input )
2208 demux_sys_t *p_avi = p_input->p_demux_data;
2209 AVIStreamInfo_t *p_stream_master;
2214 /* *** send audio data to decoder only if rate == DEFAULT_RATE *** */
2215 vlc_mutex_lock( &p_input->stream.stream_lock );
2216 b_audio = p_input->stream.control.i_rate == DEFAULT_RATE;
2217 vlc_mutex_unlock( &p_input->stream.stream_lock );
2219 input_ClockManageRef( p_input,
2220 p_input->stream.p_selected_program,
2222 /* *** find master stream for data packet skipping algo *** */
2223 /* *** -> first video, if any, or first audio ES *** */
2224 for( i_stream = 0, p_stream_master = NULL;
2225 i_stream < p_avi->i_streams; i_stream++ )
2227 #define p_stream p_avi->pp_info[i_stream]
2228 if( p_stream->p_es &&
2229 p_stream->p_es->p_decoder_fifo )
2231 if( p_stream->i_cat == VIDEO_ES )
2233 p_stream_master = p_stream;
2236 if( p_stream->i_cat == AUDIO_ES && !p_stream_master )
2238 p_stream_master = p_stream;
2243 if( !p_stream_master )
2245 msg_Err( p_input, "no more stream selected" );
2249 p_avi->i_pcr = AVI_GetPTS( p_stream_master ) * 9 / 100;
2251 for( i_packet = 0; i_packet < 10; i_packet++)
2253 #define p_stream p_avi->pp_info[avi_pk.i_stream]
2255 avi_packet_t avi_pk;
2257 if( !AVI_PacketGetHeader( p_input, &avi_pk ) )
2261 // AVI_ParseStreamHeader( avi_pk.i_fourcc, &i_stream, &i_cat );
2263 if( avi_pk.i_stream >= p_avi->i_streams ||
2264 ( avi_pk.i_cat != AUDIO_ES && avi_pk.i_cat != VIDEO_ES ) )
2266 /* we haven't found an audio or video packet:
2267 - we have seek, found first next packet
2268 - others packets could be found, skip them
2270 switch( avi_pk.i_fourcc )
2272 case AVIFOURCC_JUNK:
2273 case AVIFOURCC_LIST:
2274 return( AVI_PacketNext( p_input ) ? 1 : 0 );
2275 case AVIFOURCC_idx1:
2279 "seems to have lost position, resync" );
2280 if( !AVI_PacketSearch( p_input ) )
2282 msg_Err( p_input, "resync failed" );
2289 /* do will send this packet to decoder ? */
2290 if( ( !b_audio && avi_pk.i_cat == AUDIO_ES )||
2292 !p_stream->p_es->p_decoder_fifo )
2294 if( !AVI_PacketNext( p_input ) )
2301 /* it's a selected stream, check for time */
2302 if( __ABS( AVI_GetPTS( p_stream ) -
2303 AVI_GetPTS( p_stream_master ) )< 600*1000 )
2305 /* load it and send to decoder */
2306 pes_packet_t *p_pes;
2307 if( !AVI_PacketRead( p_input, &avi_pk, &p_pes ) || !p_pes)
2311 p_pes->i_pts = AVI_GetPTS( p_stream );
2312 AVI_DecodePES( p_input, p_stream, p_pes );
2316 if( !AVI_PacketNext( p_input ) )
2323 /* *** update stream time position *** */
2324 if( p_stream->i_samplesize )
2326 p_stream->i_idxposb += avi_pk.i_size;
2330 p_stream->i_idxposc++;