[FFmpeg-devel] [PATCH 2/2] Support playing SMV files.

Michael Niedermayer michaelni at gmx.at
Fri Oct 26 04:04:21 CEST 2012


On Thu, Oct 25, 2012 at 07:59:30PM +0000, Ash Hughes wrote:
> Updated to patch against trunk.

tried it with:

ffmpeg -i smv/bear3.smv out.avi
fails with:
Unable to parse option value "-1" as pixel format

[...]

> @@ -326,9 +328,16 @@
>              avio_r8(pb);
>              vst->id = 1;
>              vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
> -            vst->codec->codec_id = AV_CODEC_ID_MJPEG;
> +            vst->codec->codec_id = AV_CODEC_ID_SMVJPEG;
>              vst->codec->width  = avio_rl24(pb);
>              vst->codec->height = avio_rl24(pb);
> +            vst->codec->extradata_size = 4;
> +            vst->codec->extradata = av_malloc(vst->codec->extradata_size +
> +                                              FF_INPUT_BUFFER_PADDING_SIZE);
> +            if (!vst->codec->extradata) {
> +                av_log(s, AV_LOG_ERROR, "Could not allocate extradata.\n");
> +                return AVERROR(ENOMEM);
> +            }
>              size = avio_rl24(pb);
>              wav->smv_data_ofs = avio_tell(pb) + (size - 5) * 3;
>              avio_rl24(pb);
> @@ -338,6 +347,10 @@
>              avio_rl24(pb);
>              avio_rl24(pb);
>              wav->smv_frames_per_jpeg = avio_rl24(pb);
> +            AV_WL32(vst->codec->extradata, wav->smv_frames_per_jpeg);
> +            wav->smv_cur_pt = 0;
> +            if (wav->smv_frames_per_jpeg > 0)
> +                vst->codec->height /= wav->smv_frames_per_jpeg;
>              goto break_loop;
>          case MKTAG('L', 'I', 'S', 'T'):
>              if (size < 4) {
> @@ -436,8 +449,13 @@
>              if (ret < 0)
>                  goto smv_out;
>              pkt->pos -= 3;
> -            pkt->pts = wav->smv_block * wav->smv_frames_per_jpeg;
> -            wav->smv_block++;
> +            pkt->pts = wav->smv_block * wav->smv_frames_per_jpeg + wav->smv_cur_pt;
> +            wav->smv_cur_pt++;
> +            if (wav->smv_frames_per_jpeg > 0)
> +                wav->smv_cur_pt %= wav->smv_frames_per_jpeg;
> +            if (!wav->smv_cur_pt)
> +                wav->smv_block++;
> +
>              pkt->stream_index = 1;
>  smv_out:
>              avio_seek(s->pb, old_pos, SEEK_SET);
> @@ -496,7 +514,10 @@
>              smv_timestamp = av_rescale_q(timestamp, s->streams[0]->time_base, s->streams[1]->time_base);
>          else
>              timestamp = av_rescale_q(smv_timestamp, s->streams[1]->time_base, s->streams[0]->time_base);
> -        wav->smv_block = smv_timestamp / wav->smv_frames_per_jpeg;
> +        if (wav->smv_frames_per_jpeg > 0) {
> +            wav->smv_block = smv_timestamp / wav->smv_frames_per_jpeg;
> +            wav->smv_cur_pt = smv_timestamp % wav->smv_frames_per_jpeg;
> +        }
>      }
>  
>      st = s->streams[0];
> diff -uNr ffmpeg-vanilla/libavcodec/smvjpegdec.c ffmpeg/libavcodec/smvjpegdec.c
> --- ffmpeg-vanilla/libavcodec/smvjpegdec.c    1970-01-01 01:00:00.000000000 +0100
> +++ ffmpeg/libavcodec/smvjpegdec.c    2012-10-19 01:48:26.496972741 +0100
> @@ -0,0 +1,182 @@
> +/*
> + * SMV JPEG decoder
> + * Copyright (c) 2012 Ash Hughes
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +/**
> + * @file
> + * SMV JPEG decoder.
> + */
> +
> +// #define DEBUG
> +#include "avcodec.h"
> +#include "libavutil/opt.h"
> +#include "libavutil/imgutils.h"
> +#include "mjpegdec.h"
> +#include "internal.h"
> +
> +typedef struct SMVJpegDecodeContext {
> +    MJpegDecodeContext jpg;
> +    AVFrame picture[2]; /* pictures array */
> +    AVCodecContext* avctx;
> +    int frames_per_jpeg;
> +} SMVJpegDecodeContext;
> +
> +static inline void smv_img_pnt_plane(uint8_t      **dst, uint8_t *src,
> +                                     int src_linesize, int height, int nlines)
> +{
> +    if (!dst || !src)
> +        return;
> +    src += (nlines) * src_linesize * height;
> +    *dst = src;
> +}
> +
> +static inline void smv_img_pnt(uint8_t *dst_data[4], uint8_t *src_data[4],
> +                               const int src_linesizes[4],
> +                               enum PixelFormat pix_fmt, int width, int height,
> +                               int nlines)
> +{
> +    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
> +    int i, planes_nb = 0;
> +
> +    if (desc->flags & PIX_FMT_HWACCEL)
> +        return;
> +
> +    for (i = 0; i < desc->nb_components; i++)
> +        planes_nb = FFMAX(planes_nb, desc->comp[i].plane + 1);
> +
> +    for (i = 0; i < planes_nb; i++) {
> +        int h = height;
> +        if (i == 1 || i == 2) {
> +            h= -((-height)>>desc->log2_chroma_h);
> +        }
> +        smv_img_pnt_plane(&dst_data[i], src_data[i],
> +            src_linesizes[i], h, nlines);
> +    }
> +}
> +
> +static av_cold int smvjpeg_decode_init(AVCodecContext *avctx)
> +{
> +    SMVJpegDecodeContext *s = avctx->priv_data;
> +    AVCodec *codec;
> +    AVDictionary *thread_opt = NULL;
> +    int ret = 0;
> +
> +    s->frames_per_jpeg = 0;
> +    s->jpg.picture_ptr      = &s->picture[0];
> +
> +    if (avctx->extradata_size >= 4)
> +        s->frames_per_jpeg = AV_RL32(avctx->extradata);
> +
> +    if (s->frames_per_jpeg <= 0) {
> +        av_log(avctx, AV_LOG_ERROR, "Invalid number of frames per jpeg.\n");
> +        ret = -1;
> +    }
> +
> +    avcodec_get_frame_defaults(&s->picture[1]);
> +    avctx->coded_frame = &s->picture[1];
> +    codec = avcodec_find_decoder(AV_CODEC_ID_MJPEG);
> +    if (!codec) {
> +        av_log(avctx, AV_LOG_ERROR, "MJPEG codec not found\n");
> +        ret = -1;
> +    }

iam not sure its a good idea to continue on errors like this
have you tested that this works ?

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

It is what and why we do it that matters, not just one of them.
-------------- 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/20121026/14ef6973/attachment.asc>


More information about the ffmpeg-devel mailing list