Commit 2f0dfb7c authored by Laurent Aimar's avatar Laurent Aimar

* mp4: - add +1 to PCR/DTS/PTS.

        - preliminary support of avc (using a draft+google without
samples to test, so don't expect it to work ;)
 * libmp4: parse the avcC atom.
parent c1a67dc7
......@@ -1080,6 +1080,100 @@ static void MP4_FreeBox_esds( MP4_Box_t *p_box )
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;
......@@ -2048,6 +2142,7 @@ static struct
{ 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 },
......@@ -2106,6 +2201,7 @@ static struct
{ 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 },
......
......@@ -136,6 +136,10 @@
#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', ' ' )
......@@ -728,6 +732,31 @@ typedef struct
} 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
{
......@@ -759,6 +788,7 @@ typedef union 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;
......
......@@ -529,7 +529,7 @@ static int Demux( demux_t *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 );
es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr + 1 );
p_sys->i_pcr = MP4_GetMoviePTS( p_sys );
......@@ -580,9 +580,9 @@ static int Demux( demux_t *p_demux )
(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 ) )
{
......@@ -1179,6 +1179,28 @@ static int TrackCreateES ( demux_t *p_demux,
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;
}
......@@ -1693,6 +1715,7 @@ static int MP4_TrackSelect ( demux_t *p_demux,
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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment