[FFmpeg-soc] [soc]: r4321 - in concat/libavformat: . m3u.c playlist.c playlist.h

Baptiste Coudurier baptiste.coudurier at gmail.com
Sat May 30 03:47:32 CEST 2009


Hi,

Overall comment,

Placement of braces in FFmpeg is:
while () {
}

With or without the whitespaces, as you wish.

gkovacs wrote:
> +
> +/*
> + * Based on AU muxer and demuxer in au.c
> + */
> +

You left a bit too much stuff from it though :>

> [...]
>
> +static int m3u_write_trailer(AVFormatContext *s)
> +{
> +    ByteIOContext *pb = s->pb;
> +    int64_t file_size;
> +
> +    if (!url_is_streamed(s->pb)) {
> +
> +        /* update file size */
> +        file_size = url_ftell(pb);
> +        url_fseek(pb, 8, SEEK_SET);
> +        put_be32(pb, (uint32_t)(file_size - 24));
> +        url_fseek(pb, file_size, SEEK_SET);
> +
> +        put_flush_packet(pb);
> +    }
> +

Forget about the muxer for now, you can remove it.

> [...]
>
> +static int compare_bufs(unsigned char *buf, unsigned char *rbuf)
> +{
> +    while (*rbuf != 0)
> +    {
> +        if (*rbuf != *buf)
> +            return 0;
> +        ++buf;
> +        ++rbuf;
> +    }
> +    return 1;

Humm, strcmp ?

> +static int m3u_probe(AVProbeData *p)
> +{
> +    if (p->buf_size >= 7 && p->buf != 0)
> +    {
> +        if (compare_bufs(p->buf, "#EXTM3U"))
> +            return AVPROBE_SCORE_MAX;
> +        else
> +            return 0;
> +    }
> +    if (check_file_extn(p->filename, "m3u"))
> +        return AVPROBE_SCORE_MAX/2;
> +    else
> +        return 0;
> +}

use match_ext instead of check_file_extn
p->buf must be at least AVPROBE_PADDING_SIZE (32)

> +
> +static int m3u_list_files(unsigned char *buffer, int buffer_size, unsigned char **file_list, unsigned int *lfx_ptr)
> +{
> +    unsigned int i;
> +    unsigned int lfx = 0;
> +    unsigned int fx = 0;
> +    unsigned char hashed_out = 0;
> +    unsigned char fldata[262144];
> +    memset(fldata, 0, 262144);

This is big stack allocation I think. You can use realloc.

> +    memset(file_list, 0, 512 * sizeof(unsigned char*));
> +    for (i = 0; i < 512; ++i)
> +    {
> +        file_list[i] = fldata+i*512;
> +    }

Having a 512 limitation seems bad.

> +    for (i = 0; i < buffer_size; ++i)
> +    {
> +        if (buffer[i] == 0)
> +            break;
> +        if (buffer[i] == '#')
> +        {
> +            hashed_out = 1;
> +            continue;
> +        }
> +        if (buffer[i] == '\n')
> +        {
> +            hashed_out = 0;
> +            if (fx != 0)
> +            {
> +                fx = 0;
> +                ++lfx;
> +            }
> +            continue;
> +        }
> +        if (hashed_out)
> +            continue;
> +        file_list[lfx][fx] = buffer[i];
> +        ++fx;
> +    }
> +    *lfx_ptr = lfx;
> +    return 0;
> +}

I think you can simplify using url_fgets.

> +/* m3u input */
> +static int m3u_read_header(AVFormatContext *s,
> +                          AVFormatParameters *ap)
> +{
> +    unsigned char *flist[512];
> +    int flist_len;
> +    ByteIOContext *pb;
> +    PlaylistD *playld;
> +    pb = s->pb;
> +    m3u_list_files(pb->buffer, pb->buffer_size, flist, &flist_len);
> +    playld = av_make_playlistd(flist, flist_len);
> +    s->priv_data = playld;
> +    playlist_populate_context(playld, s);
> +    return 0;
> +}

Hummmm, you must not access pb->buffer directly.
I think it might be better to build a list of PlayElem directly.

Also I don't think user will want to open all files at the beginning,
it could be slow with network and file might not exist yet (being
downloaded).

> [...]
>
> +int av_open_input_playelem(PlayElem *pe)
> +{
> +    return av_open_input_file(&(pe->ic), pe->filename, pe->fmt, pe->buf_size, pe->ap);

Useless function wrapper.

> [...]
>
> +// based on decode_thread() in ffplay.c
> +int av_alloc_playelem(unsigned char *filename, PlayElem *pe)
> +{
> +//    AVProbeData *pd;
> +    AVFormatContext *ic;
> +    AVFormatParameters *ap;
> +//    pd = av_malloc(sizeof(AVProbeData));
> +//    ic = av_malloc(sizeof(AVFormatContext));
> +    ap = av_malloc(sizeof(AVFormatParameters));
> +    memset(ap, 0, sizeof(AVFormatParameters));
> +    ap->width = 0;
> +    ap->height = 0;
> +    ap->time_base = (AVRational){1, 25};
> +    ap->pix_fmt = 0;
> +//    pd->filename = filename;
> +//    pd->buf = NULL;
> +//    pd->buf_size = 0;
> +    pe->ic = ic;
> +    pe->filename = filename;
> +    pe->fmt = 0;
> +    pe->buf_size = 0;
> +    pe->ap = ap;
> +//    pe->fmt = pe->ic->iformat;
> +    return 0;
> +}

Please clean what's not necessary, we need a clean implementation,
and forget about AVFormatParameters for now.

> +PlayElem* av_make_playelem(unsigned char *filename)
> +{
> +    int err;
> +    PlayElem *pe = av_malloc(sizeof(PlayElem));
> +    err = av_alloc_playelem(filename, pe);
> +    if (err < 0)
> +        print_error("during-av_alloc_playelem", err);
> +    err = av_open_input_playelem(pe);
> +    if (err < 0)
> +        print_error("during-open_input_playelem", err);
> +    pe->fmt = pe->ic->iformat;
> +    if (!pe->fmt)
> +    {
> +        fprintf(stderr, "pefmt not set\n");
> +        fflush(stderr);

Why fflush ?

> +    }
> +    err = av_find_stream_info(pe->ic);
> +    if (err < 0)
> +    {
> +        fprintf(stderr, "failed codec probe av_find_stream_info");
> +        fflush(stderr);

Missing \n ?

> +    }
> +    if(pe->ic->pb)
> +    {
> +        pe->ic->pb->eof_reached = 0;
> +    }
> +    else
> +    {
> +        fprintf(stderr, "failed pe ic pb not set");
> +        fflush(stderr);
> +    }

Why do you need to reset eof_reached ?

Overall comment: do you feel confident everything will fit in a demuxer ?

I think some API calls will be useful like play 5th element in the
playlist, play next element, play prev, shuffle, etc...

-- 
Baptiste COUDURIER                              GnuPG Key Id: 0x5C1ABAAA
Key fingerprint                 8D77134D20CC9220201FC5DB0AC9325C5C1ABAAA
FFmpeg maintainer                                  http://www.ffmpeg.org


More information about the FFmpeg-soc mailing list