uint64_t i_duration; /* movie duration */
unsigned int i_tracks; /* number of tracks */
mp4_track_t *track; /* array of track */
+ float f_fps; /* number of frame per seconds */
/* */
MP4_Box_t *p_tref_chap;
p_demux->pf_control = Control;
/* create our structure that will contains all data */
- p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
- memset( p_sys, 0, sizeof( demux_sys_t ) );
+ p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
/* Now load all boxes ( except raw data ) */
if( ( p_sys->p_root = MP4_BoxGetRoot( p_demux->s ) ) == NULL )
input_thread_t *p_input = demux_GetParentInput( p_demux );
input_item_t *p_current = input_GetItem( p_input );
+ input_item_node_t *p_subitems = input_item_node_Create( p_current );
+
for( i = 0; i < i_count; i++ )
{
MP4_Box_t *p_rdrf = MP4_BoxGet( p_rmra, "rmda[%d]/rdrf", i );
msg_Dbg( p_demux, "adding ref = `%s'", psz_ref );
input_item_t *p_input = input_item_New( p_demux, psz_ref, NULL );
input_item_CopyOptions( p_current, p_input );
- input_item_AddSubItem( p_current, p_input );
+ input_item_node_AppendItem( p_subitems, p_input );
vlc_gc_decref( p_input );
}
else
}
free( psz_ref );
}
+ input_item_node_PostAndDelete( p_subitems );
vlc_object_release( p_input );
}
MP4_UpdateSeekpoint( p_demux );
/* first wait for the good time to read a packet */
- es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr + 1 );
+ es_out_Control( p_demux->out, ES_OUT_SET_PCR, VLC_TS_0 + p_sys->i_pcr );
p_sys->i_pcr = MP4_GetMoviePTS( p_sys );
}
}
/* dts */
- p_block->i_dts = MP4_TrackGetDTS( p_demux, tk ) + 1;
+ p_block->i_dts = VLC_TS_0 + MP4_TrackGetDTS( p_demux, tk );
/* pts */
i_delta = MP4_TrackGetPTSDelta( tk );
if( i_delta != -1 )
else if( tk->fmt.i_cat != VIDEO_ES )
p_block->i_pts = p_block->i_dts;
else
- p_block->i_pts = 0;
+ p_block->i_pts = VLC_TS_INVALID;
if( !tk->b_drms || ( tk->b_drms && tk->p_drms ) )
es_out_Send( p_demux->out, tk->p_es, p_block );
return VLC_SUCCESS;
case DEMUX_GET_FPS:
- msg_Warn( p_demux, "DEMUX_GET_FPS unimplemented !!" );
- return VLC_EGENERIC;
+ pf = (double*)va_arg( args, double* );
+ *pf = p_sys->f_fps;
+ return VLC_SUCCESS;
case DEMUX_GET_META:
{
MP4_Box_t *p_sample;
MP4_Box_t *p_esds;
MP4_Box_t *p_frma;
+ MP4_Box_t *p_enda;
if( pp_es )
*pp_es = NULL;
p_sample->i_type = p_frma->data.p_frma->i_type;
}
+ p_enda = MP4_BoxGet( p_sample, "wave/enda" );
+ if( !p_enda )
+ p_enda = MP4_BoxGet( p_sample, "enda" );
+
if( p_track->fmt.i_cat == AUDIO_ES && ( p_track->i_sample_size == 1 || p_track->i_sample_size == 2 ) )
{
MP4_Box_data_sample_soun_t *p_soun;
p_soun->i_qt_version = 0;
}
}
+ else if( p_track->fmt.i_cat == AUDIO_ES && p_sample->data.p_sample_soun->i_qt_version == 1 )
+ {
+ MP4_Box_data_sample_soun_t *p_soun = p_sample->data.p_sample_soun;
+
+ switch( p_sample->i_type )
+ {
+ case( VLC_FOURCC( '.', 'm', 'p', '3' ) ):
+ case( VLC_FOURCC( 'm', 's', 0x00, 0x55 ) ):
+ {
+ if( p_track->i_sample_size > 1 )
+ p_soun->i_qt_version = 0;
+ break;
+ }
+ case( VLC_FOURCC( 'a', 'c', '-', '3' ) ):
+ case( VLC_FOURCC( 'e', 'c', '-', '3' ) ):
+ case( VLC_FOURCC( 'm', 's', 0x20, 0x00 ) ):
+ p_soun->i_qt_version = 0;
+ break;
+ default:
+ break;
+ }
+ }
/* */
switch( p_track->fmt.i_cat )
if( p_track->i_width > 0 && p_track->i_height > 0 &&
/* Work-around buggy muxed files */
p_sample->data.p_sample_vide->i_width != p_track->i_width )
- p_track->fmt.video.i_aspect =
- VOUT_ASPECT_FACTOR * p_track->i_width / p_track->i_height;
+ {
+ p_track->fmt.video.i_sar_num = p_track->i_width * p_track->fmt.video.i_height;
+ p_track->fmt.video.i_sar_den = p_track->i_height * p_track->fmt.video.i_width;
+ }
/* Support for cropping (eg. in H263 files) */
p_track->fmt.video.i_visible_width = p_track->fmt.video.i_width;
TrackGetESSampleRate( &p_track->fmt.video.i_frame_rate,
&p_track->fmt.video.i_frame_rate_base,
p_track, i_sample_description_index, i_chunk );
+ p_demux->p_sys->f_fps = (float)p_track->fmt.video.i_frame_rate /
+ (float)p_track->fmt.video.i_frame_rate_base;
break;
case AUDIO_ES:
case( VLC_FOURCC( '.', 'm', 'p', '3' ) ):
case( VLC_FOURCC( 'm', 's', 0x00, 0x55 ) ):
{
- MP4_Box_data_sample_soun_t *p_soun = p_sample->data.p_sample_soun;
p_track->fmt.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'a' );
- if( p_track->i_sample_size > 1 )
- p_soun->i_qt_version = 0;
break;
}
case( VLC_FOURCC( 'a', 'c', '-', '3' ) ):
break;
case VLC_FOURCC('i','n','2','4'):
- /* in in24/in32 there's enda-atom to tell it's little-endian (if present) */
- if( ( MP4_BoxGet( p_sample, "wave/enda" ) ) ||
- ( MP4_BoxGet( p_sample, "enda" ) ) )
- {
- p_track->fmt.i_codec = VLC_FOURCC('4','2','n','i');
- } else {
- p_track->fmt.i_codec = p_sample->i_type;
- }
+ p_track->fmt.i_codec = p_enda && p_enda->data.p_enda->i_little_endian == 1 ?
+ VLC_FOURCC('4','2','n','i') : VLC_FOURCC('i','n','2','4');
+ break;
+ case VLC_FOURCC('f','l','3','2'):
+ p_track->fmt.i_codec = p_enda && p_enda->data.p_enda->i_little_endian == 1 ?
+ VLC_CODEC_F32L : VLC_CODEC_F32B;
+ break;
+ case VLC_FOURCC('f','l','6','4'):
+ p_track->fmt.i_codec = p_enda && p_enda->data.p_enda->i_little_endian == 1 ?
+ VLC_CODEC_F64L : VLC_CODEC_F64B;
break;
default:
break;
case( 0x40):
p_track->fmt.i_codec = VLC_FOURCC( 'm','p','4','a' );
+ if( p_decconfig->i_decoder_specific_info_len >= 2 &&
+ p_decconfig->p_decoder_specific_info[0] == 0xF8 &&
+ (p_decconfig->p_decoder_specific_info[1]&0xE0) == 0x80 )
+ {
+ p_track->fmt.i_codec = VLC_CODEC_ALS;
+ }
break;
case( 0x60):
case( 0x61):
uint32_t *pi_sample )
{
demux_sys_t *p_sys = p_demux->p_sys;
- MP4_Box_t *p_stss;
+ MP4_Box_t *p_box_stss;
uint64_t i_dts;
unsigned int i_sample;
unsigned int i_chunk;
/* *** Try to find nearest sync points *** */
- if( ( p_stss = MP4_BoxGet( p_track->p_stbl, "stss" ) ) )
+ if( ( p_box_stss = MP4_BoxGet( p_track->p_stbl, "stss" ) ) )
{
- unsigned int i_index;
- msg_Dbg( p_demux,
- "track[Id 0x%x] using Sync Sample Box (stss)",
- p_track->i_track_ID );
- for( i_index = 0; i_index < p_stss->data.p_stss->i_entry_count; i_index++ )
+ MP4_Box_data_stss_t *p_stss = p_box_stss->data.p_stss;
+ msg_Dbg( p_demux, "track[Id 0x%x] using Sync Sample Box (stss)",
+ p_track->i_track_ID );
+ for( unsigned i_index = 0; i_index < p_stss->i_entry_count; i_index++ )
{
- if( p_stss->data.p_stss->i_sample_number[i_index] >= i_sample )
+ if( i_index >= p_stss->i_entry_count - 1 ||
+ i_sample < p_stss->i_sample_number[i_index+1] )
{
- if( i_index > 0 )
+ unsigned i_sync_sample = p_stss->i_sample_number[i_index];
+ msg_Dbg( p_demux, "stts gives %d --> %d (sample number)",
+ i_sample, i_sync_sample );
+
+ if( i_sync_sample <= i_sample )
{
- msg_Dbg( p_demux, "stts gives %d --> %d (sample number)",
- i_sample,
- p_stss->data.p_stss->i_sample_number[i_index-1] );
- i_sample = p_stss->data.p_stss->i_sample_number[i_index-1];
- /* new i_sample is less than old so i_chunk can only decreased */
while( i_chunk > 0 &&
- i_sample < p_track->chunk[i_chunk].i_sample_first )
- {
+ i_sync_sample < p_track->chunk[i_chunk].i_sample_first )
i_chunk--;
- }
}
else
{
- msg_Dbg( p_demux, "stts gives %d --> %d (sample number)",
- i_sample,
- p_stss->data.p_stss->i_sample_number[i_index] );
- i_sample = p_stss->data.p_stss->i_sample_number[i_index];
- /* new i_sample is more than old so i_chunk can only increased */
while( i_chunk < p_track->i_chunk_count - 1 &&
- i_sample >= p_track->chunk[i_chunk].i_sample_first +
- p_track->chunk[i_chunk].i_sample_count )
- {
+ i_sync_sample >= p_track->chunk[i_chunk].i_sample_first +
+ p_track->chunk[i_chunk].i_sample_count )
i_chunk++;
- }
}
+ i_sample = i_sync_sample;
break;
}
}