]> git.sesse.net Git - vlc/commitdiff
* mp4: added text track support. (there is a problem with the encoding).
authorLaurent Aimar <fenrir@videolan.org>
Thu, 27 May 2004 22:30:12 +0000 (22:30 +0000)
committerLaurent Aimar <fenrir@videolan.org>
Thu, 27 May 2004 22:30:12 +0000 (22:30 +0000)
modules/demux/mp4/libmp4.c
modules/demux/mp4/libmp4.h
modules/demux/mp4/mp4.c

index 2cdb03ce29ecd43ba52449d904090e048f9db090..e5c1a37fc06b27c54e1d8f5001694a8ed1527a3d 100644 (file)
@@ -1367,6 +1367,58 @@ static void MP4_FreeBox_sample_vide( MP4_Box_t *p_box )
 }
 
 
+static int MP4_ReadBox_sample_text( MP4_Stream_t *p_stream, MP4_Box_t *p_box )
+{
+    unsigned int i;
+
+    MP4_READBOX_ENTER( MP4_Box_data_sample_text_t );
+
+    for( i = 0; i < 6 ; i++ )
+    {
+        MP4_GET1BYTE( p_box->data.p_sample_text->i_reserved1[i] );
+    }
+    MP4_GET2BYTES( p_box->data.p_sample_text->i_data_reference_index );
+
+    MP4_GET4BYTES( p_box->data.p_sample_text->i_display_flags );
+    MP4_GET4BYTES( p_box->data.p_sample_text->i_justification );
+
+    MP4_GET2BYTES( p_box->data.p_sample_text->i_background_color[0] );
+    MP4_GET2BYTES( p_box->data.p_sample_text->i_background_color[1] );
+    MP4_GET2BYTES( p_box->data.p_sample_text->i_background_color[2] );
+
+    MP4_GET8BYTES( p_box->data.p_sample_text->i_text_box );
+    MP4_GET8BYTES( p_box->data.p_sample_text->i_reserved2 );
+
+    MP4_GET2BYTES( p_box->data.p_sample_text->i_font_number );
+    MP4_GET2BYTES( p_box->data.p_sample_text->i_font_face );
+
+    MP4_GET2BYTES( p_box->data.p_sample_text->i_reserved3 );
+
+    MP4_GET2BYTES( p_box->data.p_sample_text->i_foreground_color[0] );
+    MP4_GET2BYTES( p_box->data.p_sample_text->i_foreground_color[1] );
+    MP4_GET2BYTES( p_box->data.p_sample_text->i_foreground_color[2] );
+
+    MP4_GET1BYTE( i );
+    p_box->data.p_sample_text->psz_text_name = malloc( i + 1 );
+    memcpy( p_box->data.p_sample_text->psz_text_name, p_peek, i );
+    p_box->data.p_sample_text->psz_text_name[i] = '\0';
+
+#ifdef MP4_VERBOSE
+    msg_Dbg( p_stream->s, "read box: \"text\" in stsd text name=%s",
+             p_box->data.p_sample_text->psz_text_name );
+#endif
+    MP4_READBOX_EXIT( 1 );
+}
+
+#if 0
+/* We can't easily call it, and anyway ~ 20 bytes lost isn't a real problem */
+static void MP4_FreeBox_sample_text( MP4_Box_t *p_box )
+{
+    FREE( p_box->data.p_sample_text->psz_text_name );
+}
+#endif
+
+
 static int MP4_ReadBox_stsd( MP4_Stream_t *p_stream, MP4_Box_t *p_box )
 {
 
@@ -2084,6 +2136,46 @@ static void MP4_FreeBox_0xa9xxx( MP4_Box_t *p_box )
     FREE( p_box->data.p_0xa9xxx->psz_text );
 }
 
+/* For generic */
+static int MP4_ReadBox_default( MP4_Stream_t *p_stream, MP4_Box_t *p_box )
+{
+    if( !p_box->p_father )
+    {
+        goto unknown;
+    }
+    if( p_box->p_father->i_type == FOURCC_stsd )
+    {
+        MP4_Box_t *p_mdia = MP4_BoxGet( p_box, "../../../.." );
+        MP4_Box_t *p_hdlr;
+
+        if( p_mdia == NULL || p_mdia->i_type != FOURCC_mdia ||
+            (p_hdlr = MP4_BoxGet( p_mdia, "hdlr" )) == NULL )
+        {
+            goto unknown;
+        }
+        switch( p_hdlr->data.p_hdlr->i_handler_type )
+        {
+            case FOURCC_soun:
+                return MP4_ReadBox_sample_soun( p_stream, p_box );
+            case FOURCC_vide:
+                return MP4_ReadBox_sample_vide( p_stream, p_box );
+            case FOURCC_text:
+                return MP4_ReadBox_sample_text( p_stream, p_box );
+            default:
+                msg_Warn( p_stream->s,
+                          "unknown handler type in stsd (uncompletetly loaded)" );
+                return 1;
+        }
+    }
+
+unknown:
+    msg_Warn( p_stream->s,
+              "unknown box type %4.4s (uncompletetly loaded)",
+              (char*)&p_box->i_type );
+
+    return 1;
+}
+
 /**** ------------------------------------------------------------------- ****/
 /****                   "Higher level" Functions                          ****/
 /**** ------------------------------------------------------------------- ****/
