Navigation Menu

Skip to content

Commit

Permalink
Winnov WNV1 video decoder, courtesy of Konstantin Shishkov
Browse files Browse the repository at this point in the history
Originally committed as revision 4083 to svn://svn.ffmpeg.org/ffmpeg/trunk
  • Loading branch information
multimediamike committed Mar 26, 2005
1 parent cec1f05 commit a8a15e9
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 2 deletions.
1 change: 1 addition & 0 deletions Changelog
Expand Up @@ -12,6 +12,7 @@ version <next>
- Shorten audio decoder
- LOCO video decoder
- Apple Lossless Audio Codec (ALAC) decoder
- Winnov WNV1 video decoder

version 0.4.9-pre1:

Expand Down
1 change: 1 addition & 0 deletions doc/ffmpeg-doc.texi
Expand Up @@ -773,6 +773,7 @@ following image formats are supported:
@item Miro VideoXL @tab @tab X @tab fourcc: VIXL
@item QPEG @tab @tab X @tab fourccs: QPEG, Q1.0, Q1.1
@item LOCO @tab @tab X @tab
@item Winnov WNV1 @tab @tab X @tab
@end multitable

@code{X} means that the encoding (resp. decoding) is supported.
Expand Down
2 changes: 1 addition & 1 deletion libavcodec/Makefile
Expand Up @@ -23,7 +23,7 @@ OBJS= bitstream.o utils.o mem.o allcodecs.o \
flac.o vp3dsp.o integer.o snow.o tscc.o sonic.o ulti.o h264idct.o \
qdrw.o xl.o rangecoder.o png.o pnm.o qpeg.o vc9.o h263.o h261.o \
msmpeg4.o h263dec.o svq1.o rv10.o wmadec.o indeo3.o shorten.o loco.o \
alac.o
alac.o wnv1.o

