[FFmpeg-devel] Fwd: [PATCH] Psygnosis YOP demuxer
Michael Niedermayer
michaelni
Fri Jan 15 01:11:51 CET 2010
On Thu, Jan 14, 2010 at 02:22:04AM +0530, Mohamed Naufal wrote:
> 2010/1/6 Benoit Fouet <benoit.fouet at free.fr>
>
>
> [...]
>
> at least the decoder should be submitted first so that build is not broken
> > :)
> > I've quickly tested the yop files available in the samples directory;
> > they do not crash, the audio plays ok, but seek does not work.
> >
> >
>
> [...]
>
> I think seeking works now. Have set PKT_FLAG_KEY for every packet but not
> sure this is the proper method. Have also included the decoder code.
>
> Naufal
[..]
> +typedef struct YopDecContext {
> + AVFrame frame;
> + AVCodecContext *avctx;
> + AVPacket *avpkt;
> +
> + int num_pal_colors;
> + int first_color[2];
> + int tag_needs_next_byte;
> + int current_tag_byte;
you dont need that variable
> + int frame_data_length;
> + int block_offset_lut[4];
> + int row_pos;
> +
> + uint8_t *srcptr;
> + uint8_t *dstptr;
> + uint8_t *dstbuf;
> +
> + uint8_t palette[256][3];
> +} YopDecContext;
> +
> +// These tables are taken directly from:
> +// http://wiki.multimedia.cx/index.php?title=Psygnosis_YOP
[...]
> +/**
> + * Lookup table for copying macroblocks. Each entry contains the respective
> + * x and y pixel offset for the copy source.
> + */
> +static const int8_t copy_lut[16][2] = { {-4, -4},
its called a motion vector
> + {-2, -4},
> + { 0, -4},
> + { 2, -4},
> + {-4, -2},
> + {-4, 0},
> + {-3, -3},
> + {-1, -3},
> + { 1, -3},
> + { 3, -3},
> + {-3, -1},
> + {-2, -2},
> + { 0, -2},
> + { 2, -2},
> + { 4, -2},
> + {-2, 0},
> + };
> +
> +static av_cold int yop_decode_init(AVCodecContext *avctx)
> +{
> + YopDecContext *s = avctx->priv_data;
> +
> + 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;
> + }
> +
> + avctx->pix_fmt = PIX_FMT_RGB24;
> +
> + memset(s->palette, 0, sizeof(s->palette));
> +
> + s->num_pal_colors = AV_RL8(avctx->extradata);
> + s->first_color[0] = AV_RL8(avctx->extradata + 1);
> + s->first_color[1] = AV_RL8(avctx->extradata + 2);
> +
> + if (s->num_pal_colors + s->first_color[0] > 256 ||
> + s->num_pal_colors + s->first_color[1] > 256) {
> + av_log(avctx, AV_LOG_ERROR,
> + "YOP: palette parameters invalid, header probably corrupt\n");
> + return -1;
> + }
> +
> + s->tag_needs_next_byte = 1;
> +
> + s->block_offset_lut[0] = 0;
> + s->block_offset_lut[1] = RGB_COLORS;
> + s->block_offset_lut[2] = avctx->width * RGB_COLORS;
> + s->block_offset_lut[3] = (avctx->width + 1) * RGB_COLORS;
this is incorrect, you mix width and linesize
> +
> + return 0;
> +}
> +
> +
> +static av_cold int yop_decode_close(AVCodecContext *avctx)
> +{
> + YopDecContext *s = avctx->priv_data;
> + if (s->frame.data[0]) {
> + av_free(s->frame.data[0]);
> + }
the if is superfous also use av_freep()
> + return 0;
> +}
> +
> +/**
> + * Paint a macroblock using the pattern in paint_lut.
> + * @param s codec context
> + * @param tag The tag that was in the nibble.
> + */
> +static void yop_paint_block(YopDecContext *s, int tag)
> +{
> + int i;
> + int color_num, offset;
> +
> + for (i = 0; i < 4; i++) {
> + color_num = *(s->srcptr + paint_lut[tag][i]);
> + offset = s->block_offset_lut[i];
> +
> + *(s->dstptr + offset) = s->palette[color_num][0];
> + *(s->dstptr + offset + 1) = s->palette[color_num][1];
> + *(s->dstptr + offset + 2) = s->palette[color_num][2];
> + }
> + // The number of src bytes consumed is in the last part of the lut entry.
> + s->srcptr += paint_lut[tag][4];
> +}
> +
> +/**
> + * Copy a previously painted macroblock to the current_block.
> + * @param copy_tag The tag that was in the nibble.
> + */
> +static void yop_copy_previous_block(YopDecContext *s, int copy_tag)
> +{
> + int i;
> + int offset;
> + uint8_t *bufptr;
> +
> + // calculate position for the copy source
> + bufptr = s->dstptr + copy_lut[copy_tag][0] * RGB_COLORS +
> + s->frame.linesize[0] * copy_lut[copy_tag][1];
> +
> + // Each pixel in the macroblock
> + for (i = 0; i < 4; i++) {
> + offset = s->block_offset_lut[i];
> + *(s->dstptr + offset) = *(bufptr + offset);
> + *(s->dstptr + offset + 1) = *(bufptr + offset + 1);
> + *(s->dstptr + offset + 2) = *(bufptr + offset + 2);
> + }
for(6){
s->dstptr[i] = bufptr[i];
s->dstptr[i+linesize]= bufptr[i+linesize];
}
> +}
> +
> +/**
> + * Return the next nibble in sequence, consuming a new byte on the input
> + * only if necessary.
> + */
> +static int yop_get_next_nibble(YopDecContext *s)
> +{
> + int ret;
> +
> + if (s->tag_needs_next_byte) {
> + s->current_tag_byte = *s->srcptr++;
> + ret = s->current_tag_byte >> 4;
> + }else {
> + ret = s->current_tag_byte & 0x0f;
> + }
> +
> + s->tag_needs_next_byte ^= 1;
> +
> + return ret;
> +}
> +
[...]
> +/**
> + * Update the palette based on the frame number. Consume all of the palette
> + * bytes on the input.
> + */
> +static void yop_update_palette(YopDecContext *s)
> +{
> + int firstcolor;
> + int i, j;
> +
> + firstcolor = s->first_color[s->avctx->frame_number & 1];
this will be wrong with seeking id suspect
> +
> + for (i = 0; i < s->num_pal_colors; i++) {
> + for (j = 0; j < RGB_COLORS; j++) {
> + // shift left by 2 because the encoded palette is 6-bit color
> + s->palette[i + firstcolor][j] = *s->srcptr++ << 2;
> + }
> + }
> +}
> +
> +static int yop_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
> + AVPacket *avpkt)
> +{
> + YopDecContext *s = avctx->priv_data;
> + int current_nibble;
> +
> + s->srcptr = avpkt->data;
> + s->avpkt = avpkt;
> +
> + if (!s->frame.data[0]) {
> + s->frame.data[0] = av_mallocz(avctx->width * RGB_COLORS * avctx->height);
> + if (!s->frame.data[0])
> + return AVERROR(ENOMEM);
> + }
if you allocate a frame like this then you must implement all the logic that
sets up various fields that you skip
look at avcodec_get_frame_defaults() and get_buffer()
also theres an integer overflow in your code
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Republics decline into democracies and democracies degenerate into
despotisms. -- Aristotle
-------------- 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/20100115/8831eae9/attachment.pgp>
More information about the ffmpeg-devel
mailing list