Commit 6dcbb0a9 authored by Laurent Aimar's avatar Laurent Aimar

* all: fixed the way h264 streams are stored in .mp4

parent 224d24d4
...@@ -1220,7 +1220,7 @@ static int TrackCreateES ( demux_t *p_demux, ...@@ -1220,7 +1220,7 @@ static int TrackCreateES ( demux_t *p_demux,
} }
break; break;
/* avc1: send avcC (h264 without annexe B) */ /* avc1: send avcC (h264 without annexe B, ie without start code)*/
case VLC_FOURCC( 'a', 'v', 'c', '1' ): case VLC_FOURCC( 'a', 'v', 'c', '1' ):
{ {
MP4_Box_t *p_avcC = MP4_BoxGet( p_sample, "avcC" ); MP4_Box_t *p_avcC = MP4_BoxGet( p_sample, "avcC" );
......
...@@ -665,70 +665,58 @@ static block_t *ConvertSUBT( sout_mux_t *p_mux, mp4_stream_t *tk, block_t *p_blo ...@@ -665,70 +665,58 @@ static block_t *ConvertSUBT( sout_mux_t *p_mux, mp4_stream_t *tk, block_t *p_blo
static void ConvertAVC1( sout_mux_t *p_mux, mp4_stream_t *tk, block_t *p_block ) static void ConvertAVC1( sout_mux_t *p_mux, mp4_stream_t *tk, block_t *p_block )
{ {
uint8_t *src = p_block->p_buffer; uint8_t *last = p_block->p_buffer; /* Assume it starts with 0x00000001 */
int i_src = p_block->i_buffer; uint8_t *dat = &p_block->p_buffer[4];
uint8_t *end = &p_block->p_buffer[i_src]; uint8_t *end = &p_block->p_buffer[p_block->i_buffer];
uint8_t *dst = p_block->p_buffer;
while( src < end ) /* Replace the 4 bytes start code with 4 bytes size,
* FIXME are all startcode 4 bytes ? (I don't think :( */
while( dat < end )
{ {
uint8_t *fix = dst;
int i_type;
int i_size; int i_size;
if( src[0] != 0 || src[1] != 0 || src[2] != 0 || src[3] != 1 ) while( dat < end - 4 )
break;
/* skip start code and room for size */
src += 4;
dst += 4;
/* nal type */
i_type = (*dst++ = *src++)&0x1f;
/* nal content */
while( src < end )
{ {
if( src < end - 4 && src[0] == 0x00 && src[1] == 0x00 && src[2] == 0x00 && src[3] == 0x01 ) if( dat[0] == 0x00 && dat[1] == 0x00 &&
dat[2] == 0x00 && dat[3] == 0x01 )
{ {
break; break;
} }
dat++;
if( src < end - 3 && src[0] == 0x00 && src[1] == 0x00 && src[2] == 0x03 ) }
{ if( dat >= end - 4 )
*dst++ = 0x00; {
*dst++ = 0x00; dat = end;
src += 3;
continue;
}
*dst++ = *src++;
} }
i_size = dst - &fix[4];
fix[0] = (i_size >> 24)&0xff;
fix[1] = (i_size >> 16)&0xff;
fix[2] = (i_size >> 8)&0xff;
fix[3] = (i_size )&0xff;
if( i_type == 7 && tk->avc.i_sps <= 0 ) /* SPS */ /* Fix size */
i_size = dat - &last[4];
last[0] = ( i_size >> 24 )&0xff;
last[1] = ( i_size >> 16 )&0xff;
last[2] = ( i_size >> 8 )&0xff;
last[3] = ( i_size )&0xff;
if( last[4] == 7 && tk->avc.i_sps <= 0 ) /* SPS */
{ {
tk->avc.i_sps = i_size; tk->avc.i_sps = i_size;
tk->avc.sps = malloc( i_size ); tk->avc.sps = malloc( i_size );
memcpy( tk->avc.sps, &fix[4], i_size ); memcpy( tk->avc.sps, &last[4], i_size );
tk->avc.i_profile = tk->avc.sps[1]; tk->avc.i_profile = tk->avc.sps[1];
tk->avc.i_level = tk->avc.sps[3]; tk->avc.i_level = tk->avc.sps[3];
} }
else if( i_type == 8 && tk->avc.i_pps <= 0) /* PPS */ else if( last[4] == 8 && tk->avc.i_pps <= 0 ) /* PPS */
{ {
tk->avc.i_pps = i_size; tk->avc.i_pps = i_size;
tk->avc.pps = malloc( i_size ); tk->avc.pps = malloc( i_size );
memcpy( tk->avc.pps, &fix[4], i_size ); memcpy( tk->avc.pps, &last[4], i_size );
} }
}
p_block->i_buffer = dst - p_block->p_buffer; last = dat;
dat += 4;
}
} }
......
...@@ -105,7 +105,7 @@ enum nal_priority_e ...@@ -105,7 +105,7 @@ enum nal_priority_e
static block_t *ParseNALBlock( decoder_t *, block_t * ); static block_t *ParseNALBlock( decoder_t *, block_t * );
static block_t *nal_get_encoded( decoder_t *, uint8_t *p, int ); static block_t *nal_get_annexeb( decoder_t *, uint8_t *p, int );
/***************************************************************************** /*****************************************************************************
* Open: probe the packetizer and return score * Open: probe the packetizer and return score
...@@ -163,7 +163,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -163,7 +163,7 @@ static int Open( vlc_object_t *p_this )
for( i = 0; i < i_sps; i++ ) for( i = 0; i < i_sps; i++ )
{ {
int i_length = GetWBE( p ); int i_length = GetWBE( p );
block_t *p_sps = nal_get_encoded( p_dec, p+2, i_length ); block_t *p_sps = nal_get_annexeb( p_dec, p+2, i_length );
ParseNALBlock( p_dec, p_sps ); ParseNALBlock( p_dec, p_sps );
p += 2 + i_length; p += 2 + i_length;
...@@ -173,7 +173,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -173,7 +173,7 @@ static int Open( vlc_object_t *p_this )
for( i = 0; i < i_pps; i++ ) for( i = 0; i < i_pps; i++ )
{ {
int i_length = GetWBE( p ); int i_length = GetWBE( p );
block_t *p_pps = nal_get_encoded( p_dec, p+2, i_length ); block_t *p_pps = nal_get_annexeb( p_dec, p+2, i_length );
ParseNALBlock( p_dec, p_pps ); ParseNALBlock( p_dec, p_pps );
p += 2 + i_length; p += 2 + i_length;
...@@ -307,7 +307,7 @@ static block_t *PacketizeAVC1( decoder_t *p_dec, block_t **pp_block ) ...@@ -307,7 +307,7 @@ static block_t *PacketizeAVC1( decoder_t *p_dec, block_t **pp_block )
if( i_size > 0 ) if( i_size > 0 )
{ {
block_t *p_part = nal_get_encoded( p_dec, p, i_size ); block_t *p_part = nal_get_annexeb( p_dec, p, i_size );
p_part->i_dts = p_block->i_dts; p_part->i_dts = p_block->i_dts;
p_part->i_pts = p_block->i_pts; p_part->i_pts = p_block->i_pts;
...@@ -323,67 +323,19 @@ static block_t *PacketizeAVC1( decoder_t *p_dec, block_t **pp_block ) ...@@ -323,67 +323,19 @@ static block_t *PacketizeAVC1( decoder_t *p_dec, block_t **pp_block )
return p_ret; return p_ret;
} }
static block_t *nal_get_encoded( decoder_t *p_dec, uint8_t *p, int i_size ) static block_t *nal_get_annexeb( decoder_t *p_dec, uint8_t *p, int i_size )
{ {
block_t *p_nal; block_t *p_nal;
int i_nal_size = 5;
uint8_t *src = &p[1];
uint8_t *end = &p[i_size];
uint8_t *dst;
int i_count = 0;
/* 1: compute real size */ p_nal = block_New( p_dec, 4 + i_size );
while( src < end )
{
if( i_count == 2 && *src <= 0x03 )
{
i_nal_size++;
i_count = 0;
}
if( *src == 0 )
{
i_count++;
}
else
{
i_count = 0;
}
i_nal_size++;
src++;
}
/* 2: encode it */
p_nal = block_New( p_dec, i_nal_size );
i_count = 0;
src = p;
dst = p_nal->p_buffer;
/* add start code */
*dst++ = 0x00;
*dst++ = 0x00;
*dst++ = 0x00;
*dst++ = 0x01;
/* nal type */ /* Add start code */
*dst++ = *src++; p_nal->p_buffer[0] = 0x00;
p_nal->p_buffer[1] = 0x00;
while( src < end ) p_nal->p_buffer[2] = 0x00;
{ p_nal->p_buffer[3] = 0x01;
if( i_count == 2 && *src <= 0x03 ) /* Copy nalu */
{ memcpy( &p_nal->p_buffer[4], p, i_size );
*dst++ = 0x03;
i_count = 0;
}
if( *src == 0 )
{
i_count++;
}
else
{
i_count = 0;
}
*dst++ = *src++;
}
return p_nal; return p_nal;
} }
......
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