* mp4: added text track support. (there is a problem with the encoding).

This commit is contained in:
Laurent Aimar 2004-05-27 22:30:12 +00:00
parent e7e6e9df50
commit 3633449efb
3 changed files with 159 additions and 16 deletions

View 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;

View File

@ -127,6 +127,7 @@
#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' )
@ -168,6 +169,8 @@
#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;

View 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;
}