[FFmpeg-devel] [PATCH] Kega Game Video (KGV1) decoder
Michael Niedermayer
michaelni
Thu Feb 4 04:02:27 CET 2010
On Wed, Feb 03, 2010 at 11:49:32AM -0600, Daniel Verkamp wrote:
> On Wed, Feb 3, 2010 at 10:41 AM, Daniel Verkamp <daniel at drv.nu> wrote:
> > Hi,
> >
> > This is a video capture codec used by the Kega emulator.
> >
> > See http://wiki.multimedia.cx/index.php?title=Kega_Video for more information.
> >
> > Thanks,
> > -- Daniel Verkamp
> >
>
> Slightly changed version which (hopefully) fixes endianness issues;
> still only tested on LE.
>
[...]
> +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
> +{
> + const uint8_t *buf = avpkt->data;
> + const uint8_t *buf_end = buf + avpkt->size;
> + uint8_t *dst;
> + KgvContext * const c = avctx->priv_data;
> + int offsets[7];
> + uint16_t *out, *prev;
> + int outcnt = 0, maxcnt;
> + int w, h, i, stride;
> +
> + if (avpkt->size < 2)
> + return -1;
> +
> + avctx->width = w = (buf[0] + 1) * 8;
> + avctx->height = h = (buf[1] + 1) * 8;
> + buf += 2;
> +
> + maxcnt = w * h;
> +
> + if(c->pic.data[0])
> + avctx->release_buffer(avctx, &c->pic);
> +
> + c->pic.reference = 1;
> + c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
> + if(avctx->get_buffer(avctx, &c->pic) < 0){
> + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
> + return -1;
> + }
> +
> + out = av_realloc(c->cur, (w * h + 0x3FF + 3) * 2);
> + if (!out)
> + return -1;
> + c->cur = out;
> +
> + prev = av_realloc(c->prev, (w * h + 0x3FF + 3) * 2);
> + if (!prev)
> + return -1;
> + c->prev = prev;
> +
> + for (i = 0; i < 7; i++)
> + offsets[i] = -1;
> +
> + while (outcnt < maxcnt && buf_end - 2 > buf) {
> + int code = AV_RL16(buf);
> + buf += 2;
> + if (!(code & 0x8000)) {
> + out[outcnt++] = code;
> + } else {
> + // code = 1xx
> + if ((code & 0x6000) == 0x6000) {
> + // 111
> + int count = (code & 0x3FF) + 3;
> + int oidx = (code >> 10) & 7;
> + int offset;
> +
> + if (offsets[oidx] == -1) {
> + if (buf_end - 3 < buf)
> + break;
> + offsets[oidx] = AV_RL24(buf);
> + buf += 3;
> + }
> +
> + offset = outcnt + offsets[oidx];
> + if (offset >= maxcnt)
> + offset -= maxcnt;
> +
> + for (i = 0; i < count; i++) {
> + out[outcnt] = prev[offset + i];
> + outcnt++;
> + }
are you missing checks for the outpt array size, if so please double
check your code that there are no further such issues and also try a
fuzzer
[...]
> + dst = c->pic.data[0];
> + stride = c->pic.linesize[0];
> + for (i = 0; i < h; i++)
> + memcpy(dst + i * stride, c->cur + i * w, w * 2);
return your internal buffer dont copy and disable CODEC_CAP_DR1
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
While the State exists there can be no freedom; when there is freedom there
will be no State. -- Vladimir Lenin
-------------- 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/20100204/dd50bc86/attachment.pgp>
More information about the ffmpeg-devel
mailing list