]> git.sesse.net Git - vlc/commitdiff
* plugins/avi/avi.c : seek is faster
authorLaurent Aimar <fenrir@videolan.org>
Sat, 27 Apr 2002 16:13:23 +0000 (16:13 +0000)
committerLaurent Aimar <fenrir@videolan.org>
Sat, 27 Apr 2002 16:13:23 +0000 (16:13 +0000)
plugins/avi/avi.c
plugins/ffmpeg/ffmpeg.c

index 4e4ab5ebae7df9c483d80db5580143d9a081d84a..2ff07648de0861eb94e06e640b8f442fb44969dd 100644 (file)
@@ -2,7 +2,7 @@
  * avi.c : AVI file Stream input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: avi.c,v 1.5 2002/04/26 14:29:26 fenrir Exp $
+ * $Id: avi.c,v 1.6 2002/04/27 16:13:23 fenrir Exp $
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  * 
  * This program is free software; you can redistribute it and/or modify
@@ -204,7 +204,7 @@ static int __AVI_ParseStreamHeader( u32 i_id, int *i_number, u16 *i_type )
         return( -1 );
     }
     *i_number = (c1 - '0') * 10 + (c2 - '0' );
-    *i_type = ( c3 << 8) + c4;
+    *i_type = ( c4 << 8) + c3;
     return( 0 );
 }   
 
