[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