AMROBJS=
ifeq ($(AMR_NB),yes)
Expand Down
1 change: 1 addition & 0 deletions libavcodec/allcodecs.c
Expand Up @@ -129,6 +129,7 @@ void avcodec_register_all(void)
register_avcodec(&xl_decoder);
register_avcodec(&qpeg_decoder);
register_avcodec(&loco_decoder);
register_avcodec(&wnv1_decoder);
#ifdef CONFIG_FAAD
register_avcodec(&aac_decoder);
register_avcodec(&mpeg4aac_decoder);
Expand Down
4 changes: 3 additions & 1 deletion libavcodec/avcodec.h
Expand Up @@ -17,7 +17,7 @@ extern "C" {

#define FFMPEG_VERSION_INT 0x000409
#define FFMPEG_VERSION "0.4.9-pre1"
#define LIBAVCODEC_BUILD 4748
#define LIBAVCODEC_BUILD 4749

#define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT
#define LIBAVCODEC_VERSION FFMPEG_VERSION
Expand Down Expand Up @@ -105,6 +105,7 @@ enum CodecID {
CODEC_ID_VC9,
CODEC_ID_WMV3,
CODEC_ID_LOCO,
CODEC_ID_WNV1,

/* various pcm "codecs" */
CODEC_ID_PCM_S16LE= 0x10000,
Expand Down Expand Up @@ -2005,6 +2006,7 @@ extern AVCodec xl_decoder;
extern AVCodec qpeg_decoder;
extern AVCodec shorten_decoder;
extern AVCodec loco_decoder;
extern AVCodec wnv1_decoder;
extern AVCodec alac_decoder;

/* pcm codecs */
Expand Down
169 changes: 169 additions & 0 deletions libavcodec/wnv1.c
@@ -0,0 +1,169 @@
/*
* Winnov WNV1 codec
* Copyright (c) 2005 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/

/**
* @file wnv1.c
* Winnov WNV1 codec.
*/

#include "avcodec.h"
#include "common.h"


typedef struct WNV1Context{
AVCodecContext *avctx;
AVFrame pic;

int shift;
/* bit buffer */
unsigned long bitbuf;
int bits;
uint8_t *buf;
} WNV1Context;

/* returns modified base_value */
static inline int wnv1_get_code(WNV1Context *w, int base_value)
{
int v = 0;

if (w->bits < 16) { /* need to fill bit buffer */
w->bitbuf |= LE_16(w->buf) << w->bits;
w->buf += 2;
w->bits += 16;
}

/* escape code */
if ((w->bitbuf & 0xFF) == 0xFF) {
w->bitbuf >>= 8;
w->bits -= 8;
if (w->bits < 16) { /* need to fill bit buffer */
w->bitbuf |= LE_16(w->buf) << w->bits;
w->buf += 2;
w->bits += 16;
}
v = w->bitbuf & (0xFF >> w->shift);
w->bitbuf >>= 8 - w->shift;
w->bits -= 8 - w->shift;
return v << w->shift;
}

/* zero code */
if (!(w->bitbuf & 1)) {
w->bitbuf >>= 1;
w->bits--;
return base_value;
}

/* reversed unary code and sign */
while (w->bits && w->bitbuf & 1) {
w->bitbuf >>= 1;
w->bits--;
v++;
}
w->bitbuf >>= 1;
w->bits--;
if(w->bitbuf & 1)
v = -v;
w->bitbuf >>= 1;
w->bits--;
v <<= w->shift;
return base_value + v;
}

static int decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
uint8_t *buf, int buf_size)
{
WNV1Context * const l = avctx->priv_data;
AVFrame * const p= (AVFrame*)&l->pic;
unsigned char *Y,*U,*V;
int i, j;
int prev_y = 0, prev_u = 0, prev_v = 0;

if(p->data[0])
avctx->release_buffer(avctx, p);

p->reference = 0;
if(avctx->get_buffer(avctx, p) < 0){
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
}
p->key_frame = 1;

l->bitbuf = 0;
l->bits = 0;
l->buf = buf + 8;

if (buf[2] >> 4 == 6)
l->shift = 2;
else {
l->shift = 8 - (buf[2] >> 4);
if (l->shift > 4) {
av_log(avctx, AV_LOG_ERROR, "Unknown WNV1 frame header value %i, please upload file for study\n", buf[2] >> 4);
l->shift = 4;
}
if (l->shift < 1) {
av_log(avctx, AV_LOG_ERROR, "Unknown WNV1 frame header value %i, please upload file for study\n", buf[2] >> 4);
l->shift = 1;
}
}

Y = p->data[0];
U = p->data[1];
V = p->data[2];
for (j = 0; j < avctx->height; j++) {
for (i = 0; i < avctx->width / 2; i++) {
Y[i * 2] = wnv1_get_code(l, prev_y);
prev_u = U[i] = wnv1_get_code(l, prev_u);
prev_y = Y[(i * 2) + 1] = wnv1_get_code(l, Y[i * 2]);
prev_v = V[i] = wnv1_get_code(l, prev_v);
}
Y += p->linesize[0];
U += p->linesize[1];
V += p->linesize[2];
}


*data_size = sizeof(AVFrame);
*(AVFrame*)data = l->pic;

return buf_size;
}

static int decode_init(AVCodecContext *avctx){
WNV1Context * const l = avctx->priv_data;

l->avctx = avctx;
avctx->pix_fmt = PIX_FMT_YUV422P;

return 0;
}

AVCodec wnv1_decoder = {
"wnv1",
CODEC_TYPE_VIDEO,
CODEC_ID_WNV1,
sizeof(WNV1Context),
decode_init,
NULL,
NULL,
decode_frame,
CODEC_CAP_DR1,
};
1 change: 1 addition & 0 deletions libavformat/avienc.c
Expand Up @@ -178,6 +178,7 @@ const CodecTag codec_bmp_tags[] = {
{ CODEC_ID_QPEG, MKTAG('Q', '1', '.', '1') },
{ CODEC_ID_WMV3, MKTAG('W', 'M', 'V', '3') },
{ CODEC_ID_LOCO, MKTAG('L', 'O', 'C', 'O') },
{ CODEC_ID_WNV1, MKTAG('W', 'N', 'V', '1') },
{ CODEC_ID_RAWVIDEO, 0 },
{ 0, 0 },
};
Expand Down

0 comments on commit a8a15e9

Please sign in to comment.