@@ -2179,6 +2271,7 @@ static struct
     { FOURCC_SVQ3,  MP4_ReadBox_sample_vide,    MP4_FreeBox_sample_vide },
     { FOURCC_ZyGo,  MP4_ReadBox_sample_vide,    MP4_FreeBox_sample_vide },
     { FOURCC_DIVX,  MP4_ReadBox_sample_vide,    MP4_FreeBox_sample_vide },
+    { FOURCC_XVID,  MP4_ReadBox_sample_vide,    MP4_FreeBox_sample_vide },
     { FOURCC_h263,  MP4_ReadBox_sample_vide,    MP4_FreeBox_sample_vide },
     { FOURCC_s263,  MP4_ReadBox_sample_vide,    MP4_FreeBox_sample_vide },
     { FOURCC_cvid,  MP4_ReadBox_sample_vide,    MP4_FreeBox_sample_vide },
@@ -2192,8 +2285,10 @@ static struct
     { FOURCC_3vid,  MP4_ReadBox_sample_vide,    MP4_FreeBox_sample_vide },
     { FOURCC_mjpa,  MP4_ReadBox_sample_vide,    MP4_FreeBox_sample_vide },
     { FOURCC_mjpb,  MP4_ReadBox_sample_vide,    MP4_FreeBox_sample_vide },
-    { FOURCC_mjqt,  NULL,                       NULL }, /* found in mjpa/b */
-    { FOURCC_mjht,  NULL,                       NULL },
+
+    { FOURCC_mjqt,  MP4_ReadBox_default,        NULL }, /* found in mjpa/b */
+    { FOURCC_mjht,  MP4_ReadBox_default,        NULL },
+
     { FOURCC_dvc,   MP4_ReadBox_sample_vide,    MP4_FreeBox_sample_vide },
     { FOURCC_dvp,   MP4_ReadBox_sample_vide,    MP4_FreeBox_sample_vide },
     { FOURCC_VP31,  MP4_ReadBox_sample_vide,    MP4_FreeBox_sample_vide },
@@ -2203,18 +2298,18 @@ static struct
     { FOURCC_jpeg,  MP4_ReadBox_sample_vide,    MP4_FreeBox_sample_vide },
     { FOURCC_avc1,  MP4_ReadBox_sample_vide,    MP4_FreeBox_sample_vide },
 
-    { FOURCC_mp4s,  NULL,                       MP4_FreeBox_Common },
+    { FOURCC_mp4s,  MP4_ReadBox_default,        MP4_FreeBox_Common },
 
     /* XXX there is 2 box where we could find this entry stbl and tref*/
-    { FOURCC_hint,  NULL,                       MP4_FreeBox_Common },
+    { FOURCC_hint,  MP4_ReadBox_default,        MP4_FreeBox_Common },
 
     /* found in tref box */
-    { FOURCC_dpnd,  NULL,   NULL },
-    { FOURCC_ipir,  NULL,   NULL },
-    { FOURCC_mpod,  NULL,   NULL },
+    { FOURCC_dpnd,  MP4_ReadBox_default,   NULL },
+    { FOURCC_ipir,  MP4_ReadBox_default,   NULL },
+    { FOURCC_mpod,  MP4_ReadBox_default,   NULL },
 
     /* found in hnti */
-    { FOURCC_rtp,   NULL,   NULL },
+    { FOURCC_rtp,   MP4_ReadBox_default,   NULL },
 
     /* found in rmra */
     { FOURCC_rdrf,  MP4_ReadBox_rdrf,           MP4_FreeBox_rdrf   },
@@ -2249,7 +2344,7 @@ static struct
     { FOURCC_0xa9src,MP4_ReadBox_0xa9xxx,       MP4_FreeBox_0xa9xxx },
 
     /* Last entry */
-    { 0,            NULL,                   NULL }
+    { 0,             MP4_ReadBox_default,       NULL }
 };
 
 
@@ -2286,13 +2381,8 @@ static MP4_Box_t *MP4_ReadBox( MP4_Stream_t *p_stream, MP4_Box_t *p_father )
             break;
         }
     }
