* cinepak: add a new fourcc
authorLaurent Aimar <fenrir@videolan.org>
Tue, 23 Jul 2002 17:19:02 +0000 (17:19 +0000)
committerLaurent Aimar <fenrir@videolan.org>
Tue, 23 Jul 2002 17:19:02 +0000 (17:19 +0000)
 * ffmpeg and mp4: some clean up and change the way ffmpeg is
initialised.

plugins/cinepak/cinepak.c
plugins/ffmpeg/ffmpeg.c
plugins/ffmpeg/ffmpeg.h
plugins/mp4/libmp4.c
plugins/mp4/libmp4.h
plugins/mp4/mp4.c
plugins/mp4/mp4.h

index 064ae28..d15fc3a 100644 (file)
@@ -2,7 +2,7 @@
  * cinepak.c: cinepak video decoder 
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: cinepak.c,v 1.3 2002/07/23 00:39:16 sam Exp $
+ * $Id: cinepak.c,v 1.4 2002/07/23 17:19:02 fenrir Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -92,7 +92,14 @@ MODULE_DEACTIVATE_STOP
  *****************************************************************************/
 static int decoder_Probe( vlc_fourcc_t *pi_type )
 {
-    return( ( *pi_type == VLC_FOURCC('c','v','i','d') ) ? 0 : -1 );
+    switch(  *pi_type )
+    {
+        case( VLC_FOURCC('c','v','i','d') ):
+        case( VLC_FOURCC('C','V','I','D') ):
+            return( 0);
+        default:
+            return( -1 );
+    }
 }
 
 /*****************************************************************************
index 1ea72b0..5c9fc56 100644 (file)
@@ -2,7 +2,7 @@
  * ffmpeg.c: video decoder using ffmpeg library
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: ffmpeg.c,v 1.19 2002/07/23 00:39:17 sam Exp $
+ * $Id: ffmpeg.c,v 1.20 2002/07/23 17:19:02 fenrir Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -174,19 +174,33 @@ static int decoder_Run ( decoder_fifo_t * p_fifo )
     (  *(u8*)(p) + ( *((u8*)(p)+1) << 8 ) + \
       ( *((u8*)(p)+2) << 16 ) + ( *((u8*)(p)+3) << 24 ) )
 
-static void __ParseBitMapInfoHeader( bitmapinfoheader_t *h, byte_t *p_data )
+static void ffmpeg_ParseBitMapInfoHeader( bitmapinfoheader_t *p_bh, 
+                                          u8 *p_data )
 {
-    h->i_size          = GetDWLE( p_data );
-    h->i_width         = GetDWLE( p_data + 4 );
-    h->i_height        = GetDWLE( p_data + 8 );
-    h->i_planes        = GetWLE( p_data + 12 );
-    h->i_bitcount      = GetWLE( p_data + 14 );
-    h->i_compression   = GetDWLE( p_data + 16 );
-    h->i_sizeimage     = GetDWLE( p_data + 20 );
-    h->i_xpelspermeter = GetDWLE( p_data + 24 );
-    h->i_ypelspermeter = GetDWLE( p_data + 28 );
-    h->i_clrused       = GetDWLE( p_data + 32 );
-    h->i_clrimportant  = GetDWLE( p_data + 36 );
+    p_bh->i_size          = GetDWLE( p_data );
+    p_bh->i_width         = GetDWLE( p_data + 4 );
+    p_bh->i_height        = GetDWLE( p_data + 8 );
+    p_bh->i_planes        = GetWLE( p_data + 12 );
+    p_bh->i_bitcount      = GetWLE( p_data + 14 );
+    p_bh->i_compression   = GetDWLE( p_data + 16 );
+    p_bh->i_sizeimage     = GetDWLE( p_data + 20 );
+    p_bh->i_xpelspermeter = GetDWLE( p_data + 24 );
+    p_bh->i_ypelspermeter = GetDWLE( p_data + 28 );
+    p_bh->i_clrused       = GetDWLE( p_data + 32 );
+    p_bh->i_clrimportant  = GetDWLE( p_data + 36 );
+
+    if( p_bh->i_size > 40 )
+    {
+        p_bh->i_data = p_bh->i_size - 40;
+        p_bh->p_data = malloc( p_bh->i_data ); 
+        memcpy( p_bh->p_data, p_data + 40, p_bh->i_data );
+    }
+    else
+    {
+        p_bh->i_data = 0;
+        p_bh->p_data = NULL;
+    } 
+
 }
 /* get the first pes from fifo */
 static pes_packet_t *__PES_GET( decoder_fifo_t *p_fifo )
