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,
}
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' ):
{
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
static void ConvertAVC1( sout_mux_t *p_mux, mp4_stream_t *tk, block_t *p_block )
{
uint8_t *src = p_block->p_buffer;
int i_src = p_block->i_buffer;
uint8_t *end = &p_block->p_buffer[i_src];
uint8_t *last = p_block->p_buffer; /* Assume it starts with 0x00000001 */
uint8_t *dat = &p_block->p_buffer[4];
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;
if( src[0] != 0 || src[1] != 0 || src[2] != 0 || src[3] != 1 )
break;
/* skip start code and room for size */
src += 4;
dst += 4;
/* nal type */
i_type = (*dst++ = *src++)&0x1f;
/* nal content */
while( src < end )
while( dat < end - 4 )
{
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;
}
if( src < end - 3 && src[0] == 0x00 && src[1] == 0x00 && src[2] == 0x03 )
{
*dst++ = 0x00;
*dst++ = 0x00;
src += 3;
continue;
}
*dst++ = *src++;
dat++;
}
if( dat >= end - 4 )
{
dat = end;
}
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.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_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.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
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
......@@ -163,7 +163,7 @@ static int Open( vlc_object_t *p_this )
for( i = 0; i < i_sps; i++ )
{
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 );
p += 2 + i_length;
......@@ -173,7 +173,7 @@ static int Open( vlc_object_t *p_this )
for( i = 0; i < i_pps; i++ )
{
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 );
p += 2 + i_length;
......@@ -307,7 +307,7 @@ static block_t *PacketizeAVC1( decoder_t *p_dec, block_t **pp_block )
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_pts = p_block->i_pts;
......@@ -323,67 +323,19 @@ static block_t *PacketizeAVC1( decoder_t *p_dec, block_t **pp_block )
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;
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 */
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;
p_nal = block_New( p_dec, 4 + i_size );
/* nal type */
*dst++ = *src++;
while( src < end )
{
if( i_count == 2 && *src <= 0x03 )
{
*dst++ = 0x03;
i_count = 0;
}
if( *src == 0 )
{
i_count++;
}
else
{
i_count = 0;
}
*dst++ = *src++;
}
/* Add start code */
p_nal->p_buffer[0] = 0x00;
p_nal->p_buffer[1] = 0x00;
p_nal->p_buffer[2] = 0x00;
p_nal->p_buffer[3] = 0x01;
/* Copy nalu */
memcpy( &p_nal->p_buffer[4], p, i_size );
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