@@ -214,7 +214,7 @@ static void __AVI_AddEntryIndex( AVIStreamInfo_t *p_info,
     AVIIndexEntry_t *p_tmp;
     if( p_info->p_index == NULL )
     {
-        p_info->i_idxmax = 4096;
+        p_info->i_idxmax = 16384;
         p_info->i_idxnb = 0;
         p_info->p_index = calloc( p_info->i_idxmax, 
                                   sizeof( AVIIndexEntry_t ) );
@@ -222,13 +222,13 @@ static void __AVI_AddEntryIndex( AVIStreamInfo_t *p_info,
     }
     if( p_info->i_idxnb >= p_info->i_idxmax )
     {
-        p_info->i_idxmax += 4096;
+        p_info->i_idxmax += 16384;
         p_tmp = realloc( (void*)p_info->p_index,
                            p_info->i_idxmax * 
                            sizeof( AVIIndexEntry_t ) );
         if( p_tmp == NULL ) 
         { 
-            p_info->i_idxmax -= 4096;
+            p_info->i_idxmax -= 16384;
             return; 
         }
         p_info->p_index = p_tmp;
@@ -321,7 +321,7 @@ static int __AVI_SeekToChunk( input_thread_t *p_input, AVIStreamInfo_t *p_info )
         return( 0 );
     }
     /* no index can't arrive but ...*/
-    intf_WarnMsg( 1, "CAN'T SEEK");
+    intf_WarnMsg( 1, "input error: can't seek");
     return( -1 );
 }
 
@@ -422,7 +422,14 @@ static int AVIInit( input_thread_t *p_input )
     es_descriptor_t *p_es_audio;
 
     int i;
-    
+
+    /* we need to seek to be able to readcorrectly */
+    if( !p_input->stream.b_seekable ) 
+    {
+        intf_ErrMsg( "input error: need the ability to seek in stream" );
+        return( -1 );
+    }
+
     p_input->p_demux_data = 
                 p_avi_demux = malloc( sizeof(demux_data_avi_file_t) );
     if( p_avi_demux == NULL )
@@ -643,17 +650,16 @@ static int AVIInit( input_thread_t *p_input )
     p_avi_demux->p_movi = p_movi;
     
     /* get index  XXX need to have p_movi */
-    
-    if( (p_input->stream.b_seekable)
-         &&((p_avi_demux->avih.i_flags&AVIF_HASINDEX) != 0) )
+    if( (p_avi_demux->avih.i_flags&AVIF_HASINDEX) != 0 )
     {
+        /* get index */
         __AVI_GetIndex( p_input ); 
         /* try to get i_idxoffset for each stream  */
         __AVI_GetIndexOffset( p_input );
     }
     else
     {
-        intf_WarnMsg( 1, "input init: cannot get index" );
+        intf_WarnMsg( 1, "input init: no index !" );
     }
 
     
@@ -815,7 +821,7 @@ static void AVIEnd( input_thread_t *p_input )
 
 static mtime_t __AVI_GetPTS( AVIStreamInfo_t *p_info )
 {
-    /* XXX you need to had p_info->i_date to have correct pts */
+    /* XXX you need to add p_info->i_date to have correct pts */
     /* p_info->p_index[p_info->i_idxpos] need to be valid !! */
     mtime_t i_pts;
 
@@ -846,9 +852,11 @@ static int __AVI_NextIndexEntry( input_thread_t *p_input,
     AVIIndexEntry_t index;
     riffchunk_t     *p_chunk;
     demux_data_avi_file_t *p_avi_demux;
-
+    AVIStreamInfo_t *p_info_tmp;
+    int             i;
+    int             i_idxpos;
+    int             b_inc = 0;
     p_avi_demux = (demux_data_avi_file_t*)p_input->p_demux_data;
-        
 
     p_info->i_idxpos++;
 
@@ -856,35 +864,90 @@ static int __AVI_NextIndexEntry( input_thread_t *p_input,
     {
         return( 0 );
     }
+    p_info->i_idxpos--;
     /* create entry on the fly */
     /* TODO: when parsing for a stream take care of the other to not do 
        the same things two time */
-    p_info->i_idxpos--;
-    __AVI_SeekToChunk( p_input, p_info );
+    /* search for the less advance stream and parse from it for all streams*/
+    p_info_tmp = p_info;
+    
+    for( i = 0; i < p_avi_demux->i_streams; i++ )
+    {
+#define p_info_i p_avi_demux->pp_info[i]
+        if( p_info_i->p_index[p_info_i->i_idxnb - 1].i_offset + 
+                        p_info_i->i_idxoffset < 
+            p_info_tmp->p_index[p_info_tmp->i_idxnb - 1].i_offset +
+                        p_info_tmp->i_idxoffset )
+        {
+            p_info_tmp = p_info_i;
+        }
+#undef  p_info_i
+    }
+    /* go to last defined entry */
+    i_idxpos = p_info_tmp->i_idxpos; /* save p_info_tmp->i_idxpos */
+    p_info_tmp->i_idxpos = p_info_tmp->i_idxnb - 1;
+    __AVI_SeekToChunk( p_input, p_info_tmp );
+    p_info_tmp->i_idxpos = i_idxpos;
+
     if( RIFF_NextChunk( p_input, p_avi_demux->p_movi ) != 0 )
     {
+        __AVI_SeekToChunk( p_input, p_info );
         return( -1 );
     }
-    /* FIXME */
-    /* p_info->p_input[0].i_id may not always be true for video 
-        because of db and dc */
-    if( (RIFF_FindChunk( p_input, p_info->p_index[0].i_id, 
-                                    p_avi_demux->p_movi ) == 0)
-        &&( (p_chunk = RIFF_ReadChunk( p_input )) != NULL) )
+    /* save idxpos of p_info */
+    /* now parse for all stream and stop when reach next chunk for p_info */
+    for( i = 0; (i < 20)||(!b_inc); i++)
     {
+        int i_number;
+        u16 i_type;
+        if( (p_chunk = RIFF_ReadChunk( p_input )) == NULL )
+        {
+            if( i > 0)
+            {
+                return( 0 );
+            }
+            else
+            {
+                return( -1 );
+            }
+        }
+
         index.i_id = p_chunk->i_id;
         index.i_flags = AVIIF_KEYFRAME;
         index.i_offset = p_chunk->i_pos;
         index.i_length = p_chunk->i_size;
-        __AVI_AddEntryIndex( p_info, &index );
-        p_info->i_idxpos++;
-    }
-    else
-    {
-        __AVI_SeekToChunk( p_input, p_info ); /* if readchunk failed */
-        return( -1 );
-    }
-    return( 0 );    
+        RIFF_DeleteChunk( p_input, p_chunk );
+
+#define p_info_i    p_avi_demux->pp_info[i_number]
+       if( (__AVI_ParseStreamHeader( index.i_id, &i_number, &i_type ) == 0)
+             &&( i_number < p_avi_demux->i_streams )
+             && (p_info_i->p_index[p_info_i->i_idxnb - 1].i_offset + 
+                     p_info_i->p_index[p_info_i->i_idxnb - 1].i_length <= 
+                        index.i_offset ) )
+        {
+            /* do we need to check i_type ? */
+            __AVI_AddEntryIndex( p_info_i, &index );
+            if( (p_info_i == p_info)&&(!b_inc) )
+            {
+                p_info->i_idxpos++;
+                b_inc = 1;
+            }
+        }
+#undef  p_info_i
+        if( RIFF_NextChunk( p_input, p_avi_demux->p_movi ) != 0 )
+        {
+            if( i > 0)
+            {
+                return( 0 );
+            }
+            else
+            {
+                return( -1 );
+            }
+        }
+    } 
+    return( 0 );
+    intf_WarnMsg( 1, "input demux: added index entry(%d)",i );
 }
 
 static int __AVI_ReAlign( input_thread_t *p_input, 
@@ -1045,7 +1108,6 @@ static int AVIDemux( input_thread_t *p_input )
         intf_ErrMsg( "input error: no video ouput selected" );
         return( -1 );
     }
-
     if( (input_ClockManageControl( p_input, p_input->stream.p_selected_program,
                             (mtime_t)0) == PAUSE_S) )
     {   
index 779566d61907f81c82c32529dba45bb4cb5adcfe..0b50d1fd15c67ca778f6be31eb5776bff0564207 100644 (file)
@@ -2,7 +2,7 @@
  * ffmpeg.c: video decoder using ffmpeg library
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: ffmpeg.c,v 1.2 2002/04/25 03:01:03 fenrir Exp $
+ * $Id: ffmpeg.c,v 1.3 2002/04/27 16:13:23 fenrir Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -454,10 +454,10 @@ static void EndThread( videodec_thread_t *p_vdec )
 
 static void  DecodeThread( videodec_thread_t *p_vdec )
 {
-    int i_len;
-    int b_gotpicture;
-    int b_convert;
-   
+    int     i_len;
+    int     b_gotpicture;
+    int     b_convert;
+    mtime_t i_pts; 
     pes_packet_t  *p_pes;
     AVPicture avpicture;  /* ffmpeg picture */
     u32 i_chroma;
@@ -475,7 +475,7 @@ static void  DecodeThread( videodec_thread_t *p_vdec )
      int linesize[3];
  } AVPicture;
  */
-    p_pes = NULL;
+    i_pts = -1 ;
     do
     {
         __PACKET_FILL( p_vdec );
@@ -483,13 +483,15 @@ static void  DecodeThread( videodec_thread_t *p_vdec )
         {
             return;
         }
-        /* save p_pes for pts */
-        if( p_pes == NULL ) {p_pes = __PES_GET( p_vdec->p_fifo );}
+        /* save pts */
+        if( i_pts < 0 ) {i_pts =  __PES_GET( p_vdec->p_fifo )->i_pts;}
+
         i_len = avcodec_decode_video( p_vdec->p_context,
                                       &avpicture,
                                       &b_gotpicture,
                                       p_vdec->p_buff,
                                       p_vdec->i_data_size);
+                                      
         if( i_len < 0 )
         {
             intf_WarnMsg( 1, "vdec error: cannot decode one frame (%d bytes)",
@@ -603,7 +605,7 @@ static void  DecodeThread( videodec_thread_t *p_vdec )
         __ConvertAVPictureToPicture( &avpicture, p_picture );
     }
 
-    vout_DatePicture( p_vdec->p_vout, p_picture, p_pes->i_pts );
+    vout_DatePicture( p_vdec->p_vout, p_picture, i_pts );
     vout_DisplayPicture( p_vdec->p_vout, p_picture );
     
     return;