@@ -423,89 +437,6 @@ static vout_thread_t *ffmpeg_CreateVout( videodec_thread_t *p_vdec,
     return( p_vout );
 }
 
-#if 0
-/* segfault some^Wevery times*/
-static void ffmpeg_ConvertPictureI410toI420( picture_t *p_pic,
-                                             AVPicture *p_avpicture,
-                                             videodec_thread_t   *p_vdec )
-{
-    int i_plane; 
-    
-    int i_x, i_y;
-    int i_x_max, i_y_max;
-
-    int i_width;
-    int i_height; 
-
-    int i_dst_stride;
-    int i_src_stride;
-    
-    u8  *p_dest;
-    u8  *p_src;
-
-    i_width = p_vdec->p_context->width;
-    i_height= p_vdec->p_context->height;
-    
-
-    p_dest = p_pic->p[0].p_pixels;
-    p_src  = p_avpicture->data[0];
-
-    i_src_stride = p_avpicture->linesize[0];
-    i_dst_stride = p_pic->p[0].i_pitch;
-    
-    if( i_src_stride == i_dst_stride )
-    {
-        p_vdec->p_fifo->p_vlc->pf_memcpy( p_dest, p_src, i_src_stride * i_height  );
-    }
-    else
-    {
-        for( i_y = 0; i_y < i_height; i_y++ )
-        {
-            p_vdec->p_fifo->p_vlc->pf_memcpy( p_dest, p_src, i_width );
-            p_dest += i_dst_stride;
-            p_src  += i_src_stride;
-        }
-    }
-
-    for( i_plane = 1; i_plane < 3; i_plane++ )
-    {
-        i_y_max = p_pic->p[i_plane].i_lines;
-        
-        p_src  = p_avpicture->data[i_plane];
-        p_dest = p_pic->p[i_plane].p_pixels;
-        i_dst_stride = p_pic->p[i_plane].i_pitch;
-        i_src_stride = p_avpicture->linesize[i_plane];
-
-        i_x_max = __MIN( i_dst_stride / 2, i_src_stride );
-
-        for( i_y = 0; i_y <( i_y_max + 1 ) / 2 ; i_y++ )
-        {
-            for( i_x = 0; i_x < i_x_max - 1; i_x++ )
-            {
-                p_dest[2 * i_x    ] = p_src[i_x];
-                p_dest[2 * i_x + 1] = ( p_src[i_x] + p_src[i_x + 1] ) / 2;
-            }
-            p_dest[2 * i_x_max - 2] = p_src[i_x];
-            p_dest[2 * i_x_max - 1] = p_src[i_x];
-
-            p_dest += 2 * i_dst_stride;
-            p_src  += i_src_stride;
-        }
-        
-        p_src  = p_pic->p[i_plane].p_pixels;
-        p_dest = p_src + i_dst_stride;
-
-        for( i_y = 0; i_y < ( i_y_max + 1 ) / 2 ; i_y++ )
-        {
-            p_vdec->p_fifo->p_vlc->pf_memcpy( p_dest, p_src, i_dst_stride ); 
-            p_dest += 2*i_dst_stride;
-            p_src  += 2*i_dst_stride;
-        }
-
-    }
-}
-#endif
-
 /* FIXME FIXME FIXME this is a big shit
    does someone want to rewrite this function ? 
    or said to me how write a better thing
@@ -679,8 +610,8 @@ static int InitThread( videodec_thread_t *p_vdec )
     
     if( p_vdec->p_fifo->p_demux_data )
     {
-        __ParseBitMapInfoHeader( &p_vdec->format, 
-                                (byte_t*)p_vdec->p_fifo->p_demux_data );
+        ffmpeg_ParseBitMapInfoHeader( &p_vdec->format, 
+                                      (u8*)p_vdec->p_fifo->p_demux_data );
     }
     else
     {
@@ -755,10 +686,29 @@ static int InitThread( videodec_thread_t *p_vdec )
         msg_Dbg( p_vdec->p_fifo, "ffmpeg codec (%s) started",
                                  p_vdec->psz_namecodec );
     }
-
+    
+    /* first give init data */
+    if( p_vdec->format.i_data )
+    {
+        AVPicture avpicture;
+        int b_gotpicture;
+        
+        switch( i_ffmpeg_codec )
+        {
+            case( CODEC_ID_MPEG4 ):
+                avcodec_decode_video( p_vdec->p_context, &avpicture, 
+                                      &b_gotpicture,
+                                      p_vdec->format.p_data,
+                                      p_vdec->format.i_data );
+                break;
+            default:
+                break;
+        }
+    }
+    
     /* This will be created after the first decoded frame */
     p_vdec->p_vout = NULL;
