[Ffmpeg-devel] [PATCH] h264 muxing in mp4

Loren Merritt lorenm
Mon Mar 6 03:30:20 CET 2006


On Sun, 5 Mar 2006, Baptiste COUDURIER wrote:

> Hi,
>
> Second attempt. Nal parsing is done in mov muxer, works for h264
> bytestream in avi, x264 encoding, and stream copy from mp4.
>
> I would like some comments about avc_parse_nal_units and mov_write_avcc,

You only look for 1 sps and 1 pps? There can be more than 1 of each.
In a h264 elementary stream, they're even allowed to be spread throughout 
the file, not all at the beginning.
Though I haven't seen any codecs other than the reference which use 
multiple sps/pps, so it's not a high priority.

> If anyone see a better or faster way to parse, it would be great.

174795 dezicycles in find_startcode_v0 (your algo)
  90398 dezicycles in find_startcode_v1
  72391 dezicycles in find_startcode_v2 (generic)
  69425 dezicycles in find_startcode_v2 (endian)

--Loren Merritt
-------------- next part --------------
uint8_t *find_startcode_v0( uint8_t *p, uint8_t *end )
{
    for( end -= 3; p < end; p++ )
    {
        if( p[0] == 0 && p[1] == 0 && p[2] == 1 )
            return p;
    }
    return NULL;
}

uint8_t *find_startcode_v1( uint8_t *p, uint8_t *end )
{
    for( end -= 4; p < end; p += 2 )
    {
        if( p[1] == 0 )
        {
            if( p[0] == 0 && p[2] == 1 )
                return p;
            if( p[2] == 0 && p[3] == 1 )
                return p+1;
        }
    }
    if( p == end && p[0] == 0 && p[1] == 0 && p[2] == 1 )
        return p;
    return NULL;
}

uint8_t *find_startcode_v2( uint8_t *p, uint8_t *end )
{
    uint8_t *a = p + 4 - ((int)p & 3);

    for( end -= 3; p < a && p < end; p++ )
    {
        if( p[0] == 0 && p[1] == 0 && p[2] == 1 )
            return p;
    }

    for( end -= 3; p < end; p += 4 )
    {
        uint32_t x = *(uint32_t*)p;
//      if( (x - 0x01000100) & (~x) & 0x80008000 ) // little endian
//      if( (x - 0x00010001) & (~x) & 0x00800080 ) // big endian
        if( (x - 0x01010101) & (~x) & 0x80808080 ) // generic
        {
            if( p[1] == 0 )
            {
                if( p[0] == 0 && p[2] == 1 )
                    return p;
                if( p[2] == 0 && p[3] == 1 )
                    return p+1;
            }
            if( p[3] == 0 )
            {
                if( p[2] == 0 && p[4] == 1 )
                    return p+2;
                if( p[4] == 0 && p[5] == 1 )
                    return p+3;
            }
        }
    }

    for( end += 3; p < end; p++ )
    {
        if( p[0] == 0 && p[1] == 0 && p[2] == 1 )
            return p;
    }

    return NULL;
}



More information about the ffmpeg-devel mailing list