[FFmpeg-devel] [PATCH] Psygnosis YOP demuxer

Michael Niedermayer michaelni
Mon Aug 10 13:52:05 CEST 2009


On Sun, Aug 09, 2009 at 08:57:16PM -0400, Thomas Higdon wrote:
> On Sun, Aug 9, 2009 at 8:47 PM, Michael Niedermayer<michaelni at gmx.at> wrote:
> > On Sun, Aug 09, 2009 at 03:10:36AM -0400, Thomas Higdon wrote:
> >> On Sat, Aug 8, 2009 at 11:21 PM, Mike Melanson<mike at multimedia.cx> wrote:
> >> > Thomas Higdon wrote:
> >> >>
> >> >> On Sat, Aug 8, 2009 at 7:10 PM, Thomas Higdon<thomas.p.higdon at gmail.com>
> >> >> wrote:
> >> >>>
> >> >>> Also, I believe there still may be problems with this demuxer. When
> >> >>> the stream ends, the video freezes, and A-V sync continues into the
> >> >>> negative indefinitely. Any ideas on what might be causing this?
> >> >>
> >> >> Further investigation reveals that this happens with some other clips
> >> >> I tried, so perhaps it's just a bug in ffplay.
> >> >
> >> > Does FFmpeg work? (E.g., 'ffmpeg -i file.yop %04d.png' should decode the
> >> > frames to a series of PNG files and exit cleanly.)
> >>
> >> As a matter of fact, it didn't (it continued decoding frames
> >> indefinitely). I've fixed it by returning AVERROR(EIO) in the event
> >> that an av_get_packet() returns with a size less than I asked for in
> >> yop_read_packet().
> >
> > probabl should be AVERROR_EOF
> 
> Fixed.