-
+    
     return( 0 );
 }
 
@@ -921,6 +871,11 @@ static void EndThread( videodec_thread_t *p_vdec )
         vlc_object_detach( p_vdec->p_vout, p_vdec->p_fifo );
         vlc_object_attach( p_vdec->p_vout, p_vdec->p_fifo->p_vlc );
     }
+
+    if( p_vdec->format.p_data != NULL)
+    {
+        free( p_vdec->format.p_data );
+    }
     
     free( p_vdec );
 }
index 79eb22f..c3eb770 100644 (file)
@@ -2,7 +2,7 @@
  * ffmpeg_vdec.h: video decoder using ffmpeg library
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: ffmpeg.h,v 1.7 2002/07/23 00:39:17 sam Exp $
+ * $Id: ffmpeg.h,v 1.8 2002/07/23 17:19:02 fenrir Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  * 
@@ -35,6 +35,10 @@ typedef struct bitmapinfoheader_s
     u32 i_ypelspermeter;
     u32 i_clrused;
     u32 i_clrimportant;
+
+    int i_data;
+    u8  *p_data;
+
 } bitmapinfoheader_t;
 
 /* MPEG4 video */
index c965f81..618224e 100644 (file)
@@ -2,7 +2,7 @@
  * libmp4.c : LibMP4 library for mp4 module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: libmp4.c,v 1.4 2002/07/23 00:39:17 sam Exp $
+ * $Id: libmp4.c,v 1.5 2002/07/23 17:19:02 fenrir Exp $
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  * 
  * This program is free software; you can redistribute it and/or modify
@@ -1208,6 +1208,9 @@ int MP4_ReadBox_sample_soun( MP4_Stream_t *p_stream, MP4_Box_t *p_box )
     MP4_GET2BYTES( p_box->data.p_sample_soun->i_sampleratehi );
     MP4_GET2BYTES( p_box->data.p_sample_soun->i_sampleratelo );
     
+    MP4_SeekStream( p_stream, p_box->i_pos + MP4_BOX_HEADERSIZE( p_box ) + 28 );
+    MP4_ReadBoxContainerRaw( p_stream, p_box ); /* esds */
+   
 #ifdef MP4_VERBOSE
     msg_Dbg( p_stream->p_input, "Read Box: \"soun\" in stsd channel %d sample size %d sampl rate %f",
                       p_box->data.p_sample_soun->i_channelcount,
@@ -1219,6 +1222,7 @@ int MP4_ReadBox_sample_soun( MP4_Stream_t *p_stream, MP4_Box_t *p_box )
     MP4_READBOX_EXIT( 1 );
 }
 
+#if 0
 int MP4_ReadBox_sample_mp4a( MP4_Stream_t *p_stream, MP4_Box_t *p_box )
 {
     int i;    
@@ -1257,6 +1261,7 @@ int MP4_ReadBox_sample_mp4a( MP4_Stream_t *p_stream, MP4_Box_t *p_box )
 #endif
     MP4_READBOX_EXIT( 1 );
 }
