FREE( p_box->data.p_esds->es_descriptor.p_decConfigDescr );
}
+static int MP4_ReadBox_avcC( MP4_Stream_t *p_stream, MP4_Box_t *p_box )
+{
+ MP4_Box_data_avcC_t *p_avcC;
+ int i;
+
+ MP4_READBOX_ENTER( MP4_Box_data_avcC_t );
+ p_avcC = p_box->data.p_avcC;
+
+ p_avcC->i_avcC = i_read;
+ p_avcC->p_avcC = malloc( p_avcC->i_avcC );
+ memcpy( p_avcC->p_avcC, p_peek, i_read );
+
+ MP4_GET1BYTE( p_avcC->i_version );
+ MP4_GET1BYTE( p_avcC->i_profile );
+ MP4_GET1BYTE( p_avcC->i_profile_compatibility );
+ MP4_GET1BYTE( p_avcC->i_level );
+ MP4_GET1BYTE( p_avcC->i_reserved1 );
+ p_avcC->i_length_size = (p_avcC->i_reserved1&0x03) + 1;
+ p_avcC->i_reserved1 >>= 2;
+
+ MP4_GET1BYTE( p_avcC->i_reserved2 );
+ p_avcC->i_sps = p_avcC->i_reserved2&0x1f;
+ p_avcC->i_reserved2 >>= 5;
+
+ if( p_avcC->i_sps > 0 )
+ {
+ p_avcC->i_sps_length = malloc( p_avcC->i_sps * sizeof( uint16_t ) );
+ p_avcC->sps = malloc( p_avcC->i_sps * sizeof( uint8_t* ) );
+
+ for( i = 0; i < p_avcC->i_sps; i++ )
+ {
+ MP4_GET2BYTES( p_avcC->i_sps_length[i] );
+ p_avcC->sps[i] = malloc( p_avcC->i_sps_length[i] );
+ memcpy( p_avcC->sps[i], p_peek, p_avcC->i_sps_length[i] );
+
+ p_peek += p_avcC->i_sps_length[i];
+ i_read -= p_avcC->i_sps_length[i];
+ }
+ }
+
+ MP4_GET1BYTE( p_avcC->i_pps );
+ if( p_avcC->i_pps > 0 )
+ {
+ p_avcC->i_pps_length = malloc( p_avcC->i_pps * sizeof( uint16_t ) );
+ p_avcC->pps = malloc( p_avcC->i_pps * sizeof( uint8_t* ) );
+
+ for( i = 0; i < p_avcC->i_pps; i++ )
+ {
+ MP4_GET2BYTES( p_avcC->i_pps_length[i] );
+ p_avcC->pps[i] = malloc( p_avcC->i_pps_length[i] );
+ memcpy( p_avcC->pps[i], p_peek, p_avcC->i_pps_length[i] );
+
+ p_peek += p_avcC->i_pps_length[i];
+ i_read -= p_avcC->i_pps_length[i];
+ }
+ }
+#ifdef MP4_VERBOSE
+ msg_Dbg( p_stream->s,
+ "read box: \"avcC\" version=%d profile=0x%x level=0x%x lengh size=%d sps=%d pps=%d",
+ p_avcC->i_version, p_avcC->i_profile, p_avcC->i_level,
+ p_avcC->i_length_size,
+ p_avcC->i_sps, p_avcC->i_pps );
+ for( i = 0; i < p_avcC->i_sps; i++ )
+ {
+ msg_Dbg( p_stream->s, " - sps[%d] length=%d",
+ i, p_avcC->i_sps_length[i] );
+ }
+ for( i = 0; i < p_avcC->i_pps; i++ )
+ {
+ msg_Dbg( p_stream->s, " - pps[%d] length=%d",
+ i, p_avcC->i_pps_length[i] );
+ }
+
+#endif
+ MP4_READBOX_EXIT( 1 );
+}
+
+static void MP4_FreeBox_avcC( MP4_Box_t *p_box )
+{
+ MP4_Box_data_avcC_t *p_avcC = p_box->data.p_avcC;
+ int i;
+
+ for( i = 0; i < p_avcC->i_sps; i++ )
+ {
+ FREE( p_avcC->sps[i] );
+ }
+ for( i = 0; i < p_avcC->i_pps; i++ )
+ {
+ FREE( p_avcC->pps[i] );
+ }
+ if( p_avcC->i_sps > 0 ) FREE( p_avcC->sps );
+ if( p_avcC->i_pps > 0 ) FREE( p_avcC->pps );
+}
+
static int MP4_ReadBox_sample_soun( MP4_Stream_t *p_stream, MP4_Box_t *p_box )
{
unsigned int i;
{ FOURCC_esds, MP4_ReadBox_esds, MP4_FreeBox_esds },
{ FOURCC_dcom, MP4_ReadBox_dcom, MP4_FreeBox_Common },
{ FOURCC_cmvd, MP4_ReadBox_cmvd, MP4_FreeBox_cmvd },
+ { FOURCC_avcC, MP4_ReadBox_avcC, MP4_FreeBox_avcC },
/* Nothing to do with this box */
{ FOURCC_mdat, MP4_ReadBoxSkip, MP4_FreeBox_Common },
{ FOURCC_h264, MP4_ReadBox_sample_vide, MP4_FreeBox_sample_vide },
{ 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 },
#define FOURCC_vp31 VLC_FOURCC( 'v', 'p', '3', '1' )
#define FOURCC_h264 VLC_FOURCC( 'h', '2', '6', '4' )
+#define FOURCC_avc1 VLC_FOURCC( 'a', 'v', 'c', '1' )
+#define FOURCC_avcC VLC_FOURCC( 'a', 'v', 'c', 'C' )
+#define FOURCC_m4ds VLC_FOURCC( 'm', '4', 'd', 's' )
+
#define FOURCC_dvc VLC_FOURCC( 'd', 'v', 'c', ' ' )
#define FOURCC_dvp VLC_FOURCC( 'd', 'v', 'p', ' ' )
#define FOURCC_raw VLC_FOURCC( 'r', 'a', 'w', ' ' )
} MP4_Box_data_0xa9xxx_t;
+typedef struct
+{
+ uint8_t i_version;
+ uint8_t i_profile;
+ uint8_t i_profile_compatibility;
+ uint8_t i_level;
+
+ uint8_t i_reserved1; /* 6 bits */
+ uint8_t i_length_size;
+
+ uint8_t i_reserved2; /* 3 bits */
+ uint8_t i_sps;
+ uint16_t *i_sps_length;
+ uint8_t **sps;
+
+ uint8_t i_pps;
+ uint16_t *i_pps_length;
+ uint8_t **pps;
+
+ /* XXX: Hack raw avcC atom payload */
+ int i_avcC;
+ uint8_t *p_avcC;
+
+} MP4_Box_data_avcC_t;
+
/*
typedef struct MP4_Box_data__s
{
MP4_Box_data_sample_hint_t *p_sample_hint;
MP4_Box_data_esds_t *p_esds;
+ MP4_Box_data_avcC_t *p_avcC;
MP4_Box_data_stsz_t *p_stsz;
MP4_Box_data_stz2_t *p_stz2;
}
/* first wait for the good time to read a packet */
- es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr );
+ es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr + 1 );
p_sys->i_pcr = MP4_GetMoviePTS( p_sys );
(uint32_t*)p_block->p_buffer,
p_block->i_buffer );
}
- p_block->i_dts = MP4_TrackGetPTS( p_demux, tk );
+ 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;
+ p_block->i_pts = tk->fmt.i_cat == VIDEO_ES ? 0 : p_block->i_dts + 1;
if( !tk->b_drms || ( tk->b_drms && tk->p_drms ) )
{
p_track->fmt.i_extra);
}
break;
+
+ /* avc1: send avcC (h264 without annexe B) */
+ case VLC_FOURCC( 'a', 'v', 'c', '1' ):
+ {
+ MP4_Box_t *p_avcC = MP4_BoxGet( p_sample, "avcC" );
+
+ if( p_avcC )
+ {
+ /* Hack: use a packetizer to reecampsulate data in anexe B format */
+ msg_Dbg( p_demux, "avcC: size=%d", p_avcC->data.p_avcC->i_avcC );
+ p_track->fmt.i_extra = p_avcC->data.p_avcC->i_avcC;
+ p_track->fmt.p_extra = malloc( p_avcC->data.p_avcC->i_avcC );
+ memcpy( p_track->fmt.p_extra, p_avcC->data.p_avcC->p_avcC, p_track->fmt.i_extra );
+ p_track->fmt.b_packetized = VLC_FALSE;
+ }
+ else
+ {
+ msg_Err( p_demux, "missing avcC" );
+ }
+ break;
+ }
+
default:
break;
}
static void MP4_TrackUnselect(demux_t *p_demux,
mp4_track_t *p_track )
{
+ fprintf( stderr, "MP4_TrackUnselect: id=%d\n", p_track->i_track_ID );
if( !p_track->b_ok )
{
return;