[...]
> +static int yop_read_header(AVFormatContext *s, AVFormatParameters *ap)
> +{
> +    YopDecContext *yop = s->priv_data;
> +    ByteIOContext *pb = s->pb;
> +
> +    AVCodecContext *sound_dec, *video_dec;
> +    AVStream *sound_stream, *video_stream;
> +
> +    int header_data_length;
> +    int num_frames, frame_rate, num_pal_colors;
> +    int firstcolor_even, firstcolor_odd;
> +    int sound_chunk_length;
> +
> +    sound_stream = av_new_stream(s, 0);
> +    video_stream = av_new_stream(s, 1);
> +
> +    // Sound
> +    sound_dec = sound_stream->codec;

> +    sound_dec->codec_type = CODEC_TYPE_AUDIO;
> +    sound_dec->codec_id = CODEC_ID_ADPCM_IMA_WS;

vertical align like:
sound_dec->codec_type = CODEC_TYPE_AUDIO;
sound_dec->codec_id   = CODEC_ID_ADPCM_IMA_WS;

looks prettier IMHO


> +    sound_dec->channels = YOP_AUDIO_NUM_CHANNELS;
> +    sound_dec->sample_rate = YOP_AUDIO_SAMPLE_RATE;

iam not sure but dont you think using the literal values here would
be clearer?
sound_dec->channels = 1
says more, with YOP_AUDIO_NUM_CHANNELS one has to look it up


> +
> +    // Video
> +    video_dec = video_stream->codec;
> +    video_dec->codec_type = CODEC_TYPE_VIDEO;
> +    video_dec->codec_id = CODEC_ID_YOP;
> +    video_dec->pix_fmt = PIX_FMT_RGB24;
> +
> +    url_fskip(pb, 4);
> +
> +    num_frames = get_le16(pb);
> +    frame_rate = get_byte(pb);
> +    yop->frame_size = get_byte(pb) * YOP_SECTOR_SIZE;
> +
> +    video_dec->width = get_le16(pb);
> +    video_dec->height = get_le16(pb);
> +
> +    yop->num_pal_colors = get_byte(pb);
> +    firstcolor_odd = get_byte(pb);
> +    firstcolor_even = get_byte(pb);
> +
> +    url_fskip(pb, 3);
> +
> +    sound_chunk_length = get_le16(pb);
> +
> +    // 1 nibble per sample
> +    yop->sound_data_length = YOP_AUDIO_SAMPLES_PER_FRAME / 2;
> +

> +    header_data_length = (size_t)pb->buf_ptr - (size_t)pb->buffer;

hmm


> +    url_fskip(pb, YOP_HEADER_LENGTH - header_data_length);

should be url_fseek to an absolute pos i suspect


> +
> +    // Frame rate and timestamp info

> +    video_stream->r_frame_rate = av_d2q(frame_rate, 6000);

use of av_d2q() here is misleading
also why do you have to set r_frame_rate at all?


> +    av_set_pts_info(video_stream, 32, 1, frame_rate);
> +    video_stream->nb_frames = num_frames;
> +
> +    // Extra data that will be passed to the decoder
> +    video_stream->codec->extradata_size = 5;
> +
> +    video_stream->codec->extradata =
> +        av_mallocz(video_stream->codec->extradata_size +
> +                   FF_INPUT_BUFFER_PADDING_SIZE);
> +
> +    if (!video_stream->codec->extradata) {
> +        return AVERROR(ENOMEM);
> +    }
> +

> +    AV_WL8(video_stream->codec->extradata, yop->num_pal_colors);
> +    AV_WL8(video_stream->codec->extradata + 1, firstcolor_odd);
> +    AV_WL8(video_stream->codec->extradata + 2, firstcolor_even);
> +    AV_WL16(video_stream->codec->extradata + 3, sound_chunk_length);

this should be read with a single get_buffer() into extradata id guess


> +
> +    yop->stream = 1;
> +
> +    return 0;
> +}
> +
> +static int yop_read_packet(AVFormatContext *s, AVPacket *pkt)
> +{
> +    YopDecContext *yop = s->priv_data;
> +    ByteIOContext *pb = s->pb;
> +
> +    int ret;
> +    int skip = 4 + yop->num_pal_colors * 3;
> +
> +    AVStream *st;

> +    yop->stream = (yop->stream + 1) % 2;

^= 1;


> +    if (yop->stream == 0) { // audio
> +        st = s->streams[yop->stream];
> +
> +        // skip over video data
> +        url_fskip(pb, skip);
> +        ret = av_get_packet(pb, pkt, yop->sound_data_length);
> +        if (ret < yop->sound_data_length) {
> +            return AVERROR_EOF;
> +        }
> +        // seek back to beginning of packet for the video data
> +        url_fseek(pb, -(skip + yop->sound_data_length), SEEK_CUR);

can seek back be avoided?
because seeking back can cause problems if the underlaying protocol doesnt
support seeking back


[...]
> Index: libavformat/yop.h
> ===================================================================
> --- libavformat/yop.h	(revision 0)
> +++ libavformat/yop.h	(revision 0)
> @@ -0,0 +1,42 @@
> +/**
> + * @file libavformat/yop.h
> + * Psygnosis YOP header
> + *
> + * Copyright (C) 2009 Thomas P. Higdon <thomas.p.higdon at gmail.com>
> + *
> + * 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
> + */
> +
> +#ifndef AVFORMAT_YOP_H
> +#define AVFORMAT_YOP_H
> +
> +#define YOP_SIGNATURE "YO"
> +
> +#define YOP_AUDIO_SAMPLE_RATE 22050
> +#define YOP_AUDIO_SAMPLES_PER_FRAME 1840
> +#define YOP_AUDIO_NUM_CHANNELS 1
> +
> +#define YOP_SECTOR_SIZE 2048
> +#define YOP_HEADER_LENGTH YOP_SECTOR_SIZE
> +

> +typedef struct yop_dec_context {
> +    int frame_size;
> +    int sound_data_length;
> +    int stream;
> +    int num_pal_colors;
> +} YopDecContext;
> +#endif

that belongs in the demuxer (it says dec so its not common between
demuxer & muxer)

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

If a bugfix only changes things apparently unrelated to the bug with no
further explanation, that is a good sign that the bugfix is wrong.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090810/0564e119/attachment.pgp>



More information about the ffmpeg-devel mailing list