+#endif
 
 int MP4_ReadBox_sample_vide( MP4_Stream_t *p_stream, MP4_Box_t *p_box )
 {
@@ -1991,7 +1996,7 @@ static struct
     /* for codecs */
     { FOURCC_soun,  MP4_ReadBox_sample_soun,    MP4_FreeBox_Common },
     { FOURCC__mp3,  MP4_ReadBox_sample_soun,    MP4_FreeBox_Common },
-    { FOURCC_mp4a,  MP4_ReadBox_sample_mp4a,    MP4_FreeBox_Common },
+    { FOURCC_mp4a,  MP4_ReadBox_sample_soun,    MP4_FreeBox_Common },
 
     { FOURCC_vide,  MP4_ReadBox_sample_vide,    MP4_FreeBox_Common },
     { FOURCC_mp4v,  MP4_ReadBox_sample_vide,    MP4_FreeBox_Common },
index f1b7472..f376942 100644 (file)
@@ -2,7 +2,7 @@
  * libmp4.h : LibMP4 library for mp4 module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: libmp4.h,v 1.4 2002/07/23 00:39:17 sam Exp $
+ * $Id: libmp4.h,v 1.5 2002/07/23 17:19:02 fenrir Exp $
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  * 
  * This program is free software; you can redistribute it and/or modify
@@ -321,22 +321,6 @@ typedef struct MP4_Box_data_sample_soun_s
     
 } MP4_Box_data_sample_soun_t;
 
-typedef struct MP4_Box_data_sample_mp4a_s
-{
-    u8  i_reserved1[6];
-    u16 i_data_reference_index;
-
-    u32 i_reserved2[2];
-    u16 i_channelcount;
-    u16 i_samplesize;
-    u16 i_predefined;
-    u16 i_reserved3;
-    u16 i_sampleratehi; /* timescale of track */
-    u16 i_sampleratelo;
-    
-} MP4_Box_data_sample_mp4a_t;
-
-
 typedef struct MP4_Box_data_sample_vide_s
 {
     u8  i_reserved1[6];
@@ -362,34 +346,6 @@ typedef struct MP4_Box_data_sample_vide_s
     
 } MP4_Box_data_sample_vide_t;
 
-/*
-typedef struct MP4_Box_data_sample_mp4v_s
-{
-    u8  i_reserved1[6];
-    u16 i_data_reference_index;
-
-    u16 i_predefined1;
-    u16 i_reserved2;
-    u32 i_predefined2[3];
-
-    s16 i_width;
-    s16 i_height;
-
-    u32 i_horizresolution;
-    u32 i_vertresolution;
-
-    u32 i_reserved3;
-    u16 i_predefined3;
-    
-    u8  i_compressorname[32];
-    s16 i_depth;
-
-    s16 i_predefined4;
-    
-} MP4_Box_data_sample_mp4v_t;
-
-*/
-
 typedef struct MP4_Box_data_sample_hint_s
 {
     u8  i_reserved1[6];
@@ -648,9 +604,7 @@ typedef union MP4_Box_data_s
     MP4_Box_data_ctts_t *p_ctts;
     MP4_Box_data_stsd_t *p_stsd;
         MP4_Box_data_sample_vide_t *p_sample_vide;
-        MP4_Box_data_sample_vide_t *p_sample_mp4v;
         MP4_Box_data_sample_soun_t *p_sample_soun;
-        MP4_Box_data_sample_soun_t *p_sample_mp4a;
         MP4_Box_data_sample_hint_t *p_sample_hint;
 
         MP4_Box_data_esds_t *p_esds;
index 366ce71..a994874 100644 (file)
@@ -2,7 +2,7 @@
  * mp4.c : MP4 file input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: mp4.c,v 1.5 2002/07/23 00:39:17 sam Exp $
+ * $Id: mp4.c,v 1.6 2002/07/23 17:19:02 fenrir Exp $
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  * 
  * This program is free software; you can redistribute it and/or modify
@@ -89,7 +89,7 @@ static int  MP4_ReadSample();
 static int  MP4_DecodeSample();
 
 #define MP4_Set4BytesLE( p, dw ) \
-    *((u8*)p) = ( dw&0xff ); \
+    *((u8*)p)   = ( (dw)&0xff ); \
     *((u8*)p+1) = ( ((dw)>> 8)&0xff ); \
     *((u8*)p+2) = ( ((dw)>>16)&0xff ); \
     *((u8*)p+3) = ( ((dw)>>24)&0xff )
@@ -186,7 +186,11 @@ static int MP4Init( input_thread_t *p_input )
                 break;
             default:
                 msg_Info( p_input,
-                          "Unrecognize major file specification." );
+                          "Unrecognize major file specification (%c%c%c%c).",
+                           p_ftyp->data.p_ftyp->i_major_brand&0xff,
+                           ( p_ftyp->data.p_ftyp->i_major_brand >>  8)&0xff,
+                           ( p_ftyp->data.p_ftyp->i_major_brand >> 16 )&0xff,
+                           ( p_ftyp->data.p_ftyp->i_major_brand >> 24 )&0xff );
                 break;
         }
     }
