[FFmpeg-devel] [PATCHv3 1/2] Magic Lantern Video (MLV) demuxer

Michael Niedermayer michaelni at gmx.at
Mon Mar 31 05:09:43 CEST 2014


On Sun, Mar 30, 2014 at 01:09:06PM +1100, Peter Ross wrote:
> Signed-off-by: Peter Ross <pross at xvid.org>
> ---
> (This addresses Clément's earlier comments.)
> 
>  Changelog                |   1 +
>  doc/general.texi         |   1 +
>  libavformat/Makefile     |   1 +
>  libavformat/allformats.c |   1 +
>  libavformat/mlvdec.c     | 453 +++++++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 457 insertions(+)
>  create mode 100644 libavformat/mlvdec.c
[...]
> +    /* scan secondary files */
> +    if (strlen(avctx->filename) > 2) {
> +        int i;
> +        char *filename = av_strdup(avctx->filename);
> +        if (!filename)
> +            return AVERROR(ENOMEM);
> +        for (i = 0; i < 100; i++) {

> +            sprintf(filename + strlen(filename) - 2, "%02d", i);

please use snprintf()
i dont think its needed but it feels safer to always use it


> +            if (avio_open2(&mlv->pb[i], filename, AVIO_FLAG_READ, &avctx->interrupt_callback, NULL) < 0)
> +                break;
> +            if (check_file_header(mlv->pb[i], guid) < 0) {
> +                av_log(avctx, AV_LOG_WARNING, "ignoring %s; bad format or guid mismatch\n", filename);
> +                avio_close(mlv->pb[i]);
> +                mlv->pb[i] = NULL;
> +                continue;
> +            }
> +            av_log(avctx, AV_LOG_INFO, "scanning %s\n", filename);
> +            scan_file(avctx, vst, ast, i);
> +        }
> +        av_free(filename);
> +    }
> +
> +    if (vst)
> +        vst->duration = vst->nb_index_entries;
> +    if (ast)
> +        ast->duration = ast->nb_index_entries;
> +
> +    if (vst && ast)
> +        avio_seek(pb, FFMIN(vst->index_entries[0].pos, ast->index_entries[0].pos), SEEK_SET);
> +    else if (vst)
> +        avio_seek(pb, vst->index_entries[0].pos, SEEK_SET);
> +    else if (ast)
> +        avio_seek(pb, ast->index_entries[0].pos, SEEK_SET);
> +
> +    return 0;
> +}
> +
> +static int read_packet(AVFormatContext *avctx, AVPacket *pkt)
> +{
> +    MlvContext *mlv = avctx->priv_data;
> +    AVIOContext *pb;
> +    AVStream *st = avctx->streams[mlv->stream_index];
> +    int index, ret;
> +    unsigned int size, space;
> +
> +    if (mlv->pts >= st->duration)
> +        return AVERROR_EOF;
> +
> +    index = av_index_search_timestamp(st, mlv->pts, AVSEEK_FLAG_ANY);
> +    if (index < 0) {
> +        av_log(avctx, AV_LOG_ERROR, "could not find index entry for frame %"PRId64"\n", mlv->pts);
> +        return AVERROR(EIO);
> +    }
> +
> +    pb = mlv->pb[st->index_entries[index].size];
> +    avio_seek(pb, st->index_entries[index].pos, SEEK_SET);
> +
> +    avio_skip(pb, 4); // blockType
> +    size = avio_rl32(pb);
> +    if (size < 16)
> +        return AVERROR_INVALIDDATA;
> +    avio_skip(pb, 12); //timestamp, frameNumber
> +    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
> +        avio_skip(pb, 8); // cropPosX, cropPosY, panPosX, panPosY
> +    space = avio_rl32(pb);
> +    avio_skip(pb, space);
> +
> +    if ((mlv->class[st->id] & (MLV_CLASS_FLAG_DELTA|MLV_CLASS_FLAG_LZMA))) {
> +        ret = AVERROR_PATCHWELCOME;
> +    } else {
> +        ret = av_get_packet(pb, pkt, (st->codec->width * st->codec->height * st->codec->bits_per_coded_sample + 7) >> 3);
> +        if (ret < 0)
> +            return ret;
> +    }
> +
> +    pkt->stream_index = mlv->stream_index;
> +    pkt->pts = mlv->pts;
> +
> +    mlv->stream_index++;
> +    if (mlv->stream_index == avctx->nb_streams) {
> +        mlv->stream_index = 0;
> +        mlv->pts++;
> +    }
> +    return 0;
> +}
> +
> +static int read_seek(AVFormatContext *avctx, int stream_index, int64_t timestamp, int flags)
> +{
> +    MlvContext *mlv = avctx->priv_data;
> +
> +    if ((flags & AVSEEK_FLAG_FRAME) || (flags & AVSEEK_FLAG_BYTE))
> +        return AVERROR(ENOSYS);
> +
> +    if (!avctx->pb->seekable)
> +        return AVERROR(EIO);
> +
> +    mlv->pts = timestamp;
> +    return 0;
> +}
> +

> +static int read_close(AVFormatContext *s)
> +{
> +    MlvContext *mlv = s->priv_data;
> +    av_free(mlv->buffer);

av_freep() to avoid stale pointers


> +    return 0;
> +}
> +
> +AVInputFormat ff_mlv_demuxer = {

> +    .name           = "mv",

typo, mLv
there is already a "mv" demuxer

[...]

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Into a blind darkness they enter who follow after the Ignorance,
they as if into a greater darkness enter who devote themselves
to the Knowledge alone. -- Isha Upanishad
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20140331/ff736ee5/attachment.asc>


More information about the ffmpeg-devel mailing list