[FFmpeg-devel] [PATCH] Psygnosis YOP demuxer/decoder
Michael Niedermayer
michaelni
Mon Aug 10 14:06:12 CEST 2009
On Sun, Aug 09, 2009 at 11:54:36AM -0400, Thomas Higdon wrote:
> Here is the decoder plus the latest version of the demuxer with
> current comments addressed.
[...]
> +/**
> + * Lookup table for painting macroblocks. Bytes 0-3 of each entry contain
> + * the macroblock positions to be painted. Byte 4 contains the number of bytes
> + * consumed on the input, equal to max(bytes 0-3) + 1.
> + */
> +int paint_lut[15][5] = { {0, 1, 2, 3, 4},
uint8_t
[...]
> +static av_cold int decode_init(AVCodecContext *avctx)
> +{
> + YopDecContext *s = avctx->priv_data;
> + int i,j;
> +
> + s->avctx = avctx;
> +
> + if (avctx->width & 1 || avctx->height & 1) {
> + av_log(avctx, AV_LOG_ERROR, "yop needs even width and height\n");
> + return -1;
> + }
> +
> + if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) {
> + return -1;
> + }
you should only need that if you set width/height
> +
> + avctx->pix_fmt = PIX_FMT_RGB24;
> +
> + for (i = 0; i < 256; i++) {
> + for (j = 0; j < RGB_COLORS; j++) {
> + s->palette[i][j] = 0;
> + }
> + }
memset
> +
> + s->num_pal_colors = AV_RL8(avctx->extradata);
> + s->firstcolor_even = AV_RL8(avctx->extradata + 1);
> + s->firstcolor_odd = AV_RL8(avctx->extradata + 2);
> + s->sound_chunk_length = AV_RL16(avctx->extradata + 3);
vertical align
> + s->tag_needs_next_byte = 1;
> +
> + if (s->num_pal_colors + s->firstcolor_even > 256 ||
> + s->num_pal_colors + s->firstcolor_odd > 256) {
> + av_log(avctx, AV_LOG_ERROR,
> + "palette parameters invalid: header probably corrupt\n");
> + }
you probably want a return -1 here
> +
> + return 0;
> +}
> +
> +
> +static av_cold int decode_close(AVCodecContext *avctx)
> +{
> + YopDecContext *s = avctx->priv_data;
> + if (s->frame.data[0]) {
> + avctx->release_buffer(avctx, &s->frame);
> + }
> + return 0;
> +}
> +
> +
> +/**
> + * Calculate the buffer offset necessary to index into the destination
> + * buffer at a certain x and y offset from bufpos. This function wraps around
> + * in both the x and y directions.
> + * @param s context
> + * @param bufpos the current position in the destination buffer. Must be a
> + * valid buffer position that's within the image frame.
> + * @param dx change in x
> + * @param dy change in y
> + */
> +static int buffer_pos(YopDecContext *s, int bufpos, int dx, int dy)
> +{
> + int new_x, new_y;
> + int new_bufpos;
> +
> + int cur_x = bufpos % s->frame.linesize[0];
> + int cur_y = bufpos / s->frame.linesize[0];
> +
> + if (cur_x > s->avctx->width * RGB_COLORS) {
> + av_log(0, AV_LOG_ERROR, "cur_x: %d beyond image edge\n", cur_x);
> + }
> + if (cur_y > s->avctx->height) {
> + av_log(0, AV_LOG_ERROR, "cur_y: %d beyond image edge\n", cur_y);
> + }
how can these happen?
> +
> + new_x = (cur_x + dx) % (s->avctx->width * RGB_COLORS);
> + new_y = (cur_y + dy) % s->avctx->height;
> +
> + if (new_x < 0) {
> + new_x += s->avctx->width * RGB_COLORS;
> + }
> + if (new_y < 0) {
> + new_y += s->avctx->height;
> + }
> + new_bufpos = new_x + new_y * s->frame.linesize[0];
> +
> + // Return the relative offset to bufpos rather than the absolute offset
> + // within the output buffer.
> + return new_bufpos - bufpos;
> +}
[...]
> +/**
> + * Copy a previously painted macroblock to the current_block.
> + * @param copy_tag The tag that was in the nibble.
> + */
> +static void copy_previous_block(YopDecContext *s, int copy_tag)
> +{
> + int i, j;
> + uint8_t *bufptr;
> + int bufpos = (size_t) s->dstptr - (size_t) s->dstbuf;
> +
> + // calculate position for the copy source
> + bufptr = s->dstbuf + bufpos + buffer_pos(s, bufpos,
> + copy_lut[copy_tag][0] * RGB_COLORS,
> + copy_lut[copy_tag][1]);
> + // Each pixel in the macroblock
> + for (i = 0; i < 4; i++) {
> + int offset = macroblock_pixel_offset(s, i, bufpos);
> + // Each color in the pixel
> + for (j = 0; j < RGB_COLORS; j++) {
> + *(s->dstptr + offset + j) = *(bufptr + offset + j);
> + }
> + }
> +}
this code is a mess
make linesize = width if it helps but dont run such code per pixel
> +
> +/**
> + * Return the next nibble in sequence, consuming a new byte on the input
> + * only if necessary.
> + */
> +static int get_next_nibble(YopDecContext *s)
> +{
> + int high_nibble, low_nibble;
> + if (s->tag_needs_next_byte) {
> + s->current_tag_byte = *s->srcptr++;
> + high_nibble = s->current_tag_byte >> 4;
> + s->tag_needs_next_byte = 0;
> + return high_nibble;
> + } else {
> + low_nibble = s->current_tag_byte & 0x0f;
> + s->tag_needs_next_byte = 1;
> + return low_nibble;
> + }
> +}
duplicating get_bits ?
[...]
> Index: libavcodec/yop.h
> ===================================================================
> --- libavcodec/yop.h (revision 0)
> +++ libavcodec/yop.h (revision 0)
> @@ -0,0 +1,44 @@
> +/**
> + * @file libavcodec/yop.h
> + * Psygnosis YOP codec 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
> + */
> +
> +#define RGB_COLORS 3
> +
> +typedef struct YopDecContext {
> + AVFrame frame;
> + AVCodecContext *avctx;
> + AVPacket *avpkt;
> +
> + int num_pal_colors;
> + int firstcolor_even;
> + int firstcolor_odd;
> + int sound_chunk_length;
> + int tag_needs_next_byte;
> + int current_tag_byte;
> + int frame_data_length;
> +
> + uint8_t *srcptr;
> + uint8_t *dstptr;
> + uint8_t *dstbuf;
> +
> + uint8_t palette[256][3];
> +} YopDecContext;
belongs in the .c file if there is just one .c file for the decoder
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
The bravest are surely those who have the clearest vision
of what is before them, glory and danger alike, and yet
notwithstanding go out to meet it. -- Thucydides
-------------- 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/c67aa4dc/attachment.pgp>
More information about the ffmpeg-devel
mailing list