@@ -406,14 +410,7 @@ static void MP4End( input_thread_t *p_input )
                FREE(p_demux->track[i_track].chunk[i_chunk].p_sample_delta_dts );
             }
         }
-#if 0
-/*        if( p_demux->track->p_data_init )
-        {
-            input_DeletePacket( p_input->p_method_data, 
-                                p_demux->track->p_data_init );
-        }
-        */
-#endif 
+
         if( !p_demux->track[i_track].i_sample_size )
         {
             FREE( p_demux->track[i_track].p_sample_size );
@@ -754,7 +751,11 @@ static void MP4_StartDecoder( input_thread_t *p_input,
     MP4_Box_t *p_sample;
     int i;
     int i_chunk;
-    u8  *p_bmih;
+
+    int i_decoder_specific_info_len;
+    u8  *p_decoder_specific_info;
+    
+    u8  *p_init;
  
     MP4_Box_t *p_esds;
 
@@ -772,20 +773,29 @@ static void MP4_StartDecoder( input_thread_t *p_input,
 
     if( !p_demux_track->chunk[i_chunk].i_sample_description_index )
     {
-        msg_Warn( p_input, "invalid SampleEntry index for this track i_cat %d" );
+        msg_Warn( p_input, 
+                  "invalid SampleEntry index (track ID 0x%x)",
+                  p_demux_track->i_track_ID );
         return;
     } 
     
     p_sample = MP4_FindNbBox( p_demux_track->p_stsd,
-                              p_demux_track->chunk[i_chunk].i_sample_description_index - 1);
+                 p_demux_track->chunk[i_chunk].i_sample_description_index - 1);
 
-    if( !p_sample )
+    if( ( !p_sample )||( !p_sample->data.p_data ) )
     {
-        msg_Warn( p_input, "cannot find SampleEntry for this track" );
+        msg_Warn( p_input, 
+                  "cannot find SampleEntry (track ID 0x%x)",
+                  p_demux_track->i_track_ID );
         return;
     }
 
-    
+    if( !p_sample->data.p_data )
+    {
+        printf( "\nAhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh %.4s\n",
+                &p_sample->i_type );
+        return;
+    } 
     vlc_mutex_lock( &p_input->stream.stream_lock );
     p_demux_track->p_es = input_AddES( p_input,
                                        p_input->stream.p_selected_program, 
@@ -803,68 +813,149 @@ static void MP4_StartDecoder( input_thread_t *p_input,
 
     p_demux_track->p_es->i_fourcc = p_sample->i_type;
     p_demux_track->p_es->i_cat = p_demux_track->i_cat;
+    
+    i_decoder_specific_info_len = 0;
+    p_decoder_specific_info = NULL;
 
     /* now see if esds is present and if so create a data packet 
         with decoder_specific_info  */
 #define p_decconfig p_esds->data.p_esds->es_descriptor.p_decConfigDescr
-    if( ( p_esds = MP4_FindBox( p_sample, FOURCC_esds ) )
-         && p_decconfig && p_decconfig->i_decoder_specific_info_len )
+    if( ( p_esds = MP4_FindBox( p_sample, FOURCC_esds ) )&&
+        ( p_esds->data.p_esds )&&
+        ( p_decconfig ) )
     {
-        data_packet_t *p_data;
-        int i_size = p_decconfig->i_decoder_specific_info_len;
-
-        /* data packet for the data */
-        if( !(p_data = input_NewPacket( p_input->p_method_data, i_size ) ) )
+        /* First update information based on i_objectTypeIndication */
+        switch( p_decconfig->i_objectTypeIndication )
         {
-            return;
+            case( 0x20 ): /* MPEG4 VIDEO */
+                p_demux_track->p_es->i_fourcc = VLC_FOURCC( 'm','p','4','v' );
+                break;
+            case( 0x40):
+                p_demux_track->p_es->i_fourcc = VLC_FOURCC( 'm','p','4','a' );
+                break;
+            case( 0x60):
+            case( 0x61):
+            case( 0x62):
+            case( 0x63):
+            case( 0x64):
+            case( 0x65): /* MPEG2 video */
+                p_demux_track->p_es->i_fourcc = VLC_FOURCC( 'm','p','g','v' );
+                break;
+            /* Theses are MPEG2-AAC (what is this codec ?) */
+            case( 0x66): /* main profile */
+            case( 0x67): /* Low complexity profile */
+            case( 0x68): /* Scaleable Sampling rate profile */
+                p_demux_track->p_es->i_fourcc = VLC_FOURCC( 'm','p','4','a' );
+                break;
+            /* true MPEG 2 audio */
+            case( 0x69): 
+                p_demux_track->p_es->i_fourcc = VLC_FOURCC( 'm','p','g','a' );
+                break;
+            case( 0x6a): /* MPEG1 video */
+                p_demux_track->p_es->i_fourcc = VLC_FOURCC( 'm','p','g','v' );
+                break;
+            case( 0x6b): /* MPEG1 audio */
+                p_demux_track->p_es->i_fourcc = VLC_FOURCC( 'm','p','g','a' );
+                break;
+            case( 0x6c ): /* jpeg */
+                p_demux_track->p_es->i_fourcc = VLC_FOURCC( 'j','p','e','g' );
+                break;
+            default:
+                /* Unknown entry, but don't touch i_fourcc */
+                msg_Warn( p_input, 
+                          "objectTypeIndication(0x%x) unknow (Track ID 0x%x)",
+                          p_decconfig->i_objectTypeIndication,
+                          p_demux_track->i_track_ID );
+                break;
         }
-
-        memcpy( p_data->p_payload_start,
-                p_decconfig->p_decoder_specific_info,
-                i_size ); 
-        p_demux_track->p_data_init = p_data;
+        i_decoder_specific_info_len = 
+                p_decconfig->i_decoder_specific_info_len;
+        p_decoder_specific_info = 
+                p_decconfig->p_decoder_specific_info;
     }
+
 #undef p_decconfig
 
     /* some last initialisation */
+    /* XXX I create a bitmapinfoheader_t or 
+       waveformatex_t for each stream, up to now it's the best thing 
+       I've found but it could exist a better solution :) as something 
+       like adding some new fields in p_es ...
+
+       XXX I don't set all values, only thoses that are interesting or known
+        --> bitmapinfoheader_t : width and height 
+        --> waveformatex_t : channels, samplerate, bitspersample
+        and at the end I add p_decoder_specific_info 
+        
+        TODO set more values
+     
+     */
+
     switch( p_demux_track->i_cat )
     {
         case( VIDEO_ES ):    
-            /* now create a bitmapinfoheader_t for decoder */
-            p_bmih = malloc( 40 );
-            memset( p_bmih, 0, 40);
-            MP4_Set4BytesLE( p_bmih, 40 );
-            if( p_sample->data.p_sample_mp4v
-                 && p_sample->data.p_sample_mp4v->i_width )
+            /* now create a bitmapinfoheader_t for decoder and 
+               add information found in p_esds */
+            p_init = malloc( 40 + i_decoder_specific_info_len);
+            memset( p_init, 0, 40 + i_decoder_specific_info_len);
+            MP4_Set4BytesLE( p_init, 40 + i_decoder_specific_info_len );
+            if( p_sample->data.p_sample_vide->i_width )
             {
-                MP4_Set4BytesLE( p_bmih + 4, 
-                                 p_sample->data.p_sample_mp4v->i_width );
+                MP4_Set4BytesLE( p_init + 4, 
+                                 p_sample->data.p_sample_vide->i_width );
             }
             else
             {
                 /* use display size */
-                MP4_Set4BytesLE( p_bmih + 4, p_demux_track->i_width );
+                MP4_Set4BytesLE( p_init + 4, p_demux_track->i_width );
             }
-            if( p_sample->data.p_sample_mp4v
-                 && p_sample->data.p_sample_mp4v->i_height )
+            if( p_sample->data.p_sample_vide->i_height )
             {
-                MP4_Set4BytesLE( p_bmih + 8, 
-                                 p_sample->data.p_sample_mp4v->i_height );
+                MP4_Set4BytesLE( p_init + 8, 
+                                 p_sample->data.p_sample_vide->i_height );
             }
             else
             {
-                MP4_Set4BytesLE( p_bmih + 8, p_demux_track->i_height );
+                MP4_Set4BytesLE( p_init + 8, p_demux_track->i_height );
+            }
+            if( i_decoder_specific_info_len )
+            {
+                memcpy( p_init + 40, 
+                        p_decoder_specific_info,
+                        i_decoder_specific_info_len);
             }
-
-            p_demux_track->p_es->p_demux_data = p_bmih;
             break;
+
         case( AUDIO_ES ):
+            p_init = malloc( 18 + i_decoder_specific_info_len);
+            memset( p_init, 0, 18 + i_decoder_specific_info_len);
+            MP4_Set2BytesLE( p_init + 2, /* i_channel */
+                             p_sample->data.p_sample_soun->i_channelcount );
+            MP4_Set4BytesLE( p_init + 4, /* samplepersec */
+                             p_sample->data.p_sample_soun->i_sampleratehi );
+            MP4_Set4BytesLE( p_init + 8, /* avgbytespersec */
+                             p_sample->data.p_sample_soun->i_channelcount *
+                                p_sample->data.p_sample_soun->i_sampleratehi *
+                             (p_sample->data.p_sample_soun->i_samplesize/8) );
+            MP4_Set2BytesLE( p_init + 14, /* bits/sample */
+                             p_sample->data.p_sample_soun->i_samplesize );
+
+            MP4_Set2BytesLE( p_init + 16, /* i_size, specific info len*/
+                             i_decoder_specific_info_len );
+            if( i_decoder_specific_info_len )
+            {
+                memcpy( p_init + 18, 
+                        p_decoder_specific_info,
+                        i_decoder_specific_info_len);
+            }
             break;
+
         default:
+            p_init = NULL;
             break;
     }
 
-
+    p_demux_track->p_es->p_demux_data = p_init;
     vlc_mutex_lock( &p_input->stream.stream_lock );
     input_SelectES( p_input, p_demux_track->p_es );
     vlc_mutex_unlock( &p_input->stream.stream_lock );
@@ -872,7 +963,6 @@ static void MP4_StartDecoder( input_thread_t *p_input,
     p_demux_track->b_ok = 1;
 }
 
-
 static void MP4_StopDecoder( input_thread_t *p_input,
                              track_data_mp4_t *p_demux_track )
 {
@@ -881,13 +971,6 @@ static void MP4_StopDecoder( input_thread_t *p_input,
 
     input_UnselectES( p_input, p_demux_track->p_es );
     p_demux_track->p_es = NULL;
-    if( p_demux_track->p_data_init )
-    {
-        input_DeletePacket( p_input->p_method_data, 
-                            p_demux_track->p_data_init );
-        p_demux_track->p_data_init = NULL;
-    }
-    
 }
 
 static int  MP4_ReadSample( input_thread_t *p_input,
@@ -908,7 +991,8 @@ static int  MP4_ReadSample( input_thread_t *p_input,
     }
     /* caculate size and position for this sample */
     i_size = p_demux_track->i_sample_size ? 
-        p_demux_track->i_sample_size : p_demux_track->p_sample_size[p_demux_track->i_sample];
+                    p_demux_track->i_sample_size : 
+                    p_demux_track->p_sample_size[p_demux_track->i_sample];
     /* TODO */
     i_pos  = MP4_GetTrackPos( p_demux_track );
 
@@ -974,28 +1058,6 @@ static int  MP4_DecodeSample( input_thread_t *p_input,
                                          p_pes->i_pts * 9/100);
 
     
-    if( p_demux_track->p_data_init )
-    {
-        pes_packet_t *p_pes_init;
-        /* create a pes packet containing decoder initialisation 
-           with the one we will send to decoder */
-        if( !(p_pes_init = input_NewPES( p_input->p_method_data ) ) )
-        {
-            msg_Err( p_input, "out of memory" );
-            return( 0 );
-        }
-        
-        p_pes_init->p_first = 
-            p_pes_init->p_last = p_demux_track->p_data_init;
-
-        p_pes_init->i_pes_size = p_demux_track->p_data_init->p_payload_end - 
-                                   p_demux_track->p_data_init->p_payload_start;
-        p_pes_init->i_nb_data = 1;
-
-        input_DecodePES( p_demux_track->p_es->p_decoder_fifo, p_pes_init );
-        p_demux_track->p_data_init = NULL;
-    }
-
     input_DecodePES( p_demux_track->p_es->p_decoder_fifo, p_pes );
     
     /* now update sample position */
@@ -1020,8 +1082,10 @@ static int  MP4_DecodeSample( input_thread_t *p_input,
               != p_demux_track->chunk[p_demux_track->i_chunk].i_sample_description_index  )
         {
             /* FIXME */
-            msg_Err( p_input, "I need to change the decoder but not yet implemented" );
-            return( 0 );
+            msg_Warn( p_input, 
+                      "SampleEntry have changed, starting a new decoder" );
+            MP4_StopDecoder( p_input, p_demux_track );
+            MP4_StartDecoder( p_input, p_demux_track );
         }
     }
 
index 20bcc32..b2f7d60 100644 (file)
@@ -2,7 +2,7 @@
  * mp4.h : MP4 file input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: mp4.h,v 1.5 2002/07/23 00:39:17 sam Exp $
+ * $Id: mp4.h,v 1.6 2002/07/23 17:19:02 fenrir Exp $
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  * 
  * This program is free software; you can redistribute it and/or modify
 
 
 /*****************************************************************************
- * Structure needed for ffmpeg decoder
+ * Structure needed for decoder
  *****************************************************************************/
-
 typedef struct bitmapinfoheader_s
 {
-    u32 i_size; /* size of header */
+    u32 i_size; /* size of header 40 + size of data follwoing this header */
     u32 i_width;
     u32 i_height;
     u16 i_planes;
@@ -41,7 +40,17 @@ typedef struct bitmapinfoheader_s
     u32 i_clrimportant;
 } bitmapinfoheader_t;
 
-
+typedef struct waveformatex_s
+{
+    u16 i_format;
+    u16 i_channels;
+    u32 i_samplepersec;
+    u32 i_avgbytespersec;
+    u16 i_blockalign;
+    u16 i_bitspersample;
+    u16 i_size;          /* This give size of data 
+                            imediatly following this header. */
+} waveformatex_t;
 
 /*****************************************************************************
  * Contain all information about a chunk
@@ -103,8 +112,6 @@ typedef struct track_data_mp4_s
                                     too much time to do sumations each time*/
     
     es_descriptor_t *p_es; /* vlc es for this track */
-    data_packet_t   *p_data_init; /* send this with the first packet, 
-                                        and then discarded it*/
 
     MP4_Box_t *p_stbl;  /* will contain all timing information */
     MP4_Box_t *p_stsd;  /* will contain all data to initialize decoder */
@@ -199,4 +206,3 @@ static inline mtime_t MP4_GetMoviePTS(demux_data_mp4_t *p_demux )
                 (mtime_t)p_demux->i_timescale )
           );
 }
-