CVS: ffmpeg/libavcodec kmvc.c, NONE, 1.1 Makefile, 1.250, 1.251 allcodecs.c, 1.134, 1.135 avcodec.h, 1.461, 1.462
Update of /cvsroot/ffmpeg/ffmpeg/libavcodec In directory mail:/var2/tmp/cvs-serv12938/libavcodec Modified Files: Makefile allcodecs.c avcodec.h Added Files: kmvc.c Log Message: KMVC (used in Worms games) decoder. Works fine with samples from MPHQ --- NEW FILE: kmvc.c --- /* * KMVC decoder * Copyright (c) 2006 Konstantin Shishkov * * This library 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 of the License, or (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * @file kmvc.c * Karl Morton's Video Codec decoder */ #include <stdio.h> #include <stdlib.h> #include "common.h" #include "avcodec.h" #define KMVC_KEYFRAME 0x80 #define KMVC_PALETTE 0x40 #define KMVC_METHOD 0x0F /* * Decoder context */ typedef struct KmvcContext { AVCodecContext *avctx; AVFrame pic; int setpal; int palsize; uint32_t pal[256]; uint8_t *cur, *prev; uint8_t *frm0, *frm1; } KmvcContext; typedef struct BitBuf { int bits; int bitbuf; } BitBuf; #define BLK(data, x, y) data[(x) + (y) * 320] #define kmvc_init_getbits(bb, src) bb.bits = 7; bb.bitbuf = *src++; #define kmvc_getbit(bb, src, res) {\ res = 0; \ if (bb.bitbuf & (1 << bb.bits)) res = 1; \ bb.bits--; \ if(bb.bits == -1) { \ bb.bitbuf = *src++; \ bb.bits = 7; \ } \ } static void kmvc_decode_intra_8x8(KmvcContext * ctx, uint8_t * src, int w, int h) { BitBuf bb; int res, val; int i, j; int bx, by; int l0x, l1x, l0y, l1y; int mx, my; kmvc_init_getbits(bb, src); for (by = 0; by < h; by += 8) for (bx = 0; bx < w; bx += 8) { kmvc_getbit(bb, src, res); if (!res) { // fill whole 8x8 block val = *src++; for (i = 0; i < 64; i++) BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val; } else { // handle four 4x4 subblocks for (i = 0; i < 4; i++) { l0x = bx + (i & 1) * 4; l0y = by + (i & 2) * 2; kmvc_getbit(bb, src, res); if (!res) { kmvc_getbit(bb, src, res); if (!res) { // fill whole 4x4 block val = *src++; for (j = 0; j < 16; j++) BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val; } else { // copy block from already decoded place val = *src++; mx = val & 0xF; my = val >> 4; for (j = 0; j < 16; j++) BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = BLK(ctx->cur, l0x + (j & 3) - mx, l0y + (j >> 2) - my); } } else { // descend to 2x2 sub-sub-blocks for (j = 0; j < 4; j++) { l1x = l0x + (j & 1) * 2; l1y = l0y + (j & 2); kmvc_getbit(bb, src, res); if (!res) { kmvc_getbit(bb, src, res); if (!res) { // fill whole 2x2 block val = *src++; BLK(ctx->cur, l1x, l1y) = val; BLK(ctx->cur, l1x + 1, l1y) = val; BLK(ctx->cur, l1x, l1y + 1) = val; BLK(ctx->cur, l1x + 1, l1y + 1) = val; } else { // copy block from already decoded place val = *src++; mx = val & 0xF; my = val >> 4; BLK(ctx->cur, l1x, l1y) = BLK(ctx->cur, l1x - mx, l1y - my); BLK(ctx->cur, l1x + 1, l1y) = BLK(ctx->cur, l1x + 1 - mx, l1y - my); BLK(ctx->cur, l1x, l1y + 1) = BLK(ctx->cur, l1x - mx, l1y + 1 - my); BLK(ctx->cur, l1x + 1, l1y + 1) = BLK(ctx->cur, l1x + 1 - mx, l1y + 1 - my); } } else { // read values for block BLK(ctx->cur, l1x, l1y) = *src++; BLK(ctx->cur, l1x + 1, l1y) = *src++; BLK(ctx->cur, l1x, l1y + 1) = *src++; BLK(ctx->cur, l1x + 1, l1y + 1) = *src++; } } } } } } } static void kmvc_decode_inter_8x8(KmvcContext * ctx, uint8_t * src, int w, int h) { BitBuf bb; int res, val; int i, j; int bx, by; int l0x, l1x, l0y, l1y; int mx, my; kmvc_init_getbits(bb, src); for (by = 0; by < h; by += 8) for (bx = 0; bx < w; bx += 8) { kmvc_getbit(bb, src, res); if (!res) { kmvc_getbit(bb, src, res); if (!res) { // fill whole 8x8 block val = *src++; for (i = 0; i < 64; i++) BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val; } else { // copy block from previous frame for (i = 0; i < 64; i++) BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = BLK(ctx->prev, bx + (i & 0x7), by + (i >> 3)); } } else { // handle four 4x4 subblocks for (i = 0; i < 4; i++) { l0x = bx + (i & 1) * 4; l0y = by + (i & 2) * 2; kmvc_getbit(bb, src, res); if (!res) { kmvc_getbit(bb, src, res); if (!res) { // fill whole 4x4 block val = *src++; for (j = 0; j < 16; j++) BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val; } else { // copy block val = *src++; mx = (val & 0xF) - 8; my = (val >> 4) - 8; for (j = 0; j < 16; j++) BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = BLK(ctx->prev, l0x + (j & 3) + mx, l0y + (j >> 2) + my); } } else { // descend to 2x2 sub-sub-blocks for (j = 0; j < 4; j++) { l1x = l0x + (j & 1) * 2; l1y = l0y + (j & 2); kmvc_getbit(bb, src, res); if (!res) { kmvc_getbit(bb, src, res); if (!res) { // fill whole 2x2 block val = *src++; BLK(ctx->cur, l1x, l1y) = val; BLK(ctx->cur, l1x + 1, l1y) = val; BLK(ctx->cur, l1x, l1y + 1) = val; BLK(ctx->cur, l1x + 1, l1y + 1) = val; } else { // copy block val = *src++; mx = (val & 0xF) - 8; my = (val >> 4) - 8; BLK(ctx->cur, l1x, l1y) = BLK(ctx->prev, l1x + mx, l1y + my); BLK(ctx->cur, l1x + 1, l1y) = BLK(ctx->prev, l1x + 1 + mx, l1y + my); BLK(ctx->cur, l1x, l1y + 1) = BLK(ctx->prev, l1x + mx, l1y + 1 + my); BLK(ctx->cur, l1x + 1, l1y + 1) = BLK(ctx->prev, l1x + 1 + mx, l1y + 1 + my); } } else { // read values for block BLK(ctx->cur, l1x, l1y) = *src++; BLK(ctx->cur, l1x + 1, l1y) = *src++; BLK(ctx->cur, l1x, l1y + 1) = *src++; BLK(ctx->cur, l1x + 1, l1y + 1) = *src++; } } } } } } } static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, uint8_t * buf, int buf_size) { KmvcContext *const ctx = (KmvcContext *) avctx->priv_data; uint8_t *out, *src; int i; int header; int blocksize; if (ctx->pic.data[0]) avctx->release_buffer(avctx, &ctx->pic); ctx->pic.reference = 1; ctx->pic.buffer_hints = FF_BUFFER_HINTS_VALID; if (avctx->get_buffer(avctx, &ctx->pic) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } header = buf[0]; buf++; if (header & KMVC_KEYFRAME) { ctx->pic.key_frame = 1; ctx->pic.pict_type = FF_I_TYPE; } else { ctx->pic.key_frame = 0; ctx->pic.pict_type = FF_P_TYPE; } if (header & KMVC_PALETTE) { ctx->pic.palette_has_changed = 1; // palette starts from index 1 and has 127 entries for (i = 1; i <= ctx->palsize; i++) { ctx->pal[i] = (buf[0] << 16) | (buf[1] << 8) | buf[2]; buf += 3; } } if (ctx->setpal) { ctx->setpal = 0; ctx->pic.palette_has_changed = 1; } /* make the palette available on the way out */ memcpy(ctx->pic.data[1], ctx->pal, 1024); blocksize = *buf++; if (blocksize != 8) { av_log(avctx, AV_LOG_ERROR, "Block size = %i\n", blocksize); return -1; } memset(ctx->cur, 0, 320 * 200); switch (header & KMVC_METHOD) { case 3: kmvc_decode_intra_8x8(ctx, buf, avctx->width, avctx->height); break; case 4: kmvc_decode_inter_8x8(ctx, buf, avctx->width, avctx->height); break; default: av_log(avctx, AV_LOG_ERROR, "Unknown compression method %i\n", header & KMVC_METHOD); return -1; } out = ctx->pic.data[0]; src = ctx->cur; for (i = 0; i < avctx->height; i++) { memcpy(out, src, avctx->width); src += 320; out += ctx->pic.linesize[0]; } /* flip buffers */ if (ctx->cur == ctx->frm0) { ctx->cur = ctx->frm1; ctx->prev = ctx->frm0; } else { ctx->cur = ctx->frm0; ctx->prev = ctx->frm1; } *data_size = sizeof(AVFrame); *(AVFrame *) data = ctx->pic; /* always report that the buffer was completely consumed */ return buf_size; } /* * Init kmvc decoder */ static int decode_init(AVCodecContext * avctx) { KmvcContext *const c = (KmvcContext *) avctx->priv_data; int i; c->avctx = avctx; avctx->has_b_frames = 0; c->pic.data[0] = NULL; if (avctx->width > 320 || avctx->height > 200) { av_log(avctx, AV_LOG_ERROR, "KMVC supports frames <= 320x200\n"); return -1; } c->frm0 = av_mallocz(320 * 200); c->frm1 = av_mallocz(320 * 200); c->cur = c->frm0; c->prev = c->frm1; for (i = 0; i < 256; i++) { c->pal[i] = i * 0x10101; } if (avctx->extradata_size < 12) { av_log(NULL, 0, "Extradata missing, decoding may not work properly...\n"); c->palsize = 127; } else { c->palsize = LE_16(avctx->extradata + 10); } if (avctx->extradata_size == 1036) { // palette in extradata uint8_t *src = avctx->extradata + 12; for (i = 0; i < c->palsize; i++) { c->pal[i] = LE_32(src); src += 4; } c->setpal = 1; } avctx->pix_fmt = PIX_FMT_PAL8; return 0; } /* * Uninit kmvc decoder */ static int decode_end(AVCodecContext * avctx) { KmvcContext *const c = (KmvcContext *) avctx->priv_data; if (c->frm0) av_free(c->frm0); if (c->frm1) av_free(c->frm1); if (c->pic.data[0]) avctx->release_buffer(avctx, &c->pic); return 0; } AVCodec kmvc_decoder = { "kmvc", CODEC_TYPE_VIDEO, CODEC_ID_KMVC, sizeof(KmvcContext), decode_init, NULL, decode_end, decode_frame }; Index: Makefile =================================================================== RCS file: /cvsroot/ffmpeg/ffmpeg/libavcodec/Makefile,v retrieving revision 1.250 retrieving revision 1.251 diff -u -d -r1.250 -r1.251 --- Makefile 29 Mar 2006 10:59:09 -0000 1.250 +++ Makefile 7 Apr 2006 16:59:57 -0000 1.251 @@ -98,6 +98,9 @@ ifeq ($(CONFIG_INTERPLAY_VIDEO_DECODER),yes) OBJS+= interplayvideo.o endif +ifeq ($(CONFIG_KMVC_DECODER),yes) + OBJS+= kmvc.o +endif ifneq ($(CONFIG_MSZH_DECODER)$(CONFIG_ZLIB_DECODER)$(CONFIG_ZLIB_ENCODER),) OBJS+= lcl.o endif Index: allcodecs.c =================================================================== RCS file: /cvsroot/ffmpeg/ffmpeg/libavcodec/allcodecs.c,v retrieving revision 1.134 retrieving revision 1.135 diff -u -d -r1.134 -r1.135 --- allcodecs.c 31 Mar 2006 13:06:24 -0000 1.134 +++ allcodecs.c 7 Apr 2006 16:59:57 -0000 1.135 @@ -289,6 +289,9 @@ #ifdef CONFIG_LOCO_DECODER register_avcodec(&loco_decoder); #endif //CONFIG_LOCO_DECODER +#ifdef CONFIG_KMVC_DECODER + register_avcodec(&kmvc_decoder); +#endif //CONFIG_KMVC_DECODER #ifdef CONFIG_WNV1_DECODER register_avcodec(&wnv1_decoder); #endif //CONFIG_WNV1_DECODER Index: avcodec.h =================================================================== RCS file: /cvsroot/ffmpeg/ffmpeg/libavcodec/avcodec.h,v retrieving revision 1.461 retrieving revision 1.462 diff -u -d -r1.461 -r1.462 --- avcodec.h 5 Apr 2006 18:56:22 -0000 1.461 +++ avcodec.h 7 Apr 2006 16:59:57 -0000 1.462 @@ -21,8 +21,8 @@ #define AV_STRINGIFY(s) AV_TOSTRING(s) #define AV_TOSTRING(s) #s -#define LIBAVCODEC_VERSION_INT ((51<<16)+(8<<8)+0) -#define LIBAVCODEC_VERSION 51.8.0 +#define LIBAVCODEC_VERSION_INT ((51<<16)+(9<<8)+0) +#define LIBAVCODEC_VERSION 51.9.0 #define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT #define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) @@ -120,6 +120,7 @@ CODEC_ID_AVS, CODEC_ID_SMACKVIDEO, CODEC_ID_NUV, + CODEC_ID_KMVC, /* various pcm "codecs" */ CODEC_ID_PCM_S16LE= 0x10000,
On Fri, 7 Apr 2006 19:00:00 +0200 (CEST) kostya at mplayerhq.hu (Konstantin Shishkov CVS) wrote:
Update of /cvsroot/ffmpeg/ffmpeg/libavcodec In directory mail:/var2/tmp/cvs-serv12938/libavcodec
Modified Files: Makefile allcodecs.c avcodec.h Added Files: kmvc.c Log Message: KMVC (used in Worms games) decoder. Works fine with samples from MPHQ
You forgot to add the extern declaration for the codec. Ciao, Roberto Index: avcodec.h =================================================================== RCS file: /cvsroot/ffmpeg/ffmpeg/libavcodec/avcodec.h,v retrieving revision 1.462 diff -u -r1.462 avcodec.h --- avcodec.h 7 Apr 2006 16:59:57 -0000 1.462 +++ avcodec.h 7 Apr 2006 17:25:15 -0000 @@ -2200,6 +2200,7 @@ extern AVCodec avs_decoder; extern AVCodec smacker_decoder; extern AVCodec smackaud_decoder; +extern AVCodec kmvc_decoder; /* pcm codecs */ #define PCM_CODEC(id, name) \
On Fri, 7 Apr 2006 19:26:49 +0200 Roberto Togni <r_togni at tiscali.it> wrote: [...]
You forgot to add the extern declaration for the codec.
applied Ciao, Roberto
On Fri, Apr 07, 2006 at 11:08:56PM +0200, Roberto Togni wrote:
On Fri, 7 Apr 2006 19:26:49 +0200 Roberto Togni <r_togni at tiscali.it> wrote:
[...]
You forgot to add the extern declaration for the codec.
applied
Ciao, Roberto
Thanks for applying, that's 20l to me.
On Fri, Apr 07, 2006 at 07:00:00PM +0200, Konstantin Shishkov CVS wrote:
Update of /cvsroot/ffmpeg/ffmpeg/libavcodec In directory mail:/var2/tmp/cvs-serv12938/libavcodec
Modified Files: Makefile allcodecs.c avcodec.h Added Files: kmvc.c Log Message: KMVC (used in Worms games) decoder. Works fine with samples from MPHQ
Breaks the build: [snip] gcc -O3 -g -Wall -Wno-switch -Wdeclaration-after-statement -DHAVE_AV_CONFIG_H -I.. -I/home/snacky/src/ffmpeg/libavutil -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE -c -o allcodecs.o allcodecs.c allcodecs.c: In function `avcodec_register_all': allcodecs.c:293: error: `kmvc_decoder' undeclared (first use in this function) allcodecs.c:293: error: (Each undeclared identifier is reported only once allcodecs.c:293: error: for each function it appears in.) make[1]: *** [allcodecs.o] Error 1 make[1]: Leaving directory `/home/snacky/src/ffmpeg/libavcodec' make: *** [lib] Error 2
Hi On Fri, Apr 07, 2006 at 07:00:00PM +0200, Konstantin Shishkov CVS wrote:
Update of /cvsroot/ffmpeg/ffmpeg/libavcodec In directory mail:/var2/tmp/cvs-serv12938/libavcodec
Modified Files: Makefile allcodecs.c avcodec.h Added Files: kmvc.c Log Message: KMVC (used in Worms games) decoder. Works fine with samples from MPHQ [...] #define kmvc_init_getbits(bb, src) bb.bits = 7; bb.bitbuf = *src++;
#define kmvc_getbit(bb, src, res) {\ res = 0; \ if (bb.bitbuf & (1 << bb.bits)) res = 1; \ bb.bits--; \ if(bb.bits == -1) { \ bb.bitbuf = *src++; \ bb.bits = 7; \ } \ }
is there a special reason why this is a macro and no inline function or maybe even get_bits1() standard bitstream stuff ... ? [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Breaking DRM is a little like attempting to break through a door even though the window is wide open and the only thing in the house is a bunch of things you dont want and which you would get tomorrow for free anyway
On Mon, Apr 02, 2007 at 02:29:26AM +0200, Michael Niedermayer wrote:
Hi
On Fri, Apr 07, 2006 at 07:00:00PM +0200, Konstantin Shishkov CVS wrote:
Update of /cvsroot/ffmpeg/ffmpeg/libavcodec In directory mail:/var2/tmp/cvs-serv12938/libavcodec
Modified Files: Makefile allcodecs.c avcodec.h Added Files: kmvc.c Log Message: KMVC (used in Worms games) decoder. Works fine with samples from MPHQ [...] #define kmvc_init_getbits(bb, src) bb.bits = 7; bb.bitbuf = *src++;
#define kmvc_getbit(bb, src, res) {\ res = 0; \ if (bb.bitbuf & (1 << bb.bits)) res = 1; \ bb.bits--; \ if(bb.bits == -1) { \ bb.bitbuf = *src++; \ bb.bits = 7; \ } \ }
is there a special reason why this is a macro and no inline function or maybe even get_bits1() standard bitstream stuff ... ?
It cannot be get_bits1() as bits are grouped by 8 and are interwoven into data stream so it may be like this: <pixel> <pixel> <bits> <pixel> <pixel> <pixel> <bits> <pixel> <bits> Also there is no need to use bitstream as everything is read by bytes. About macro vs. inline function - Is there any rule when to use which? I prefer to use macros in such situations.
[...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Breaking DRM is a little like attempting to break through a door even though the window is wide open and the only thing in the house is a bunch of things you dont want and which you would get tomorrow for free anyway
Hi On Tue, Apr 03, 2007 at 08:15:32AM +0300, Kostya wrote:
On Mon, Apr 02, 2007 at 02:29:26AM +0200, Michael Niedermayer wrote:
Hi
On Fri, Apr 07, 2006 at 07:00:00PM +0200, Konstantin Shishkov CVS wrote:
Update of /cvsroot/ffmpeg/ffmpeg/libavcodec In directory mail:/var2/tmp/cvs-serv12938/libavcodec
Modified Files: Makefile allcodecs.c avcodec.h Added Files: kmvc.c Log Message: KMVC (used in Worms games) decoder. Works fine with samples from MPHQ [...] #define kmvc_init_getbits(bb, src) bb.bits = 7; bb.bitbuf = *src++;
#define kmvc_getbit(bb, src, res) {\ res = 0; \ if (bb.bitbuf & (1 << bb.bits)) res = 1; \ bb.bits--; \ if(bb.bits == -1) { \ bb.bitbuf = *src++; \ bb.bits = 7; \ } \ }
is there a special reason why this is a macro and no inline function or maybe even get_bits1() standard bitstream stuff ... ?
It cannot be get_bits1() as bits are grouped by 8 and are interwoven into data stream so it may be like this: <pixel> <pixel> <bits> <pixel> <pixel> <pixel> <bits> <pixel> <bits> Also there is no need to use bitstream as everything is read by bytes.
ok
About macro vs. inline function - Is there any rule when to use which? I prefer to use macros in such situations.
i generally prefer inline functions as the compiler can, if size matters simply decide not to inline it ... of course if a macro is faster then a macro is better ... [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB I am the wisest man alive, for I know one thing, and that is that I know nothing. -- Socrates
participants (5)
-
kostya.shishkov@gmail.com -
kostya@mplayerhq.hu -
michaelni@gmx.at -
r_togni@tiscali.it -
snacky@ikaruga.co.uk