[FFmpeg-devel] [PATCH] FLAC parser

Michael Niedermayer michaelni
Wed Jul 21 05:01:31 CEST 2010


On Mon, Jul 19, 2010 at 12:55:05AM +0200, Michael Chinen wrote:
> Hi,
> 
> This FLAC parser takes the suggestions from a thread from another FLAC
> parser patch submitted by Jason Ruggles in March 2009[1].
> Currently it stores 20 headers (8 bit crc verified) and finds all
> possible (16 bit footer) crc-verified sequences within a neighbor
> distance of 4.
> It penalizes sequences that have changes in sample rate, bit depth,
> and channel arrangement.
> The settings probably need some twiddling.

you should check the frame number too (unless encoders dont set it like
ours does)
without the frame number there can be ambigous cases with finite probability
even as the number of frames considered goes to infinity


[...]
> +static void update_sequences_header(FLACParseContext *fpc, FLACHeaderMarker *mid, FLACHeaderMarker *end, int distance)
> +{
[...]
> +
> +    /* do the children first to find out where they connect to */
> +    if(!mid->next)
> +        return;
> +    update_sequences_header(fpc, mid->next, end, distance -1);
> +
[...]
> +        /* set a bit showing the validity at this distance if crc is ok
> +           (distance variable is really one less than linked list distance) */
> +        if(!av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, fpc->buffer + mid->offset, end->offset - mid->offset) )
> +            mid->crc_valid |= 1 << distance;
> +        else
> +            av_log(NULL,AV_LOG_DEBUG,"    update_sequence crc failed at dist %i from %i to %i\n", distance, mid->offset, end->offset);
> +
[...]
> +}

CRCs are linear, you never should need to read a byte more than once.
you can combine the CRCs of 2 blocks into one for their concatenated block


> +
> +static void update_sequences(FLACParseContext *fpc, int start_index, int start_distance, FLACHeaderMarker *end)
> +{
> +    int distance = start_distance - 1;
> +    FLACHeaderMarker* mid = fpc->headers;
> +
> +    while(start_index-- > 0)
> +        mid = mid->next;
> +
> +    update_sequences_header(fpc, mid, end, distance);
> +}
> +

> +static int find_new_headers(FLACParseContext *fpc, int search_start)
> +{
> +    FLACFrameInfo fi;
> +    FLACHeaderMarker *end;
> +    int i, size = 0;
> +
> +    fpc->nb_headers_found = 0;
> +    /* search for a new header of at least 16 bytes */
> +    for (i = search_start; i < fpc->buffer_size-MAX_FRAME_HEADER_SIZE; i++) {
> +        if (frame_header_is_valid(fpc->buffer + i, &fi)) {

i think you should search for the startcode first and only once its
found do (slower) calls


> +            end = fpc->headers;
> +            size = 0;
> +            while(end && end->next) {
> +                end = end->next;
> +                size++;
> +            }
> +            if(!fpc->headers) {
> +                fpc->headers = av_mallocz( sizeof(FLACHeaderMarker));
> +                end = fpc->headers;
> +            } else {
> +                end->next = av_mallocz( sizeof(FLACHeaderMarker));
> +                end = end->next;
> +                size++;
> +            }

FLACHeaderMarker **ptr= &fpc->headers;
while(*ptr)
    ptr= &(*ptr)->next;
*ptr= av_mallocz( sizeof(FLACHeaderMarker));

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Asymptotically faster algorithms should always be preferred if you have
asymptotical amounts of data
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 190 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20100721/86d6527d/attachment.pgp>



More information about the ffmpeg-devel mailing list