-    if( MP4_Box_Function[i_index].MP4_ReadBox_function == NULL )
-    {
-        msg_Warn( p_stream->s,
-                  "unknown box type %4.4s (uncompletetly loaded)",
-                  (char*)&p_box->i_type );
-    }
-    else if( !(MP4_Box_Function[i_index].MP4_ReadBox_function)( p_stream, p_box ) )
+
+    if( !(MP4_Box_Function[i_index].MP4_ReadBox_function)( p_stream, p_box ) )
     {
         free( p_box );
         return NULL;
index 8cb0c634e8f542e1c832b7369dd58d62afefb678..42098115c8bc2698d5aa38f85eaceaa8d40da396 100644 (file)
 #define FOURCC_h263 VLC_FOURCC( 'h', '2', '6', '3' )
 #define FOURCC_s263 VLC_FOURCC( 's', '2', '6', '3' )
 #define FOURCC_DIVX VLC_FOURCC( 'D', 'I', 'V', 'X' )
+#define FOURCC_XVID VLC_FOURCC( 'X', 'V', 'I', 'D' )
 #define FOURCC_cvid VLC_FOURCC( 'c', 'v', 'i', 'd' )
 #define FOURCC_mjpa VLC_FOURCC( 'm', 'j', 'p', 'a' )
 #define FOURCC_mjpb VLC_FOURCC( 'm', 'j', 'q', 't' )
 #define FOURCC_name VLC_FOURCC( 'n', 'a', 'm', 'e' )
 #define FOURCC_priv VLC_FOURCC( 'p', 'r', 'i', 'v' )
 
+#define FOURCC_text VLC_FOURCC( 't', 'e', 'x', 't' )
+
 #define FOURCC_0xa9nam VLC_FOURCC( 0xa9, 'n', 'a', 'm' )
 #define FOURCC_0xa9aut VLC_FOURCC( 0xa9, 'a', 'u', 't' )
 #define FOURCC_0xa9swr VLC_FOURCC( 0xa9, 's', 'w', 'r' )
@@ -447,6 +450,25 @@ typedef struct MP4_Box_data_sample_vide_s
 
 } MP4_Box_data_sample_vide_t;
 
+typedef struct
+{
+    uint8_t  i_reserved1[6];
+    uint16_t i_data_reference_index;
+
+    uint32_t i_display_flags;
+    uint32_t i_justification;
+    uint16_t i_background_color[3];
+    uint64_t i_text_box;
+    uint64_t i_reserved2;
+    uint16_t i_font_number;
+    uint16_t i_font_face;
+    uint16_t i_reserved3;
+
+    uint16_t i_foreground_color[3];
+
+    char    *psz_text_name;
+} MP4_Box_data_sample_text_t;
+
 typedef struct MP4_Box_data_sample_hint_s
 {
     uint8_t  i_reserved1[6];
@@ -785,6 +807,7 @@ typedef union MP4_Box_data_s
     MP4_Box_data_stsd_t *p_stsd;
         MP4_Box_data_sample_vide_t *p_sample_vide;
         MP4_Box_data_sample_soun_t *p_sample_soun;
+        MP4_Box_data_sample_text_t *p_sample_text;
         MP4_Box_data_sample_hint_t *p_sample_hint;
 
         MP4_Box_data_esds_t *p_esds;
index a797e5a40e5e817b8459b62b9a9ca99cd2068e8a..ad0845281e92f8726af1772c9f093c5ca5b4fdbf 100644 (file)
@@ -450,6 +450,10 @@ static int Open( vlc_object_t * p_this )
                 case( AUDIO_ES ):
                     psz_cat = "audio";
                     break;
+                case( SPU_ES ):
+                    psz_cat = "subtitle";
+                    break;
+
                 default:
                     psz_cat = "unknown";
                     break;
@@ -580,6 +584,23 @@ static int Demux( demux_t *p_demux )
                                   (uint32_t*)p_block->p_buffer,
                                   p_block->i_buffer );
                 }
+                else if( tk->fmt.i_cat == SPU_ES && p_block->i_buffer >= 2 )
+                {
+                    uint16_t i_size = GetWBE( p_block->p_buffer );
+
+                    if( i_size + 2 <= p_block->i_buffer )
+                    {
+                        /* remove the length field, and append a '\0' */
+                        memmove( &p_block->p_buffer[0], &p_block->p_buffer[2], i_size );
+                        p_block->p_buffer[i_size] = '\0';
+                        p_block->i_buffer = i_size + 1;
+                    }
+                    else
+                    {
+                        /* Invalid */
+                        p_block->i_buffer = 0;
+                    }
+                }
                 p_block->i_dts = MP4_TrackGetPTS( p_demux, tk ) + 1;
 
                 p_block->i_pts = tk->fmt.i_cat == VIDEO_ES ? 0 : p_block->i_dts + 1;
@@ -1084,6 +1105,11 @@ static int  TrackCreateES   ( demux_t   *p_demux,
         case( VLC_FOURCC( 's', '2', '6', '3' ) ):
             p_track->fmt.i_codec = VLC_FOURCC( 'h', '2', '6', '3' );
             break;
+
+        case( VLC_FOURCC( 't', 'e', 'x', 't' ) ):
+            p_track->fmt.i_codec = VLC_FOURCC( 's', 'u', 'b', 't' );
+            break;
+
         default:
             p_track->fmt.i_codec = p_sample->i_type;
             break;
@@ -1559,6 +1585,10 @@ static void MP4_TrackCreate( demux_t *p_demux,
             p_track->fmt.i_cat = VIDEO_ES;
             break;
 
+        case( FOURCC_text ):
+            p_track->fmt.i_cat = SPU_ES;
+            break;
+
         default:
             return;
     }