summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuenter Bartsch <guenter@users.sourceforge.net>2001-08-07 12:41:46 +0000
committerGuenter Bartsch <guenter@users.sourceforge.net>2001-08-07 12:41:46 +0000
commit7925b0a98d936c4b8ad0a5fee9ef08b3b2dafd5e (patch)
tree472f0d251a6071daafa7c1d6fc4cfe9e289af7f6
parentc002c9aa9c541fa75bc8e9a5fb15722f70d853f9 (diff)
downloadxine-lib-7925b0a98d936c4b8ad0a5fee9ef08b3b2dafd5e.tar.gz
xine-lib-7925b0a98d936c4b8ad0a5fee9ef08b3b2dafd5e.tar.bz2
introducing the ffmpeg video decoder plugin for ms mpeg 4, opendivx and motion jpeg decoding
CVS patchset: 395 CVS date: 2001/08/07 12:41:46
-rw-r--r--configure.in7
-rw-r--r--src/Makefile.am2
-rw-r--r--src/libffmpeg/Makefile.am35
-rw-r--r--src/libffmpeg/bswap.h91
-rw-r--r--src/libffmpeg/config.h6
-rw-r--r--src/libffmpeg/libavcodec/Makefile.am38
-rw-r--r--src/libffmpeg/libavcodec/avcodec.h179
-rw-r--r--src/libffmpeg/libavcodec/common.c495
-rw-r--r--src/libffmpeg/libavcodec/common.h228
-rw-r--r--src/libffmpeg/libavcodec/dsputil.c381
-rw-r--r--src/libffmpeg/libavcodec/dsputil.h100
-rw-r--r--src/libffmpeg/libavcodec/dsputil_mmx.c1073
-rw-r--r--src/libffmpeg/libavcodec/dsputil_mmx_avg.h344
-rw-r--r--src/libffmpeg/libavcodec/fdctref.c118
-rw-r--r--src/libffmpeg/libavcodec/h263.c1292
-rw-r--r--src/libffmpeg/libavcodec/h263data.h115
-rw-r--r--src/libffmpeg/libavcodec/h263dec.c204
-rw-r--r--src/libffmpeg/libavcodec/jfdctfst.c224
-rw-r--r--src/libffmpeg/libavcodec/jrevdct.c1167
-rw-r--r--src/libffmpeg/libavcodec/mjpeg.c943
-rw-r--r--src/libffmpeg/libavcodec/motion_est.c514
-rw-r--r--src/libffmpeg/libavcodec/mpeg12.c1534
-rw-r--r--src/libffmpeg/libavcodec/mpeg12data.h363
-rw-r--r--src/libffmpeg/libavcodec/mpeg4data.h106
-rw-r--r--src/libffmpeg/libavcodec/mpegvideo.c1357
-rw-r--r--src/libffmpeg/libavcodec/mpegvideo.h285
-rw-r--r--src/libffmpeg/libavcodec/mpegvideo_mmx.c232
-rw-r--r--src/libffmpeg/libavcodec/msmpeg4.c932
-rw-r--r--src/libffmpeg/libavcodec/msmpeg4data.h1767
-rw-r--r--src/libffmpeg/libavcodec/rv10.c487
-rw-r--r--src/libffmpeg/libavcodec/sad_mmx.s799
-rw-r--r--src/libffmpeg/libavcodec/utils.c319
-rw-r--r--src/libffmpeg/xine_decoder.c319
-rw-r--r--src/xine-engine/cpu_accel.c5
-rw-r--r--src/xine-engine/cpu_accel.h6
35 files changed, 16066 insertions, 1 deletions
diff --git a/configure.in b/configure.in
index ff54d065d..d1e9d4a4a 100644
--- a/configure.in
+++ b/configure.in
@@ -342,6 +342,7 @@ dnl Common cflags for all platforms
COMMON_CFLAGS="$wall -D_REENTRANT -D_FILE_OFFSET_BITS=64 -DXINE_COMPILE"
enable_w32dll="no"
+enable_ffmmx="no"
case $host in
i386-*-freebsd*)
@@ -352,6 +353,7 @@ case $host in
AC_DEFINE([ARCH_X86],,[x86 architecture])
enable_w32dll="yes"
+ enable_ffmmx="yes"
;;
*)
dnl Set the appropriate architecture define
@@ -378,6 +380,7 @@ case $host in
dnl enable x86 specific parts of the code
enable_w32dll="yes"
+ enable_ffmmx="yes"
if test x"$sarchopt" != "xno"; then
[case "$host_alias" in
@@ -463,6 +466,8 @@ else
fi
AC_SUBST(W32DLL_DEP)
+AM_CONDITIONAL(HAVE_FFMMX, test x"$enable_ffmmx" = "xyes")
+
dnl
dnl gcc __attribute__ ((aligned ()))
@@ -571,6 +576,8 @@ src/demuxers/Makefile
src/dxr3/Makefile
src/libmpeg2/Makefile
src/libac3/Makefile
+src/libffmpeg/Makefile
+src/libffmpeg/libavcodec/Makefile
src/liblpcm/Makefile
src/libmpg123/Makefile
src/libw32dll/Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index c452cb82c..f3317e936 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,6 @@
SUBDIRS = audio_out video_out dxr3 input libmpeg2 libspudec demuxers \
- libac3 libmpg123 liblpcm libw32dll xine-engine
+ libac3 libffmpeg libmpg123 liblpcm libw32dll xine-engine
debug:
@list='$(SUBDIRS)'; for subdir in $$list; do \
diff --git a/src/libffmpeg/Makefile.am b/src/libffmpeg/Makefile.am
new file mode 100644
index 000000000..28086e79f
--- /dev/null
+++ b/src/libffmpeg/Makefile.am
@@ -0,0 +1,35 @@
+##
+## Process this file with automake to produce Makefile.in
+##
+
+SUBDIRS = libavcodec
+
+CFLAGS = @GLOBAL_CFLAGS@
+
+LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic
+
+libdir = $(XINE_PLUGINDIR)
+
+lib_LTLIBRARIES = xineplug_decode_ff.la
+
+xineplug_decode_ff_la_SOURCES = xine_decoder.c
+
+xineplug_decode_ff_la_LDFLAGS = \
+ $(top_builddir)/src/libffmpeg/libavcodec/libavcodec.la \
+ -avoid-version -module
+
+noinst_HEADERS = config.h
+
+debug:
+ $(MAKE) CFLAGS="-Wall -DDEBUG -g -DXINE_COMPILE"
+
+install-debug: debug
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+mostlyclean-generic:
+ -rm -f *~ \#* .*~ .\#*
+
+maintainer-clean-generic:
+ -@echo "This command is intended for maintainers to use;"
+ -@echo "it deletes files that may require special tools to rebuild."
+ -rm -f Makefile.in
diff --git a/src/libffmpeg/bswap.h b/src/libffmpeg/bswap.h
new file mode 100644
index 000000000..21ef3a74e
--- /dev/null
+++ b/src/libffmpeg/bswap.h
@@ -0,0 +1,91 @@
+#ifndef __BSWAP_H__
+#define __BSWAP_H__
+
+/* It's need for ffmpeg. Else where will be defined ARCH_X86?*/
+#include "config.h"
+
+#ifdef HAVE_BYTESWAP_H
+#include <byteswap.h>
+#else
+
+#include <inttypes.h>
+
+#ifdef ARCH_X86
+inline static unsigned short ByteSwap16(unsigned short x)
+{
+ __asm("xchgb %b0,%h0" :
+ "=q" (x) :
+ "0" (x));
+ return x;
+}
+#define bswap_16(x) ByteSwap16(x)
+
+inline static unsigned int ByteSwap32(unsigned int x)
+{
+#if __CPU__ > 386
+ __asm("bswap %0":
+ "=r" (x) :
+#else
+ __asm("xchgb %b0,%h0\n"
+ " rorl $16,%0\n"
+ " xchgb %b0,%h0":
+ "=q" (x) :
+#endif
+ "0" (x));
+ return x;
+}
+#define bswap_32(x) ByteSwap32(x)
+
+inline static unsigned long long int ByteSwap64(unsigned long long int x)
+{
+ register union { __extension__ unsigned long long int __ll;
+ unsigned long int __l[2]; } __x;
+ asm("xchgl %0,%1":
+ "=r"(__x.__l[0]),"=r"(__x.__l[1]):
+ "0"(bswap_32((unsigned long)x)),"1"(bswap_32((unsigned long)(x>>32))));
+ return __x.__ll;
+}
+#define bswap_64(x) ByteSwap64(x)
+
+#else
+
+#define bswap_16(x) (((x) & 0x00ff) << 8 | ((x) & 0xff00) >> 8)
+
+
+// code from bits/byteswap.h (C) 1997, 1998 Free Software Foundation, Inc.
+#define bswap_32(x) \
+ ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
+ (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
+
+#define bswap_64(x) \
+ (__extension__ \
+ ({ union { __extension__ unsigned long long int __ll; \
+ unsigned long int __l[2]; } __w, __r; \
+ __w.__ll = (x); \
+ __r.__l[0] = bswap_32 (__w.__l[1]); \
+ __r.__l[1] = bswap_32 (__w.__l[0]); \
+ __r.__ll; }))
+#endif /* !ARCH_X86 */
+
+#endif /* !HAVE_BYTESWAP_H */
+
+// be2me ... BigEndian to MachineEndian
+// le2me ... LittleEndian to MachineEndian
+
+#ifdef WORDS_BIGENDIAN
+#define be2me_16(x) (x)
+#define be2me_32(x) (x)
+#define be2me_64(x) (x)
+#define le2me_16(x) bswap_16(x)
+#define le2me_32(x) bswap_32(x)
+#define le2me_64(x) bswap_64(x)
+#else
+#define be2me_16(x) bswap_16(x)
+#define be2me_32(x) bswap_32(x)
+#define be2me_64(x) bswap_64(x)
+#define le2me_16(x) (x)
+#define le2me_32(x) (x)
+#define le2me_64(x) (x)
+#endif
+
+#endif
diff --git a/src/libffmpeg/config.h b/src/libffmpeg/config.h
new file mode 100644
index 000000000..e560cbebb
--- /dev/null
+++ b/src/libffmpeg/config.h
@@ -0,0 +1,6 @@
+/*
+ * this is just a fake config.h for libavcodec
+ */
+
+#include "../../config.h"
+
diff --git a/src/libffmpeg/libavcodec/Makefile.am b/src/libffmpeg/libavcodec/Makefile.am
new file mode 100644
index 000000000..2f5ddff1e
--- /dev/null
+++ b/src/libffmpeg/libavcodec/Makefile.am
@@ -0,0 +1,38 @@
+##
+## Process this file with automake to produce Makefile.in
+##
+
+CFLAGS = @GLOBAL_CFLAGS@ -DCONFIG_DECODERS -DHAVE_AV_CONFIG_H
+
+LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic
+
+noinst_LTLIBRARIES = libavcodec.la
+
+if HAVE_FFMMX
+mmx_modules = mpegvideo_mmx.c sad_mmx.s dsputil_mmx.c
+endif
+
+libavcodec_la_SOURCES = dsputil.c fdctref.c jfdctfst.c mpeg12.c \
+ utils.c rv10.c h263.c jrevdct.c \
+ common.c h263dec.c msmpeg4.c \
+ mpegvideo.c mjpeg.c motion_est.c \
+ $(mmx_modules)
+
+
+noinst_HEADERS = avcodec.h dsputil.h mpegvideo.h dsputil_mmx_avg.h\
+ common.h h263data.h mpeg4data.h msmpeg4data.h \
+ mpeg12data.h
+
+debug:
+ $(MAKE) CFLAGS="-Wall -DDEBUG -g -DXINE_COMPILE"
+
+install-debug: debug
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+mostlyclean-generic:
+ -rm -f *~ \#* .*~ .\#*
+
+maintainer-clean-generic:
+ -@echo "This command is intended for maintainers to use;"
+ -@echo "it deletes files that may require special tools to rebuild."
+ -rm -f Makefile.in
diff --git a/src/libffmpeg/libavcodec/avcodec.h b/src/libffmpeg/libavcodec/avcodec.h
new file mode 100644
index 000000000..fe7855740
--- /dev/null
+++ b/src/libffmpeg/libavcodec/avcodec.h
@@ -0,0 +1,179 @@
+#include "common.h"
+
+enum CodecID {
+ CODEC_ID_NONE,
+ CODEC_ID_MPEG1VIDEO,
+ CODEC_ID_H263,
+ CODEC_ID_RV10,
+ CODEC_ID_MP2,
+ CODEC_ID_AC3,
+ CODEC_ID_MJPEG,
+ CODEC_ID_OPENDIVX,
+ CODEC_ID_PCM,
+ CODEC_ID_RAWVIDEO,
+ CODEC_ID_MSMPEG4,
+ CODEC_ID_H263P,
+ CODEC_ID_H263I,
+};
+
+enum CodecType {
+ CODEC_TYPE_VIDEO,
+ CODEC_TYPE_AUDIO,
+};
+
+enum PixelFormat {
+ PIX_FMT_YUV420P,
+ PIX_FMT_YUV422,
+ PIX_FMT_RGB24,
+ PIX_FMT_BGR24,
+ PIX_FMT_YUV422P,
+ PIX_FMT_YUV444P,
+};
+
+/* in bytes */
+#define AVCODEC_MAX_AUDIO_FRAME_SIZE 18432
+
+/* motion estimation type */
+extern int motion_estimation_method;
+#define ME_ZERO 0
+#define ME_FULL 1
+#define ME_LOG 2
+#define ME_PHODS 3
+
+/* encoding support */
+
+#define CODEC_FLAG_HQ 0x0001 /* high quality (non real time) encoding */
+#define CODEC_FLAG_QSCALE 0x0002 /* use fixed qscale */
+
+#define FRAME_RATE_BASE 10000
+
+typedef struct AVCodecContext {
+ int bit_rate;
+ int flags;
+ int sub_id; /* some codecs needs additionnal format info. It is
+ stored there */
+ /* video only */
+ int frame_rate; /* frames per sec multiplied by FRAME_RATE_BASE */
+ int width, height;
+ int gop_size; /* 0 = intra only */
+ int pix_fmt; /* pixel format, see PIX_FMT_xxx */
+ /* audio only */
+ int sample_rate; /* samples per sec */
+ int channels;
+
+ /* the following data should not be initialized */
+ int frame_size; /* in samples, initialized when calling 'init' */
+ int frame_number; /* audio or video frame number */
+ int key_frame; /* true if the previous compressed frame was
+ a key frame (intra, or seekable) */
+ int quality; /* quality of the previous encoded frame
+ (between 1 (good) and 31 (bad)) */
+ struct AVCodec *codec;
+ void *priv_data;
+
+ /* the following fields are ignored */
+ char codec_name[32];
+ int codec_type; /* see CODEC_TYPE_xxx */
+ int codec_id; /* see CODEC_ID_xxx */
+ unsigned int codec_tag; /* codec tag, only used if unknown codec */
+} AVCodecContext;
+
+typedef struct AVCodec {
+ char *name;
+ int type;
+ int id;
+ int priv_data_size;
+ int (*init)(AVCodecContext *);
+ int (*encode)(AVCodecContext *, UINT8 *buf, int buf_size, void *data);
+ int (*close)(AVCodecContext *);
+ int (*decode)(AVCodecContext *, void *outdata, int *outdata_size,
+ UINT8 *buf, int buf_size);
+ struct AVCodec *next;
+} AVCodec;
+
+/* three components are given, that's all */
+typedef struct AVPicture {
+ UINT8 *data[3];
+ int linesize[3];
+} AVPicture;
+
+extern AVCodec ac3_encoder;
+extern AVCodec mp2_encoder;
+extern AVCodec mpeg1video_encoder;
+extern AVCodec h263_encoder;
+extern AVCodec h263p_encoder;
+extern AVCodec rv10_encoder;
+extern AVCodec mjpeg_encoder;
+extern AVCodec opendivx_encoder;
+extern AVCodec msmpeg4_encoder;
+
+extern AVCodec h263_decoder;
+extern AVCodec opendivx_decoder;
+extern AVCodec msmpeg4_decoder;
+extern AVCodec mpeg_decoder;
+extern AVCodec h263i_decoder;
+extern AVCodec rv10_decoder;
+extern AVCodec mjpeg_decoder;
+
+/* dummy raw codecs */
+extern AVCodec pcm_codec;
+extern AVCodec rawvideo_codec;
+
+/* the following codecs use external GPL libs */
+extern AVCodec mp3_decoder;
+extern AVCodec ac3_decoder;
+
+/* resample.c */
+
+struct ReSampleContext;
+
+typedef struct ReSampleContext ReSampleContext;
+
+ReSampleContext *audio_resample_init(int output_channels, int input_channels,
+ int output_rate, int input_rate);
+int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples);
+void audio_resample_close(ReSampleContext *s);
+
+/* YUV420 format is assumed ! */
+
+struct ImgReSampleContext;
+
+typedef struct ImgReSampleContext ImgReSampleContext;
+
+ImgReSampleContext *img_resample_init(int output_width, int output_height,
+ int input_width, int input_height);
+void img_resample(ImgReSampleContext *s,
+ AVPicture *output, AVPicture *input);
+
+void img_resample_close(ImgReSampleContext *s);
+
+int img_convert_to_yuv420(UINT8 *img_out, UINT8 *img,
+ int pix_fmt, int width, int height);
+
+/* external high level API */
+
+extern AVCodec *first_avcodec;
+
+void avcodec_init(void);
+
+void register_avcodec(AVCodec *format);
+AVCodec *avcodec_find_encoder(enum CodecID id);
+AVCodec *avcodec_find_decoder(enum CodecID id);
+AVCodec *avcodec_find_decoder_by_name(const char *name);
+void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode);
+
+int avcodec_open(AVCodecContext *avctx, AVCodec *codec);
+int avcodec_decode_audio(AVCodecContext *avctx, INT16 *samples,
+ int *frame_size_ptr,
+ UINT8 *buf, int buf_size);
+int avcodec_decode_video(AVCodecContext *avctx, AVPicture *picture,
+ int *got_picture_ptr,
+ UINT8 *buf, int buf_size);
+int avcodec_encode_audio(AVCodecContext *avctx, UINT8 *buf, int buf_size,
+ const short *samples);
+int avcodec_encode_video(AVCodecContext *avctx, UINT8 *buf, int buf_size,
+ const AVPicture *pict);
+
+int avcodec_close(AVCodecContext *avctx);
+
+void avcodec_register_all(void);
diff --git a/src/libffmpeg/libavcodec/common.c b/src/libffmpeg/libavcodec/common.c
new file mode 100644
index 000000000..24a9a1656
--- /dev/null
+++ b/src/libffmpeg/libavcodec/common.c
@@ -0,0 +1,495 @@
+/*
+ * Common bit i/o utils
+ * Copyright (c) 2000, 2001 Gerard Lantau.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef __FreeBSD__
+#include <sys/param.h>
+#endif
+#include <netinet/in.h>
+#include <math.h>
+#include "common.h"
+
+#define NDEBUG
+#include <assert.h>
+
+#include "../bswap.h"
+
+void init_put_bits(PutBitContext *s,
+ UINT8 *buffer, int buffer_size,
+ void *opaque,
+ void (*write_data)(void *, UINT8 *, int))
+{
+ s->buf = buffer;
+ s->buf_ptr = s->buf;
+ s->buf_end = s->buf + buffer_size;
+ s->bit_cnt=0;
+ s->bit_buf=0;
+ s->data_out_size = 0;
+ s->write_data = write_data;
+ s->opaque = opaque;
+}
+
+static void flush_buffer(PutBitContext *s)
+{
+ int size;
+ if (s->write_data) {
+ size = s->buf_ptr - s->buf;
+ if (size > 0)
+ s->write_data(s->opaque, s->buf, size);
+ s->buf_ptr = s->buf;
+ s->data_out_size += size;
+ }
+}
+
+void put_bits(PutBitContext *s, int n, unsigned int value)
+{
+ unsigned int bit_buf;
+ int bit_cnt;
+
+#ifdef STATS
+ st_out_bit_counts[st_current_index] += n;
+#endif
+ // printf("put_bits=%d %x\n", n, value);
+ assert(n == 32 || value < (1U << n));
+
+ bit_buf = s->bit_buf;
+ bit_cnt = s->bit_cnt;
+
+ // printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf);
+ /* XXX: optimize */
+ if (n < (32-bit_cnt)) {
+ bit_buf |= value << (32 - n - bit_cnt);
+ bit_cnt+=n;
+ } else {
+ bit_buf |= value >> (n + bit_cnt - 32);
+ *(UINT32 *)s->buf_ptr = htonl(bit_buf);
+ //printf("bitbuf = %08x\n", bit_buf);
+ s->buf_ptr+=4;
+ if (s->buf_ptr >= s->buf_end)
+ flush_buffer(s);
+ bit_cnt=bit_cnt + n - 32;
+ if (bit_cnt == 0) {
+ bit_buf = 0;
+ } else {
+ bit_buf = value << (32 - bit_cnt);
+ }
+ }
+
+ s->bit_buf = bit_buf;
+ s->bit_cnt = bit_cnt;
+}
+
+/* return the number of bits output */
+long long get_bit_count(PutBitContext *s)
+{
+ return (s->buf_ptr - s->buf + s->data_out_size) * 8 + (long long)s->bit_cnt;
+}
+
+void align_put_bits(PutBitContext *s)
+{
+ put_bits(s,(8 - s->bit_cnt) & 7,0);
+}
+
+/* pad the end of the output stream with zeros */
+void flush_put_bits(PutBitContext *s)
+{
+ while (s->bit_cnt > 0) {
+ /* XXX: should test end of buffer */
+ *s->buf_ptr++=s->bit_buf >> 24;
+ s->bit_buf<<=8;
+ s->bit_cnt-=8;
+ }
+ flush_buffer(s);
+ s->bit_cnt=0;
+ s->bit_buf=0;
+}
+
+/* for jpeg : escape 0xff with 0x00 after it */
+void jput_bits(PutBitContext *s, int n, unsigned int value)
+{
+ unsigned int bit_buf, b;
+ int bit_cnt, i;
+
+ assert(n == 32 || value < (1U << n));
+
+ bit_buf = s->bit_buf;
+ bit_cnt = s->bit_cnt;
+
+ //printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf);
+ /* XXX: optimize */
+ if (n < (32-bit_cnt)) {
+ bit_buf |= value << (32 - n - bit_cnt);
+ bit_cnt+=n;
+ } else {
+ bit_buf |= value >> (n + bit_cnt - 32);
+ /* handle escape */
+ for(i=0;i<4;i++) {
+ b = (bit_buf >> 24);
+ *(s->buf_ptr++) = b;
+ if (b == 0xff)
+ *(s->buf_ptr++) = 0;
+ bit_buf <<= 8;
+ }
+ /* we flush the buffer sooner to handle worst case */
+ if (s->buf_ptr >= (s->buf_end - 8))
+ flush_buffer(s);
+
+ bit_cnt=bit_cnt + n - 32;
+ if (bit_cnt == 0) {
+ bit_buf = 0;
+ } else {
+ bit_buf = value << (32 - bit_cnt);
+ }
+ }
+
+ s->bit_buf = bit_buf;
+ s->bit_cnt = bit_cnt;
+}
+
+/* pad the end of the output stream with zeros */
+void jflush_put_bits(PutBitContext *s)
+{
+ unsigned int b;
+
+ while (s->bit_cnt > 0) {
+ b = s->bit_buf >> 24;
+ *s->buf_ptr++ = b;
+ if (b == 0xff)
+ *s->buf_ptr++ = 0;
+ s->bit_buf<<=8;
+ s->bit_cnt-=8;
+ }
+ flush_buffer(s);
+ s->bit_cnt=0;
+ s->bit_buf=0;
+}
+
+/* bit input functions */
+
+void init_get_bits(GetBitContext *s,
+ UINT8 *buffer, int buffer_size)
+{
+ s->buf = buffer;
+ s->buf_ptr = buffer;
+ s->buf_end = buffer + buffer_size;
+ s->bit_cnt = 0;
+ s->bit_buf = 0;
+ while (s->buf_ptr < s->buf_end &&
+ s->bit_cnt < 32) {
+ s->bit_buf |= (*s->buf_ptr++ << (24 - s->bit_cnt));
+ s->bit_cnt += 8;
+ }
+}
+
+/* n must be >= 1 and <= 32 */
+/* also true: n > s->bit_cnt */
+unsigned int get_bits_long(GetBitContext *s, int n)
+{
+ unsigned int val;
+ int bit_cnt;
+ unsigned int bit_buf;
+
+#ifdef STATS
+ st_bit_counts[st_current_index] += n;
+#endif
+
+ bit_buf = s->bit_buf;
+ bit_cnt = s->bit_cnt - n;
+
+// if (bit_cnt >= 0) {
+// val = bit_buf >> (32 - n);
+// bit_buf <<= n;
+// } else
+ {
+ UINT8 *buf_ptr;
+ val = bit_buf >> (32 - n);
+ buf_ptr = s->buf_ptr;
+ buf_ptr += 4;
+ /* handle common case: we can read everything */
+ if (buf_ptr <= s->buf_end) {
+#ifdef ARCH_X86
+ bit_buf = bswap_32(*((unsigned long*)(&buf_ptr[-4])));
+#else
+ bit_buf = (buf_ptr[-4] << 24) |
+ (buf_ptr[-3] << 16) |
+ (buf_ptr[-2] << 8) |
+ (buf_ptr[-1]);
+#endif
+ } else {
+ buf_ptr -= 4;
+ bit_buf = 0;
+ if (buf_ptr < s->buf_end)
+ bit_buf |= *buf_ptr++ << 24;
+ if (buf_ptr < s->buf_end)
+ bit_buf |= *buf_ptr++ << 16;
+ if (buf_ptr < s->buf_end)
+ bit_buf |= *buf_ptr++ << 8;
+ if (buf_ptr < s->buf_end)
+ bit_buf |= *buf_ptr++;
+ }
+ s->buf_ptr = buf_ptr;
+ val |= bit_buf >> (32 + bit_cnt);
+ bit_buf <<= - bit_cnt;
+ bit_cnt += 32;
+ }
+ s->bit_buf = bit_buf;
+ s->bit_cnt = bit_cnt;
+ return val;
+}
+
+void align_get_bits(GetBitContext *s)
+{
+ int n;
+ n = s->bit_cnt & 7;
+ if (n > 0) {
+ get_bits(s, n);
+ }
+}
+
+/* VLC decoding */
+
+//#define DEBUG_VLC
+
+#define GET_DATA(v, table, i, wrap, size) \
+{\
+ UINT8 *ptr = (UINT8 *)table + i * wrap;\
+ switch(size) {\
+ case 1:\
+ v = *(UINT8 *)ptr;\
+ break;\
+ case 2:\
+ v = *(UINT16 *)ptr;\
+ break;\
+ default:\
+ v = *(UINT32 *)ptr;\
+ break;\
+ }\
+}
+
+
+static int alloc_table(VLC *vlc, int size)
+{
+ int index;
+ index = vlc->table_size;
+ vlc->table_size += size;
+ if (vlc->table_size > vlc->table_allocated) {
+ vlc->table_allocated += (1 << vlc->bits);
+ vlc->table_bits = realloc(vlc->table_bits,
+ sizeof(INT8) * vlc->table_allocated);
+ vlc->table_codes = realloc(vlc->table_codes,
+ sizeof(INT16) * vlc->table_allocated);
+ if (!vlc->table_bits ||
+ !vlc->table_codes)
+ return -1;
+ }
+ return index;
+}
+
+static int build_table(VLC *vlc, int table_nb_bits,
+ int nb_codes,
+ const void *bits, int bits_wrap, int bits_size,
+ const void *codes, int codes_wrap, int codes_size,
+ UINT32 code_prefix, int n_prefix)
+{
+ int i, j, k, n, table_size, table_index, nb, n1, index;
+ UINT32 code;
+ INT8 *table_bits;
+ INT16 *table_codes;
+
+ table_size = 1 << table_nb_bits;
+ table_index = alloc_table(vlc, table_size);
+#ifdef DEBUG_VLC
+ printf("new table index=%d size=%d code_prefix=%x n=%d\n",
+ table_index, table_size, code_prefix, n_prefix);
+#endif
+ if (table_index < 0)
+ return -1;
+ table_bits = &vlc->table_bits[table_index];
+ table_codes = &vlc->table_codes[table_index];
+
+ for(i=0;i<table_size;i++) {
+ table_bits[i] = 0;
+ table_codes[i] = -1;
+ }
+
+ /* first pass: map codes and compute auxillary table sizes */
+ for(i=0;i<nb_codes;i++) {
+ GET_DATA(n, bits, i, bits_wrap, bits_size);
+ GET_DATA(code, codes, i, codes_wrap, codes_size);
+ /* we accept tables with holes */
+ if (n <= 0)
+ continue;
+#if defined(DEBUG_VLC) && 0
+ printf("i=%d n=%d code=0x%x\n", i, n, code);
+#endif
+ /* if code matches the prefix, it is in the table */
+ n -= n_prefix;
+ if (n > 0 && (code >> n) == code_prefix) {
+ if (n <= table_nb_bits) {
+ /* no need to add another table */
+ j = (code << (table_nb_bits - n)) & (table_size - 1);
+ nb = 1 << (table_nb_bits - n);
+ for(k=0;k<nb;k++) {
+#ifdef DEBUG_VLC
+ printf("%4x: code=%d n=%d\n",
+ j, i, n);
+#endif
+ if (table_bits[j] != 0) {
+ fprintf(stderr, "incorrect codes\n");
+ exit(1);
+ }
+ table_bits[j] = n;
+ table_codes[j] = i;
+ j++;
+ }
+ } else {
+ n -= table_nb_bits;
+ j = (code >> n) & ((1 << table_nb_bits) - 1);
+#ifdef DEBUG_VLC
+ printf("%4x: n=%d (subtable)\n",
+ j, n);
+#endif
+ /* compute table size */
+ n1 = -table_bits[j];
+ if (n > n1)
+ n1 = n;
+ table_bits[j] = -n1;
+ }
+ }
+ }
+
+ /* second pass : fill auxillary tables recursively */
+ for(i=0;i<table_size;i++) {
+ n = table_bits[i];
+ if (n < 0) {
+ n = -n;
+ if (n > table_nb_bits) {
+ n = table_nb_bits;
+ table_bits[i] = -n;
+ }
+ index = build_table(vlc, n, nb_codes,
+ bits, bits_wrap, bits_size,
+ codes, codes_wrap, codes_size,
+ (code_prefix << table_nb_bits) | i,
+ n_prefix + table_nb_bits);
+ if (index < 0)
+ return -1;
+ /* note: realloc has been done, so reload tables */
+ table_bits = &vlc->table_bits[table_index];
+ table_codes = &vlc->table_codes[table_index];
+ table_codes[i] = index;
+ }
+ }
+ return table_index;
+}
+
+
+/* Build VLC decoding tables suitable for use with get_vlc().
+
+ 'nb_bits' set thee decoding table size (2^nb_bits) entries. The
+ bigger it is, the faster is the decoding. But it should not be too
+ big to save memory and L1 cache. '9' is a good compromise.
+
+ 'nb_codes' : number of vlcs codes
+
+ 'bits' : table which gives the size (in bits) of each vlc code.
+
+ 'codes' : table which gives the bit pattern of of each vlc code.
+
+ 'xxx_wrap' : give the number of bytes between each entry of the
+ 'bits' or 'codes' tables.
+
+ 'xxx_size' : gives the number of bytes of each entry of the 'bits'
+ or 'codes' tables.
+
+ 'wrap' and 'size' allows to use any memory configuration and types
+ (byte/word/long) to store the 'bits' and 'codes' tables.
+*/
+int init_vlc(VLC *vlc, int nb_bits, int nb_codes,
+ const void *bits, int bits_wrap, int bits_size,
+ const void *codes, int codes_wrap, int codes_size)
+{
+ vlc->bits = nb_bits;
+ vlc->table_bits = NULL;
+ vlc->table_codes = NULL;
+ vlc->table_allocated = 0;
+ vlc->table_size = 0;
+#ifdef DEBUG_VLC
+ printf("build table nb_codes=%d\n", nb_codes);
+#endif
+
+ if (build_table(vlc, nb_bits, nb_codes,
+ bits, bits_wrap, bits_size,
+ codes, codes_wrap, codes_size,
+ 0, 0) < 0) {
+ if (vlc->table_bits)
+ free(vlc->table_bits);
+ if (vlc->table_codes)
+ free(vlc->table_codes);
+ return -1;
+ }
+ return 0;
+}
+
+
+void free_vlc(VLC *vlc)
+{
+ free(vlc->table_bits);
+ free(vlc->table_codes);
+}
+
+int get_vlc(GetBitContext *s, VLC *vlc)
+{
+ int bit_cnt, code, n, nb_bits, index;
+ UINT32 bit_buf;
+ INT16 *table_codes;
+ INT8 *table_bits;
+ UINT8 *buf_ptr;
+
+ SAVE_BITS(s);
+ nb_bits = vlc->bits;
+ table_codes = vlc->table_codes;
+ table_bits = vlc->table_bits;
+ for(;;) {
+ SHOW_BITS(s, index, nb_bits);
+ code = table_codes[index];
+ n = table_bits[index];
+ if (n > 0) {
+ /* most common case */
+ FLUSH_BITS(n);
+#ifdef STATS
+ st_bit_counts[st_current_index] += n;
+#endif
+ break;
+ } else if (n == 0) {
+ return -1;
+ } else {
+ FLUSH_BITS(nb_bits);
+#ifdef STATS
+ st_bit_counts[st_current_index] += nb_bits;
+#endif
+ nb_bits = -n;
+ table_codes = vlc->table_codes + code;
+ table_bits = vlc->table_bits + code;
+ }
+ }
+ RESTORE_BITS(s);
+ return code;
+}
diff --git a/src/libffmpeg/libavcodec/common.h b/src/libffmpeg/libavcodec/common.h
new file mode 100644
index 000000000..75908245c
--- /dev/null
+++ b/src/libffmpeg/libavcodec/common.h
@@ -0,0 +1,228 @@
+#ifndef COMMON_H
+#define COMMON_H
+
+#ifdef HAVE_AV_CONFIG_H
+#include "../config.h"
+#endif
+
+#ifndef __WINE_WINDEF16_H
+/* workaround for typedef conflict in MPlayer (wine typedefs) */
+typedef unsigned short UINT16;
+typedef signed short INT16;
+#endif
+
+typedef unsigned char UINT8;
+typedef unsigned int UINT32;
+typedef unsigned long long UINT64;
+typedef signed char INT8;
+typedef signed int INT32;
+typedef signed long long INT64;
+
+/* bit output */
+
+struct PutBitContext;
+
+typedef void (*WriteDataFunc)(void *, UINT8 *, int);
+
+typedef struct PutBitContext {
+ UINT32 bit_buf;
+ int bit_cnt;
+ UINT8 *buf, *buf_ptr, *buf_end;
+ long long data_out_size; /* in bytes */
+ void *opaque;
+ WriteDataFunc write_data;
+} PutBitContext;
+
+void init_put_bits(PutBitContext *s,
+ UINT8 *buffer, int buffer_size,
+ void *opaque,
+ void (*write_data)(void *, UINT8 *, int));
+void put_bits(PutBitContext *s, int n, unsigned int value);
+long long get_bit_count(PutBitContext *s);
+void align_put_bits(PutBitContext *s);
+void flush_put_bits(PutBitContext *s);
+
+/* jpeg specific put_bits */
+void jput_bits(PutBitContext *s, int n, unsigned int value);
+void jflush_put_bits(PutBitContext *s);
+
+/* bit input */
+
+typedef struct GetBitContext {
+ UINT32 bit_buf;
+ int bit_cnt;
+ UINT8 *buf, *buf_ptr, *buf_end;
+} GetBitContext;
+
+typedef struct VLC {
+ int bits;
+ INT16 *table_codes;
+ INT8 *table_bits;
+ int table_size, table_allocated;
+} VLC;
+
+void init_get_bits(GetBitContext *s,
+ UINT8 *buffer, int buffer_size);
+
+unsigned int get_bits_long(GetBitContext *s, int n);
+
+static inline unsigned int get_bits(GetBitContext *s, int n){
+ if(s->bit_cnt>=n){
+ /* most common case here */
+ unsigned int val = s->bit_buf >> (32 - n);
+ s->bit_buf <<= n;
+ s->bit_cnt -= n;
+#ifdef STATS
+ st_bit_counts[st_current_index] += n;
+#endif
+ return val;
+ }
+ return get_bits_long(s,n);
+}
+
+static inline unsigned int get_bits1(GetBitContext *s){
+ if(s->bit_cnt>0){
+ /* most common case here */
+ unsigned int val = s->bit_buf >> 31;
+ s->bit_buf <<= 1;
+ s->bit_cnt--;
+#ifdef STATS
+ st_bit_counts[st_current_index]++;
+#endif
+ return val;
+ }
+ return get_bits_long(s,1);
+}
+
+static inline void skip_bits(GetBitContext *s, int n){
+ if(s->bit_cnt>=n){
+ /* most common case here */
+ s->bit_buf <<= n;
+ s->bit_cnt -= n;
+#ifdef STATS
+ st_bit_counts[st_current_index] += n;
+#endif
+ } else {
+ get_bits_long(s,n);
+ }
+}
+
+static inline void skip_bits1(GetBitContext *s){
+ if(s->bit_cnt>0){
+ /* most common case here */
+ s->bit_buf <<= 1;
+ s->bit_cnt--;
+#ifdef STATS
+ st_bit_counts[st_current_index]++;
+#endif
+ } else {
+ get_bits_long(s,1);
+ }
+}
+
+
+void align_get_bits(GetBitContext *s);
+int init_vlc(VLC *vlc, int nb_bits, int nb_codes,
+ const void *bits, int bits_wrap, int bits_size,
+ const void *codes, int codes_wrap, int codes_size);
+void free_vlc(VLC *vlc);
+int get_vlc(GetBitContext *s, VLC *vlc);
+
+/* macro to go faster */
+/* n must be <= 24 */
+/* XXX: optimize buffer end test */
+#define SHOW_BITS(s, val, n)\
+{\
+ if (bit_cnt < n && buf_ptr < (s)->buf_end) {\
+ bit_buf |= *buf_ptr++ << (24 - bit_cnt);\
+ bit_cnt += 8;\
+ if (bit_cnt < n && buf_ptr < (s)->buf_end) {\
+ bit_buf |= *buf_ptr++ << (24 - bit_cnt);\
+ bit_cnt += 8;\
+ if (bit_cnt < n && buf_ptr < (s)->buf_end) {\
+ bit_buf |= *buf_ptr++ << (24 - bit_cnt);\
+ bit_cnt += 8;\
+ }\
+ }\
+ }\
+ val = bit_buf >> (32 - n);\
+}
+
+/* SHOW_BITS with n1 >= n must be been done before */
+#define FLUSH_BITS(n)\
+{\
+ bit_buf <<= n;\
+ bit_cnt -= n;\
+}
+
+#define SAVE_BITS(s) \
+{\
+ bit_cnt = (s)->bit_cnt;\
+ bit_buf = (s)->bit_buf;\
+ buf_ptr = (s)->buf_ptr;\
+}
+
+#define RESTORE_BITS(s) \
+{\
+ (s)->buf_ptr = buf_ptr;\
+ (s)->bit_buf = bit_buf;\
+ (s)->bit_cnt = bit_cnt;\
+}
+
+/* define it to include statistics code (useful only for optimizing
+ codec efficiency */
+//#define STATS
+
+#ifdef STATS
+
+enum {
+ ST_UNKNOWN,
+ ST_DC,
+ ST_INTRA_AC,
+ ST_INTER_AC,
+ ST_INTRA_MB,
+ ST_INTER_MB,
+ ST_MV,
+ ST_NB,
+};
+
+extern int st_current_index;
+extern unsigned int st_bit_counts[ST_NB];
+extern unsigned int st_out_bit_counts[ST_NB];
+
+void print_stats(void);
+#endif
+
+/* misc math functions */
+
+extern inline int log2(unsigned int v)
+{
+ int n;
+
+ n = 0;
+ if (v & 0xffff0000) {
+ v >>= 16;
+ n += 16;
+ }
+ if (v & 0xff00) {
+ v >>= 8;
+ n += 8;
+ }
+ if (v & 0xf0) {
+ v >>= 4;
+ n += 4;
+ }
+ if (v & 0xc) {
+ v >>= 2;
+ n += 2;
+ }
+ if (v & 0x2) {
+ n++;
+ }
+ return n;
+}
+
+/* memory */
+void *av_mallocz(int size);
+
+#endif
diff --git a/src/libffmpeg/libavcodec/dsputil.c b/src/libffmpeg/libavcodec/dsputil.c
new file mode 100644
index 000000000..a41f1bef6
--- /dev/null
+++ b/src/libffmpeg/libavcodec/dsputil.c
@@ -0,0 +1,381 @@
+/*
+ * DSP utils
+ * Copyright (c) 2000, 2001 Gerard Lantau.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include "avcodec.h"
+#include "dsputil.h"
+
+void (*ff_idct)(DCTELEM *block);
+void (*get_pixels)(DCTELEM *block, const UINT8 *pixels, int line_size);
+void (*put_pixels_clamped)(const DCTELEM *block, UINT8 *pixels, int line_size);
+void (*add_pixels_clamped)(const DCTELEM *block, UINT8 *pixels, int line_size);
+
+op_pixels_abs_func pix_abs16x16;
+op_pixels_abs_func pix_abs16x16_x2;
+op_pixels_abs_func pix_abs16x16_y2;
+op_pixels_abs_func pix_abs16x16_xy2;
+
+static UINT8 cropTbl[256 + 2 * MAX_NEG_CROP];
+UINT32 squareTbl[512];
+
+void get_pixels_c(DCTELEM *block, const UINT8 *pixels, int line_size)
+{
+ DCTELEM *p;
+ const UINT8 *pix;
+ int i;
+
+ /* read the pixels */
+ p = block;
+ pix = pixels;
+ for(i=0;i<8;i++) {
+ p[0] = pix[0];
+ p[1] = pix[1];
+ p[2] = pix[2];
+ p[3] = pix[3];
+ p[4] = pix[4];
+ p[5] = pix[5];
+ p[6] = pix[6];
+ p[7] = pix[7];
+ pix += line_size;
+ p += 8;
+ }
+}
+
+void put_pixels_clamped_c(const DCTELEM *block, UINT8 *pixels, int line_size)
+{
+ const DCTELEM *p;
+ UINT8 *pix;
+ int i;
+ UINT8 *cm = cropTbl + MAX_NEG_CROP;
+
+ /* read the pixels */
+ p = block;
+ pix = pixels;
+ for(i=0;i<8;i++) {
+ pix[0] = cm[p[0]];
+ pix[1] = cm[p[1]];
+ pix[2] = cm[p[2]];
+ pix[3] = cm[p[3]];
+ pix[4] = cm[p[4]];
+ pix[5] = cm[p[5]];
+ pix[6] = cm[p[6]];
+ pix[7] = cm[p[7]];
+ pix += line_size;
+ p += 8;
+ }
+}
+
+void add_pixels_clamped_c(const DCTELEM *block, UINT8 *pixels, int line_size)
+{
+ const DCTELEM *p;
+ UINT8 *pix;
+ int i;
+ UINT8 *cm = cropTbl + MAX_NEG_CROP;
+
+ /* read the pixels */
+ p = block;
+ pix = pixels;
+ for(i=0;i<8;i++) {
+ pix[0] = cm[pix[0] + p[0]];
+ pix[1] = cm[pix[1] + p[1]];
+ pix[2] = cm[pix[2] + p[2]];
+ pix[3] = cm[pix[3] + p[3]];
+ pix[4] = cm[pix[4] + p[4]];
+ pix[5] = cm[pix[5] + p[5]];
+ pix[6] = cm[pix[6] + p[6]];
+ pix[7] = cm[pix[7] + p[7]];
+ pix += line_size;
+ p += 8;
+ }
+}
+
+#define PIXOP(BTYPE, OPNAME, OP, INCR) \
+ \
+static void OPNAME ## _pixels(BTYPE *block, const UINT8 *pixels, int line_size, int h) \
+{ \
+ BTYPE *p; \
+ const UINT8 *pix; \
+ \
+ p = block; \
+ pix = pixels; \
+ do { \
+ OP(p[0], pix[0]); \
+ OP(p[1], pix[1]); \
+ OP(p[2], pix[2]); \
+ OP(p[3], pix[3]); \
+ OP(p[4], pix[4]); \
+ OP(p[5], pix[5]); \
+ OP(p[6], pix[6]); \
+ OP(p[7], pix[7]); \
+ pix += line_size; \
+ p += INCR; \
+ } while (--h);; \
+} \
+ \
+static void OPNAME ## _pixels_x2(BTYPE *block, const UINT8 *pixels, int line_size, int h) \
+{ \
+ BTYPE *p; \
+ const UINT8 *pix; \
+ \
+ p = block; \
+ pix = pixels; \
+ do { \
+ OP(p[0], avg2(pix[0], pix[1])); \
+ OP(p[1], avg2(pix[1], pix[2])); \
+ OP(p[2], avg2(pix[2], pix[3])); \
+ OP(p[3], avg2(pix[3], pix[4])); \
+ OP(p[4], avg2(pix[4], pix[5])); \
+ OP(p[5], avg2(pix[5], pix[6])); \
+ OP(p[6], avg2(pix[6], pix[7])); \
+ OP(p[7], avg2(pix[7], pix[8])); \
+ pix += line_size; \
+ p += INCR; \
+ } while (--h); \
+} \
+ \
+static void OPNAME ## _pixels_y2(BTYPE *block, const UINT8 *pixels, int line_size, int h) \
+{ \
+ BTYPE *p; \
+ const UINT8 *pix; \
+ const UINT8 *pix1; \
+ \
+ p = block; \
+ pix = pixels; \
+ pix1 = pixels + line_size; \
+ do { \
+ OP(p[0], avg2(pix[0], pix1[0])); \
+ OP(p[1], avg2(pix[1], pix1[1])); \
+ OP(p[2], avg2(pix[2], pix1[2])); \
+ OP(p[3], avg2(pix[3], pix1[3])); \
+ OP(p[4], avg2(pix[4], pix1[4])); \
+ OP(p[5], avg2(pix[5], pix1[5])); \
+ OP(p[6], avg2(pix[6], pix1[6])); \
+ OP(p[7], avg2(pix[7], pix1[7])); \
+ pix += line_size; \
+ pix1 += line_size; \
+ p += INCR; \
+ } while(--h); \
+} \
+ \
+static void OPNAME ## _pixels_xy2(BTYPE *block, const UINT8 *pixels, int line_size, int h) \
+{ \
+ BTYPE *p; \
+ const UINT8 *pix; \
+ const UINT8 *pix1; \
+ \
+ p = block; \
+ pix = pixels; \
+ pix1 = pixels + line_size; \
+ do { \
+ OP(p[0], avg4(pix[0], pix[1], pix1[0], pix1[1])); \
+ OP(p[1], avg4(pix[1], pix[2], pix1[1], pix1[2])); \
+ OP(p[2], avg4(pix[2], pix[3], pix1[2], pix1[3])); \
+ OP(p[3], avg4(pix[3], pix[4], pix1[3], pix1[4])); \
+ OP(p[4], avg4(pix[4], pix[5], pix1[4], pix1[5])); \
+ OP(p[5], avg4(pix[5], pix[6], pix1[5], pix1[6])); \
+ OP(p[6], avg4(pix[6], pix[7], pix1[6], pix1[7])); \
+ OP(p[7], avg4(pix[7], pix[8], pix1[7], pix1[8])); \
+ pix += line_size; \
+ pix1 += line_size; \
+ p += INCR; \
+ } while(--h); \
+} \
+ \
+void (*OPNAME ## _pixels_tab[4])(BTYPE *block, const UINT8 *pixels, int line_size, int h) = { \
+ OPNAME ## _pixels, \
+ OPNAME ## _pixels_x2, \
+ OPNAME ## _pixels_y2, \
+ OPNAME ## _pixels_xy2, \
+};
+
+
+/* rounding primitives */
+#define avg2(a,b) ((a+b+1)>>1)
+#define avg4(a,b,c,d) ((a+b+c+d+2)>>2)
+
+#define op_put(a, b) a = b
+#define op_avg(a, b) a = avg2(a, b)
+#define op_sub(a, b) a -= b
+
+PIXOP(UINT8, put, op_put, line_size)
+PIXOP(UINT8, avg, op_avg, line_size)
+
+PIXOP(DCTELEM, sub, op_sub, 8)
+
+/* not rounding primitives */
+#undef avg2
+#undef avg4
+#define avg2(a,b) ((a+b)>>1)
+#define avg4(a,b,c,d) ((a+b+c+d+1)>>2)
+
+PIXOP(UINT8, put_no_rnd, op_put, line_size)
+PIXOP(UINT8, avg_no_rnd, op_avg, line_size)
+
+/* motion estimation */
+
+#undef avg2
+#undef avg4
+#define avg2(a,b) ((a+b+1)>>1)
+#define avg4(a,b,c,d) ((a+b+c+d+2)>>2)
+
+int pix_abs16x16_c(UINT8 *pix1, UINT8 *pix2, int line_size, int h)
+{
+ int s, i;
+
+ s = 0;
+ for(i=0;i<h;i++) {
+ s += abs(pix1[0] - pix2[0]);
+ s += abs(pix1[1] - pix2[1]);
+ s += abs(pix1[2] - pix2[2]);
+ s += abs(pix1[3] - pix2[3]);
+ s += abs(pix1[4] - pix2[4]);
+ s += abs(pix1[5] - pix2[5]);
+ s += abs(pix1[6] - pix2[6]);
+ s += abs(pix1[7] - pix2[7]);
+ s += abs(pix1[8] - pix2[8]);
+ s += abs(pix1[9] - pix2[9]);
+ s += abs(pix1[10] - pix2[10]);
+ s += abs(pix1[11] - pix2[11]);
+ s += abs(pix1[12] - pix2[12]);
+ s += abs(pix1[13] - pix2[13]);
+ s += abs(pix1[14] - pix2[14]);
+ s += abs(pix1[15] - pix2[15]);
+ pix1 += line_size;
+ pix2 += line_size;
+ }
+ return s;
+}
+
+int pix_abs16x16_x2_c(UINT8 *pix1, UINT8 *pix2, int line_size, int h)
+{
+ int s, i;
+
+ s = 0;
+ for(i=0;i<h;i++) {
+ s += abs(pix1[0] - avg2(pix2[0], pix2[1]));
+ s += abs(pix1[1] - avg2(pix2[1], pix2[2]));
+ s += abs(pix1[2] - avg2(pix2[2], pix2[3]));
+ s += abs(pix1[3] - avg2(pix2[3], pix2[4]));
+ s += abs(pix1[4] - avg2(pix2[4], pix2[5]));
+ s += abs(pix1[5] - avg2(pix2[5], pix2[6]));
+ s += abs(pix1[6] - avg2(pix2[6], pix2[7]));
+ s += abs(pix1[7] - avg2(pix2[7], pix2[8]));
+ s += abs(pix1[8] - avg2(pix2[8], pix2[9]));
+ s += abs(pix1[9] - avg2(pix2[9], pix2[10]));
+ s += abs(pix1[10] - avg2(pix2[10], pix2[11]));
+ s += abs(pix1[11] - avg2(pix2[11], pix2[12]));
+ s += abs(pix1[12] - avg2(pix2[12], pix2[13]));
+ s += abs(pix1[13] - avg2(pix2[13], pix2[14]));
+ s += abs(pix1[14] - avg2(pix2[14], pix2[15]));
+ s += abs(pix1[15] - avg2(pix2[15], pix2[16]));
+ pix1 += line_size;
+ pix2 += line_size;
+ }
+ return s;
+}
+
+int pix_abs16x16_y2_c(UINT8 *pix1, UINT8 *pix2, int line_size, int h)
+{
+ int s, i;
+ UINT8 *pix3 = pix2 + line_size;
+
+ s = 0;
+ for(i=0;i<h;i++) {
+ s += abs(pix1[0] - avg2(pix2[0], pix3[0]));
+ s += abs(pix1[1] - avg2(pix2[1], pix3[1]));
+ s += abs(pix1[2] - avg2(pix2[2], pix3[2]));
+ s += abs(pix1[3] - avg2(pix2[3], pix3[3]));
+ s += abs(pix1[4] - avg2(pix2[4], pix3[4]));
+ s += abs(pix1[5] - avg2(pix2[5], pix3[5]));
+ s += abs(pix1[6] - avg2(pix2[6], pix3[6]));
+ s += abs(pix1[7] - avg2(pix2[7], pix3[7]));
+ s += abs(pix1[8] - avg2(pix2[8], pix3[8]));
+ s += abs(pix1[9] - avg2(pix2[9], pix3[9]));
+ s += abs(pix1[10] - avg2(pix2[10], pix3[10]));
+ s += abs(pix1[11] - avg2(pix2[11], pix3[11]));
+ s += abs(pix1[12] - avg2(pix2[12], pix3[12]));
+ s += abs(pix1[13] - avg2(pix2[13], pix3[13]));
+ s += abs(pix1[14] - avg2(pix2[14], pix3[14]));
+ s += abs(pix1[15] - avg2(pix2[15], pix3[15]));
+ pix1 += line_size;
+ pix2 += line_size;
+ pix3 += line_size;
+ }
+ return s;
+}
+
+int pix_abs16x16_xy2_c(UINT8 *pix1, UINT8 *pix2, int line_size, int h)
+{
+ int s, i;
+ UINT8 *pix3 = pix2 + line_size;
+
+ s = 0;
+ for(i=0;i<h;i++) {
+ s += abs(pix1[0] - avg4(pix2[0], pix2[1], pix3[0], pix3[1]));
+ s += abs(pix1[1] - avg4(pix2[1], pix2[2], pix3[1], pix3[2]));
+ s += abs(pix1[2] - avg4(pix2[2], pix2[3], pix3[2], pix3[3]));
+ s += abs(pix1[3] - avg4(pix2[3], pix2[4], pix3[3], pix3[4]));
+ s += abs(pix1[4] - avg4(pix2[4], pix2[5], pix3[4], pix3[5]));
+ s += abs(pix1[5] - avg4(pix2[5], pix2[6], pix3[5], pix3[6]));
+ s += abs(pix1[6] - avg4(pix2[6], pix2[7], pix3[6], pix3[7]));
+ s += abs(pix1[7] - avg4(pix2[7], pix2[8], pix3[7], pix3[8]));
+ s += abs(pix1[8] - avg4(pix2[8], pix2[9], pix3[8], pix3[9]));
+ s += abs(pix1[9] - avg4(pix2[9], pix2[10], pix3[9], pix3[10]));
+ s += abs(pix1[10] - avg4(pix2[10], pix2[11], pix3[10], pix3[11]));
+ s += abs(pix1[11] - avg4(pix2[11], pix2[12], pix3[11], pix3[12]));
+ s += abs(pix1[12] - avg4(pix2[12], pix2[13], pix3[12], pix3[13]));
+ s += abs(pix1[13] - avg4(pix2[13], pix2[14], pix3[13], pix3[14]));
+ s += abs(pix1[14] - avg4(pix2[14], pix2[15], pix3[14], pix3[15]));
+ s += abs(pix1[15] - avg4(pix2[15], pix2[16], pix3[15], pix3[16]));
+ pix1 += line_size;
+ pix2 += line_size;
+ pix3 += line_size;
+ }
+ return s;
+}
+
+void dsputil_init(void)
+{
+ int i;
+
+ for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i;
+ for(i=0;i<MAX_NEG_CROP;i++) {
+ cropTbl[i] = 0;
+ cropTbl[i + MAX_NEG_CROP + 256] = 255;
+ }
+
+ for(i=0;i<512;i++) {
+ squareTbl[i] = (i - 256) * (i - 256);
+ }
+
+ ff_idct = j_rev_dct;
+ get_pixels = get_pixels_c;
+ put_pixels_clamped = put_pixels_clamped_c;
+ add_pixels_clamped = add_pixels_clamped_c;
+
+ pix_abs16x16 = pix_abs16x16_c;
+ pix_abs16x16_x2 = pix_abs16x16_x2_c;
+ pix_abs16x16_y2 = pix_abs16x16_y2_c;
+ pix_abs16x16_xy2 = pix_abs16x16_xy2_c;
+ av_fdct = jpeg_fdct_ifast;
+
+#ifdef HAVE_MMX
+ dsputil_init_mmx();
+#endif
+}
diff --git a/src/libffmpeg/libavcodec/dsputil.h b/src/libffmpeg/libavcodec/dsputil.h
new file mode 100644
index 000000000..ffbc395ba
--- /dev/null
+++ b/src/libffmpeg/libavcodec/dsputil.h
@@ -0,0 +1,100 @@
+#ifndef DSPUTIL_H
+#define DSPUTIL_H
+
+#include "common.h"
+#include <inttypes.h>
+
+/* dct code */
+typedef short DCTELEM;
+
+void jpeg_fdct_ifast (DCTELEM *data);
+
+void j_rev_dct (DCTELEM *data);
+
+void fdct_mmx(DCTELEM *block);
+
+void (*av_fdct)(DCTELEM *block);
+
+/* pixel operations */
+#define MAX_NEG_CROP 384
+
+/* temporary */
+extern UINT32 squareTbl[512];
+
+void dsputil_init(void);
+
+/* pixel ops : interface with DCT */
+
+extern void (*ff_idct)(DCTELEM *block);
+extern void (*get_pixels)(DCTELEM *block, const UINT8 *pixels, int line_size);
+extern void (*put_pixels_clamped)(const DCTELEM *block, UINT8 *pixels, int line_size);
+extern void (*add_pixels_clamped)(const DCTELEM *block, UINT8 *pixels, int line_size);
+
+void get_pixels_c(DCTELEM *block, const UINT8 *pixels, int line_size);
+void put_pixels_clamped_c(const DCTELEM *block, UINT8 *pixels, int line_size);
+void add_pixels_clamped_c(const DCTELEM *block, UINT8 *pixels, int line_size);
+
+/* add and put pixel (decoding) */
+typedef void (*op_pixels_func)(UINT8 *block, const UINT8 *pixels, int line_size, int h);
+
+extern op_pixels_func put_pixels_tab[4];
+extern op_pixels_func avg_pixels_tab[4];
+extern op_pixels_func put_no_rnd_pixels_tab[4];
+extern op_pixels_func avg_no_rnd_pixels_tab[4];
+
+/* sub pixel (encoding) */
+extern void (*sub_pixels_tab[4])(DCTELEM *block, const UINT8 *pixels, int line_size, int h);
+
+#define sub_pixels_2(block, pixels, line_size, dxy) \
+ sub_pixels_tab[dxy](block, pixels, line_size, 8)
+
+/* motion estimation */
+
+typedef int (*op_pixels_abs_func)(UINT8 *blk1, UINT8 *blk2, int line_size, int h);
+
+extern op_pixels_abs_func pix_abs16x16;
+extern op_pixels_abs_func pix_abs16x16_x2;
+extern op_pixels_abs_func pix_abs16x16_y2;
+extern op_pixels_abs_func pix_abs16x16_xy2;
+
+int pix_abs16x16_c(UINT8 *blk1, UINT8 *blk2, int lx, int h);
+int pix_abs16x16_x2_c(UINT8 *blk1, UINT8 *blk2, int lx, int h);
+int pix_abs16x16_y2_c(UINT8 *blk1, UINT8 *blk2, int lx, int h);
+int pix_abs16x16_xy2_c(UINT8 *blk1, UINT8 *blk2, int lx, int h);
+
+#ifdef HAVE_MMX
+
+#define MM_MMX 0x0001 /* standard MMX */
+#define MM_3DNOW 0x0004 /* AMD 3DNOW */
+#define MM_MMXEXT 0x0002 /* SSE integer functions or AMD MMX ext */
+#define MM_SSE 0x0008 /* SSE functions */
+#define MM_SSE2 0x0010 /* PIV SSE2 functions */
+
+extern int mm_flags;
+
+int mm_support(void);
+
+static inline void emms(void)
+{
+ __asm __volatile ("emms;":::"memory");
+}
+
+#define emms_c() \
+{\
+ if (mm_flags & MM_MMX)\
+ emms();\
+}
+
+#define __align8 __attribute__ ((aligned (8)))
+
+void dsputil_init_mmx(void);
+
+#else
+
+#define emms_c()
+
+#define __align8
+
+#endif
+
+#endif
diff --git a/src/libffmpeg/libavcodec/dsputil_mmx.c b/src/libffmpeg/libavcodec/dsputil_mmx.c
new file mode 100644
index 000000000..ddb91f54c
--- /dev/null
+++ b/src/libffmpeg/libavcodec/dsputil_mmx.c
@@ -0,0 +1,1073 @@
+/*
+ * MMX optimized DSP utils
+ * Copyright (c) 2000, 2001 Gerard Lantau.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * MMX optimization by Nick Kurshev <nickols_k@mail.ru>
+ */
+
+#include "dsputil.h"
+#include "cpu_accel.h"
+
+int mm_flags; /* multimedia extension flags */
+
+int pix_abs16x16_mmx(UINT8 *blk1, UINT8 *blk2, int lx, int h);
+int pix_abs16x16_sse(UINT8 *blk1, UINT8 *blk2, int lx, int h);
+int pix_abs16x16_x2_mmx(UINT8 *blk1, UINT8 *blk2, int lx, int h);
+int pix_abs16x16_y2_mmx(UINT8 *blk1, UINT8 *blk2, int lx, int h);
+int pix_abs16x16_xy2_mmx(UINT8 *blk1, UINT8 *blk2, int lx, int h);
+
+#ifdef USE_MMX_IDCT
+/* external functions, defined in libmpeg2 */
+void mmx_idct(DCTELEM *block);
+void mmxext_idct(DCTELEM *block);
+/* this should be in dsputil.h? -- A'rpi */
+extern UINT8 ff_alternate_horizontal_scan[64];
+extern UINT8 ff_alternate_vertical_scan[64];
+extern UINT8 zigzag_direct[64];
+#endif
+
+/* pixel operations */
+static const unsigned long long int mm_wone __attribute__ ((aligned(8))) = 0x0001000100010001;
+static const unsigned long long int mm_wtwo __attribute__ ((aligned(8))) = 0x0002000200020002;
+//static const unsigned short mm_wone[4] __attribute__ ((aligned(8))) = { 0x1, 0x1, 0x1, 0x1 };
+//static const unsigned short mm_wtwo[4] __attribute__ ((aligned(8))) = { 0x2, 0x2, 0x2, 0x2 };
+
+/***********************************/
+/* 3Dnow specific */
+
+#define DEF(x) x ## _3dnow
+/* for Athlons PAVGUSB is prefered */
+#define PAVGB "pavgusb"
+
+#include "dsputil_mmx_avg.h"
+
+#undef DEF
+#undef PAVGB
+
+/***********************************/
+/* MMX2 specific */
+
+#define DEF(x) x ## _sse
+
+/* Introduced only in MMX2 set */
+#define PAVGB "pavgb"
+
+#include "dsputil_mmx_avg.h"
+
+#undef DEF
+#undef PAVGB
+
+/***********************************/
+/* standard MMX */
+
+static void get_pixels_mmx(DCTELEM *block, const UINT8 *pixels, int line_size)
+{
+ DCTELEM *p;
+ const UINT8 *pix;
+ int i;
+
+ /* read the pixels */
+ p = block;
+ pix = pixels;
+ __asm __volatile("pxor %%mm7, %%mm7":::"memory");
+ for(i=0;i<4;i++) {
+ __asm __volatile(
+ "movq %1, %%mm0\n\t"
+ "movq %2, %%mm1\n\t"
+ "movq %%mm0, %%mm2\n\t"
+ "movq %%mm1, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm0\n\t"
+ "punpckhbw %%mm7, %%mm2\n\t"
+ "punpcklbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "movq %%mm0, %0\n\t"
+ "movq %%mm2, 8%0\n\t"
+ "movq %%mm1, 16%0\n\t"
+ "movq %%mm3, 24%0\n\t"
+ :"=m"(*p)
+ :"m"(*pix), "m"(*(pix+line_size))
+ :"memory");
+ pix += line_size*2;
+ p += 16;
+ }
+}
+
+static void put_pixels_clamped_mmx(const DCTELEM *block, UINT8 *pixels, int line_size)
+{
+ const DCTELEM *p;
+ UINT8 *pix;
+ int i;
+
+ /* read the pixels */
+ p = block;
+ pix = pixels;
+ for(i=0;i<2;i++) {
+ __asm __volatile(
+ "movq %4, %%mm0\n\t"
+ "movq 8%4, %%mm1\n\t"
+ "movq 16%4, %%mm2\n\t"
+ "movq 24%4, %%mm3\n\t"
+ "movq 32%4, %%mm4\n\t"
+ "movq 40%4, %%mm5\n\t"
+ "movq 48%4, %%mm6\n\t"
+ "movq 56%4, %%mm7\n\t"
+ "packuswb %%mm1, %%mm0\n\t"
+ "packuswb %%mm3, %%mm2\n\t"
+ "packuswb %%mm5, %%mm4\n\t"
+ "packuswb %%mm7, %%mm6\n\t"
+ "movq %%mm0, %0\n\t"
+ "movq %%mm2, %1\n\t"
+ "movq %%mm4, %2\n\t"
+ "movq %%mm6, %3\n\t"
+ :"=m"(*pix), "=m"(*(pix+line_size))
+ ,"=m"(*(pix+line_size*2)), "=m"(*(pix+line_size*3))
+ :"m"(*p)
+ :"memory");
+ pix += line_size*4;
+ p += 32;
+ }
+}
+
+static void add_pixels_clamped_mmx(const DCTELEM *block, UINT8 *pixels, int line_size)
+{
+ const DCTELEM *p;
+ UINT8 *pix;
+ int i;
+
+ /* read the pixels */
+ p = block;
+ pix = pixels;
+ __asm __volatile("pxor %%mm7, %%mm7":::"memory");
+ for(i=0;i<4;i++) {
+ __asm __volatile(
+ "movq %2, %%mm0\n\t"
+ "movq 8%2, %%mm1\n\t"
+ "movq 16%2, %%mm2\n\t"
+ "movq 24%2, %%mm3\n\t"
+ "movq %0, %%mm4\n\t"
+ "movq %1, %%mm6\n\t"
+ "movq %%mm4, %%mm5\n\t"
+ "punpcklbw %%mm7, %%mm4\n\t"
+ "punpckhbw %%mm7, %%mm5\n\t"
+ "paddsw %%mm4, %%mm0\n\t"
+ "paddsw %%mm5, %%mm1\n\t"
+ "movq %%mm6, %%mm5\n\t"
+ "punpcklbw %%mm7, %%mm6\n\t"
+ "punpckhbw %%mm7, %%mm5\n\t"
+ "paddsw %%mm6, %%mm2\n\t"
+ "paddsw %%mm5, %%mm3\n\t"
+ "packuswb %%mm1, %%mm0\n\t"
+ "packuswb %%mm3, %%mm2\n\t"
+ "movq %%mm0, %0\n\t"
+ "movq %%mm2, %1\n\t"
+ :"=m"(*pix), "=m"(*(pix+line_size))
+ :"m"(*p)
+ :"memory");
+ pix += line_size*2;
+ p += 16;
+ }
+}
+
+static void put_pixels_mmx(UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ int dh, hh;
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ hh=h>>2;
+ dh=h&3;
+ while(hh--) {
+ __asm __volatile(
+ "movq %4, %%mm0\n\t"
+ "movq %5, %%mm1\n\t"
+ "movq %6, %%mm2\n\t"
+ "movq %7, %%mm3\n\t"
+ "movq %%mm0, %0\n\t"
+ "movq %%mm1, %1\n\t"
+ "movq %%mm2, %2\n\t"
+ "movq %%mm3, %3\n\t"
+ :"=m"(*p), "=m"(*(p+line_size)), "=m"(*(p+line_size*2)), "=m"(*(p+line_size*3))
+ :"m"(*pix), "m"(*(pix+line_size)), "m"(*(pix+line_size*2)), "m"(*(pix+line_size*3))
+ :"memory");
+ pix = pix + line_size*4;
+ p = p + line_size*4;
+ }
+ while(dh--) {
+ __asm __volatile(
+ "movq %1, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix)
+ :"memory");
+ pix = pix + line_size;
+ p = p + line_size;
+ }
+}
+
+static void put_pixels_x2_mmx(UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile(
+ "pxor %%mm7, %%mm7\n\t"
+ "movq %0, %%mm4\n\t"
+ ::"m"(mm_wone):"memory");
+ do {
+ __asm __volatile(
+ "movq %1, %%mm0\n\t"
+ "movq 1%1, %%mm1\n\t"
+ "movq %%mm0, %%mm2\n\t"
+ "movq %%mm1, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm0\n\t"
+ "punpcklbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm2\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "paddusw %%mm1, %%mm0\n\t"
+ "paddusw %%mm3, %%mm2\n\t"
+ "paddusw %%mm4, %%mm0\n\t"
+ "paddusw %%mm4, %%mm2\n\t"
+ "psrlw $1, %%mm0\n\t"
+ "psrlw $1, %%mm2\n\t"
+ "packuswb %%mm2, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix)
+ :"memory");
+ pix += line_size; p += line_size;
+ } while (--h);
+}
+
+static void put_pixels_y2_mmx(UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile(
+ "pxor %%mm7, %%mm7\n\t"
+ "movq %0, %%mm4\n\t"
+ ::"m"(mm_wone):"memory");
+ do {
+ __asm __volatile(
+ "movq %1, %%mm0\n\t"
+ "movq %2, %%mm1\n\t"
+ "movq %%mm0, %%mm2\n\t"
+ "movq %%mm1, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm0\n\t"
+ "punpcklbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm2\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "paddusw %%mm1, %%mm0\n\t"
+ "paddusw %%mm3, %%mm2\n\t"
+ "paddusw %%mm4, %%mm0\n\t"
+ "paddusw %%mm4, %%mm2\n\t"
+ "psrlw $1, %%mm0\n\t"
+ "psrlw $1, %%mm2\n\t"
+ "packuswb %%mm2, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix),
+ "m"(*(pix+line_size))
+ :"memory");
+ pix += line_size;
+ p += line_size;
+ } while (--h);
+}
+
+static void put_pixels_xy2_mmx(UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile(
+ "pxor %%mm7, %%mm7\n\t"
+ "movq %0, %%mm6\n\t"
+ ::"m"(mm_wtwo):"memory");
+ do {
+ __asm __volatile(
+ "movq %1, %%mm0\n\t"
+ "movq %2, %%mm1\n\t"
+ "movq 1%1, %%mm4\n\t"
+ "movq 1%2, %%mm5\n\t"
+ "movq %%mm0, %%mm2\n\t"
+ "movq %%mm1, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm0\n\t"
+ "punpcklbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm2\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "paddusw %%mm1, %%mm0\n\t"
+ "paddusw %%mm3, %%mm2\n\t"
+ "movq %%mm4, %%mm1\n\t"
+ "movq %%mm5, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm4\n\t"
+ "punpcklbw %%mm7, %%mm5\n\t"
+ "punpckhbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "paddusw %%mm5, %%mm4\n\t"
+ "paddusw %%mm3, %%mm1\n\t"
+ "paddusw %%mm6, %%mm4\n\t"
+ "paddusw %%mm6, %%mm1\n\t"
+ "paddusw %%mm4, %%mm0\n\t"
+ "paddusw %%mm1, %%mm2\n\t"
+ "psrlw $2, %%mm0\n\t"
+ "psrlw $2, %%mm2\n\t"
+ "packuswb %%mm2, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix),
+ "m"(*(pix+line_size))
+ :"memory");
+ pix += line_size;
+ p += line_size;
+ } while(--h);
+}
+
+static void put_no_rnd_pixels_x2_mmx( UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile("pxor %%mm7, %%mm7\n\t":::"memory");
+ do {
+ __asm __volatile(
+ "movq %1, %%mm0\n\t"
+ "movq 1%1, %%mm1\n\t"
+ "movq %%mm0, %%mm2\n\t"
+ "movq %%mm1, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm0\n\t"
+ "punpcklbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm2\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "paddusw %%mm1, %%mm0\n\t"
+ "paddusw %%mm3, %%mm2\n\t"
+ "psrlw $1, %%mm0\n\t"
+ "psrlw $1, %%mm2\n\t"
+ "packuswb %%mm2, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix)
+ :"memory");
+ pix += line_size;
+ p += line_size;
+ } while (--h);
+}
+
+static void put_no_rnd_pixels_y2_mmx( UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile("pxor %%mm7, %%mm7\n\t":::"memory");
+ do {
+ __asm __volatile(
+ "movq %1, %%mm0\n\t"
+ "movq %2, %%mm1\n\t"
+ "movq %%mm0, %%mm2\n\t"
+ "movq %%mm1, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm0\n\t"
+ "punpcklbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm2\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "paddusw %%mm1, %%mm0\n\t"
+ "paddusw %%mm3, %%mm2\n\t"
+ "psrlw $1, %%mm0\n\t"
+ "psrlw $1, %%mm2\n\t"
+ "packuswb %%mm2, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix),
+ "m"(*(pix+line_size))
+ :"memory");
+ pix += line_size;
+ p += line_size;
+ } while(--h);
+}
+
+static void put_no_rnd_pixels_xy2_mmx( UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile(
+ "pxor %%mm7, %%mm7\n\t"
+ "movq %0, %%mm6\n\t"
+ ::"m"(mm_wone):"memory");
+ do {
+ __asm __volatile(
+ "movq %1, %%mm0\n\t"
+ "movq %2, %%mm1\n\t"
+ "movq 1%1, %%mm4\n\t"
+ "movq 1%2, %%mm5\n\t"
+ "movq %%mm0, %%mm2\n\t"
+ "movq %%mm1, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm0\n\t"
+ "punpcklbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm2\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "paddusw %%mm1, %%mm0\n\t"
+ "paddusw %%mm3, %%mm2\n\t"
+ "movq %%mm4, %%mm1\n\t"
+ "movq %%mm5, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm4\n\t"
+ "punpcklbw %%mm7, %%mm5\n\t"
+ "punpckhbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "paddusw %%mm5, %%mm4\n\t"
+ "paddusw %%mm3, %%mm1\n\t"
+ "paddusw %%mm6, %%mm4\n\t"
+ "paddusw %%mm6, %%mm1\n\t"
+ "paddusw %%mm4, %%mm0\n\t"
+ "paddusw %%mm1, %%mm2\n\t"
+ "psrlw $2, %%mm0\n\t"
+ "psrlw $2, %%mm2\n\t"
+ "packuswb %%mm2, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix),
+ "m"(*(pix+line_size))
+ :"memory");
+ pix += line_size;
+ p += line_size;
+ } while(--h);
+}
+
+static void avg_pixels_mmx(UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile(
+ "pxor %%mm7, %%mm7\n\t"
+ "movq %0, %%mm6\n\t"
+ ::"m"(mm_wone):"memory");
+ do {
+ __asm __volatile(
+ "movq %0, %%mm0\n\t"
+ "movq %1, %%mm1\n\t"
+ "movq %%mm0, %%mm2\n\t"
+ "movq %%mm1, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm0\n\t"
+ "punpcklbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm2\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "paddusw %%mm1, %%mm0\n\t"
+ "paddusw %%mm3, %%mm2\n\t"
+ "paddusw %%mm6, %%mm0\n\t"
+ "paddusw %%mm6, %%mm2\n\t"
+ "psrlw $1, %%mm0\n\t"
+ "psrlw $1, %%mm2\n\t"
+ "packuswb %%mm2, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix)
+ :"memory");
+ pix += line_size;
+ p += line_size;
+ }
+ while (--h);
+}
+
+static void avg_pixels_x2_mmx( UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile(
+ "pxor %%mm7, %%mm7\n\t"
+ "movq %0, %%mm6\n\t"
+ ::"m"(mm_wone):"memory");
+ do {
+ __asm __volatile(
+ "movq %1, %%mm1\n\t"
+ "movq %0, %%mm0\n\t"
+ "movq 1%1, %%mm4\n\t"
+ "movq %%mm0, %%mm2\n\t"
+ "movq %%mm1, %%mm3\n\t"
+ "movq %%mm4, %%mm5\n\t"
+ "punpcklbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm4\n\t"
+ "punpckhbw %%mm7, %%mm5\n\t"
+ "punpcklbw %%mm7, %%mm0\n\t"
+ "punpckhbw %%mm7, %%mm2\n\t"
+ "paddusw %%mm4, %%mm1\n\t"
+ "paddusw %%mm5, %%mm3\n\t"
+ "paddusw %%mm6, %%mm1\n\t"
+ "paddusw %%mm6, %%mm3\n\t"
+ "psrlw $1, %%mm1\n\t"
+ "psrlw $1, %%mm3\n\t"
+ "paddusw %%mm6, %%mm0\n\t"
+ "paddusw %%mm6, %%mm2\n\t"
+ "paddusw %%mm1, %%mm0\n\t"
+ "paddusw %%mm3, %%mm2\n\t"
+ "psrlw $1, %%mm0\n\t"
+ "psrlw $1, %%mm2\n\t"
+ "packuswb %%mm2, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix)
+ :"memory");
+ pix += line_size;
+ p += line_size;
+ } while (--h);
+}
+
+static void avg_pixels_y2_mmx( UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile(
+ "pxor %%mm7, %%mm7\n\t"
+ "movq %0, %%mm6\n\t"
+ ::"m"(mm_wone):"memory");
+ do {
+ __asm __volatile(
+ "movq %1, %%mm1\n\t"
+ "movq %0, %%mm0\n\t"
+ "movq %2, %%mm4\n\t"
+ "movq %%mm0, %%mm2\n\t"
+ "movq %%mm1, %%mm3\n\t"
+ "movq %%mm4, %%mm5\n\t"
+ "punpcklbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm4\n\t"
+ "punpckhbw %%mm7, %%mm5\n\t"
+ "punpcklbw %%mm7, %%mm0\n\t"
+ "punpckhbw %%mm7, %%mm2\n\t"
+ "paddusw %%mm4, %%mm1\n\t"
+ "paddusw %%mm5, %%mm3\n\t"
+ "paddusw %%mm6, %%mm1\n\t"
+ "paddusw %%mm6, %%mm3\n\t"
+ "psrlw $1, %%mm1\n\t"
+ "psrlw $1, %%mm3\n\t"
+ "paddusw %%mm6, %%mm0\n\t"
+ "paddusw %%mm6, %%mm2\n\t"
+ "paddusw %%mm1, %%mm0\n\t"
+ "paddusw %%mm3, %%mm2\n\t"
+ "psrlw $1, %%mm0\n\t"
+ "psrlw $1, %%mm2\n\t"
+ "packuswb %%mm2, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix), "m"(*(pix+line_size))
+ :"memory");
+ pix += line_size;
+ p += line_size ;
+ } while(--h);
+}
+
+static void avg_pixels_xy2_mmx( UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile(
+ "pxor %%mm7, %%mm7\n\t"
+ "movq %0, %%mm6\n\t"
+ ::"m"(mm_wtwo):"memory");
+ do {
+ __asm __volatile(
+ "movq %1, %%mm0\n\t"
+ "movq %2, %%mm1\n\t"
+ "movq 1%1, %%mm4\n\t"
+ "movq 1%2, %%mm5\n\t"
+ "movq %%mm0, %%mm2\n\t"
+ "movq %%mm1, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm0\n\t"
+ "punpcklbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm2\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "paddusw %%mm1, %%mm0\n\t"
+ "paddusw %%mm3, %%mm2\n\t"
+ "movq %%mm4, %%mm1\n\t"
+ "movq %%mm5, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm4\n\t"
+ "punpcklbw %%mm7, %%mm5\n\t"
+ "punpckhbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "paddusw %%mm5, %%mm4\n\t"
+ "paddusw %%mm3, %%mm1\n\t"
+ "paddusw %%mm6, %%mm4\n\t"
+ "paddusw %%mm6, %%mm1\n\t"
+ "paddusw %%mm4, %%mm0\n\t"
+ "paddusw %%mm1, %%mm2\n\t"
+ "movq %3, %%mm5\n\t"
+ "psrlw $2, %%mm0\n\t"
+ "movq %0, %%mm1\n\t"
+ "psrlw $2, %%mm2\n\t"
+ "movq %%mm1, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "paddusw %%mm1, %%mm0\n\t"
+ "paddusw %%mm3, %%mm2\n\t"
+ "paddusw %%mm5, %%mm0\n\t"
+ "paddusw %%mm5, %%mm2\n\t"
+ "psrlw $1, %%mm0\n\t"
+ "psrlw $1, %%mm2\n\t"
+ "packuswb %%mm2, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix),
+ "m"(*(pix+line_size)), "m"(mm_wone)
+ :"memory");
+ pix += line_size;
+ p += line_size ;
+ } while(--h);
+}
+
+static void avg_no_rnd_pixels_mmx( UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile("pxor %%mm7, %%mm7\n\t":::"memory");
+ do {
+ __asm __volatile(
+ "movq %1, %%mm0\n\t"
+ "movq %0, %%mm1\n\t"
+ "movq %%mm0, %%mm2\n\t"
+ "movq %%mm1, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm0\n\t"
+ "punpcklbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm2\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "paddusw %%mm1, %%mm0\n\t"
+ "paddusw %%mm3, %%mm2\n\t"
+ "psrlw $1, %%mm0\n\t"
+ "psrlw $1, %%mm2\n\t"
+ "packuswb %%mm2, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix)
+ :"memory");
+ pix += line_size;
+ p += line_size ;
+ } while (--h);
+}
+
+static void avg_no_rnd_pixels_x2_mmx( UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile(
+ "pxor %%mm7, %%mm7\n\t":::"memory");
+ do {
+ __asm __volatile(
+ "movq %1, %%mm0\n\t"
+ "movq 1%1, %%mm1\n\t"
+ "movq %0, %%mm4\n\t"
+ "movq %%mm0, %%mm2\n\t"
+ "movq %%mm1, %%mm3\n\t"
+ "movq %%mm4, %%mm5\n\t"
+ "punpcklbw %%mm7, %%mm0\n\t"
+ "punpcklbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm2\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm4\n\t"
+ "punpckhbw %%mm7, %%mm5\n\t"
+ "paddusw %%mm1, %%mm0\n\t"
+ "paddusw %%mm3, %%mm2\n\t"
+ "psrlw $1, %%mm0\n\t"
+ "psrlw $1, %%mm2\n\t"
+ "paddusw %%mm4, %%mm0\n\t"
+ "paddusw %%mm5, %%mm2\n\t"
+ "psrlw $1, %%mm0\n\t"
+ "psrlw $1, %%mm2\n\t"
+ "packuswb %%mm2, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix)
+ :"memory");
+ pix += line_size;
+ p += line_size;
+ } while (--h);
+}
+
+static void avg_no_rnd_pixels_y2_mmx( UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile(
+ "pxor %%mm7, %%mm7\n\t":::"memory");
+ do {
+ __asm __volatile(
+ "movq %1, %%mm0\n\t"
+ "movq %2, %%mm1\n\t"
+ "movq %0, %%mm4\n\t"
+ "movq %%mm0, %%mm2\n\t"
+ "movq %%mm1, %%mm3\n\t"
+ "movq %%mm4, %%mm5\n\t"
+ "punpcklbw %%mm7, %%mm0\n\t"
+ "punpcklbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm2\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm4\n\t"
+ "punpckhbw %%mm7, %%mm5\n\t"
+ "paddusw %%mm1, %%mm0\n\t"
+ "paddusw %%mm3, %%mm2\n\t"
+ "psrlw $1, %%mm0\n\t"
+ "psrlw $1, %%mm2\n\t"
+ "paddusw %%mm4, %%mm0\n\t"
+ "paddusw %%mm5, %%mm2\n\t"
+ "psrlw $1, %%mm0\n\t"
+ "psrlw $1, %%mm2\n\t"
+ "packuswb %%mm2, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix), "m"(*(pix+line_size))
+ :"memory");
+ pix += line_size;
+ p += line_size ;
+ } while(--h);
+}
+
+static void avg_no_rnd_pixels_xy2_mmx( UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile(
+ "pxor %%mm7, %%mm7\n\t"
+ "movq %0, %%mm6\n\t"
+ ::"m"(mm_wone):"memory");
+ do {
+ __asm __volatile(
+ "movq %1, %%mm0\n\t"
+ "movq %2, %%mm1\n\t"
+ "movq 1%1, %%mm4\n\t"
+ "movq 1%2, %%mm5\n\t"
+ "movq %%mm0, %%mm2\n\t"
+ "movq %%mm1, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm0\n\t"
+ "punpcklbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm2\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "paddusw %%mm1, %%mm0\n\t"
+ "paddusw %%mm3, %%mm2\n\t"
+ "movq %%mm4, %%mm1\n\t"
+ "movq %%mm5, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm4\n\t"
+ "punpcklbw %%mm7, %%mm5\n\t"
+ "punpckhbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "paddusw %%mm5, %%mm4\n\t"
+ "paddusw %%mm3, %%mm1\n\t"
+ "paddusw %%mm6, %%mm4\n\t"
+ "paddusw %%mm6, %%mm1\n\t"
+ "paddusw %%mm4, %%mm0\n\t"
+ "paddusw %%mm1, %%mm2\n\t"
+ "movq %0, %%mm1\n\t"
+ "psrlw $2, %%mm0\n\t"
+ "movq %%mm1, %%mm3\n\t"
+ "psrlw $2, %%mm2\n\t"
+ "punpcklbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "paddusw %%mm1, %%mm0\n\t"
+ "paddusw %%mm3, %%mm2\n\t"
+ "psrlw $1, %%mm0\n\t"
+ "psrlw $1, %%mm2\n\t"
+ "packuswb %%mm2, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix),
+ "m"(*(pix+line_size))
+ :"memory");
+ pix += line_size;
+ p += line_size;
+ } while(--h);
+}
+
+static void sub_pixels_mmx( DCTELEM *block, const UINT8 *pixels, int line_size, int h)
+{
+ DCTELEM *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile("pxor %%mm7, %%mm7":::"memory");
+ do {
+ __asm __volatile(
+ "movq %0, %%mm0\n\t"
+ "movq %1, %%mm2\n\t"
+ "movq 8%0, %%mm1\n\t"
+ "movq %%mm2, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm2\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "psubsw %%mm2, %%mm0\n\t"
+ "psubsw %%mm3, %%mm1\n\t"
+ "movq %%mm0, %0\n\t"
+ "movq %%mm1, 8%0\n\t"
+ :"=m"(*p)
+ :"m"(*pix)
+ :"memory");
+ pix += line_size;
+ p += 8;
+ } while (--h);
+}
+
+static void sub_pixels_x2_mmx( DCTELEM *block, const UINT8 *pixels, int line_size, int h)
+{
+ DCTELEM *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile(
+ "pxor %%mm7, %%mm7\n\t"
+ "movq %0, %%mm6"
+ ::"m"(mm_wone):"memory");
+ do {
+ __asm __volatile(
+ "movq %0, %%mm0\n\t"
+ "movq %1, %%mm2\n\t"
+ "movq 8%0, %%mm1\n\t"
+ "movq 1%1, %%mm4\n\t"
+ "movq %%mm2, %%mm3\n\t"
+ "movq %%mm4, %%mm5\n\t"
+ "punpcklbw %%mm7, %%mm2\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm4\n\t"
+ "punpckhbw %%mm7, %%mm5\n\t"
+ "paddusw %%mm4, %%mm2\n\t"
+ "paddusw %%mm5, %%mm3\n\t"
+ "paddusw %%mm6, %%mm2\n\t"
+ "paddusw %%mm6, %%mm3\n\t"
+ "psrlw $1, %%mm2\n\t"
+ "psrlw $1, %%mm3\n\t"
+ "psubsw %%mm2, %%mm0\n\t"
+ "psubsw %%mm3, %%mm1\n\t"
+ "movq %%mm0, %0\n\t"
+ "movq %%mm1, 8%0\n\t"
+ :"=m"(*p)
+ :"m"(*pix)
+ :"memory");
+ pix += line_size;
+ p += 8;
+ } while (--h);
+}
+
+static void sub_pixels_y2_mmx( DCTELEM *block, const UINT8 *pixels, int line_size, int h)
+{
+ DCTELEM *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile(
+ "pxor %%mm7, %%mm7\n\t"
+ "movq %0, %%mm6"
+ ::"m"(mm_wone):"memory");
+ do {
+ __asm __volatile(
+ "movq %0, %%mm0\n\t"
+ "movq %1, %%mm2\n\t"
+ "movq 8%0, %%mm1\n\t"
+ "movq %2, %%mm4\n\t"
+ "movq %%mm2, %%mm3\n\t"
+ "movq %%mm4, %%mm5\n\t"
+ "punpcklbw %%mm7, %%mm2\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm4\n\t"
+ "punpckhbw %%mm7, %%mm5\n\t"
+ "paddusw %%mm4, %%mm2\n\t"
+ "paddusw %%mm5, %%mm3\n\t"
+ "paddusw %%mm6, %%mm2\n\t"
+ "paddusw %%mm6, %%mm3\n\t"
+ "psrlw $1, %%mm2\n\t"
+ "psrlw $1, %%mm3\n\t"
+ "psubsw %%mm2, %%mm0\n\t"
+ "psubsw %%mm3, %%mm1\n\t"
+ "movq %%mm0, %0\n\t"
+ "movq %%mm1, 8%0\n\t"
+ :"=m"(*p)
+ :"m"(*pix), "m"(*(pix+line_size))
+ :"memory");
+ pix += line_size;
+ p += 8;
+ } while (--h);
+}
+
+static void sub_pixels_xy2_mmx( DCTELEM *block, const UINT8 *pixels, int line_size, int h)
+{
+ DCTELEM *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile(
+ "pxor %%mm7, %%mm7\n\t"
+ "movq %0, %%mm6\n\t"
+ ::"m"(mm_wtwo):"memory");
+ do {
+ __asm __volatile(
+ "movq %1, %%mm0\n\t"
+ "movq %2, %%mm1\n\t"
+ "movq 1%1, %%mm4\n\t"
+ "movq 1%2, %%mm5\n\t"
+ "movq %%mm0, %%mm2\n\t"
+ "movq %%mm1, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm0\n\t"
+ "punpcklbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm2\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "paddusw %%mm1, %%mm0\n\t"
+ "paddusw %%mm3, %%mm2\n\t"
+ "movq %%mm4, %%mm1\n\t"
+ "movq %%mm5, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm4\n\t"
+ "punpcklbw %%mm7, %%mm5\n\t"
+ "punpckhbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "paddusw %%mm5, %%mm4\n\t"
+ "paddusw %%mm3, %%mm1\n\t"
+ "paddusw %%mm6, %%mm4\n\t"
+ "paddusw %%mm6, %%mm1\n\t"
+ "paddusw %%mm4, %%mm0\n\t"
+ "paddusw %%mm1, %%mm2\n\t"
+ "movq %0, %%mm1\n\t"
+ "movq 8%0, %%mm3\n\t"
+ "psrlw $2, %%mm0\n\t"
+ "psrlw $2, %%mm2\n\t"
+ "psubsw %%mm0, %%mm1\n\t"
+ "psubsw %%mm2, %%mm3\n\t"
+ "movq %%mm1, %0\n\t"
+ "movq %%mm3, 8%0\n\t"
+ :"=m"(*p)
+ :"m"(*pix),
+ "m"(*(pix+line_size))
+ :"memory");
+ pix += line_size;
+ p += 8 ;
+ } while(--h);
+}
+
+void dsputil_init_mmx(void)
+{
+ mm_flags = mm_support();
+#if 0
+ printf("CPU flags:");
+ if (mm_flags & MM_MMX)
+ printf(" mmx");
+ if (mm_flags & MM_MMXEXT)
+ printf(" mmxext");
+ if (mm_flags & MM_3DNOW)
+ printf(" 3dnow");
+ if (mm_flags & MM_SSE)
+ printf(" sse");
+ if (mm_flags & MM_SSE2)
+ printf(" sse2");
+ printf("\n");
+#endif
+
+ if (mm_flags & MM_MMX) {
+ get_pixels = get_pixels_mmx;
+ put_pixels_clamped = put_pixels_clamped_mmx;
+ add_pixels_clamped = add_pixels_clamped_mmx;
+
+ pix_abs16x16 = pix_abs16x16_mmx;
+ pix_abs16x16_x2 = pix_abs16x16_x2_mmx;
+ pix_abs16x16_y2 = pix_abs16x16_y2_mmx;
+ pix_abs16x16_xy2 = pix_abs16x16_xy2_mmx;
+ //av_fdct = fdct_mmx;
+ av_fdct = 0;
+
+ put_pixels_tab[0] = put_pixels_mmx;
+ put_pixels_tab[1] = put_pixels_x2_mmx;
+ put_pixels_tab[2] = put_pixels_y2_mmx;
+ put_pixels_tab[3] = put_pixels_xy2_mmx;
+
+ put_no_rnd_pixels_tab[0] = put_pixels_mmx;
+ put_no_rnd_pixels_tab[1] = put_no_rnd_pixels_x2_mmx;
+ put_no_rnd_pixels_tab[2] = put_no_rnd_pixels_y2_mmx;
+ put_no_rnd_pixels_tab[3] = put_no_rnd_pixels_xy2_mmx;
+
+ avg_pixels_tab[0] = avg_pixels_mmx;
+ avg_pixels_tab[1] = avg_pixels_x2_mmx;
+ avg_pixels_tab[2] = avg_pixels_y2_mmx;
+ avg_pixels_tab[3] = avg_pixels_xy2_mmx;
+
+ avg_no_rnd_pixels_tab[0] = avg_no_rnd_pixels_mmx;
+ avg_no_rnd_pixels_tab[1] = avg_no_rnd_pixels_x2_mmx;
+ avg_no_rnd_pixels_tab[2] = avg_no_rnd_pixels_y2_mmx;
+ avg_no_rnd_pixels_tab[3] = avg_no_rnd_pixels_xy2_mmx;
+
+ sub_pixels_tab[0] = sub_pixels_mmx;
+ sub_pixels_tab[1] = sub_pixels_x2_mmx;
+ sub_pixels_tab[2] = sub_pixels_y2_mmx;
+ sub_pixels_tab[3] = sub_pixels_xy2_mmx;
+
+ if (mm_flags & MM_MMXEXT) {
+ pix_abs16x16 = pix_abs16x16_sse;
+ }
+
+ if (mm_flags & MM_SSE) {
+ put_pixels_tab[1] = put_pixels_x2_sse;
+ put_pixels_tab[2] = put_pixels_y2_sse;
+
+ avg_pixels_tab[0] = avg_pixels_sse;
+ avg_pixels_tab[1] = avg_pixels_x2_sse;
+ avg_pixels_tab[2] = avg_pixels_y2_sse;
+ avg_pixels_tab[3] = avg_pixels_xy2_sse;
+
+ sub_pixels_tab[1] = sub_pixels_x2_sse;
+ sub_pixels_tab[2] = sub_pixels_y2_sse;
+ } else if (mm_flags & MM_3DNOW) {
+ put_pixels_tab[1] = put_pixels_x2_3dnow;
+ put_pixels_tab[2] = put_pixels_y2_3dnow;
+
+ avg_pixels_tab[0] = avg_pixels_3dnow;
+ avg_pixels_tab[1] = avg_pixels_x2_3dnow;
+ avg_pixels_tab[2] = avg_pixels_y2_3dnow;
+ avg_pixels_tab[3] = avg_pixels_xy2_3dnow;
+
+ sub_pixels_tab[1] = sub_pixels_x2_3dnow;
+ sub_pixels_tab[2] = sub_pixels_y2_3dnow;
+ }
+
+#ifdef USE_MMX_IDCT
+ /* use MMX / MMXEXT iDCT code from libmpeg2 */
+ //printf("LIBAVCODEC: Using MMX%s iDCT code\n",(mm_flags & MM_MMXEXT)?"EXT":"");
+ ff_idct = (mm_flags & MM_MMXEXT) ? mmxext_idct : mmx_idct;
+ /* the mmx/mmxext idct uses a reordered input, so we patch scan tables */
+ { int i,j;
+ for (i = 0; i < 64; i++) {
+ j = zigzag_direct[i];
+ zigzag_direct[i] = (j & 0x38) | ((j & 6) >> 1) | ((j & 1) << 2);
+ j = ff_alternate_horizontal_scan[i];
+ ff_alternate_horizontal_scan[i] = (j & 0x38) | ((j & 6) >> 1) | ((j & 1) << 2);
+ j = ff_alternate_vertical_scan[i];
+ ff_alternate_vertical_scan[i] = (j & 0x38) | ((j & 6) >> 1) | ((j & 1) << 2);
+ }
+ }
+#endif
+
+ }
+}
diff --git a/src/libffmpeg/libavcodec/dsputil_mmx_avg.h b/src/libffmpeg/libavcodec/dsputil_mmx_avg.h
new file mode 100644
index 000000000..5cd640f71
--- /dev/null
+++ b/src/libffmpeg/libavcodec/dsputil_mmx_avg.h
@@ -0,0 +1,344 @@
+/*
+ * DSP utils : average functions are compiled twice for 3dnow/mmx2
+ * Copyright (c) 2000, 2001 Gerard Lantau.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * MMX optimization by Nick Kurshev <nickols_k@mail.ru>
+ */
+
+static void DEF(put_pixels_x2)(UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ int dh, hh;
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ hh=h>>2;
+ dh=h&3;
+ while(hh--) {
+ __asm __volatile(
+ "movq %4, %%mm0\n\t"
+ "movq 1%4, %%mm1\n\t"
+ "movq %5, %%mm2\n\t"
+ "movq 1%5, %%mm3\n\t"
+ "movq %6, %%mm4\n\t"
+ "movq 1%6, %%mm5\n\t"
+ "movq %7, %%mm6\n\t"
+ "movq 1%7, %%mm7\n\t"
+ PAVGB" %%mm1, %%mm0\n\t"
+ PAVGB" %%mm3, %%mm2\n\t"
+ PAVGB" %%mm5, %%mm4\n\t"
+ PAVGB" %%mm7, %%mm6\n\t"
+ "movq %%mm0, %0\n\t"
+ "movq %%mm2, %1\n\t"
+ "movq %%mm4, %2\n\t"
+ "movq %%mm6, %3\n\t"
+ :"=m"(*p), "=m"(*(p+line_size)), "=m"(*(p+line_size*2)), "=m"(*(p+line_size*3))
+ :"m"(*pix), "m"(*(pix+line_size)), "m"(*(pix+line_size*2)), "m"(*(pix+line_size*3))
+ :"memory");
+ pix += line_size*4; p += line_size*4;
+ }
+ while(dh--) {
+ __asm __volatile(
+ "movq %1, %%mm0\n\t"
+ "movq 1%1, %%mm1\n\t"
+ PAVGB" %%mm1, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix)
+ :"memory");
+ pix += line_size; p += line_size;
+ }
+}
+
+static void DEF(put_pixels_y2)(UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ int dh, hh;
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+
+ hh=h>>1;
+ dh=h&1;
+ while(hh--) {
+ __asm __volatile(
+ "movq %2, %%mm0\n\t"
+ "movq %3, %%mm1\n\t"
+ "movq %4, %%mm2\n\t"
+ PAVGB" %%mm1, %%mm0\n\t"
+ PAVGB" %%mm2, %%mm1\n\t"
+ "movq %%mm0, %0\n\t"
+ "movq %%mm1, %1\n\t"
+ :"=m"(*p), "=m"(*(p+line_size))
+ :"m"(*pix), "m"(*(pix+line_size)),
+ "m"(*(pix+line_size*2))
+ :"memory");
+ pix += line_size*2;
+ p += line_size*2;
+ }
+ if(dh) {
+ __asm __volatile(
+ "movq %1, %%mm0\n\t"
+ "movq %2, %%mm1\n\t"
+ PAVGB" %%mm1, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix),
+ "m"(*(pix+line_size))
+ :"memory");
+ }
+}
+
+static void DEF(avg_pixels)(UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ int dh, hh;
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ hh=h>>2;
+ dh=h&3;
+ while(hh--) {
+ __asm __volatile(
+ "movq %0, %%mm0\n\t"
+ "movq %4, %%mm1\n\t"
+ "movq %1, %%mm2\n\t"
+ "movq %5, %%mm3\n\t"
+ "movq %2, %%mm4\n\t"
+ "movq %6, %%mm5\n\t"
+ "movq %3, %%mm6\n\t"
+ "movq %7, %%mm7\n\t"
+ PAVGB" %%mm1, %%mm0\n\t"
+ PAVGB" %%mm3, %%mm2\n\t"
+ PAVGB" %%mm5, %%mm4\n\t"
+ PAVGB" %%mm7, %%mm6\n\t"
+ "movq %%mm0, %0\n\t"
+ "movq %%mm2, %1\n\t"
+ "movq %%mm4, %2\n\t"
+ "movq %%mm6, %3\n\t"
+ :"=m"(*p), "=m"(*(p+line_size)), "=m"(*(p+line_size*2)), "=m"(*(p+line_size*3))
+ :"m"(*pix), "m"(*(pix+line_size)), "m"(*(pix+line_size*2)), "m"(*(pix+line_size*3))
+ :"memory");
+ pix += line_size*4; p += line_size*4;
+ }
+ while(dh--) {
+ __asm __volatile(
+ "movq %0, %%mm0\n\t"
+ "movq %1, %%mm1\n\t"
+ PAVGB" %%mm1, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix)
+ :"memory");
+ pix += line_size; p += line_size;
+ }
+}
+
+static void DEF(avg_pixels_x2)( UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ int dh, hh;
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ hh=h>>1;
+ dh=h&1;
+ while(hh--) {
+ __asm __volatile(
+ "movq %2, %%mm2\n\t"
+ "movq 1%2, %%mm3\n\t"
+ "movq %3, %%mm4\n\t"
+ "movq 1%3, %%mm5\n\t"
+ "movq %0, %%mm0\n\t"
+ "movq %1, %%mm1\n\t"
+ PAVGB" %%mm3, %%mm2\n\t"
+ PAVGB" %%mm2, %%mm0\n\t"
+ PAVGB" %%mm5, %%mm4\n\t"
+ PAVGB" %%mm4, %%mm1\n\t"
+ "movq %%mm0, %0\n\t"
+ "movq %%mm1, %1\n\t"
+ :"=m"(*p), "=m"(*(p+line_size))
+ :"m"(*pix), "m"(*(pix+line_size))
+ :"memory");
+ pix += line_size*2;
+ p += line_size*2;
+ }
+ if(dh) {
+ __asm __volatile(
+ "movq %1, %%mm1\n\t"
+ "movq 1%1, %%mm2\n\t"
+ "movq %0, %%mm0\n\t"
+ PAVGB" %%mm2, %%mm1\n\t"
+ PAVGB" %%mm1, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix)
+ :"memory");
+ }
+}
+
+static void DEF(avg_pixels_y2)( UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ int dh, hh;
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ hh=h>>1;
+ dh=h&1;
+ while(hh--) {
+ __asm __volatile(
+ "movq %2, %%mm2\n\t"
+ "movq %3, %%mm3\n\t"
+ "movq %3, %%mm4\n\t"
+ "movq %4, %%mm5\n\t"
+ "movq %0, %%mm0\n\t"
+ "movq %1, %%mm1\n\t"
+ PAVGB" %%mm3, %%mm2\n\t"
+ PAVGB" %%mm2, %%mm0\n\t"
+ PAVGB" %%mm5, %%mm4\n\t"
+ PAVGB" %%mm4, %%mm1\n\t"
+ "movq %%mm0, %0\n\t"
+ "movq %%mm1, %1\n\t"
+ :"=m"(*p), "=m"(*(p+line_size))
+ :"m"(*pix), "m"(*(pix+line_size)), "m"(*(pix+line_size*2))
+ :"memory");
+ pix += line_size*2;
+ p += line_size*2;
+ }
+ if(dh) {
+ __asm __volatile(
+ "movq %1, %%mm1\n\t"
+ "movq %2, %%mm2\n\t"
+ "movq %0, %%mm0\n\t"
+ PAVGB" %%mm2, %%mm1\n\t"
+ PAVGB" %%mm1, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix), "m"(*(pix+line_size))
+ :"memory");
+ }
+}
+
+static void DEF(avg_pixels_xy2)( UINT8 *block, const UINT8 *pixels, int line_size, int h)
+{
+ UINT8 *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile(
+ "pxor %%mm7, %%mm7\n\t"
+ "movq %0, %%mm6\n\t"
+ ::"m"(mm_wtwo):"memory");
+ do {
+ __asm __volatile(
+ "movq %1, %%mm0\n\t"
+ "movq %2, %%mm1\n\t"
+ "movq 1%1, %%mm4\n\t"
+ "movq 1%2, %%mm5\n\t"
+ "movq %%mm0, %%mm2\n\t"
+ "movq %%mm1, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm0\n\t"
+ "punpcklbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm2\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "paddusw %%mm1, %%mm0\n\t"
+ "paddusw %%mm3, %%mm2\n\t"
+ "movq %%mm4, %%mm1\n\t"
+ "movq %%mm5, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm4\n\t"
+ "punpcklbw %%mm7, %%mm5\n\t"
+ "punpckhbw %%mm7, %%mm1\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "paddusw %%mm5, %%mm4\n\t"
+ "paddusw %%mm3, %%mm1\n\t"
+ "paddusw %%mm6, %%mm4\n\t"
+ "paddusw %%mm6, %%mm1\n\t"
+ "paddusw %%mm4, %%mm0\n\t"
+ "paddusw %%mm1, %%mm2\n\t"
+ "psrlw $2, %%mm0\n\t"
+ "psrlw $2, %%mm2\n\t"
+ "packuswb %%mm2, %%mm0\n\t"
+ PAVGB" %0, %%mm0\n\t"
+ "movq %%mm0, %0\n\t"
+ :"=m"(*p)
+ :"m"(*pix),
+ "m"(*(pix+line_size))
+ :"memory");
+ pix += line_size;
+ p += line_size ;
+ } while(--h);
+}
+
+static void DEF(sub_pixels_x2)( DCTELEM *block, const UINT8 *pixels, int line_size, int h)
+{
+ DCTELEM *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile(
+ "pxor %%mm7, %%mm7":::"memory");
+ do {
+ __asm __volatile(
+ "movq 1%1, %%mm2\n\t"
+ "movq %0, %%mm0\n\t"
+ PAVGB" %1, %%mm2\n\t"
+ "movq 8%0, %%mm1\n\t"
+ "movq %%mm2, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm2\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "psubsw %%mm2, %%mm0\n\t"
+ "psubsw %%mm3, %%mm1\n\t"
+ "movq %%mm0, %0\n\t"
+ "movq %%mm1, 8%0\n\t"
+ :"=m"(*p)
+ :"m"(*pix)
+ :"memory");
+ pix += line_size;
+ p += 8;
+ } while (--h);
+}
+
+static void DEF(sub_pixels_y2)( DCTELEM *block, const UINT8 *pixels, int line_size, int h)
+{
+ DCTELEM *p;
+ const UINT8 *pix;
+ p = block;
+ pix = pixels;
+ __asm __volatile(
+ "pxor %%mm7, %%mm7":::"memory");
+ do {
+ __asm __volatile(
+ "movq %2, %%mm2\n\t"
+ "movq %0, %%mm0\n\t"
+ PAVGB" %1, %%mm2\n\t"
+ "movq 8%0, %%mm1\n\t"
+ "movq %%mm2, %%mm3\n\t"
+ "punpcklbw %%mm7, %%mm2\n\t"
+ "punpckhbw %%mm7, %%mm3\n\t"
+ "psubsw %%mm2, %%mm0\n\t"
+ "psubsw %%mm3, %%mm1\n\t"
+ "movq %%mm0, %0\n\t"
+ "movq %%mm1, 8%0\n\t"
+ :"=m"(*p)
+ :"m"(*pix), "m"(*(pix+line_size))
+ :"memory");
+ pix += line_size;
+ p += 8;
+ } while (--h);
+}
+
diff --git a/src/libffmpeg/libavcodec/fdctref.c b/src/libffmpeg/libavcodec/fdctref.c
new file mode 100644
index 000000000..b90a2e52e
--- /dev/null
+++ b/src/libffmpeg/libavcodec/fdctref.c
@@ -0,0 +1,118 @@
+/* fdctref.c, forward discrete cosine transform, double precision */
+
+/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
+
+/*
+ * Disclaimer of Warranty
+ *
+ * These software programs are available to the user without any license fee or
+ * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims
+ * any and all warranties, whether express, implied, or statuary, including any
+ * implied warranties or merchantability or of fitness for a particular
+ * purpose. In no event shall the copyright-holder be liable for any
+ * incidental, punitive, or consequential damages of any kind whatsoever
+ * arising from the use of these programs.
+ *
+ * This disclaimer of warranty extends to the user of these programs and user's
+ * customers, employees, agents, transferees, successors, and assigns.
+ *
+ * The MPEG Software Simulation Group does not represent or warrant that the
+ * programs furnished hereunder are free of infringement of any third-party
+ * patents.
+ *
+ * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
+ * are subject to royalty fees to patent holders. Many of these patents are
+ * general enough such that they are unavoidable regardless of implementation
+ * design.
+ *
+ */
+
+#include <math.h>
+
+#ifndef PI
+# ifdef M_PI
+# define PI M_PI
+# else
+# define PI 3.14159265358979323846
+# endif
+#endif
+
+/* global declarations */
+void init_fdct (void);
+void fdct (short *block);
+
+/* private data */
+static double c[8][8]; /* transform coefficients */
+
+void init_fdct()
+{
+ int i, j;
+ double s;
+
+ for (i=0; i<8; i++)
+ {
+ s = (i==0) ? sqrt(0.125) : 0.5;
+
+ for (j=0; j<8; j++)
+ c[i][j] = s * cos((PI/8.0)*i*(j+0.5));
+ }
+}
+
+void fdct(block)
+short *block;
+{
+ register int i, j;
+ double s;
+ double tmp[64];
+
+ for(i = 0; i < 8; i++)
+ for(j = 0; j < 8; j++)
+ {
+ s = 0.0;
+
+/*
+ * for(k = 0; k < 8; k++)
+ * s += c[j][k] * block[8 * i + k];
+ */
+ s += c[j][0] * block[8 * i + 0];
+ s += c[j][1] * block[8 * i + 1];
+ s += c[j][2] * block[8 * i + 2];
+ s += c[j][3] * block[8 * i + 3];
+ s += c[j][4] * block[8 * i + 4];
+ s += c[j][5] * block[8 * i + 5];
+ s += c[j][6] * block[8 * i + 6];
+ s += c[j][7] * block[8 * i + 7];
+
+ tmp[8 * i + j] = s;
+ }
+
+ for(j = 0; j < 8; j++)
+ for(i = 0; i < 8; i++)
+ {
+ s = 0.0;
+
+/*
+ * for(k = 0; k < 8; k++)
+ * s += c[i][k] * tmp[8 * k + j];
+ */
+ s += c[i][0] * tmp[8 * 0 + j];
+ s += c[i][1] * tmp[8 * 1 + j];
+ s += c[i][2] * tmp[8 * 2 + j];
+ s += c[i][3] * tmp[8 * 3 + j];
+ s += c[i][4] * tmp[8 * 4 + j];
+ s += c[i][5] * tmp[8 * 5 + j];
+ s += c[i][6] * tmp[8 * 6 + j];
+ s += c[i][7] * tmp[8 * 7 + j];
+
+ block[8 * i + j] = (short)floor(s + 0.499999);
+/*
+ * reason for adding 0.499999 instead of 0.5:
+ * s is quite often x.5 (at least for i and/or j = 0 or 4)
+ * and setting the rounding threshold exactly to 0.5 leads to an
+ * extremely high arithmetic implementation dependency of the result;
+ * s being between x.5 and x.500001 (which is now incorrectly rounded
+ * downwards instead of upwards) is assumed to occur less often
+ * (if at all)
+ */
+ }
+}
diff --git a/src/libffmpeg/libavcodec/h263.c b/src/libffmpeg/libavcodec/h263.c
new file mode 100644
index 000000000..73355a6ed
--- /dev/null
+++ b/src/libffmpeg/libavcodec/h263.c
@@ -0,0 +1,1292 @@
+/*
+ * H263/MPEG4 backend for ffmpeg encoder and decoder
+ * Copyright (c) 2000,2001 Gerard Lantau.
+ * H263+ support for custom picture format.
+ * Copyright (c) 2001 Juan J. Sierralta P.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "common.h"
+#include "dsputil.h"
+#include "avcodec.h"
+#include "mpegvideo.h"
+#include "h263data.h"
+#include "mpeg4data.h"
+
+#define NDEBUG
+#include <assert.h>
+
+static void h263_encode_block(MpegEncContext * s, DCTELEM * block,
+ int n);
+static void h263_encode_motion(MpegEncContext * s, int val);
+static void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block,
+ int n);
+static int h263_decode_motion(MpegEncContext * s, int pred);
+static int h263_decode_block(MpegEncContext * s, DCTELEM * block,
+ int n, int coded);
+static int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
+ int n, int coded);
+
+int h263_get_picture_format(int width, int height)
+{
+ int format;
+
+ if (width == 128 && height == 96)
+ format = 1;
+ else if (width == 176 && height == 144)
+ format = 2;
+ else if (width == 352 && height == 288)
+ format = 3;
+ else if (width == 704 && height == 576)
+ format = 4;
+ else if (width == 1408 && height == 1152)
+ format = 5;
+ else
+ format = 7;
+ return format;
+}
+
+void h263_encode_picture_header(MpegEncContext * s, int picture_number)
+{
+ int format, umvplus;
+
+ align_put_bits(&s->pb);
+ put_bits(&s->pb, 22, 0x20);
+ put_bits(&s->pb, 8, ((s->picture_number * 30 * FRAME_RATE_BASE) /
+ s->frame_rate) & 0xff);
+
+ put_bits(&s->pb, 1, 1); /* marker */
+ put_bits(&s->pb, 1, 0); /* h263 id */
+ put_bits(&s->pb, 1, 0); /* split screen off */
+ put_bits(&s->pb, 1, 0); /* camera off */
+ put_bits(&s->pb, 1, 0); /* freeze picture release off */
+
+ if (!s->h263_plus) {
+ /* H.263v1 */
+ format = h263_get_picture_format(s->width, s->height);
+ put_bits(&s->pb, 3, format);
+ put_bits(&s->pb, 1, (s->pict_type == P_TYPE));
+ /* By now UMV IS DISABLED ON H.263v1, since the restrictions
+ of H.263v1 UMV implies to check the predicted MV after
+ calculation of the current MB to see if we're on the limits */
+ put_bits(&s->pb, 1, 0); /* unrestricted motion vector: off */
+ put_bits(&s->pb, 1, 0); /* SAC: off */
+ put_bits(&s->pb, 1, 0); /* advanced prediction mode: off */
+ put_bits(&s->pb, 1, 0); /* not PB frame */
+ put_bits(&s->pb, 5, s->qscale);
+ put_bits(&s->pb, 1, 0); /* Continuous Presence Multipoint mode: off */
+ } else {
+ /* H.263v2 */
+ /* H.263 Plus PTYPE */
+ put_bits(&s->pb, 3, 7);
+ put_bits(&s->pb,3,1); /* Update Full Extended PTYPE */
+ put_bits(&s->pb,3,6); /* Custom Source Format */
+ put_bits(&s->pb,1,0); /* Custom PCF: off */
+ umvplus = (s->pict_type == P_TYPE) && s->unrestricted_mv;
+ put_bits(&s->pb, 1, umvplus); /* Unrestricted Motion Vector */
+ put_bits(&s->pb,1,0); /* SAC: off */
+ put_bits(&s->pb,1,0); /* Advanced Prediction Mode: off */
+ put_bits(&s->pb,1,0); /* Advanced Intra Coding: off */
+ put_bits(&s->pb,1,0); /* Deblocking Filter: off */
+ put_bits(&s->pb,1,0); /* Slice Structured: off */
+ put_bits(&s->pb,1,0); /* Reference Picture Selection: off */
+ put_bits(&s->pb,1,0); /* Independent Segment Decoding: off */
+ put_bits(&s->pb,1,0); /* Alternative Inter VLC: off */
+ put_bits(&s->pb,1,0); /* Modified Quantization: off */
+ put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */
+ put_bits(&s->pb,3,0); /* Reserved */
+
+ put_bits(&s->pb, 3, s->pict_type == P_TYPE);
+
+ put_bits(&s->pb,1,0); /* Reference Picture Resampling: off */
+ put_bits(&s->pb,1,0); /* Reduced-Resolution Update: off */
+ put_bits(&s->pb,1,0); /* Rounding Type */
+ put_bits(&s->pb,2,0); /* Reserved */
+ put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */
+
+ /* This should be here if PLUSPTYPE */
+ put_bits(&s->pb, 1, 0); /* Continuous Presence Multipoint mode: off */
+
+ /* Custom Picture Format (CPFMT) */
+
+ put_bits(&s->pb,4,2); /* Aspect ratio: CIF 12:11 (4:3) picture */
+ put_bits(&s->pb,9,(s->width >> 2) - 1);
+ put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */
+ put_bits(&s->pb,9,(s->height >> 2));
+ /* Unlimited Unrestricted Motion Vectors Indicator (UUI) */
+ if (umvplus)
+ put_bits(&s->pb,1,1); /* Limited according tables of Annex D */
+ put_bits(&s->pb, 5, s->qscale);
+ }
+
+ put_bits(&s->pb, 1, 0); /* no PEI */
+}
+
+void h263_encode_mb(MpegEncContext * s,
+ DCTELEM block[6][64],
+ int motion_x, int motion_y)
+{
+ int cbpc, cbpy, i, cbp, pred_x, pred_y;
+
+ // printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y);
+ if (!s->mb_intra) {
+ /* compute cbp */
+ cbp = 0;
+ for (i = 0; i < 6; i++) {
+ if (s->block_last_index[i] >= 0)
+ cbp |= 1 << (5 - i);
+ }
+ if ((cbp | motion_x | motion_y) == 0) {
+ /* skip macroblock */
+ put_bits(&s->pb, 1, 1);
+ return;
+ }
+ put_bits(&s->pb, 1, 0); /* mb coded */
+ cbpc = cbp & 3;
+ put_bits(&s->pb,
+ inter_MCBPC_bits[cbpc],
+ inter_MCBPC_code[cbpc]);
+ cbpy = cbp >> 2;
+ cbpy ^= 0xf;
+ put_bits(&s->pb, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]);
+
+ /* motion vectors: 16x16 mode only now */
+ h263_pred_motion(s, 0, &pred_x, &pred_y);
+
+ h263_encode_motion(s, motion_x - pred_x);
+ h263_encode_motion(s, motion_y - pred_y);
+ } else {
+ /* compute cbp */
+ cbp = 0;
+ for (i = 0; i < 6; i++) {
+ if (s->block_last_index[i] >= 1)
+ cbp |= 1 << (5 - i);
+ }
+
+ cbpc = cbp & 3;
+ if (s->pict_type == I_TYPE) {
+ put_bits(&s->pb,
+ intra_MCBPC_bits[cbpc],
+ intra_MCBPC_code[cbpc]);
+ } else {
+ put_bits(&s->pb, 1, 0); /* mb coded */
+ put_bits(&s->pb,
+ inter_MCBPC_bits[cbpc + 4],
+ inter_MCBPC_code[cbpc + 4]);
+ }
+ if (s->h263_pred) {
+ /* XXX: currently, we do not try to use ac prediction */
+ put_bits(&s->pb, 1, 0); /* no ac prediction */
+ }
+ cbpy = cbp >> 2;
+ put_bits(&s->pb, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]);
+ }
+
+ /* encode each block */
+ if (s->h263_pred) {
+ for (i = 0; i < 6; i++) {
+ mpeg4_encode_block(s, block[i], i);
+ }
+ } else {
+ for (i = 0; i < 6; i++) {
+ h263_encode_block(s, block[i], i);
+ }
+ }
+}
+
+static inline int mid_pred(int a, int b, int c)
+{
+ int vmin, vmax;
+ vmin = a;
+ if (b < vmin)
+ vmin = b;
+ if (c < vmin)
+ vmin = c;
+
+ vmax = a;
+ if (b > vmax)
+ vmax = b;
+ if (c > vmax)
+ vmax = c;
+
+ return a + b + c - vmin - vmax;
+}
+
+INT16 *h263_pred_motion(MpegEncContext * s, int block,
+ int *px, int *py)
+{
+ int x, y, wrap;
+ INT16 *A, *B, *C, *mot_val;
+
+ x = 2 * s->mb_x + 1 + (block & 1);
+ y = 2 * s->mb_y + 1 + ((block >> 1) & 1);
+ wrap = 2 * s->mb_width + 2;
+
+ mot_val = s->motion_val[(x) + (y) * wrap];
+
+ /* special case for first line */
+ if (y == 1 || s->first_slice_line) {
+ A = s->motion_val[(x-1) + (y) * wrap];
+ *px = A[0];
+ *py = A[1];
+ } else {
+ switch(block) {
+ default:
+ case 0:
+ A = s->motion_val[(x-1) + (y) * wrap];
+ B = s->motion_val[(x) + (y-1) * wrap];
+ C = s->motion_val[(x+2) + (y-1) * wrap];
+ break;
+ case 1:
+ case 2:
+ A = s->motion_val[(x-1) + (y) * wrap];
+ B = s->motion_val[(x) + (y-1) * wrap];
+ C = s->motion_val[(x+1) + (y-1) * wrap];
+ break;
+ case 3:
+ A = s->motion_val[(x-1) + (y) * wrap];
+ B = s->motion_val[(x-1) + (y-1) * wrap];
+ C = s->motion_val[(x) + (y-1) * wrap];
+ break;
+ }
+ *px = mid_pred(A[0], B[0], C[0]);
+ *py = mid_pred(A[1], B[1], C[1]);
+ }
+ return mot_val;
+}
+
+
+static void h263_encode_motion(MpegEncContext * s, int val)
+{
+ int range, l, m, bit_size, sign, code, bits;
+
+ if (val == 0) {
+ /* zero vector */
+ code = 0;
+ put_bits(&s->pb, mvtab[code][1], mvtab[code][0]);
+ } else {
+ bit_size = s->f_code - 1;
+ range = 1 << bit_size;
+ /* modulo encoding */
+ l = range * 32;
+ m = 2 * l;
+ if (val < -l) {
+ val += m;
+ } else if (val >= l) {
+ val -= m;
+ }
+
+ if (val >= 0) {
+ val--;
+ code = (val >> bit_size) + 1;
+ bits = val & (range - 1);
+ sign = 0;
+ } else {
+ val = -val;
+ val--;
+ code = (val >> bit_size) + 1;
+ bits = val & (range - 1);
+ sign = 1;
+ }
+
+ put_bits(&s->pb, mvtab[code][1] + 1, (mvtab[code][0] << 1) | sign);
+ if (bit_size > 0) {
+ put_bits(&s->pb, bit_size, bits);
+ }
+ }
+}
+
+void h263_encode_init_vlc(MpegEncContext *s)
+{
+ static int done = 0;
+
+ if (!done) {
+ done = 1;
+ init_rl(&rl_inter);
+ init_rl(&rl_intra);
+ }
+}
+
+static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n)
+{
+ int level, run, last, i, j, last_index, last_non_zero, sign, slevel;
+ int code;
+ RLTable *rl = &rl_inter;
+
+ if (s->mb_intra) {
+ /* DC coef */
+ level = block[0];
+ /* 255 cannot be represented, so we clamp */
+ if (level > 254) {
+ level = 254;
+ block[0] = 254;
+ }
+ if (level == 128)
+ put_bits(&s->pb, 8, 0xff);
+ else
+ put_bits(&s->pb, 8, level & 0xff);
+ i = 1;
+ } else {
+ i = 0;
+ }
+
+ /* AC coefs */
+ last_index = s->block_last_index[n];
+ last_non_zero = i - 1;
+ for (; i <= last_index; i++) {
+ j = zigzag_direct[i];
+ level = block[j];
+ if (level) {
+ run = i - last_non_zero - 1;
+ last = (i == last_index);
+ sign = 0;
+ slevel = level;
+ if (level < 0) {
+ sign = 1;
+ level = -level;
+ }
+ code = get_rl_index(rl, last, run, level);
+ put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
+ if (code == rl->n) {
+ put_bits(&s->pb, 1, last);
+ put_bits(&s->pb, 6, run);
+ put_bits(&s->pb, 8, slevel & 0xff);
+ } else {
+ put_bits(&s->pb, 1, sign);
+ }
+ last_non_zero = i;
+ }
+ }
+}
+
+/***************************************************/
+
+/* write mpeg4 VOP header */
+void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
+{
+ align_put_bits(&s->pb);
+
+ put_bits(&s->pb, 32, 0x1B6); /* vop header */
+ put_bits(&s->pb, 2, s->pict_type - 1); /* pict type: I = 0 , P = 1 */
+ /* XXX: time base + 1 not always correct */
+ put_bits(&s->pb, 1, 1);
+ put_bits(&s->pb, 1, 0);
+
+ put_bits(&s->pb, 1, 1); /* marker */
+ put_bits(&s->pb, 4, 1); /* XXX: correct time increment */
+ put_bits(&s->pb, 1, 1); /* marker */
+ put_bits(&s->pb, 1, 1); /* vop coded */
+ if (s->pict_type == P_TYPE) {
+ s->no_rounding = 0;
+ put_bits(&s->pb, 1, s->no_rounding); /* rounding type */
+ }
+ put_bits(&s->pb, 3, 0); /* intra dc VLC threshold */
+
+ put_bits(&s->pb, 5, s->qscale);
+
+ if (s->pict_type != I_TYPE)
+ put_bits(&s->pb, 3, s->f_code); /* fcode_for */
+ // printf("****frame %d\n", picture_number);
+}
+
+void h263_dc_scale(MpegEncContext * s)
+{
+ int quant;
+
+ quant = s->qscale;
+ /* luminance */
+ if (quant < 5)
+ s->y_dc_scale = 8;
+ else if (quant > 4 && quant < 9)
+ s->y_dc_scale = (2 * quant);
+ else if (quant > 8 && quant < 25)
+ s->y_dc_scale = (quant + 8);
+ else
+ s->y_dc_scale = (2 * quant - 16);
+ /* chrominance */
+ if (quant < 5)
+ s->c_dc_scale = 8;
+ else if (quant > 4 && quant < 25)
+ s->c_dc_scale = ((quant + 13) / 2);
+ else
+ s->c_dc_scale = (quant - 6);
+}
+
+static int mpeg4_pred_dc(MpegEncContext * s, int n, UINT16 **dc_val_ptr, int *dir_ptr)
+{
+ int a, b, c, x, y, wrap, pred, scale;
+ UINT16 *dc_val;
+
+ /* find prediction */
+ if (n < 4) {
+ x = 2 * s->mb_x + 1 + (n & 1);
+ y = 2 * s->mb_y + 1 + ((n & 2) >> 1);
+ wrap = s->mb_width * 2 + 2;
+ dc_val = s->dc_val[0];
+ scale = s->y_dc_scale;
+ } else {
+ x = s->mb_x + 1;
+ y = s->mb_y + 1;
+ wrap = s->mb_width + 2;
+ dc_val = s->dc_val[n - 4 + 1];
+ scale = s->c_dc_scale;
+ }
+
+ /* B C
+ * A X
+ */
+ a = dc_val[(x - 1) + (y) * wrap];
+ b = dc_val[(x - 1) + (y - 1) * wrap];
+ c = dc_val[(x) + (y - 1) * wrap];
+
+ if (abs(a - b) < abs(b - c)) {
+ pred = c;
+ *dir_ptr = 1; /* top */
+ } else {
+ pred = a;
+ *dir_ptr = 0; /* left */
+ }
+ /* we assume pred is positive */
+ pred = (pred + (scale >> 1)) / scale;
+
+ /* prepare address for prediction update */
+ *dc_val_ptr = &dc_val[(x) + (y) * wrap];
+
+ return pred;
+}
+
+void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n,
+ int dir)
+{
+ int x, y, wrap, i;
+ INT16 *ac_val, *ac_val1;
+
+ /* find prediction */
+ if (n < 4) {
+ x = 2 * s->mb_x + 1 + (n & 1);
+ y = 2 * s->mb_y + 1 + ((n & 2) >> 1);
+ wrap = s->mb_width * 2 + 2;
+ ac_val = s->ac_val[0][0];
+ } else {
+ x = s->mb_x + 1;
+ y = s->mb_y + 1;
+ wrap = s->mb_width + 2;
+ ac_val = s->ac_val[n - 4 + 1][0];
+ }
+ ac_val += ((y) * wrap + (x)) * 16;
+ ac_val1 = ac_val;
+ if (s->ac_pred) {
+ if (dir == 0) {
+ /* left prediction */
+ ac_val -= 16;
+ for(i=1;i<8;i++) {
+ block[i*8] += ac_val[i];
+ }
+ } else {
+ /* top prediction */
+ ac_val -= 16 * wrap;
+ for(i=1;i<8;i++) {
+ block[i] += ac_val[i + 8];
+ }
+ }
+ }
+ /* left copy */
+ for(i=1;i<8;i++)
+ ac_val1[i] = block[i * 8];
+ /* top copy */
+ for(i=1;i<8;i++)
+ ac_val1[8 + i] = block[i];
+}
+
+static inline void mpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr)
+{
+ int size, v, pred;
+ UINT16 *dc_val;
+
+ pred = mpeg4_pred_dc(s, n, &dc_val, dir_ptr);
+ if (n < 4) {
+ *dc_val = level * s->y_dc_scale;
+ } else {
+ *dc_val = level * s->c_dc_scale;
+ }
+
+ /* do the prediction */
+ level -= pred;
+ /* find number of bits */
+ size = 0;
+ v = abs(level);
+ while (v) {
+ v >>= 1;
+ size++;
+ }
+
+ if (n < 4) {
+ /* luminance */
+ put_bits(&s->pb, DCtab_lum[size][1], DCtab_lum[size][0]);
+ } else {
+ /* chrominance */
+ put_bits(&s->pb, DCtab_chrom[size][1], DCtab_chrom[size][0]);
+ }
+
+ /* encode remaining bits */
+ if (size > 0) {
+ if (level < 0)
+ level = (-level) ^ ((1 << size) - 1);
+ put_bits(&s->pb, size, level);
+ if (size > 8)
+ put_bits(&s->pb, 1, 1);
+ }
+}
+
+static void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n)
+{
+ int level, run, last, i, j, last_index, last_non_zero, sign, slevel;
+ int code, dc_pred_dir;
+ const RLTable *rl;
+
+ if (s->mb_intra) {
+ /* mpeg4 based DC predictor */
+ mpeg4_encode_dc(s, block[0], n, &dc_pred_dir);
+ i = 1;
+ rl = &rl_intra;
+ } else {
+ i = 0;
+ rl = &rl_inter;
+ }
+
+ /* AC coefs */
+ last_index = s->block_last_index[n];
+ last_non_zero = i - 1;
+ for (; i <= last_index; i++) {
+ j = zigzag_direct[i];
+ level = block[j];
+ if (level) {
+ run = i - last_non_zero - 1;
+ last = (i == last_index);
+ sign = 0;
+ slevel = level;
+ if (level < 0) {
+ sign = 1;
+ level = -level;
+ }
+ code = get_rl_index(rl, last, run, level);
+ put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
+ if (code == rl->n) {
+ int level1, run1;
+ level1 = level - rl->max_level[last][run];
+ if (level1 < 1)
+ goto esc2;
+ code = get_rl_index(rl, last, run, level1);
+ if (code == rl->n) {
+ esc2:
+ put_bits(&s->pb, 1, 1);
+ if (level > MAX_LEVEL)
+ goto esc3;
+ run1 = run - rl->max_run[last][level] - 1;
+ if (run1 < 0)
+ goto esc3;
+ code = get_rl_index(rl, last, run1, level);
+ if (code == rl->n) {
+ esc3:
+ /* third escape */
+ put_bits(&s->pb, 1, 1);
+ put_bits(&s->pb, 1, last);
+ put_bits(&s->pb, 6, run);
+ put_bits(&s->pb, 1, 1);
+ put_bits(&s->pb, 12, slevel & 0xfff);
+ put_bits(&s->pb, 1, 1);
+ } else {
+ /* second escape */
+ put_bits(&s->pb, 1, 0);
+ put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
+ put_bits(&s->pb, 1, sign);
+ }
+ } else {
+ /* first escape */
+ put_bits(&s->pb, 1, 0);
+ put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
+ put_bits(&s->pb, 1, sign);
+ }
+ } else {
+ put_bits(&s->pb, 1, sign);
+ }
+ last_non_zero = i;
+ }
+ }
+}
+
+
+
+/***********************************************/
+/* decoding */
+
+static VLC intra_MCBPC_vlc;
+static VLC inter_MCBPC_vlc;
+static VLC cbpy_vlc;
+static VLC mv_vlc;
+static VLC dc_lum, dc_chrom;
+
+void init_rl(RLTable *rl)
+{
+ INT8 max_level[MAX_RUN+1], max_run[MAX_LEVEL+1];
+ UINT8 index_run[MAX_RUN+1];
+ int last, run, level, start, end, i;
+
+ /* compute max_level[], max_run[] and index_run[] */
+ for(last=0;last<2;last++) {
+ if (last == 0) {
+ start = 0;
+ end = rl->last;
+ } else {
+ start = rl->last;
+ end = rl->n;
+ }
+
+ memset(max_level, 0, MAX_RUN + 1);
+ memset(max_run, 0, MAX_LEVEL + 1);
+ memset(index_run, rl->n, MAX_RUN + 1);
+ for(i=start;i<end;i++) {
+ run = rl->table_run[i];
+ level = rl->table_level[i];
+ if (index_run[run] == rl->n)
+ index_run[run] = i;
+ if (level > max_level[run])
+ max_level[run] = level;
+ if (run > max_run[level])
+ max_run[level] = run;
+ }
+ rl->max_level[last] = malloc(MAX_RUN + 1);
+ memcpy(rl->max_level[last], max_level, MAX_RUN + 1);
+ rl->max_run[last] = malloc(MAX_LEVEL + 1);
+ memcpy(rl->max_run[last], max_run, MAX_LEVEL + 1);
+ rl->index_run[last] = malloc(MAX_RUN + 1);
+ memcpy(rl->index_run[last], index_run, MAX_RUN + 1);
+ }
+}
+
+void init_vlc_rl(RLTable *rl)
+{
+ init_vlc(&rl->vlc, 9, rl->n + 1,
+ &rl->table_vlc[0][1], 4, 2,
+ &rl->table_vlc[0][0], 4, 2);
+}
+
+/* init vlcs */
+
+/* XXX: find a better solution to handle static init */
+void h263_decode_init_vlc(MpegEncContext *s)
+{
+ static int done = 0;
+
+ if (!done) {
+ done = 1;
+
+ init_vlc(&intra_MCBPC_vlc, 6, 8,
+ intra_MCBPC_bits, 1, 1,
+ intra_MCBPC_code, 1, 1);
+ init_vlc(&inter_MCBPC_vlc, 9, 20,
+ inter_MCBPC_bits, 1, 1,
+ inter_MCBPC_code, 1, 1);
+ init_vlc(&cbpy_vlc, 6, 16,
+ &cbpy_tab[0][1], 2, 1,
+ &cbpy_tab[0][0], 2, 1);
+ init_vlc(&mv_vlc, 9, 33,
+ &mvtab[0][1], 2, 1,
+ &mvtab[0][0], 2, 1);
+ init_rl(&rl_inter);
+ init_rl(&rl_intra);
+ init_vlc_rl(&rl_inter);
+ init_vlc_rl(&rl_intra);
+ init_vlc(&dc_lum, 9, 13,
+ &DCtab_lum[0][1], 2, 1,
+ &DCtab_lum[0][0], 2, 1);
+ init_vlc(&dc_chrom, 9, 13,
+ &DCtab_chrom[0][1], 2, 1,
+ &DCtab_chrom[0][0], 2, 1);
+ }
+}
+
+int h263_decode_mb(MpegEncContext *s,
+ DCTELEM block[6][64])
+{
+ int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant;
+ INT16 *mot_val;
+ static UINT8 quant_tab[4] = { -1, -2, 1, 2 };
+
+ if (s->pict_type == P_TYPE) {
+ if (get_bits1(&s->gb)) {
+ /* skip mb */
+ s->mb_intra = 0;
+ for(i=0;i<6;i++)
+ s->block_last_index[i] = -1;
+ s->mv_dir = MV_DIR_FORWARD;
+ s->mv_type = MV_TYPE_16X16;
+ s->mv[0][0][0] = 0;
+ s->mv[0][0][1] = 0;
+ s->mb_skiped = 1;
+ return 0;
+ }
+ cbpc = get_vlc(&s->gb, &inter_MCBPC_vlc);
+ if (cbpc < 0)
+ return -1;
+ dquant = cbpc & 8;
+ s->mb_intra = ((cbpc & 4) != 0);
+ } else {
+ cbpc = get_vlc(&s->gb, &intra_MCBPC_vlc);
+ if (cbpc < 0)
+ return -1;
+ dquant = cbpc & 4;
+ s->mb_intra = 1;
+ }
+
+ if (!s->mb_intra) {
+ cbpy = get_vlc(&s->gb, &cbpy_vlc);
+ cbp = (cbpc & 3) | ((cbpy ^ 0xf) << 2);
+ if (dquant) {
+ s->qscale += quant_tab[get_bits(&s->gb, 2)];
+ if (s->qscale < 1)
+ s->qscale = 1;
+ else if (s->qscale > 31)
+ s->qscale = 31;
+ }
+ s->mv_dir = MV_DIR_FORWARD;
+ if ((cbpc & 16) == 0) {
+ /* 16x16 motion prediction */
+ s->mv_type = MV_TYPE_16X16;
+ h263_pred_motion(s, 0, &pred_x, &pred_y);
+ mx = h263_decode_motion(s, pred_x);
+ if (mx >= 0xffff)
+ return -1;
+ my = h263_decode_motion(s, pred_y);
+ if (my >= 0xffff)
+ return -1;
+ s->mv[0][0][0] = mx;
+ s->mv[0][0][1] = my;
+ } else {
+ s->mv_type = MV_TYPE_8X8;
+ for(i=0;i<4;i++) {
+ mot_val = h263_pred_motion(s, i, &pred_x, &pred_y);
+ mx = h263_decode_motion(s, pred_x);
+ if (mx >= 0xffff)
+ return -1;
+ my = h263_decode_motion(s, pred_y);
+ if (my >= 0xffff)
+ return -1;
+ s->mv[0][i][0] = mx;
+ s->mv[0][i][1] = my;
+ mot_val[0] = mx;
+ mot_val[1] = my;
+ }
+ }
+ } else {
+ s->ac_pred = 0;
+ if (s->h263_pred) {
+ s->ac_pred = get_bits1(&s->gb);
+ }
+ cbpy = get_vlc(&s->gb, &cbpy_vlc);
+ cbp = (cbpc & 3) | (cbpy << 2);
+ if (dquant) {
+ s->qscale += quant_tab[get_bits(&s->gb, 2)];
+ if (s->qscale < 1)
+ s->qscale = 1;
+ else if (s->qscale > 31)
+ s->qscale = 31;
+ }
+ }
+
+ /* decode each block */
+ if (s->h263_pred) {
+ for (i = 0; i < 6; i++) {
+ if (mpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1) < 0)
+ return -1;
+ }
+ } else {
+ for (i = 0; i < 6; i++) {
+ if (h263_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1) < 0)
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int h263_decode_motion(MpegEncContext * s, int pred)
+{
+ int code, val, sign, shift, l, m;
+
+ code = get_vlc(&s->gb, &mv_vlc);
+ if (code < 0)
+ return 0xffff;
+
+ if (code == 0)
+ return pred;
+ sign = get_bits1(&s->gb);
+ shift = s->f_code - 1;
+ val = (code - 1) << shift;
+ if (shift > 0)
+ val |= get_bits(&s->gb, shift);
+ val++;
+ if (sign)
+ val = -val;
+ val += pred;
+
+ /* modulo decoding */
+ if (!s->h263_long_vectors) {
+ l = (1 << (s->f_code - 1)) * 32;
+ m = 2 * l;
+ if (val < -l) {
+ val += m;
+ } else if (val >= l) {
+ val -= m;
+ }
+ } else {
+ /* horrible h263 long vector mode */
+ if (pred < -31 && val < -63)
+ val += 64;
+ if (pred > 32 && val > 63)
+ val -= 64;
+ }
+ return val;
+}
+
+static int h263_decode_block(MpegEncContext * s, DCTELEM * block,
+ int n, int coded)
+{
+ int code, level, i, j, last, run;
+ RLTable *rl = &rl_inter;
+
+ if (s->mb_intra) {
+ /* DC coef */
+ if (s->h263_rv10 && s->rv10_version == 3 && s->pict_type == I_TYPE) {
+ int component, diff;
+ component = (n <= 3 ? 0 : n - 4 + 1);
+ level = s->last_dc[component];
+ if (s->rv10_first_dc_coded[component]) {
+ diff = rv_decode_dc(s, n);
+ if (diff == 0xffff)
+ return -1;
+ level += diff;
+ level = level & 0xff; /* handle wrap round */
+ s->last_dc[component] = level;
+ } else {
+ s->rv10_first_dc_coded[component] = 1;
+ }
+ } else {
+ level = get_bits(&s->gb, 8);
+ if (level == 255)
+ level = 128;
+ }
+ block[0] = level;
+ i = 1;
+ } else {
+ i = 0;
+ }
+ if (!coded) {
+ s->block_last_index[n] = i - 1;
+ return 0;
+ }
+
+ for(;;) {
+ code = get_vlc(&s->gb, &rl->vlc);
+ if (code < 0)
+ return -1;
+ if (code == rl->n) {
+ /* escape */
+ last = get_bits1(&s->gb);
+ run = get_bits(&s->gb, 6);
+ level = (INT8)get_bits(&s->gb, 8);
+ if (s->h263_rv10 && level == -128) {
+ /* XXX: should patch encoder too */
+ level = get_bits(&s->gb, 12);
+ level = (level << 20) >> 20;
+ }
+ } else {
+ run = rl->table_run[code];
+ level = rl->table_level[code];
+ last = code >= rl->last;
+ if (get_bits1(&s->gb))
+ level = -level;
+ }
+ i += run;
+ if (i >= 64)
+ return -1;
+ j = zigzag_direct[i];
+ block[j] = level;
+ if (last)
+ break;
+ i++;
+ }
+ s->block_last_index[n] = i;
+ return 0;
+}
+
+static int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
+{
+ int level, pred, code;
+ UINT16 *dc_val;
+
+ if (n < 4)
+ code = get_vlc(&s->gb, &dc_lum);
+ else
+ code = get_vlc(&s->gb, &dc_chrom);
+ if (code < 0)
+ return -1;
+ if (code == 0) {
+ level = 0;
+ } else {
+ level = get_bits(&s->gb, code);
+ if ((level >> (code - 1)) == 0) /* if MSB not set it is negative*/
+ level = - (level ^ ((1 << code) - 1));
+ if (code > 8)
+ skip_bits1(&s->gb); /* marker */
+ }
+
+ pred = mpeg4_pred_dc(s, n, &dc_val, dir_ptr);
+ level += pred;
+ if (level < 0)
+ level = 0;
+ if (n < 4) {
+ *dc_val = level * s->y_dc_scale;
+ } else {
+ *dc_val = level * s->c_dc_scale;
+ }
+ return level;
+}
+
+static int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
+ int n, int coded)
+{
+ int code, level, i, j, last, run;
+ int dc_pred_dir;
+ RLTable *rl;
+ const UINT8 *scan_table;
+
+ if (s->mb_intra) {
+ /* DC coef */
+ level = mpeg4_decode_dc(s, n, &dc_pred_dir);
+ if (level < 0)
+ return -1;
+ block[0] = level;
+ i = 1;
+ if (!coded)
+ goto not_coded;
+ rl = &rl_intra;
+ if (s->ac_pred) {
+ if (dc_pred_dir == 0)
+ scan_table = ff_alternate_vertical_scan; /* left */
+ else
+ scan_table = ff_alternate_horizontal_scan; /* top */
+ } else {
+ scan_table = zigzag_direct;
+ }
+ } else {
+ i = 0;
+ if (!coded) {
+ s->block_last_index[n] = i - 1;
+ return 0;
+ }
+ rl = &rl_inter;
+ scan_table = zigzag_direct;
+ }
+
+ for(;;) {
+ code = get_vlc(&s->gb, &rl->vlc);
+ if (code < 0)
+ return -1;
+ if (code == rl->n) {
+ /* escape */
+ if (get_bits1(&s->gb) != 0) {
+ if (get_bits1(&s->gb) != 0) {
+ /* third escape */
+ last = get_bits1(&s->gb);
+ run = get_bits(&s->gb, 6);
+ get_bits1(&s->gb); /* marker */
+ level = get_bits(&s->gb, 12);
+ level = (level << 20) >> 20; /* sign extend */
+ skip_bits1(&s->gb); /* marker */
+ } else {
+ /* second escape */
+ code = get_vlc(&s->gb, &rl->vlc);
+ if (code < 0 || code >= rl->n)
+ return -1;
+ run = rl->table_run[code];
+ level = rl->table_level[code];
+ last = code >= rl->last;
+ run += rl->max_run[last][level] + 1;
+ if (get_bits1(&s->gb))
+ level = -level;
+ }
+ } else {
+ /* first escape */
+ code = get_vlc(&s->gb, &rl->vlc);
+ if (code < 0 || code >= rl->n)
+ return -1;
+ run = rl->table_run[code];
+ level = rl->table_level[code];
+ last = code >= rl->last;
+ level += rl->max_level[last][run];
+ if (get_bits1(&s->gb))
+ level = -level;
+ }
+ } else {
+ run = rl->table_run[code];
+ level = rl->table_level[code];
+ last = code >= rl->last;
+ if (get_bits1(&s->gb))
+ level = -level;
+ }
+ i += run;
+ if (i >= 64)
+ return -1;
+ j = scan_table[i];
+ block[j] = level;
+ i++;
+ if (last)
+ break;
+ }
+ not_coded:
+ if (s->mb_intra) {
+ mpeg4_pred_ac(s, block, n, dc_pred_dir);
+ if (s->ac_pred) {
+ i = 64; /* XXX: not optimal */
+ }
+ }
+ s->block_last_index[n] = i - 1;
+ return 0;
+}
+
+/* most is hardcoded. should extend to handle all h263 streams */
+int h263_decode_picture_header(MpegEncContext *s)
+{
+ int format, width, height;
+
+ /* picture header */
+ if (get_bits(&s->gb, 22) != 0x20)
+ return -1;
+ skip_bits(&s->gb, 8); /* picture timestamp */
+
+ if (get_bits1(&s->gb) != 1)
+ return -1; /* marker */
+ if (get_bits1(&s->gb) != 0)
+ return -1; /* h263 id */
+ skip_bits1(&s->gb); /* split screen off */
+ skip_bits1(&s->gb); /* camera off */
+ skip_bits1(&s->gb); /* freeze picture release off */
+
+ format = get_bits(&s->gb, 3);
+
+ if (format != 7) {
+ s->h263_plus = 0;
+ /* H.263v1 */
+ width = h263_format[format][0];
+ height = h263_format[format][1];
+ if (!width)
+ return -1;
+
+ s->pict_type = I_TYPE + get_bits1(&s->gb);
+
+ s->unrestricted_mv = get_bits1(&s->gb);
+ s->h263_long_vectors = s->unrestricted_mv;
+
+ if (get_bits1(&s->gb) != 0)
+ return -1; /* SAC: off */
+ if (get_bits1(&s->gb) != 0)
+ return -1; /* advanced prediction mode: off */
+ if (get_bits1(&s->gb) != 0)
+ return -1; /* not PB frame */
+
+ s->qscale = get_bits(&s->gb, 5);
+ skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */
+ } else {
+ s->h263_plus = 1;
+ /* H.263v2 */
+ if (get_bits(&s->gb, 3) != 1)
+ return -1;
+ if (get_bits(&s->gb, 3) != 6) /* custom source format */
+ return -1;
+ skip_bits(&s->gb, 12);
+ skip_bits(&s->gb, 3);
+ s->pict_type = get_bits(&s->gb, 3) + 1;
+ if (s->pict_type != I_TYPE &&
+ s->pict_type != P_TYPE)
+ return -1;
+ skip_bits(&s->gb, 7);
+ skip_bits(&s->gb, 4); /* aspect ratio */
+ width = (get_bits(&s->gb, 9) + 1) * 4;
+ skip_bits1(&s->gb);
+ height = get_bits(&s->gb, 9) * 4;
+ if (height == 0)
+ return -1;
+ s->qscale = get_bits(&s->gb, 5);
+ }
+ /* PEI */
+ while (get_bits1(&s->gb) != 0) {
+ skip_bits(&s->gb, 8);
+ }
+ s->f_code = 1;
+ s->width = width;
+ s->height = height;
+ return 0;
+}
+
+/* decode mpeg4 VOP header */
+int mpeg4_decode_picture_header(MpegEncContext * s)
+{
+ int time_incr, startcode, state, v;
+
+ redo:
+ /* search next start code */
+ align_get_bits(&s->gb);
+ state = 0xff;
+ for(;;) {
+ v = get_bits(&s->gb, 8);
+ if (state == 0x000001) {
+ state = ((state << 8) | v) & 0xffffff;
+ startcode = state;
+ break;
+ }
+ state = ((state << 8) | v) & 0xffffff;
+ /* XXX: really detect end of frame */
+ if (state == 0)
+ return -1;
+ }
+
+ if (startcode == 0x120) {
+ int time_increment_resolution, width, height;
+
+ /* vol header */
+ skip_bits(&s->gb, 1); /* random access */
+ skip_bits(&s->gb, 8); /* vo_type */
+ skip_bits(&s->gb, 1); /* is_ol_id */
+ skip_bits(&s->gb, 4); /* vo_ver_id */
+ skip_bits(&s->gb, 3); /* vo_priority */
+
+ skip_bits(&s->gb, 4); /* aspect_ratio_info */
+ skip_bits(&s->gb, 1); /* vol control parameter */
+ skip_bits(&s->gb, 2); /* vol shape */
+ skip_bits1(&s->gb); /* marker */
+
+ time_increment_resolution = get_bits(&s->gb, 16);
+ s->time_increment_bits = log2(time_increment_resolution - 1) + 1;
+ skip_bits1(&s->gb); /* marker */
+
+ skip_bits1(&s->gb); /* vop rate */
+ skip_bits(&s->gb, s->time_increment_bits);
+ skip_bits1(&s->gb); /* marker */
+
+ width = get_bits(&s->gb, 13);
+ skip_bits1(&s->gb); /* marker */
+ height = get_bits(&s->gb, 13);
+ skip_bits1(&s->gb); /* marker */
+
+ skip_bits1(&s->gb); /* interfaced */
+ skip_bits1(&s->gb); /* OBMC */
+ skip_bits(&s->gb, 2); /* vol_sprite_usage */
+ skip_bits1(&s->gb); /* not_8_bit */
+
+ skip_bits1(&s->gb); /* vol_quant_type */
+ skip_bits1(&s->gb); /* vol_quarter_pixel */
+ skip_bits1(&s->gb); /* complexity_estimation_disabled */
+ skip_bits1(&s->gb); /* resync_marker_disabled */
+ skip_bits1(&s->gb); /* data_partioning_enabled */
+ goto redo;
+ } else if (startcode != 0x1b6) {
+ goto redo;
+ }
+
+ s->pict_type = get_bits(&s->gb, 2) + 1; /* pict type: I = 0 , P = 1 */
+ if (s->pict_type != I_TYPE &&
+ s->pict_type != P_TYPE)
+ return -1;
+
+ /* XXX: parse time base */
+ time_incr = 0;
+ while (get_bits1(&s->gb) != 0)
+ time_incr++;
+
+ skip_bits1(&s->gb); /* marker */
+ skip_bits(&s->gb, s->time_increment_bits);
+ skip_bits1(&s->gb); /* marker */
+ /* vop coded */
+ if (get_bits1(&s->gb) != 1)
+ return -1;
+
+ if (s->pict_type == P_TYPE) {
+ /* rounding type for motion estimation */
+ s->no_rounding = get_bits1(&s->gb);
+ }
+
+ if (get_bits(&s->gb, 3) != 0)
+ return -1; /* intra dc VLC threshold */
+
+ s->qscale = get_bits(&s->gb, 5);
+
+ if (s->pict_type != I_TYPE) {
+ s->f_code = get_bits(&s->gb, 3); /* fcode_for */
+ }
+ return 0;
+}
+
+/* don't understand why they choose a different header ! */
+int intel_h263_decode_picture_header(MpegEncContext *s)
+{
+ int format;
+
+ /* picture header */
+ if (get_bits(&s->gb, 22) != 0x20)
+ return -1;
+ skip_bits(&s->gb, 8); /* picture timestamp */
+
+ if (get_bits1(&s->gb) != 1)
+ return -1; /* marker */
+ if (get_bits1(&s->gb) != 0)
+ return -1; /* h263 id */
+ skip_bits1(&s->gb); /* split screen off */
+ skip_bits1(&s->gb); /* camera off */
+ skip_bits1(&s->gb); /* freeze picture release off */
+
+ format = get_bits(&s->gb, 3);
+ if (format != 7)
+ return -1;
+
+ s->h263_plus = 0;
+
+ s->pict_type = I_TYPE + get_bits1(&s->gb);
+
+ s->unrestricted_mv = get_bits1(&s->gb);
+ s->h263_long_vectors = s->unrestricted_mv;
+
+ if (get_bits1(&s->gb) != 0)
+ return -1; /* SAC: off */
+ if (get_bits1(&s->gb) != 0)
+ return -1; /* advanced prediction mode: off */
+ if (get_bits1(&s->gb) != 0)
+ return -1; /* not PB frame */
+
+ /* skip unknown header garbage */
+ skip_bits(&s->gb, 41);
+
+ s->qscale = get_bits(&s->gb, 5);
+ skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */
+
+ /* PEI */
+ while (get_bits1(&s->gb) != 0) {
+ skip_bits(&s->gb, 8);
+ }
+ s->f_code = 1;
+ return 0;
+}
diff --git a/src/libffmpeg/libavcodec/h263data.h b/src/libffmpeg/libavcodec/h263data.h
new file mode 100644
index 000000000..4fd9d3629
--- /dev/null
+++ b/src/libffmpeg/libavcodec/h263data.h
@@ -0,0 +1,115 @@
+
+/* intra MCBPC, mb_type = (intra), then (intraq) */
+static const UINT8 intra_MCBPC_code[8] = { 1, 1, 2, 3, 1, 1, 2, 3 };
+static const UINT8 intra_MCBPC_bits[8] = { 1, 3, 3, 3, 4, 6, 6, 6 };
+
+/* inter MCBPC, mb_type = (inter), (intra), (interq), (intraq), (inter4v) */
+static const UINT8 inter_MCBPC_code[20] = {
+ 1, 3, 2, 5,
+ 3, 4, 3, 3,
+ 0, 1, 2, 3,
+ 4, 4, 3, 2,
+ 2, 5, 4, 5,
+};
+static const UINT8 inter_MCBPC_bits[20] = {
+ 1, 4, 4, 6,
+ 5, 8, 8, 7,
+ 12, 12, 12, 12,
+ 6, 9, 9, 9,
+ 3, 7, 7, 8,
+};
+
+static const UINT8 cbpy_tab[16][2] =
+{
+ {3,4}, {5,5}, {4,5}, {9,4}, {3,5}, {7,4}, {2,6}, {11,4},
+ {2,5}, {3,6}, {5,4}, {10,4}, {4,4}, {8,4}, {6,4}, {3,2}
+};
+
+static const UINT8 mvtab[33][2] =
+{
+ {1,1}, {1,2}, {1,3}, {1,4}, {3,6}, {5,7}, {4,7}, {3,7},
+ {11,9}, {10,9}, {9,9}, {17,10}, {16,10}, {15,10}, {14,10}, {13,10},
+ {12,10}, {11,10}, {10,10}, {9,10}, {8,10}, {7,10}, {6,10}, {5,10},
+ {4,10}, {7,11}, {6,11}, {5,11}, {4,11}, {3,11}, {2,11}, {3,12},
+ {2,12}
+};
+
+/* third non intra table */
+const UINT16 inter_vlc[103][2] = {
+{ 0x2, 2 },{ 0xf, 4 },{ 0x15, 6 },{ 0x17, 7 },
+{ 0x1f, 8 },{ 0x25, 9 },{ 0x24, 9 },{ 0x21, 10 },
+{ 0x20, 10 },{ 0x7, 11 },{ 0x6, 11 },{ 0x20, 11 },
+{ 0x6, 3 },{ 0x14, 6 },{ 0x1e, 8 },{ 0xf, 10 },
+{ 0x21, 11 },{ 0x50, 12 },{ 0xe, 4 },{ 0x1d, 8 },
+{ 0xe, 10 },{ 0x51, 12 },{ 0xd, 5 },{ 0x23, 9 },
+{ 0xd, 10 },{ 0xc, 5 },{ 0x22, 9 },{ 0x52, 12 },
+{ 0xb, 5 },{ 0xc, 10 },{ 0x53, 12 },{ 0x13, 6 },
+{ 0xb, 10 },{ 0x54, 12 },{ 0x12, 6 },{ 0xa, 10 },
+{ 0x11, 6 },{ 0x9, 10 },{ 0x10, 6 },{ 0x8, 10 },
+{ 0x16, 7 },{ 0x55, 12 },{ 0x15, 7 },{ 0x14, 7 },
+{ 0x1c, 8 },{ 0x1b, 8 },{ 0x21, 9 },{ 0x20, 9 },
+{ 0x1f, 9 },{ 0x1e, 9 },{ 0x1d, 9 },{ 0x1c, 9 },
+{ 0x1b, 9 },{ 0x1a, 9 },{ 0x22, 11 },{ 0x23, 11 },
+{ 0x56, 12 },{ 0x57, 12 },{ 0x7, 4 },{ 0x19, 9 },
+{ 0x5, 11 },{ 0xf, 6 },{ 0x4, 11 },{ 0xe, 6 },
+{ 0xd, 6 },{ 0xc, 6 },{ 0x13, 7 },{ 0x12, 7 },
+{ 0x11, 7 },{ 0x10, 7 },{ 0x1a, 8 },{ 0x19, 8 },
+{ 0x18, 8 },{ 0x17, 8 },{ 0x16, 8 },{ 0x15, 8 },
+{ 0x14, 8 },{ 0x13, 8 },{ 0x18, 9 },{ 0x17, 9 },
+{ 0x16, 9 },{ 0x15, 9 },{ 0x14, 9 },{ 0x13, 9 },
+{ 0x12, 9 },{ 0x11, 9 },{ 0x7, 10 },{ 0x6, 10 },
+{ 0x5, 10 },{ 0x4, 10 },{ 0x24, 11 },{ 0x25, 11 },
+{ 0x26, 11 },{ 0x27, 11 },{ 0x58, 12 },{ 0x59, 12 },
+{ 0x5a, 12 },{ 0x5b, 12 },{ 0x5c, 12 },{ 0x5d, 12 },
+{ 0x5e, 12 },{ 0x5f, 12 },{ 0x3, 7 },
+};
+
+const INT8 inter_level[102] = {
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 1, 2, 3, 4,
+ 5, 6, 1, 2, 3, 4, 1, 2,
+ 3, 1, 2, 3, 1, 2, 3, 1,
+ 2, 3, 1, 2, 1, 2, 1, 2,
+ 1, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 2, 3, 1, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1,
+};
+
+const INT8 inter_run[102] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 1, 1, 1,
+ 1, 1, 2, 2, 2, 2, 3, 3,
+ 3, 4, 4, 4, 5, 5, 5, 6,
+ 6, 6, 7, 7, 8, 8, 9, 9,
+ 10, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 0, 0, 0, 1, 1, 2,
+ 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40,
+};
+
+static RLTable rl_inter = {
+ 102,
+ 58,
+ inter_vlc,
+ inter_run,
+ inter_level,
+};
+
+static const UINT16 h263_format[8][2] = {
+ { 0, 0 },
+ { 128, 96 },
+ { 176, 144 },
+ { 352, 288 },
+ { 704, 576 },
+ { 1408, 1152 },
+};
+
diff --git a/src/libffmpeg/libavcodec/h263dec.c b/src/libffmpeg/libavcodec/h263dec.c
new file mode 100644
index 000000000..8bbd3a758
--- /dev/null
+++ b/src/libffmpeg/libavcodec/h263dec.c
@@ -0,0 +1,204 @@
+/*
+ * H263 decoder
+ * Copyright (c) 2001 Gerard Lantau.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "dsputil.h"
+#include "avcodec.h"
+#include "mpegvideo.h"
+
+//#define DEBUG
+
+static int h263_decode_init(AVCodecContext *avctx)
+{
+ MpegEncContext *s = avctx->priv_data;
+
+ s->out_format = FMT_H263;
+
+ s->width = avctx->width;
+ s->height = avctx->height;
+
+ /* select sub codec */
+ switch(avctx->codec->id) {
+ case CODEC_ID_H263:
+ break;
+ case CODEC_ID_OPENDIVX:
+ s->time_increment_bits = 4; /* default value for broken headers */
+ s->h263_pred = 1;
+ break;
+ case CODEC_ID_MSMPEG4:
+ s->h263_msmpeg4 = 1;
+ s->h263_pred = 1;
+ break;
+ case CODEC_ID_H263I:
+ s->h263_intel = 1;
+ break;
+ default:
+ return -1;
+ }
+
+ /* for h263, we allocate the images after having read the header */
+ if (MPV_common_init(s) < 0)
+ return -1;
+
+ if (s->h263_msmpeg4)
+ msmpeg4_decode_init_vlc(s);
+ else
+ h263_decode_init_vlc(s);
+
+ return 0;
+}
+
+static int h263_decode_end(AVCodecContext *avctx)
+{
+ MpegEncContext *s = avctx->priv_data;
+
+ MPV_common_end(s);
+ return 0;
+}
+
+static int h263_decode_frame(AVCodecContext *avctx,
+ void *data, int *data_size,
+ UINT8 *buf, int buf_size)
+{
+ MpegEncContext *s = avctx->priv_data;
+ int ret;
+ AVPicture *pict = data;
+
+#ifdef DEBUG
+ printf("*****frame %d size=%d\n", avctx->frame_number, buf_size);
+ printf("bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]);
+#endif
+
+ /* no supplementary picture */
+ if (buf_size == 0) {
+ *data_size = 0;
+ return 0;
+ }
+
+ init_get_bits(&s->gb, buf, buf_size);
+
+ /* let's go :-) */
+ if (s->h263_msmpeg4) {
+ ret = msmpeg4_decode_picture_header(s);
+ } else if (s->h263_pred) {
+ ret = mpeg4_decode_picture_header(s);
+ } else if (s->h263_intel) {
+ ret = intel_h263_decode_picture_header(s);
+ } else {
+ ret = h263_decode_picture_header(s);
+ }
+ if (ret < 0)
+ return -1;
+
+ MPV_frame_start(s);
+
+#ifdef DEBUG
+ printf("qscale=%d\n", s->qscale);
+#endif
+
+ /* decode each macroblock */
+ for(s->mb_y=0; s->mb_y < s->mb_height; s->mb_y++) {
+ for(s->mb_x=0; s->mb_x < s->mb_width; s->mb_x++) {
+#ifdef DEBUG
+ printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y);
+#endif
+ /* DCT & quantize */
+ if (s->h263_msmpeg4) {
+ msmpeg4_dc_scale(s);
+ } else if (s->h263_pred) {
+ h263_dc_scale(s);
+ } else {
+ /* default quantization values */
+ s->y_dc_scale = 8;
+ s->c_dc_scale = 8;
+ }
+
+ memset(s->block, 0, sizeof(s->block));
+ s->mv_dir = MV_DIR_FORWARD;
+ s->mv_type = MV_TYPE_16X16;
+ if (s->h263_msmpeg4) {
+ if (msmpeg4_decode_mb(s, s->block) < 0)
+ return -1;
+ } else {
+ if (h263_decode_mb(s, s->block) < 0)
+ return -1;
+ }
+ MPV_decode_mb(s, s->block);
+ }
+ }
+
+ MPV_frame_end(s);
+
+ pict->data[0] = s->current_picture[0];
+ pict->data[1] = s->current_picture[1];
+ pict->data[2] = s->current_picture[2];
+ pict->linesize[0] = s->linesize;
+ pict->linesize[1] = s->linesize / 2;
+ pict->linesize[2] = s->linesize / 2;
+
+ avctx->quality = s->qscale;
+ *data_size = sizeof(AVPicture);
+ return buf_size;
+}
+
+AVCodec opendivx_decoder = {
+ "opendivx",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_OPENDIVX,
+ sizeof(MpegEncContext),
+ h263_decode_init,
+ NULL,
+ h263_decode_end,
+ h263_decode_frame,
+};
+
+AVCodec h263_decoder = {
+ "h263",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_H263,
+ sizeof(MpegEncContext),
+ h263_decode_init,
+ NULL,
+ h263_decode_end,
+ h263_decode_frame,
+};
+
+AVCodec msmpeg4_decoder = {
+ "msmpeg4",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_MSMPEG4,
+ sizeof(MpegEncContext),
+ h263_decode_init,
+ NULL,
+ h263_decode_end,
+ h263_decode_frame,
+};
+
+AVCodec h263i_decoder = {
+ "h263i",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_H263I,
+ sizeof(MpegEncContext),
+ h263_decode_init,
+ NULL,
+ h263_decode_end,
+ h263_decode_frame,
+};
+
diff --git a/src/libffmpeg/libavcodec/jfdctfst.c b/src/libffmpeg/libavcodec/jfdctfst.c
new file mode 100644
index 000000000..cdc3b47f9
--- /dev/null
+++ b/src/libffmpeg/libavcodec/jfdctfst.c
@@ -0,0 +1,224 @@
+/*
+ * jfdctfst.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains a fast, not so accurate integer implementation of the
+ * forward DCT (Discrete Cosine Transform).
+ *
+ * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
+ * on each column. Direct algorithms are also available, but they are
+ * much more complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on Arai, Agui, and Nakajima's algorithm for
+ * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in
+ * Japanese, but the algorithm is described in the Pennebaker & Mitchell
+ * JPEG textbook (see REFERENCES section in file README). The following code
+ * is based directly on figure 4-8 in P&M.
+ * While an 8-point DCT cannot be done in less than 11 multiplies, it is
+ * possible to arrange the computation so that many of the multiplies are
+ * simple scalings of the final outputs. These multiplies can then be
+ * folded into the multiplications or divisions by the JPEG quantization
+ * table entries. The AA&N method leaves only 5 multiplies and 29 adds
+ * to be done in the DCT itself.
+ * The primary disadvantage of this method is that with fixed-point math,
+ * accuracy is lost due to imprecise representation of the scaled
+ * quantization values. The smaller the quantization table entry, the less
+ * precise the scaled value, so this implementation does worse with high-
+ * quality-setting files than with low-quality ones.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "common.h"
+#include "dsputil.h"
+
+#define DCTSIZE 8
+#define GLOBAL(x) x
+#define RIGHT_SHIFT(x, n) ((x) >> (n))
+#define SHIFT_TEMPS
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+ Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/* Scaling decisions are generally the same as in the LL&M algorithm;
+ * see jfdctint.c for more details. However, we choose to descale
+ * (right shift) multiplication products as soon as they are formed,
+ * rather than carrying additional fractional bits into subsequent additions.
+ * This compromises accuracy slightly, but it lets us save a few shifts.
+ * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples)
+ * everywhere except in the multiplications proper; this saves a good deal
+ * of work on 16-bit-int machines.
+ *
+ * Again to save a few shifts, the intermediate results between pass 1 and
+ * pass 2 are not upscaled, but are represented only to integral precision.
+ *
+ * A final compromise is to represent the multiplicative constants to only
+ * 8 fractional bits, rather than 13. This saves some shifting work on some
+ * machines, and may also reduce the cost of multiplication (since there
+ * are fewer one-bits in the constants).
+ */
+
+#define CONST_BITS 8
+
+
+/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
+ * causing a lot of useless floating-point operations at run time.
+ * To get around this we use the following pre-calculated constants.
+ * If you change CONST_BITS you may want to add appropriate values.
+ * (With a reasonable C compiler, you can just rely on the FIX() macro...)
+ */
+
+#if CONST_BITS == 8
+#define FIX_0_382683433 ((INT32) 98) /* FIX(0.382683433) */
+#define FIX_0_541196100 ((INT32) 139) /* FIX(0.541196100) */
+#define FIX_0_707106781 ((INT32) 181) /* FIX(0.707106781) */
+#define FIX_1_306562965 ((INT32) 334) /* FIX(1.306562965) */
+#else
+#define FIX_0_382683433 FIX(0.382683433)
+#define FIX_0_541196100 FIX(0.541196100)
+#define FIX_0_707106781 FIX(0.707106781)
+#define FIX_1_306562965 FIX(1.306562965)
+#endif
+
+
+/* We can gain a little more speed, with a further compromise in accuracy,
+ * by omitting the addition in a descaling shift. This yields an incorrectly
+ * rounded result half the time...
+ */
+
+#ifndef USE_ACCURATE_ROUNDING
+#undef DESCALE
+#define DESCALE(x,n) RIGHT_SHIFT(x, n)
+#endif
+
+
+/* Multiply a DCTELEM variable by an INT32 constant, and immediately
+ * descale to yield a DCTELEM result.
+ */
+
+#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
+
+
+/*
+ * Perform the forward DCT on one block of samples.
+ */
+
+GLOBAL(void)
+jpeg_fdct_ifast (DCTELEM * data)
+{
+ DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ DCTELEM tmp10, tmp11, tmp12, tmp13;
+ DCTELEM z1, z2, z3, z4, z5, z11, z13;
+ DCTELEM *dataptr;
+ int ctr;
+ SHIFT_TEMPS
+
+ /* Pass 1: process rows. */
+
+ dataptr = data;
+ for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+ tmp0 = dataptr[0] + dataptr[7];
+ tmp7 = dataptr[0] - dataptr[7];
+ tmp1 = dataptr[1] + dataptr[6];
+ tmp6 = dataptr[1] - dataptr[6];
+ tmp2 = dataptr[2] + dataptr[5];
+ tmp5 = dataptr[2] - dataptr[5];
+ tmp3 = dataptr[3] + dataptr[4];
+ tmp4 = dataptr[3] - dataptr[4];
+
+ /* Even part */
+
+ tmp10 = tmp0 + tmp3; /* phase 2 */
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ dataptr[0] = tmp10 + tmp11; /* phase 3 */
+ dataptr[4] = tmp10 - tmp11;
+
+ z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
+ dataptr[2] = tmp13 + z1; /* phase 5 */
+ dataptr[6] = tmp13 - z1;
+
+ /* Odd part */
+
+ tmp10 = tmp4 + tmp5; /* phase 2 */
+ tmp11 = tmp5 + tmp6;
+ tmp12 = tmp6 + tmp7;
+
+ /* The rotator is modified from fig 4-8 to avoid extra negations. */
+ z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
+ z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
+ z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
+ z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
+
+ z11 = tmp7 + z3; /* phase 5 */
+ z13 = tmp7 - z3;
+
+ dataptr[5] = z13 + z2; /* phase 6 */
+ dataptr[3] = z13 - z2;
+ dataptr[1] = z11 + z4;
+ dataptr[7] = z11 - z4;
+
+ dataptr += DCTSIZE; /* advance pointer to next row */
+ }
+
+ /* Pass 2: process columns. */
+
+ dataptr = data;
+ for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+ tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
+ tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
+ tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
+ tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
+ tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
+ tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
+ tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
+ tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
+
+ /* Even part */
+
+ tmp10 = tmp0 + tmp3; /* phase 2 */
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
+ dataptr[DCTSIZE*4] = tmp10 - tmp11;
+
+ z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
+ dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
+ dataptr[DCTSIZE*6] = tmp13 - z1;
+
+ /* Odd part */
+
+ tmp10 = tmp4 + tmp5; /* phase 2 */
+ tmp11 = tmp5 + tmp6;
+ tmp12 = tmp6 + tmp7;
+
+ /* The rotator is modified from fig 4-8 to avoid extra negations. */
+ z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
+ z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
+ z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
+ z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
+
+ z11 = tmp7 + z3; /* phase 5 */
+ z13 = tmp7 - z3;
+
+ dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
+ dataptr[DCTSIZE*3] = z13 - z2;
+ dataptr[DCTSIZE*1] = z11 + z4;
+ dataptr[DCTSIZE*7] = z11 - z4;
+
+ dataptr++; /* advance pointer to next column */
+ }
+}
diff --git a/src/libffmpeg/libavcodec/jrevdct.c b/src/libffmpeg/libavcodec/jrevdct.c
new file mode 100644
index 000000000..2ef40f38e
--- /dev/null
+++ b/src/libffmpeg/libavcodec/jrevdct.c
@@ -0,0 +1,1167 @@
+/*
+ * jrevdct.c
+ *
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the basic inverse-DCT transformation subroutine.
+ *
+ * This implementation is based on an algorithm described in
+ * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT
+ * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics,
+ * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991.
+ * The primary algorithm described there uses 11 multiplies and 29 adds.
+ * We use their alternate method with 12 multiplies and 32 adds.
+ * The advantage of this method is that no data path contains more than one
+ * multiplication; this allows a very simple and accurate implementation in
+ * scaled fixed-point arithmetic, with a minimal number of shifts.
+ *
+ * I've made lots of modifications to attempt to take advantage of the
+ * sparse nature of the DCT matrices we're getting. Although the logic
+ * is cumbersome, it's straightforward and the resulting code is much
+ * faster.
+ *
+ * A better way to do this would be to pass in the DCT block as a sparse
+ * matrix, perhaps with the difference cases encoded.
+ */
+#include "common.h"
+#include "dsputil.h"
+
+#define EIGHT_BIT_SAMPLES
+
+#define DCTSIZE 8
+#define DCTSIZE2 64
+
+#define GLOBAL
+
+#define RIGHT_SHIFT(x, n) ((x) >> (n))
+
+typedef DCTELEM DCTBLOCK[DCTSIZE2];
+
+#define CONST_BITS 13
+
+/*
+ * This routine is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+ Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/*
+ * A 2-D IDCT can be done by 1-D IDCT on each row followed by 1-D IDCT
+ * on each column. Direct algorithms are also available, but they are
+ * much more complex and seem not to be any faster when reduced to code.
+ *
+ * The poop on this scaling stuff is as follows:
+ *
+ * Each 1-D IDCT step produces outputs which are a factor of sqrt(N)
+ * larger than the true IDCT outputs. The final outputs are therefore
+ * a factor of N larger than desired; since N=8 this can be cured by
+ * a simple right shift at the end of the algorithm. The advantage of
+ * this arrangement is that we save two multiplications per 1-D IDCT,
+ * because the y0 and y4 inputs need not be divided by sqrt(N).
+ *
+ * We have to do addition and subtraction of the integer inputs, which
+ * is no problem, and multiplication by fractional constants, which is
+ * a problem to do in integer arithmetic. We multiply all the constants
+ * by CONST_SCALE and convert them to integer constants (thus retaining
+ * CONST_BITS bits of precision in the constants). After doing a
+ * multiplication we have to divide the product by CONST_SCALE, with proper
+ * rounding, to produce the correct output. This division can be done
+ * cheaply as a right shift of CONST_BITS bits. We postpone shifting
+ * as long as possible so that partial sums can be added together with
+ * full fractional precision.
+ *
+ * The outputs of the first pass are scaled up by PASS1_BITS bits so that
+ * they are represented to better-than-integral precision. These outputs
+ * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word
+ * with the recommended scaling. (To scale up 12-bit sample data further, an
+ * intermediate int32 array would be needed.)
+ *
+ * To avoid overflow of the 32-bit intermediate results in pass 2, we must
+ * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis
+ * shows that the values given below are the most effective.
+ */
+
+#ifdef EIGHT_BIT_SAMPLES
+#define PASS1_BITS 2
+#else
+#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
+#endif
+
+#define ONE ((INT32) 1)
+
+#define CONST_SCALE (ONE << CONST_BITS)
+
+/* Convert a positive real constant to an integer scaled by CONST_SCALE.
+ * IMPORTANT: if your compiler doesn't do this arithmetic at compile time,
+ * you will pay a significant penalty in run time. In that case, figure
+ * the correct integer constant values and insert them by hand.
+ */
+
+/* Actually FIX is no longer used, we precomputed them all */
+#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5))
+
+/* Descale and correctly round an INT32 value that's scaled by N bits.
+ * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
+ * the fudge factor is correct for either sign of X.
+ */
+
+#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)
+
+/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
+ * For 8-bit samples with the recommended scaling, all the variable
+ * and constant values involved are no more than 16 bits wide, so a
+ * 16x16->32 bit multiply can be used instead of a full 32x32 multiply;
+ * this provides a useful speedup on many machines.
+ * There is no way to specify a 16x16->32 multiply in portable C, but
+ * some C compilers will do the right thing if you provide the correct
+ * combination of casts.
+ * NB: for 12-bit samples, a full 32-bit multiplication will be needed.
+ */
+
+#ifdef EIGHT_BIT_SAMPLES
+#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */
+#define MULTIPLY(var,const) (((INT16) (var)) * ((INT16) (const)))
+#endif
+#ifdef SHORTxLCONST_32 /* known to work with Microsoft C 6.0 */
+#define MULTIPLY(var,const) (((INT16) (var)) * ((INT32) (const)))
+#endif
+#endif
+
+#ifndef MULTIPLY /* default definition */
+#define MULTIPLY(var,const) ((var) * (const))
+#endif
+
+
+/*
+ Unlike our decoder where we approximate the FIXes, we need to use exact
+ones here or successive P-frames will drift too much with Reference frame coding
+*/
+#define FIX_0_211164243 1730
+#define FIX_0_275899380 2260
+#define FIX_0_298631336 2446
+#define FIX_0_390180644 3196
+#define FIX_0_509795579 4176
+#define FIX_0_541196100 4433
+#define FIX_0_601344887 4926
+#define FIX_0_765366865 6270
+#define FIX_0_785694958 6436
+#define FIX_0_899976223 7373
+#define FIX_1_061594337 8697
+#define FIX_1_111140466 9102
+#define FIX_1_175875602 9633
+#define FIX_1_306562965 10703
+#define FIX_1_387039845 11363
+#define FIX_1_451774981 11893
+#define FIX_1_501321110 12299
+#define FIX_1_662939225 13623
+#define FIX_1_847759065 15137
+#define FIX_1_961570560 16069
+#define FIX_2_053119869 16819
+#define FIX_2_172734803 17799
+#define FIX_2_562915447 20995
+#define FIX_3_072711026 25172
+
+/*
+ * Perform the inverse DCT on one block of coefficients.
+ */
+
+void j_rev_dct(DCTBLOCK data)
+{
+ INT32 tmp0, tmp1, tmp2, tmp3;
+ INT32 tmp10, tmp11, tmp12, tmp13;
+ INT32 z1, z2, z3, z4, z5;
+ INT32 d0, d1, d2, d3, d4, d5, d6, d7;
+ register DCTELEM *dataptr;
+ int rowctr;
+
+ /* Pass 1: process rows. */
+ /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
+ /* furthermore, we scale the results by 2**PASS1_BITS. */
+
+ dataptr = data;
+
+ for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) {
+ /* Due to quantization, we will usually find that many of the input
+ * coefficients are zero, especially the AC terms. We can exploit this
+ * by short-circuiting the IDCT calculation for any row in which all
+ * the AC terms are zero. In that case each output is equal to the
+ * DC coefficient (with scale factor as needed).
+ * With typical images and quantization tables, half or more of the
+ * row DCT calculations can be simplified this way.
+ */
+
+ register int *idataptr = (int*)dataptr;
+
+ d0 = dataptr[0];
+ d1 = dataptr[1];
+ d2 = dataptr[2];
+ d3 = dataptr[3];
+ d4 = dataptr[4];
+ d5 = dataptr[5];
+ d6 = dataptr[6];
+ d7 = dataptr[7];
+
+ if ((d1 == 0) && (idataptr[1] | idataptr[2] | idataptr[3]) == 0) {
+ /* AC terms all zero */
+ if (d0) {
+ /* Compute a 32 bit value to assign. */
+ DCTELEM dcval = (DCTELEM) (d0 << PASS1_BITS);
+ register int v = (dcval & 0xffff) | ((dcval << 16) & 0xffff0000);
+
+ idataptr[0] = v;
+ idataptr[1] = v;
+ idataptr[2] = v;
+ idataptr[3] = v;
+ }
+
+ dataptr += DCTSIZE; /* advance pointer to next row */
+ continue;
+ }
+
+ /* Even part: reverse the even part of the forward DCT. */
+ /* The rotator is sqrt(2)*c(-6). */
+{
+ if (d6) {
+ if (d4) {
+ if (d2) {
+ if (d0) {
+ /* d0 != 0, d2 != 0, d4 != 0, d6 != 0 */
+ z1 = MULTIPLY(d2 + d6, FIX_0_541196100);
+ tmp2 = z1 + MULTIPLY(-d6, FIX_1_847759065);
+ tmp3 = z1 + MULTIPLY(d2, FIX_0_765366865);
+
+ tmp0 = (d0 + d4) << CONST_BITS;
+ tmp1 = (d0 - d4) << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+ } else {
+ /* d0 == 0, d2 != 0, d4 != 0, d6 != 0 */
+ z1 = MULTIPLY(d2 + d6, FIX_0_541196100);
+ tmp2 = z1 + MULTIPLY(-d6, FIX_1_847759065);
+ tmp3 = z1 + MULTIPLY(d2, FIX_0_765366865);
+
+ tmp0 = d4 << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp2 - tmp0;
+ tmp12 = -(tmp0 + tmp2);
+ }
+ } else {
+ if (d0) {
+ /* d0 != 0, d2 == 0, d4 != 0, d6 != 0 */
+ tmp2 = MULTIPLY(-d6, FIX_1_306562965);
+ tmp3 = MULTIPLY(d6, FIX_0_541196100);
+
+ tmp0 = (d0 + d4) << CONST_BITS;
+ tmp1 = (d0 - d4) << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+ } else {
+ /* d0 == 0, d2 == 0, d4 != 0, d6 != 0 */
+ tmp2 = MULTIPLY(-d6, FIX_1_306562965);
+ tmp3 = MULTIPLY(d6, FIX_0_541196100);
+
+ tmp0 = d4 << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp2 - tmp0;
+ tmp12 = -(tmp0 + tmp2);
+ }
+ }
+ } else {
+ if (d2) {
+ if (d0) {
+ /* d0 != 0, d2 != 0, d4 == 0, d6 != 0 */
+ z1 = MULTIPLY(d2 + d6, FIX_0_541196100);
+ tmp2 = z1 + MULTIPLY(-d6, FIX_1_847759065);
+ tmp3 = z1 + MULTIPLY(d2, FIX_0_765366865);
+
+ tmp0 = d0 << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp0 + tmp2;
+ tmp12 = tmp0 - tmp2;
+ } else {
+ /* d0 == 0, d2 != 0, d4 == 0, d6 != 0 */
+ z1 = MULTIPLY(d2 + d6, FIX_0_541196100);
+ tmp2 = z1 + MULTIPLY(-d6, FIX_1_847759065);
+ tmp3 = z1 + MULTIPLY(d2, FIX_0_765366865);
+
+ tmp10 = tmp3;
+ tmp13 = -tmp3;
+ tmp11 = tmp2;
+ tmp12 = -tmp2;
+ }
+ } else {
+ if (d0) {
+ /* d0 != 0, d2 == 0, d4 == 0, d6 != 0 */
+ tmp2 = MULTIPLY(-d6, FIX_1_306562965);
+ tmp3 = MULTIPLY(d6, FIX_0_541196100);
+
+ tmp0 = d0 << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp0 + tmp2;
+ tmp12 = tmp0 - tmp2;
+ } else {
+ /* d0 == 0, d2 == 0, d4 == 0, d6 != 0 */
+ tmp2 = MULTIPLY(-d6, FIX_1_306562965);
+ tmp3 = MULTIPLY(d6, FIX_0_541196100);
+
+ tmp10 = tmp3;
+ tmp13 = -tmp3;
+ tmp11 = tmp2;
+ tmp12 = -tmp2;
+ }
+ }
+ }
+ } else {
+ if (d4) {
+ if (d2) {
+ if (d0) {
+ /* d0 != 0, d2 != 0, d4 != 0, d6 == 0 */
+ tmp2 = MULTIPLY(d2, FIX_0_541196100);
+ tmp3 = MULTIPLY(d2, FIX_1_306562965);
+
+ tmp0 = (d0 + d4) << CONST_BITS;
+ tmp1 = (d0 - d4) << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+ } else {
+ /* d0 == 0, d2 != 0, d4 != 0, d6 == 0 */
+ tmp2 = MULTIPLY(d2, FIX_0_541196100);
+ tmp3 = MULTIPLY(d2, FIX_1_306562965);
+
+ tmp0 = d4 << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp2 - tmp0;
+ tmp12 = -(tmp0 + tmp2);
+ }
+ } else {
+ if (d0) {
+ /* d0 != 0, d2 == 0, d4 != 0, d6 == 0 */
+ tmp10 = tmp13 = (d0 + d4) << CONST_BITS;
+ tmp11 = tmp12 = (d0 - d4) << CONST_BITS;
+ } else {
+ /* d0 == 0, d2 == 0, d4 != 0, d6 == 0 */
+ tmp10 = tmp13 = d4 << CONST_BITS;
+ tmp11 = tmp12 = -tmp10;
+ }
+ }
+ } else {
+ if (d2) {
+ if (d0) {
+ /* d0 != 0, d2 != 0, d4 == 0, d6 == 0 */
+ tmp2 = MULTIPLY(d2, FIX_0_541196100);
+ tmp3 = MULTIPLY(d2, FIX_1_306562965);
+
+ tmp0 = d0 << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp0 + tmp2;
+ tmp12 = tmp0 - tmp2;
+ } else {
+ /* d0 == 0, d2 != 0, d4 == 0, d6 == 0 */
+ tmp2 = MULTIPLY(d2, FIX_0_541196100);
+ tmp3 = MULTIPLY(d2, FIX_1_306562965);
+
+ tmp10 = tmp3;
+ tmp13 = -tmp3;
+ tmp11 = tmp2;
+ tmp12 = -tmp2;
+ }
+ } else {
+ if (d0) {
+ /* d0 != 0, d2 == 0, d4 == 0, d6 == 0 */
+ tmp10 = tmp13 = tmp11 = tmp12 = d0 << CONST_BITS;
+ } else {
+ /* d0 == 0, d2 == 0, d4 == 0, d6 == 0 */
+ tmp10 = tmp13 = tmp11 = tmp12 = 0;
+ }
+ }
+ }
+ }
+
+ /* Odd part per figure 8; the matrix is unitary and hence its
+ * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
+ */
+
+ if (d7) {
+ if (d5) {
+ if (d3) {
+ if (d1) {
+ /* d1 != 0, d3 != 0, d5 != 0, d7 != 0 */
+ z1 = d7 + d1;
+ z2 = d5 + d3;
+ z3 = d7 + d3;
+ z4 = d5 + d1;
+ z5 = MULTIPLY(z3 + z4, FIX_1_175875602);
+
+ tmp0 = MULTIPLY(d7, FIX_0_298631336);
+ tmp1 = MULTIPLY(d5, FIX_2_053119869);
+ tmp2 = MULTIPLY(d3, FIX_3_072711026);
+ tmp3 = MULTIPLY(d1, FIX_1_501321110);
+ z1 = MULTIPLY(-z1, FIX_0_899976223);
+ z2 = MULTIPLY(-z2, FIX_2_562915447);
+ z3 = MULTIPLY(-z3, FIX_1_961570560);
+ z4 = MULTIPLY(-z4, FIX_0_390180644);
+
+ z3 += z5;
+ z4 += z5;
+
+ tmp0 += z1 + z3;
+ tmp1 += z2 + z4;
+ tmp2 += z2 + z3;
+ tmp3 += z1 + z4;
+ } else {
+ /* d1 == 0, d3 != 0, d5 != 0, d7 != 0 */
+ z2 = d5 + d3;
+ z3 = d7 + d3;
+ z5 = MULTIPLY(z3 + d5, FIX_1_175875602);
+
+ tmp0 = MULTIPLY(d7, FIX_0_298631336);
+ tmp1 = MULTIPLY(d5, FIX_2_053119869);
+ tmp2 = MULTIPLY(d3, FIX_3_072711026);
+ z1 = MULTIPLY(-d7, FIX_0_899976223);
+ z2 = MULTIPLY(-z2, FIX_2_562915447);
+ z3 = MULTIPLY(-z3, FIX_1_961570560);
+ z4 = MULTIPLY(-d5, FIX_0_390180644);
+
+ z3 += z5;
+ z4 += z5;
+
+ tmp0 += z1 + z3;
+ tmp1 += z2 + z4;
+ tmp2 += z2 + z3;
+ tmp3 = z1 + z4;
+ }
+ } else {
+ if (d1) {
+ /* d1 != 0, d3 == 0, d5 != 0, d7 != 0 */
+ z1 = d7 + d1;
+ z4 = d5 + d1;
+ z5 = MULTIPLY(d7 + z4, FIX_1_175875602);
+
+ tmp0 = MULTIPLY(d7, FIX_0_298631336);
+ tmp1 = MULTIPLY(d5, FIX_2_053119869);
+ tmp3 = MULTIPLY(d1, FIX_1_501321110);
+ z1 = MULTIPLY(-z1, FIX_0_899976223);
+ z2 = MULTIPLY(-d5, FIX_2_562915447);
+ z3 = MULTIPLY(-d7, FIX_1_961570560);
+ z4 = MULTIPLY(-z4, FIX_0_390180644);
+
+ z3 += z5;
+ z4 += z5;
+
+ tmp0 += z1 + z3;
+ tmp1 += z2 + z4;
+ tmp2 = z2 + z3;
+ tmp3 += z1 + z4;
+ } else {
+ /* d1 == 0, d3 == 0, d5 != 0, d7 != 0 */
+ tmp0 = MULTIPLY(-d7, FIX_0_601344887);
+ z1 = MULTIPLY(-d7, FIX_0_899976223);
+ z3 = MULTIPLY(-d7, FIX_1_961570560);
+ tmp1 = MULTIPLY(-d5, FIX_0_509795579);
+ z2 = MULTIPLY(-d5, FIX_2_562915447);
+ z4 = MULTIPLY(-d5, FIX_0_390180644);
+ z5 = MULTIPLY(d5 + d7, FIX_1_175875602);
+
+ z3 += z5;
+ z4 += z5;
+
+ tmp0 += z3;
+ tmp1 += z4;
+ tmp2 = z2 + z3;
+ tmp3 = z1 + z4;
+ }
+ }
+ } else {
+ if (d3) {
+ if (d1) {
+ /* d1 != 0, d3 != 0, d5 == 0, d7 != 0 */
+ z1 = d7 + d1;
+ z3 = d7 + d3;
+ z5 = MULTIPLY(z3 + d1, FIX_1_175875602);
+
+ tmp0 = MULTIPLY(d7, FIX_0_298631336);
+ tmp2 = MULTIPLY(d3, FIX_3_072711026);
+ tmp3 = MULTIPLY(d1, FIX_1_501321110);
+ z1 = MULTIPLY(-z1, FIX_0_899976223);
+ z2 = MULTIPLY(-d3, FIX_2_562915447);
+ z3 = MULTIPLY(-z3, FIX_1_961570560);
+ z4 = MULTIPLY(-d1, FIX_0_390180644);
+
+ z3 += z5;
+ z4 += z5;
+
+ tmp0 += z1 + z3;
+ tmp1 = z2 + z4;
+ tmp2 += z2 + z3;
+ tmp3 += z1 + z4;
+ } else {
+ /* d1 == 0, d3 != 0, d5 == 0, d7 != 0 */
+ z3 = d7 + d3;
+
+ tmp0 = MULTIPLY(-d7, FIX_0_601344887);
+ z1 = MULTIPLY(-d7, FIX_0_899976223);
+ tmp2 = MULTIPLY(d3, FIX_0_509795579);
+ z2 = MULTIPLY(-d3, FIX_2_562915447);
+ z5 = MULTIPLY(z3, FIX_1_175875602);
+ z3 = MULTIPLY(-z3, FIX_0_785694958);
+
+ tmp0 += z3;
+ tmp1 = z2 + z5;
+ tmp2 += z3;
+ tmp3 = z1 + z5;
+ }
+ } else {
+ if (d1) {
+ /* d1 != 0, d3 == 0, d5 == 0, d7 != 0 */
+ z1 = d7 + d1;
+ z5 = MULTIPLY(z1, FIX_1_175875602);
+
+ z1 = MULTIPLY(z1, FIX_0_275899380);
+ z3 = MULTIPLY(-d7, FIX_1_961570560);
+ tmp0 = MULTIPLY(-d7, FIX_1_662939225);
+ z4 = MULTIPLY(-d1, FIX_0_390180644);
+ tmp3 = MULTIPLY(d1, FIX_1_111140466);
+
+ tmp0 += z1;
+ tmp1 = z4 + z5;
+ tmp2 = z3 + z5;
+ tmp3 += z1;
+ } else {
+ /* d1 == 0, d3 == 0, d5 == 0, d7 != 0 */
+ tmp0 = MULTIPLY(-d7, FIX_1_387039845);
+ tmp1 = MULTIPLY(d7, FIX_1_175875602);
+ tmp2 = MULTIPLY(-d7, FIX_0_785694958);
+ tmp3 = MULTIPLY(d7, FIX_0_275899380);
+ }
+ }
+ }
+ } else {
+ if (d5) {
+ if (d3) {
+ if (d1) {
+ /* d1 != 0, d3 != 0, d5 != 0, d7 == 0 */
+ z2 = d5 + d3;
+ z4 = d5 + d1;
+ z5 = MULTIPLY(d3 + z4, FIX_1_175875602);
+
+ tmp1 = MULTIPLY(d5, FIX_2_053119869);
+ tmp2 = MULTIPLY(d3, FIX_3_072711026);
+ tmp3 = MULTIPLY(d1, FIX_1_501321110);
+ z1 = MULTIPLY(-d1, FIX_0_899976223);
+ z2 = MULTIPLY(-z2, FIX_2_562915447);
+ z3 = MULTIPLY(-d3, FIX_1_961570560);
+ z4 = MULTIPLY(-z4, FIX_0_390180644);
+
+ z3 += z5;
+ z4 += z5;
+
+ tmp0 = z1 + z3;
+ tmp1 += z2 + z4;
+ tmp2 += z2 + z3;
+ tmp3 += z1 + z4;
+ } else {
+ /* d1 == 0, d3 != 0, d5 != 0, d7 == 0 */
+ z2 = d5 + d3;
+
+ z5 = MULTIPLY(z2, FIX_1_175875602);
+ tmp1 = MULTIPLY(d5, FIX_1_662939225);
+ z4 = MULTIPLY(-d5, FIX_0_390180644);
+ z2 = MULTIPLY(-z2, FIX_1_387039845);
+ tmp2 = MULTIPLY(d3, FIX_1_111140466);
+ z3 = MULTIPLY(-d3, FIX_1_961570560);
+
+ tmp0 = z3 + z5;
+ tmp1 += z2;
+ tmp2 += z2;
+ tmp3 = z4 + z5;
+ }
+ } else {
+ if (d1) {
+ /* d1 != 0, d3 == 0, d5 != 0, d7 == 0 */
+ z4 = d5 + d1;
+
+ z5 = MULTIPLY(z4, FIX_1_175875602);
+ z1 = MULTIPLY(-d1, FIX_0_899976223);
+ tmp3 = MULTIPLY(d1, FIX_0_601344887);
+ tmp1 = MULTIPLY(-d5, FIX_0_509795579);
+ z2 = MULTIPLY(-d5, FIX_2_562915447);
+ z4 = MULTIPLY(z4, FIX_0_785694958);
+
+ tmp0 = z1 + z5;
+ tmp1 += z4;
+ tmp2 = z2 + z5;
+ tmp3 += z4;
+ } else {
+ /* d1 == 0, d3 == 0, d5 != 0, d7 == 0 */
+ tmp0 = MULTIPLY(d5, FIX_1_175875602);
+ tmp1 = MULTIPLY(d5, FIX_0_275899380);
+ tmp2 = MULTIPLY(-d5, FIX_1_387039845);
+ tmp3 = MULTIPLY(d5, FIX_0_785694958);
+ }
+ }
+ } else {
+ if (d3) {
+ if (d1) {
+ /* d1 != 0, d3 != 0, d5 == 0, d7 == 0 */
+ z5 = d1 + d3;
+ tmp3 = MULTIPLY(d1, FIX_0_211164243);
+ tmp2 = MULTIPLY(-d3, FIX_1_451774981);
+ z1 = MULTIPLY(d1, FIX_1_061594337);
+ z2 = MULTIPLY(-d3, FIX_2_172734803);
+ z4 = MULTIPLY(z5, FIX_0_785694958);
+ z5 = MULTIPLY(z5, FIX_1_175875602);
+
+ tmp0 = z1 - z4;
+ tmp1 = z2 + z4;
+ tmp2 += z5;
+ tmp3 += z5;
+ } else {
+ /* d1 == 0, d3 != 0, d5 == 0, d7 == 0 */
+ tmp0 = MULTIPLY(-d3, FIX_0_785694958);
+ tmp1 = MULTIPLY(-d3, FIX_1_387039845);
+ tmp2 = MULTIPLY(-d3, FIX_0_275899380);
+ tmp3 = MULTIPLY(d3, FIX_1_175875602);
+ }
+ } else {
+ if (d1) {
+ /* d1 != 0, d3 == 0, d5 == 0, d7 == 0 */
+ tmp0 = MULTIPLY(d1, FIX_0_275899380);
+ tmp1 = MULTIPLY(d1, FIX_0_785694958);
+ tmp2 = MULTIPLY(d1, FIX_1_175875602);
+ tmp3 = MULTIPLY(d1, FIX_1_387039845);
+ } else {
+ /* d1 == 0, d3 == 0, d5 == 0, d7 == 0 */
+ tmp0 = tmp1 = tmp2 = tmp3 = 0;
+ }
+ }
+ }
+ }
+}
+ /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
+
+ dataptr[0] = (DCTELEM) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
+ dataptr[7] = (DCTELEM) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
+ dataptr[1] = (DCTELEM) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
+ dataptr[6] = (DCTELEM) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
+ dataptr[2] = (DCTELEM) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
+ dataptr[5] = (DCTELEM) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
+ dataptr[3] = (DCTELEM) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
+ dataptr[4] = (DCTELEM) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
+
+ dataptr += DCTSIZE; /* advance pointer to next row */
+ }
+
+ /* Pass 2: process columns. */
+ /* Note that we must descale the results by a factor of 8 == 2**3, */
+ /* and also undo the PASS1_BITS scaling. */
+
+ dataptr = data;
+ for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) {
+ /* Columns of zeroes can be exploited in the same way as we did with rows.
+ * However, the row calculation has created many nonzero AC terms, so the
+ * simplification applies less often (typically 5% to 10% of the time).
+ * On machines with very fast multiplication, it's possible that the
+ * test takes more time than it's worth. In that case this section
+ * may be commented out.
+ */
+
+ d0 = dataptr[DCTSIZE*0];
+ d1 = dataptr[DCTSIZE*1];
+ d2 = dataptr[DCTSIZE*2];
+ d3 = dataptr[DCTSIZE*3];
+ d4 = dataptr[DCTSIZE*4];
+ d5 = dataptr[DCTSIZE*5];
+ d6 = dataptr[DCTSIZE*6];
+ d7 = dataptr[DCTSIZE*7];
+
+ /* Even part: reverse the even part of the forward DCT. */
+ /* The rotator is sqrt(2)*c(-6). */
+ if (d6) {
+ if (d4) {
+ if (d2) {
+ if (d0) {
+ /* d0 != 0, d2 != 0, d4 != 0, d6 != 0 */
+ z1 = MULTIPLY(d2 + d6, FIX_0_541196100);
+ tmp2 = z1 + MULTIPLY(-d6, FIX_1_847759065);
+ tmp3 = z1 + MULTIPLY(d2, FIX_0_765366865);
+
+ tmp0 = (d0 + d4) << CONST_BITS;
+ tmp1 = (d0 - d4) << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+ } else {
+ /* d0 == 0, d2 != 0, d4 != 0, d6 != 0 */
+ z1 = MULTIPLY(d2 + d6, FIX_0_541196100);
+ tmp2 = z1 + MULTIPLY(-d6, FIX_1_847759065);
+ tmp3 = z1 + MULTIPLY(d2, FIX_0_765366865);
+
+ tmp0 = d4 << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp2 - tmp0;
+ tmp12 = -(tmp0 + tmp2);
+ }
+ } else {
+ if (d0) {
+ /* d0 != 0, d2 == 0, d4 != 0, d6 != 0 */
+ tmp2 = MULTIPLY(-d6, FIX_1_306562965);
+ tmp3 = MULTIPLY(d6, FIX_0_541196100);
+
+ tmp0 = (d0 + d4) << CONST_BITS;
+ tmp1 = (d0 - d4) << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+ } else {
+ /* d0 == 0, d2 == 0, d4 != 0, d6 != 0 */
+ tmp2 = MULTIPLY(-d6, FIX_1_306562965);
+ tmp3 = MULTIPLY(d6, FIX_0_541196100);
+
+ tmp0 = d4 << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp2 - tmp0;
+ tmp12 = -(tmp0 + tmp2);
+ }
+ }
+ } else {
+ if (d2) {
+ if (d0) {
+ /* d0 != 0, d2 != 0, d4 == 0, d6 != 0 */
+ z1 = MULTIPLY(d2 + d6, FIX_0_541196100);
+ tmp2 = z1 + MULTIPLY(-d6, FIX_1_847759065);
+ tmp3 = z1 + MULTIPLY(d2, FIX_0_765366865);
+
+ tmp0 = d0 << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp0 + tmp2;
+ tmp12 = tmp0 - tmp2;
+ } else {
+ /* d0 == 0, d2 != 0, d4 == 0, d6 != 0 */
+ z1 = MULTIPLY(d2 + d6, FIX_0_541196100);
+ tmp2 = z1 + MULTIPLY(-d6, FIX_1_847759065);
+ tmp3 = z1 + MULTIPLY(d2, FIX_0_765366865);
+
+ tmp10 = tmp3;
+ tmp13 = -tmp3;
+ tmp11 = tmp2;
+ tmp12 = -tmp2;
+ }
+ } else {
+ if (d0) {
+ /* d0 != 0, d2 == 0, d4 == 0, d6 != 0 */
+ tmp2 = MULTIPLY(-d6, FIX_1_306562965);
+ tmp3 = MULTIPLY(d6, FIX_0_541196100);
+
+ tmp0 = d0 << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp0 + tmp2;
+ tmp12 = tmp0 - tmp2;
+ } else {
+ /* d0 == 0, d2 == 0, d4 == 0, d6 != 0 */
+ tmp2 = MULTIPLY(-d6, FIX_1_306562965);
+ tmp3 = MULTIPLY(d6, FIX_0_541196100);
+
+ tmp10 = tmp3;
+ tmp13 = -tmp3;
+ tmp11 = tmp2;
+ tmp12 = -tmp2;
+ }
+ }
+ }
+ } else {
+ if (d4) {
+ if (d2) {
+ if (d0) {
+ /* d0 != 0, d2 != 0, d4 != 0, d6 == 0 */
+ tmp2 = MULTIPLY(d2, FIX_0_541196100);
+ tmp3 = MULTIPLY(d2, FIX_1_306562965);
+
+ tmp0 = (d0 + d4) << CONST_BITS;
+ tmp1 = (d0 - d4) << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+ } else {
+ /* d0 == 0, d2 != 0, d4 != 0, d6 == 0 */
+ tmp2 = MULTIPLY(d2, FIX_0_541196100);
+ tmp3 = MULTIPLY(d2, FIX_1_306562965);
+
+ tmp0 = d4 << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp2 - tmp0;
+ tmp12 = -(tmp0 + tmp2);
+ }
+ } else {
+ if (d0) {
+ /* d0 != 0, d2 == 0, d4 != 0, d6 == 0 */
+ tmp10 = tmp13 = (d0 + d4) << CONST_BITS;
+ tmp11 = tmp12 = (d0 - d4) << CONST_BITS;
+ } else {
+ /* d0 == 0, d2 == 0, d4 != 0, d6 == 0 */
+ tmp10 = tmp13 = d4 << CONST_BITS;
+ tmp11 = tmp12 = -tmp10;
+ }
+ }
+ } else {
+ if (d2) {
+ if (d0) {
+ /* d0 != 0, d2 != 0, d4 == 0, d6 == 0 */
+ tmp2 = MULTIPLY(d2, FIX_0_541196100);
+ tmp3 = MULTIPLY(d2, FIX_1_306562965);
+
+ tmp0 = d0 << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp0 + tmp2;
+ tmp12 = tmp0 - tmp2;
+ } else {
+ /* d0 == 0, d2 != 0, d4 == 0, d6 == 0 */
+ tmp2 = MULTIPLY(d2, FIX_0_541196100);
+ tmp3 = MULTIPLY(d2, FIX_1_306562965);
+
+ tmp10 = tmp3;
+ tmp13 = -tmp3;
+ tmp11 = tmp2;
+ tmp12 = -tmp2;
+ }
+ } else {
+ if (d0) {
+ /* d0 != 0, d2 == 0, d4 == 0, d6 == 0 */
+ tmp10 = tmp13 = tmp11 = tmp12 = d0 << CONST_BITS;
+ } else {
+ /* d0 == 0, d2 == 0, d4 == 0, d6 == 0 */
+ tmp10 = tmp13 = tmp11 = tmp12 = 0;
+ }
+ }
+ }
+ }
+
+ /* Odd part per figure 8; the matrix is unitary and hence its
+ * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
+ */
+ if (d7) {
+ if (d5) {
+ if (d3) {
+ if (d1) {
+ /* d1 != 0, d3 != 0, d5 != 0, d7 != 0 */
+ z1 = d7 + d1;
+ z2 = d5 + d3;
+ z3 = d7 + d3;
+ z4 = d5 + d1;
+ z5 = MULTIPLY(z3 + z4, FIX_1_175875602);
+
+ tmp0 = MULTIPLY(d7, FIX_0_298631336);
+ tmp1 = MULTIPLY(d5, FIX_2_053119869);
+ tmp2 = MULTIPLY(d3, FIX_3_072711026);
+ tmp3 = MULTIPLY(d1, FIX_1_501321110);
+ z1 = MULTIPLY(-z1, FIX_0_899976223);
+ z2 = MULTIPLY(-z2, FIX_2_562915447);
+ z3 = MULTIPLY(-z3, FIX_1_961570560);
+ z4 = MULTIPLY(-z4, FIX_0_390180644);
+
+ z3 += z5;
+ z4 += z5;
+
+ tmp0 += z1 + z3;
+ tmp1 += z2 + z4;
+ tmp2 += z2 + z3;
+ tmp3 += z1 + z4;
+ } else {
+ /* d1 == 0, d3 != 0, d5 != 0, d7 != 0 */
+ z1 = d7;
+ z2 = d5 + d3;
+ z3 = d7 + d3;
+ z5 = MULTIPLY(z3 + d5, FIX_1_175875602);
+
+ tmp0 = MULTIPLY(d7, FIX_0_298631336);
+ tmp1 = MULTIPLY(d5, FIX_2_053119869);
+ tmp2 = MULTIPLY(d3, FIX_3_072711026);
+ z1 = MULTIPLY(-d7, FIX_0_899976223);
+ z2 = MULTIPLY(-z2, FIX_2_562915447);
+ z3 = MULTIPLY(-z3, FIX_1_961570560);
+ z4 = MULTIPLY(-d5, FIX_0_390180644);
+
+ z3 += z5;
+ z4 += z5;
+
+ tmp0 += z1 + z3;
+ tmp1 += z2 + z4;
+ tmp2 += z2 + z3;
+ tmp3 = z1 + z4;
+ }
+ } else {
+ if (d1) {
+ /* d1 != 0, d3 == 0, d5 != 0, d7 != 0 */
+ z1 = d7 + d1;
+ z2 = d5;
+ z3 = d7;
+ z4 = d5 + d1;
+ z5 = MULTIPLY(z3 + z4, FIX_1_175875602);
+
+ tmp0 = MULTIPLY(d7, FIX_0_298631336);
+ tmp1 = MULTIPLY(d5, FIX_2_053119869);
+ tmp3 = MULTIPLY(d1, FIX_1_501321110);
+ z1 = MULTIPLY(-z1, FIX_0_899976223);
+ z2 = MULTIPLY(-d5, FIX_2_562915447);
+ z3 = MULTIPLY(-d7, FIX_1_961570560);
+ z4 = MULTIPLY(-z4, FIX_0_390180644);
+
+ z3 += z5;
+ z4 += z5;
+
+ tmp0 += z1 + z3;
+ tmp1 += z2 + z4;
+ tmp2 = z2 + z3;
+ tmp3 += z1 + z4;
+ } else {
+ /* d1 == 0, d3 == 0, d5 != 0, d7 != 0 */
+ tmp0 = MULTIPLY(-d7, FIX_0_601344887);
+ z1 = MULTIPLY(-d7, FIX_0_899976223);
+ z3 = MULTIPLY(-d7, FIX_1_961570560);
+ tmp1 = MULTIPLY(-d5, FIX_0_509795579);
+ z2 = MULTIPLY(-d5, FIX_2_562915447);
+ z4 = MULTIPLY(-d5, FIX_0_390180644);
+ z5 = MULTIPLY(d5 + d7, FIX_1_175875602);
+
+ z3 += z5;
+ z4 += z5;
+
+ tmp0 += z3;
+ tmp1 += z4;
+ tmp2 = z2 + z3;
+ tmp3 = z1 + z4;
+ }
+ }
+ } else {
+ if (d3) {
+ if (d1) {
+ /* d1 != 0, d3 != 0, d5 == 0, d7 != 0 */
+ z1 = d7 + d1;
+ z3 = d7 + d3;
+ z5 = MULTIPLY(z3 + d1, FIX_1_175875602);
+
+ tmp0 = MULTIPLY(d7, FIX_0_298631336);
+ tmp2 = MULTIPLY(d3, FIX_3_072711026);
+ tmp3 = MULTIPLY(d1, FIX_1_501321110);
+ z1 = MULTIPLY(-z1, FIX_0_899976223);
+ z2 = MULTIPLY(-d3, FIX_2_562915447);
+ z3 = MULTIPLY(-z3, FIX_1_961570560);
+ z4 = MULTIPLY(-d1, FIX_0_390180644);
+
+ z3 += z5;
+ z4 += z5;
+
+ tmp0 += z1 + z3;
+ tmp1 = z2 + z4;
+ tmp2 += z2 + z3;
+ tmp3 += z1 + z4;
+ } else {
+ /* d1 == 0, d3 != 0, d5 == 0, d7 != 0 */
+ z3 = d7 + d3;
+
+ tmp0 = MULTIPLY(-d7, FIX_0_601344887);
+ z1 = MULTIPLY(-d7, FIX_0_899976223);
+ tmp2 = MULTIPLY(d3, FIX_0_509795579);
+ z2 = MULTIPLY(-d3, FIX_2_562915447);
+ z5 = MULTIPLY(z3, FIX_1_175875602);
+ z3 = MULTIPLY(-z3, FIX_0_785694958);
+
+ tmp0 += z3;
+ tmp1 = z2 + z5;
+ tmp2 += z3;
+ tmp3 = z1 + z5;
+ }
+ } else {
+ if (d1) {
+ /* d1 != 0, d3 == 0, d5 == 0, d7 != 0 */
+ z1 = d7 + d1;
+ z5 = MULTIPLY(z1, FIX_1_175875602);
+
+ z1 = MULTIPLY(z1, FIX_0_275899380);
+ z3 = MULTIPLY(-d7, FIX_1_961570560);
+ tmp0 = MULTIPLY(-d7, FIX_1_662939225);
+ z4 = MULTIPLY(-d1, FIX_0_390180644);
+ tmp3 = MULTIPLY(d1, FIX_1_111140466);
+
+ tmp0 += z1;
+ tmp1 = z4 + z5;
+ tmp2 = z3 + z5;
+ tmp3 += z1;
+ } else {
+ /* d1 == 0, d3 == 0, d5 == 0, d7 != 0 */
+ tmp0 = MULTIPLY(-d7, FIX_1_387039845);
+ tmp1 = MULTIPLY(d7, FIX_1_175875602);
+ tmp2 = MULTIPLY(-d7, FIX_0_785694958);
+ tmp3 = MULTIPLY(d7, FIX_0_275899380);
+ }
+ }
+ }
+ } else {
+ if (d5) {
+ if (d3) {
+ if (d1) {
+ /* d1 != 0, d3 != 0, d5 != 0, d7 == 0 */
+ z2 = d5 + d3;
+ z4 = d5 + d1;
+ z5 = MULTIPLY(d3 + z4, FIX_1_175875602);
+
+ tmp1 = MULTIPLY(d5, FIX_2_053119869);
+ tmp2 = MULTIPLY(d3, FIX_3_072711026);
+ tmp3 = MULTIPLY(d1, FIX_1_501321110);
+ z1 = MULTIPLY(-d1, FIX_0_899976223);
+ z2 = MULTIPLY(-z2, FIX_2_562915447);
+ z3 = MULTIPLY(-d3, FIX_1_961570560);
+ z4 = MULTIPLY(-z4, FIX_0_390180644);
+
+ z3 += z5;
+ z4 += z5;
+
+ tmp0 = z1 + z3;
+ tmp1 += z2 + z4;
+ tmp2 += z2 + z3;
+ tmp3 += z1 + z4;
+ } else {
+ /* d1 == 0, d3 != 0, d5 != 0, d7 == 0 */
+ z2 = d5 + d3;
+
+ z5 = MULTIPLY(z2, FIX_1_175875602);
+ tmp1 = MULTIPLY(d5, FIX_1_662939225);
+ z4 = MULTIPLY(-d5, FIX_0_390180644);
+ z2 = MULTIPLY(-z2, FIX_1_387039845);
+ tmp2 = MULTIPLY(d3, FIX_1_111140466);
+ z3 = MULTIPLY(-d3, FIX_1_961570560);
+
+ tmp0 = z3 + z5;
+ tmp1 += z2;
+ tmp2 += z2;
+ tmp3 = z4 + z5;
+ }
+ } else {
+ if (d1) {
+ /* d1 != 0, d3 == 0, d5 != 0, d7 == 0 */
+ z4 = d5 + d1;
+
+ z5 = MULTIPLY(z4, FIX_1_175875602);
+ z1 = MULTIPLY(-d1, FIX_0_899976223);
+ tmp3 = MULTIPLY(d1, FIX_0_601344887);
+ tmp1 = MULTIPLY(-d5, FIX_0_509795579);
+ z2 = MULTIPLY(-d5, FIX_2_562915447);
+ z4 = MULTIPLY(z4, FIX_0_785694958);
+
+ tmp0 = z1 + z5;
+ tmp1 += z4;
+ tmp2 = z2 + z5;
+ tmp3 += z4;
+ } else {
+ /* d1 == 0, d3 == 0, d5 != 0, d7 == 0 */
+ tmp0 = MULTIPLY(d5, FIX_1_175875602);
+ tmp1 = MULTIPLY(d5, FIX_0_275899380);
+ tmp2 = MULTIPLY(-d5, FIX_1_387039845);
+ tmp3 = MULTIPLY(d5, FIX_0_785694958);
+ }
+ }
+ } else {
+ if (d3) {
+ if (d1) {
+ /* d1 != 0, d3 != 0, d5 == 0, d7 == 0 */
+ z5 = d1 + d3;
+ tmp3 = MULTIPLY(d1, FIX_0_211164243);
+ tmp2 = MULTIPLY(-d3, FIX_1_451774981);
+ z1 = MULTIPLY(d1, FIX_1_061594337);
+ z2 = MULTIPLY(-d3, FIX_2_172734803);
+ z4 = MULTIPLY(z5, FIX_0_785694958);
+ z5 = MULTIPLY(z5, FIX_1_175875602);
+
+ tmp0 = z1 - z4;
+ tmp1 = z2 + z4;
+ tmp2 += z5;
+ tmp3 += z5;
+ } else {
+ /* d1 == 0, d3 != 0, d5 == 0, d7 == 0 */
+ tmp0 = MULTIPLY(-d3, FIX_0_785694958);
+ tmp1 = MULTIPLY(-d3, FIX_1_387039845);
+ tmp2 = MULTIPLY(-d3, FIX_0_275899380);
+ tmp3 = MULTIPLY(d3, FIX_1_175875602);
+ }
+ } else {
+ if (d1) {
+ /* d1 != 0, d3 == 0, d5 == 0, d7 == 0 */
+ tmp0 = MULTIPLY(d1, FIX_0_275899380);
+ tmp1 = MULTIPLY(d1, FIX_0_785694958);
+ tmp2 = MULTIPLY(d1, FIX_1_175875602);
+ tmp3 = MULTIPLY(d1, FIX_1_387039845);
+ } else {
+ /* d1 == 0, d3 == 0, d5 == 0, d7 == 0 */
+ tmp0 = tmp1 = tmp2 = tmp3 = 0;
+ }
+ }
+ }
+ }
+
+ /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
+
+ dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp3,
+ CONST_BITS+PASS1_BITS+3);
+ dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp10 - tmp3,
+ CONST_BITS+PASS1_BITS+3);
+ dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp11 + tmp2,
+ CONST_BITS+PASS1_BITS+3);
+ dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(tmp11 - tmp2,
+ CONST_BITS+PASS1_BITS+3);
+ dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(tmp12 + tmp1,
+ CONST_BITS+PASS1_BITS+3);
+ dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp12 - tmp1,
+ CONST_BITS+PASS1_BITS+3);
+ dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp13 + tmp0,
+ CONST_BITS+PASS1_BITS+3);
+ dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp13 - tmp0,
+ CONST_BITS+PASS1_BITS+3);
+
+ dataptr++; /* advance pointer to next column */
+ }
+}
+
+
diff --git a/src/libffmpeg/libavcodec/mjpeg.c b/src/libffmpeg/libavcodec/mjpeg.c
new file mode 100644
index 000000000..e119df66f
--- /dev/null
+++ b/src/libffmpeg/libavcodec/mjpeg.c
@@ -0,0 +1,943 @@
+/*
+ * MJPEG encoder and decoder
+ * Copyright (c) 2000, 2001 Gerard Lantau.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include "avcodec.h"
+#include "dsputil.h"
+#include "mpegvideo.h"
+
+typedef struct MJpegContext {
+ UINT8 huff_size_dc_luminance[12];
+ UINT16 huff_code_dc_luminance[12];
+ UINT8 huff_size_dc_chrominance[12];
+ UINT16 huff_code_dc_chrominance[12];
+
+ UINT8 huff_size_ac_luminance[256];
+ UINT16 huff_code_ac_luminance[256];
+ UINT8 huff_size_ac_chrominance[256];
+ UINT16 huff_code_ac_chrominance[256];
+} MJpegContext;
+
+#define SOF0 0xc0
+#define SOI 0xd8
+#define EOI 0xd9
+#define DQT 0xdb
+#define DHT 0xc4
+#define SOS 0xda
+
+#if 0
+/* These are the sample quantization tables given in JPEG spec section K.1.
+ * The spec says that the values given produce "good" quality, and
+ * when divided by 2, "very good" quality.
+ */
+static const unsigned char std_luminance_quant_tbl[64] = {
+ 16, 11, 10, 16, 24, 40, 51, 61,
+ 12, 12, 14, 19, 26, 58, 60, 55,
+ 14, 13, 16, 24, 40, 57, 69, 56,
+ 14, 17, 22, 29, 51, 87, 80, 62,
+ 18, 22, 37, 56, 68, 109, 103, 77,
+ 24, 35, 55, 64, 81, 104, 113, 92,
+ 49, 64, 78, 87, 103, 121, 120, 101,
+ 72, 92, 95, 98, 112, 100, 103, 99
+};
+static const unsigned char std_chrominance_quant_tbl[64] = {
+ 17, 18, 24, 47, 99, 99, 99, 99,
+ 18, 21, 26, 66, 99, 99, 99, 99,
+ 24, 26, 56, 99, 99, 99, 99, 99,
+ 47, 66, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99
+};
+#endif
+
+/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
+/* IMPORTANT: these are only valid for 8-bit data precision! */
+static const UINT8 bits_dc_luminance[17] =
+{ /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
+static const UINT8 val_dc_luminance[] =
+{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
+
+static const UINT8 bits_dc_chrominance[17] =
+{ /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
+static const UINT8 val_dc_chrominance[] =
+{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
+
+static const UINT8 bits_ac_luminance[17] =
+{ /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
+static const UINT8 val_ac_luminance[] =
+{ 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+ 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+ 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
+ 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
+ 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
+ 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+ 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+ 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+ 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+ 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+ 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
+ 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
+ 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
+ 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
+ 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa
+};
+
+static const UINT8 bits_ac_chrominance[17] =
+{ /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
+
+static const UINT8 val_ac_chrominance[] =
+{ 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
+ 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
+ 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
+ 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
+ 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
+ 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
+ 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
+ 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+ 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+ 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
+ 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
+ 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
+ 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
+ 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
+ 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
+ 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa
+};
+
+
+/* isn't this function nicer than the one in the libjpeg ? */
+static void build_huffman_codes(UINT8 *huff_size, UINT16 *huff_code,
+ const UINT8 *bits_table, const UINT8 *val_table)
+{
+ int i, j, k,nb, code, sym;
+
+ code = 0;
+ k = 0;
+ for(i=1;i<=16;i++) {
+ nb = bits_table[i];
+ for(j=0;j<nb;j++) {
+ sym = val_table[k++];
+ huff_size[sym] = i;
+ huff_code[sym] = code;
+ code++;
+ }
+ code <<= 1;
+ }
+}
+
+int mjpeg_init(MpegEncContext *s)
+{
+ MJpegContext *m;
+
+ m = malloc(sizeof(MJpegContext));
+ if (!m)
+ return -1;
+
+ /* build all the huffman tables */
+ build_huffman_codes(m->huff_size_dc_luminance,
+ m->huff_code_dc_luminance,
+ bits_dc_luminance,
+ val_dc_luminance);
+ build_huffman_codes(m->huff_size_dc_chrominance,
+ m->huff_code_dc_chrominance,
+ bits_dc_chrominance,
+ val_dc_chrominance);
+ build_huffman_codes(m->huff_size_ac_luminance,
+ m->huff_code_ac_luminance,
+ bits_ac_luminance,
+ val_ac_luminance);
+ build_huffman_codes(m->huff_size_ac_chrominance,
+ m->huff_code_ac_chrominance,
+ bits_ac_chrominance,
+ val_ac_chrominance);
+
+ s->mjpeg_ctx = m;
+ return 0;
+}
+
+void mjpeg_close(MpegEncContext *s)
+{
+ free(s->mjpeg_ctx);
+}
+
+static inline void put_marker(PutBitContext *p, int code)
+{
+ put_bits(p, 8, 0xff);
+ put_bits(p, 8, code);
+}
+
+/* table_class: 0 = DC coef, 1 = AC coefs */
+static int put_huffman_table(MpegEncContext *s, int table_class, int table_id,
+ const UINT8 *bits_table, const UINT8 *value_table)
+{
+ PutBitContext *p = &s->pb;
+ int n, i;
+
+ put_bits(p, 4, table_class);
+ put_bits(p, 4, table_id);
+
+ n = 0;
+ for(i=1;i<=16;i++) {
+ n += bits_table[i];
+ put_bits(p, 8, bits_table[i]);
+ }
+
+ for(i=0;i<n;i++)
+ put_bits(p, 8, value_table[i]);
+
+ return n + 17;
+}
+
+static void jpeg_table_header(MpegEncContext *s)
+{
+ PutBitContext *p = &s->pb;
+ int i, size;
+ UINT8 *ptr;
+
+ /* quant matrixes */
+ put_marker(p, DQT);
+ put_bits(p, 16, 2 + 1 * (1 + 64));
+ put_bits(p, 4, 0); /* 8 bit precision */
+ put_bits(p, 4, 0); /* table 0 */
+ for(i=0;i<64;i++) {
+ put_bits(p, 8, s->intra_matrix[i]);
+ }
+#if 0
+ put_bits(p, 4, 0); /* 8 bit precision */
+ put_bits(p, 4, 1); /* table 1 */
+ for(i=0;i<64;i++) {
+ put_bits(p, 8, s->chroma_intra_matrix[i]);
+ }
+#endif
+
+ /* huffman table */
+ put_marker(p, DHT);
+ flush_put_bits(p);
+ ptr = p->buf_ptr;
+ put_bits(p, 16, 0); /* patched later */
+ size = 2;
+ size += put_huffman_table(s, 0, 0, bits_dc_luminance, val_dc_luminance);
+ size += put_huffman_table(s, 0, 1, bits_dc_chrominance, val_dc_chrominance);
+
+ size += put_huffman_table(s, 1, 0, bits_ac_luminance, val_ac_luminance);
+ size += put_huffman_table(s, 1, 1, bits_ac_chrominance, val_ac_chrominance);
+ ptr[0] = size >> 8;
+ ptr[1] = size;
+}
+
+void mjpeg_picture_header(MpegEncContext *s)
+{
+ put_marker(&s->pb, SOI);
+
+ jpeg_table_header(s);
+
+ put_marker(&s->pb, SOF0);
+
+ put_bits(&s->pb, 16, 17);
+ put_bits(&s->pb, 8, 8); /* 8 bits/component */
+ put_bits(&s->pb, 16, s->height);
+ put_bits(&s->pb, 16, s->width);
+ put_bits(&s->pb, 8, 3); /* 3 components */
+
+ /* Y component */
+ put_bits(&s->pb, 8, 1); /* component number */
+ put_bits(&s->pb, 4, 2); /* H factor */
+ put_bits(&s->pb, 4, 2); /* V factor */
+ put_bits(&s->pb, 8, 0); /* select matrix */
+
+ /* Cb component */
+ put_bits(&s->pb, 8, 2); /* component number */
+ put_bits(&s->pb, 4, 1); /* H factor */
+ put_bits(&s->pb, 4, 1); /* V factor */
+ put_bits(&s->pb, 8, 0); /* select matrix */
+
+ /* Cr component */
+ put_bits(&s->pb, 8, 3); /* component number */
+ put_bits(&s->pb, 4, 1); /* H factor */
+ put_bits(&s->pb, 4, 1); /* V factor */
+ put_bits(&s->pb, 8, 0); /* select matrix */
+
+ /* scan header */
+ put_marker(&s->pb, SOS);
+ put_bits(&s->pb, 16, 12); /* length */
+ put_bits(&s->pb, 8, 3); /* 3 components */
+
+ /* Y component */
+ put_bits(&s->pb, 8, 1); /* index */
+ put_bits(&s->pb, 4, 0); /* DC huffman table index */
+ put_bits(&s->pb, 4, 0); /* AC huffman table index */
+
+ /* Cb component */
+ put_bits(&s->pb, 8, 2); /* index */
+ put_bits(&s->pb, 4, 1); /* DC huffman table index */
+ put_bits(&s->pb, 4, 1); /* AC huffman table index */
+
+ /* Cr component */
+ put_bits(&s->pb, 8, 3); /* index */
+ put_bits(&s->pb, 4, 1); /* DC huffman table index */
+ put_bits(&s->pb, 4, 1); /* AC huffman table index */
+
+ put_bits(&s->pb, 8, 0); /* Ss (not used) */
+ put_bits(&s->pb, 8, 63); /* Se (not used) */
+ put_bits(&s->pb, 8, 0); /* (not used) */
+}
+
+void mjpeg_picture_trailer(MpegEncContext *s)
+{
+ jflush_put_bits(&s->pb);
+ put_marker(&s->pb, EOI);
+}
+
+static inline void encode_dc(MpegEncContext *s, int val,
+ UINT8 *huff_size, UINT16 *huff_code)
+{
+ int mant, nbits;
+
+ if (val == 0) {
+ jput_bits(&s->pb, huff_size[0], huff_code[0]);
+ } else {
+ mant = val;
+ if (val < 0) {
+ val = -val;
+ mant--;
+ }
+
+ /* compute the log (XXX: optimize) */
+ nbits = 0;
+ while (val != 0) {
+ val = val >> 1;
+ nbits++;
+ }
+
+ jput_bits(&s->pb, huff_size[nbits], huff_code[nbits]);
+
+ jput_bits(&s->pb, nbits, mant & ((1 << nbits) - 1));
+ }
+}
+
+static void encode_block(MpegEncContext *s, DCTELEM *block, int n)
+{
+ int mant, nbits, code, i, j;
+ int component, dc, run, last_index, val;
+ MJpegContext *m = s->mjpeg_ctx;
+ UINT8 *huff_size_ac;
+ UINT16 *huff_code_ac;
+
+ /* DC coef */
+ component = (n <= 3 ? 0 : n - 4 + 1);
+ dc = block[0]; /* overflow is impossible */
+ val = dc - s->last_dc[component];
+ if (n < 4) {
+ encode_dc(s, val, m->huff_size_dc_luminance, m->huff_code_dc_luminance);
+ huff_size_ac = m->huff_size_ac_luminance;
+ huff_code_ac = m->huff_code_ac_luminance;
+ } else {
+ encode_dc(s, val, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);
+ huff_size_ac = m->huff_size_ac_chrominance;
+ huff_code_ac = m->huff_code_ac_chrominance;
+ }
+ s->last_dc[component] = dc;
+
+ /* AC coefs */
+
+ run = 0;
+ last_index = s->block_last_index[n];
+ for(i=1;i<=last_index;i++) {
+ j = zigzag_direct[i];
+ val = block[j];
+ if (val == 0) {
+ run++;
+ } else {
+ while (run >= 16) {
+ jput_bits(&s->pb, huff_size_ac[0xf0], huff_code_ac[0xf0]);
+ run -= 16;
+ }
+ mant = val;
+ if (val < 0) {
+ val = -val;
+ mant--;
+ }
+
+ /* compute the log (XXX: optimize) */
+ nbits = 0;
+ while (val != 0) {
+ val = val >> 1;
+ nbits++;
+ }
+ code = (run << 4) | nbits;
+
+ jput_bits(&s->pb, huff_size_ac[code], huff_code_ac[code]);
+
+ jput_bits(&s->pb, nbits, mant & ((1 << nbits) - 1));
+ run = 0;
+ }
+ }
+
+ /* output EOB only if not already 64 values */
+ if (last_index < 63 || run != 0)
+ jput_bits(&s->pb, huff_size_ac[0], huff_code_ac[0]);
+}
+
+void mjpeg_encode_mb(MpegEncContext *s,
+ DCTELEM block[6][64])
+{
+ int i;
+ for(i=0;i<6;i++) {
+ encode_block(s, block[i], i);
+ }
+}
+
+/******************************************/
+/* decoding */
+
+//#define DEBUG
+
+#ifdef DEBUG
+#define dprintf(fmt,args...) printf(fmt, ## args)
+#else
+#define dprintf(fmt,args...)
+#endif
+
+/* compressed picture size */
+#define PICTURE_BUFFER_SIZE 100000
+
+#define MAX_COMPONENTS 4
+
+typedef struct MJpegDecodeContext {
+ GetBitContext gb;
+ UINT32 header_state;
+ int start_code; /* current start code */
+ UINT8 *buf_ptr;
+ int buffer_size;
+ int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
+ INT16 quant_matrixes[4][64];
+ VLC vlcs[2][4];
+ int width, height;
+ int nb_components;
+ int component_id[MAX_COMPONENTS];
+ int h_count[MAX_COMPONENTS]; /* horizontal and vertical count for each component */
+ int v_count[MAX_COMPONENTS];
+ int h_max, v_max; /* maximum h and v counts */
+ int quant_index[4]; /* quant table index for each component */
+ int last_dc[MAX_COMPONENTS]; /* last DEQUANTIZED dc (XXX: am I right to do that ?) */
+ UINT8 *current_picture[MAX_COMPONENTS]; /* picture structure */
+ int linesize[MAX_COMPONENTS];
+ DCTELEM block[64] __align8;
+ UINT8 buffer[PICTURE_BUFFER_SIZE];
+} MJpegDecodeContext;
+
+static void build_vlc(VLC *vlc, const UINT8 *bits_table, const UINT8 *val_table,
+ int nb_codes)
+{
+ UINT8 huff_size[256];
+ UINT16 huff_code[256];
+
+ memset(huff_size, 0, sizeof(huff_size));
+ build_huffman_codes(huff_size, huff_code, bits_table, val_table);
+
+ init_vlc(vlc, 9, nb_codes, huff_size, 1, 1, huff_code, 2, 2);
+}
+
+static int mjpeg_decode_init(AVCodecContext *avctx)
+{
+ MJpegDecodeContext *s = avctx->priv_data;
+
+ s->header_state = 0;
+ s->mpeg_enc_ctx_allocated = 0;
+ s->buffer_size = PICTURE_BUFFER_SIZE - 1; /* minus 1 to take into
+ account FF 00 case */
+ s->start_code = -1;
+ s->buf_ptr = s->buffer;
+
+ build_vlc(&s->vlcs[0][0], bits_dc_luminance, val_dc_luminance, 12);
+ build_vlc(&s->vlcs[0][1], bits_dc_chrominance, val_dc_chrominance, 12);
+ build_vlc(&s->vlcs[1][0], bits_ac_luminance, val_ac_luminance, 251);
+ build_vlc(&s->vlcs[1][1], bits_ac_chrominance, val_ac_chrominance, 251);
+ return 0;
+}
+
+/* quantize tables */
+static int mjpeg_decode_dqt(MJpegDecodeContext *s,
+ UINT8 *buf, int buf_size)
+{
+ int len, index, i;
+ init_get_bits(&s->gb, buf, buf_size);
+
+ len = get_bits(&s->gb, 16);
+ len -= 2;
+
+ while (len >= 65) {
+ /* only 8 bit precision handled */
+ if (get_bits(&s->gb, 4) != 0)
+ return -1;
+ index = get_bits(&s->gb, 4);
+ if (index >= 4)
+ return -1;
+ dprintf("index=%d\n", index);
+ /* read quant table */
+ for(i=0;i<64;i++)
+ s->quant_matrixes[index][i] = get_bits(&s->gb, 8);
+ len -= 65;
+ }
+ return 0;
+}
+
+/* decode huffman tables and build VLC decoders */
+static int mjpeg_decode_dht(MJpegDecodeContext *s,
+ UINT8 *buf, int buf_size)
+{
+ int len, index, i, class, n, v, code_max;
+ UINT8 bits_table[17];
+ UINT8 val_table[256];
+
+ init_get_bits(&s->gb, buf, buf_size);
+
+ len = get_bits(&s->gb, 16);
+ len -= 2;
+
+ while (len > 0) {
+ if (len < 17)
+ return -1;
+ class = get_bits(&s->gb, 4);
+ if (class >= 2)
+ return -1;
+ index = get_bits(&s->gb, 4);
+ if (index >= 4)
+ return -1;
+ n = 0;
+ for(i=1;i<=16;i++) {
+ bits_table[i] = get_bits(&s->gb, 8);
+ n += bits_table[i];
+ }
+ len -= 17;
+ if (len < n || n > 256)
+ return -1;
+
+ code_max = 0;
+ for(i=0;i<n;i++) {
+ v = get_bits(&s->gb, 8);
+ if (v > code_max)
+ code_max = v;
+ val_table[i] = v;
+ }
+ len -= n;
+
+ /* build VLC and flush previous vlc if present */
+ free_vlc(&s->vlcs[class][index]);
+ dprintf("class=%d index=%d nb_codes=%d\n",
+ class, index, code_max + 1);
+ build_vlc(&s->vlcs[class][index], bits_table, val_table, code_max + 1);
+ }
+ return 0;
+}
+
+static int mjpeg_decode_sof0(MJpegDecodeContext *s,
+ UINT8 *buf, int buf_size)
+{
+ int len, nb_components, i, width, height;
+
+ init_get_bits(&s->gb, buf, buf_size);
+
+ /* XXX: verify len field validity */
+ len = get_bits(&s->gb, 16);
+ /* only 8 bits/component accepted */
+ if (get_bits(&s->gb, 8) != 8)
+ return -1;
+ height = get_bits(&s->gb, 16);
+ width = get_bits(&s->gb, 16);
+
+ nb_components = get_bits(&s->gb, 8);
+ if (nb_components <= 0 ||
+ nb_components > MAX_COMPONENTS)
+ return -1;
+ s->nb_components = nb_components;
+ s->h_max = 1;
+ s->v_max = 1;
+ for(i=0;i<nb_components;i++) {
+ /* component id */
+ s->component_id[i] = get_bits(&s->gb, 8) - 1;
+ s->h_count[i] = get_bits(&s->gb, 4);
+ s->v_count[i] = get_bits(&s->gb, 4);
+ /* compute hmax and vmax (only used in interleaved case) */
+ if (s->h_count[i] > s->h_max)
+ s->h_max = s->h_count[i];
+ if (s->v_count[i] > s->v_max)
+ s->v_max = s->v_count[i];
+ s->quant_index[i] = get_bits(&s->gb, 8);
+ if (s->quant_index[i] >= 4)
+ return -1;
+ dprintf("component %d %d:%d\n", i, s->h_count[i], s->v_count[i]);
+ }
+
+ /* if different size, realloc/alloc picture */
+ /* XXX: also check h_count and v_count */
+ if (width != s->width || height != s->height) {
+ for(i=0;i<MAX_COMPONENTS;i++) {
+ free(s->current_picture[i]);
+ s->current_picture[i] = NULL;
+ }
+ s->width = width;
+ s->height = height;
+ for(i=0;i<nb_components;i++) {
+ int w, h, hh, vv;
+ hh = s->h_max / s->h_count[i];
+ vv = s->v_max / s->v_count[i];
+ w = (s->width + 8 * hh - 1) / (8 * hh);
+ h = (s->height + 8 * vv - 1) / (8 * vv);
+ w = w * 8;
+ h = h * 8;
+ s->linesize[i] = w;
+ /* memory test is done in mjpeg_decode_sos() */
+ s->current_picture[i] = av_mallocz(w * h);
+ }
+ }
+
+ return 0;
+}
+
+static inline int decode_dc(MJpegDecodeContext *s, int dc_index)
+{
+ VLC *dc_vlc;
+ int code, diff;
+
+ dc_vlc = &s->vlcs[0][dc_index];
+ code = get_vlc(&s->gb, dc_vlc);
+ if (code < 0)
+ return 0xffff;
+ if (code == 0) {
+ diff = 0;
+ } else {
+ diff = get_bits(&s->gb, code);
+ if ((diff & (1 << (code - 1))) == 0)
+ diff = (-1 << code) | (diff + 1);
+ }
+ return diff;
+}
+
+/* decode block and dequantize */
+static int decode_block(MJpegDecodeContext *s, DCTELEM *block,
+ int component, int dc_index, int ac_index, int quant_index)
+{
+ int nbits, code, i, j, level;
+ int run, val;
+ VLC *ac_vlc;
+ INT16 *quant_matrix;
+
+ quant_matrix = s->quant_matrixes[quant_index];
+ /* DC coef */
+ val = decode_dc(s, dc_index);
+ if (val == 0xffff) {
+ dprintf("error dc\n");
+ return -1;
+ }
+ val = val * quant_matrix[0] + s->last_dc[component];
+ s->last_dc[component] = val;
+ block[0] = val;
+ /* AC coefs */
+ ac_vlc = &s->vlcs[1][ac_index];
+ i = 1;
+ for(;;) {
+ code = get_vlc(&s->gb, ac_vlc);
+ if (code < 0) {
+ dprintf("error ac\n");
+ return -1;
+ }
+ /* EOB */
+ if (code == 0)
+ break;
+ if (code == 0xf0) {
+ i += 16;
+ } else {
+ run = code >> 4;
+ nbits = code & 0xf;
+ level = get_bits(&s->gb, nbits);
+ if ((level & (1 << (nbits - 1))) == 0)
+ level = (-1 << nbits) | (level + 1);
+ i += run;
+ if (i >= 64) {
+ dprintf("error count: %d\n", i);
+ return -1;
+ }
+ j = zigzag_direct[i];
+ block[j] = level * quant_matrix[j];
+ i++;
+ if (i >= 64)
+ break;
+ }
+ }
+ return 0;
+}
+
+static int mjpeg_decode_sos(MJpegDecodeContext *s,
+ UINT8 *buf, int buf_size)
+{
+ int len, nb_components, i, j, n, h, v;
+ int mb_width, mb_height, mb_x, mb_y, vmax, hmax, index, id;
+ int comp_index[4];
+ int dc_index[4];
+ int ac_index[4];
+ int nb_blocks[4];
+ int h_count[4];
+ int v_count[4];
+
+ init_get_bits(&s->gb, buf, buf_size);
+ /* XXX: verify len field validity */
+ len = get_bits(&s->gb, 16);
+ nb_components = get_bits(&s->gb, 8);
+ /* XXX: only interleaved scan accepted */
+ if (nb_components != 3)
+ return -1;
+ vmax = 0;
+ hmax = 0;
+ for(i=0;i<nb_components;i++) {
+ id = get_bits(&s->gb, 8) - 1;
+ /* find component index */
+ for(index=0;index<s->nb_components;index++)
+ if (id == s->component_id[index])
+ break;
+ if (index == s->nb_components)
+ return -1;
+
+ comp_index[i] = index;
+ nb_blocks[i] = s->h_count[index] * s->v_count[index];
+ h_count[i] = s->h_count[index];
+ v_count[i] = s->v_count[index];
+
+ dc_index[i] = get_bits(&s->gb, 4);
+ if (dc_index[i] >= 4)
+ return -1;
+ ac_index[i] = get_bits(&s->gb, 4);
+ if (ac_index[i] >= 4)
+ return -1;
+ }
+ get_bits(&s->gb, 8); /* Ss */
+ get_bits(&s->gb, 8); /* Se */
+ get_bits(&s->gb, 8); /* not used */
+
+ for(i=0;i<nb_components;i++)
+ s->last_dc[i] = 1024;
+
+ if (nb_components > 1) {
+ /* interleaved stream */
+ mb_width = (s->width + s->h_max * 8 - 1) / (s->h_max * 8);
+ mb_height = (s->height + s->v_max * 8 - 1) / (s->v_max * 8);
+ } else {
+ h = s->h_max / s->h_count[comp_index[0]];
+ v = s->v_max / s->v_count[comp_index[0]];
+ mb_width = (s->width + h * 8 - 1) / (h * 8);
+ mb_height = (s->height + v * 8 - 1) / (v * 8);
+ nb_blocks[0] = 1;
+ h_count[0] = 1;
+ v_count[0] = 1;
+ }
+
+ for(mb_y = 0; mb_y < mb_height; mb_y++) {
+ for(mb_x = 0; mb_x < mb_width; mb_x++) {
+ for(i=0;i<nb_components;i++) {
+ UINT8 *ptr;
+ int x, y, c;
+ n = nb_blocks[i];
+ c = comp_index[i];
+ h = h_count[i];
+ v = v_count[i];
+ x = 0;
+ y = 0;
+ for(j=0;j<n;j++) {
+ memset(s->block, 0, sizeof(s->block));
+ if (decode_block(s, s->block, i,
+ dc_index[i], ac_index[i],
+ s->quant_index[c]) < 0) {
+ dprintf("error %d %d\n", mb_y, mb_x);
+ return -1;
+ }
+ ff_idct (s->block);
+ ptr = s->current_picture[c] +
+ (s->linesize[c] * (v * mb_y + y) * 8) +
+ (h * mb_x + x) * 8;
+ put_pixels_clamped(s->block, ptr, s->linesize[c]);
+ if (++x == h) {
+ x = 0;
+ y++;
+ }
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/* return the 8 bit start code value and update the search
+ state. Return -1 if no start code found */
+static int find_marker(UINT8 **pbuf_ptr, UINT8 *buf_end,
+ UINT32 *header_state)
+{
+ UINT8 *buf_ptr;
+ unsigned int state, v;
+ int val;
+
+ state = *header_state;
+ buf_ptr = *pbuf_ptr;
+ if (state) {
+ /* get marker */
+ found:
+ if (buf_ptr < buf_end) {
+ val = *buf_ptr++;
+ state = 0;
+ } else {
+ val = -1;
+ }
+ } else {
+ while (buf_ptr < buf_end) {
+ v = *buf_ptr++;
+ if (v == 0xff) {
+ state = 1;
+ goto found;
+ }
+ }
+ val = -1;
+ }
+ *pbuf_ptr = buf_ptr;
+ *header_state = state;
+ return val;
+}
+
+static int mjpeg_decode_frame(AVCodecContext *avctx,
+ void *data, int *data_size,
+ UINT8 *buf, int buf_size)
+{
+ MJpegDecodeContext *s = avctx->priv_data;
+ UINT8 *buf_end, *buf_ptr, *buf_start;
+ int len, code, start_code, input_size, i;
+ AVPicture *picture = data;
+
+ /* no supplementary picture */
+ if (buf_size == 0) {
+ *data_size = 0;
+ return 0;
+ }
+
+ buf_ptr = buf;
+ buf_end = buf + buf_size;
+ while (buf_ptr < buf_end) {
+ buf_start = buf_ptr;
+ /* find start next marker */
+ code = find_marker(&buf_ptr, buf_end, &s->header_state);
+ /* copy to buffer */
+ len = buf_ptr - buf_start;
+ if (len + (s->buf_ptr - s->buffer) > s->buffer_size) {
+ /* data too big : flush */
+ s->buf_ptr = s->buffer;
+ if (code > 0)
+ s->start_code = code;
+ } else {
+ memcpy(s->buf_ptr, buf_start, len);
+ s->buf_ptr += len;
+ /* if we got FF 00, we copy FF to the stream to unescape FF 00 */
+ if (code == 0) {
+ s->buf_ptr--;
+ } else if (code > 0) {
+ /* prepare data for next start code */
+ input_size = s->buf_ptr - s->buffer;
+ start_code = s->start_code;
+ s->buf_ptr = s->buffer;
+ s->start_code = code;
+ switch(start_code) {
+ case SOI:
+ /* nothing to do on SOI */
+ break;
+ case DQT:
+ mjpeg_decode_dqt(s, s->buffer, input_size);
+ break;
+ case DHT:
+ mjpeg_decode_dht(s, s->buffer, input_size);
+ break;
+ case SOF0:
+ mjpeg_decode_sof0(s, s->buffer, input_size);
+ break;
+ case SOS:
+ mjpeg_decode_sos(s, s->buffer, input_size);
+ if (s->start_code == EOI) {
+ for(i=0;i<3;i++) {
+ picture->data[i] = s->current_picture[i];
+ picture->linesize[i] = s->linesize[i];
+ }
+ *data_size = sizeof(AVPicture);
+ avctx->height = s->height;
+ avctx->width = s->width;
+ /* XXX: not complete test ! */
+ switch((s->h_count[0] << 4) | s->v_count[0]) {
+ case 0x11:
+ avctx->pix_fmt = PIX_FMT_YUV444P;
+ break;
+ case 0x21:
+ avctx->pix_fmt = PIX_FMT_YUV422P;
+ break;
+ default:
+ case 0x22:
+ avctx->pix_fmt = PIX_FMT_YUV420P;
+ break;
+ }
+ goto the_end;
+ }
+ break;
+ }
+ }
+ }
+ }
+ the_end:
+ return buf_ptr - buf;
+}
+
+static int mjpeg_decode_end(AVCodecContext *avctx)
+{
+ MJpegDecodeContext *s = avctx->priv_data;
+ int i, j;
+
+ for(i=0;i<MAX_COMPONENTS;i++)
+ free(s->current_picture[i]);
+ for(i=0;i<2;i++) {
+ for(j=0;j<4;j++)
+ free_vlc(&s->vlcs[i][j]);
+ }
+ return 0;
+}
+
+AVCodec mjpeg_decoder = {
+ "mjpeg",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_MJPEG,
+ sizeof(MJpegDecodeContext),
+ mjpeg_decode_init,
+ NULL,
+ mjpeg_decode_end,
+ mjpeg_decode_frame,
+};
diff --git a/src/libffmpeg/libavcodec/motion_est.c b/src/libffmpeg/libavcodec/motion_est.c
new file mode 100644
index 000000000..d3e31fc42
--- /dev/null
+++ b/src/libffmpeg/libavcodec/motion_est.c
@@ -0,0 +1,514 @@
+/*
+ * Motion estimation
+ * Copyright (c) 2000,2001 Gerard Lantau.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include "avcodec.h"
+#include "dsputil.h"
+#include "mpegvideo.h"
+
+static void halfpel_motion_search(MpegEncContext * s,
+ int *mx_ptr, int *my_ptr, int dmin,
+ int xmin, int ymin, int xmax, int ymax);
+
+/* config it to test motion vector encoding (send random vectors) */
+//#define CONFIG_TEST_MV_ENCODE
+
+static int pix_sum(UINT8 * pix, int line_size)
+{
+ int s, i, j;
+
+ s = 0;
+ for (i = 0; i < 16; i++) {
+ for (j = 0; j < 16; j += 8) {
+ s += pix[0];
+ s += pix[1];
+ s += pix[2];
+ s += pix[3];
+ s += pix[4];
+ s += pix[5];
+ s += pix[6];
+ s += pix[7];
+ pix += 8;
+ }
+ pix += line_size - 16;
+ }
+ return s;
+}
+
+static int pix_norm1(UINT8 * pix, int line_size)
+{
+ int s, i, j;
+ UINT32 *sq = squareTbl + 256;
+
+ s = 0;
+ for (i = 0; i < 16; i++) {
+ for (j = 0; j < 16; j += 8) {
+ s += sq[pix[0]];
+ s += sq[pix[1]];
+ s += sq[pix[2]];
+ s += sq[pix[3]];
+ s += sq[pix[4]];
+ s += sq[pix[5]];
+ s += sq[pix[6]];
+ s += sq[pix[7]];
+ pix += 8;
+ }
+ pix += line_size - 16;
+ }
+ return s;
+}
+
+static int pix_norm(UINT8 * pix1, UINT8 * pix2, int line_size)
+{
+ int s, i, j;
+ UINT32 *sq = squareTbl + 256;
+
+ s = 0;
+ for (i = 0; i < 16; i++) {
+ for (j = 0; j < 16; j += 8) {
+ s += sq[pix1[0] - pix2[0]];
+ s += sq[pix1[1] - pix2[1]];
+ s += sq[pix1[2] - pix2[2]];
+ s += sq[pix1[3] - pix2[3]];
+ s += sq[pix1[4] - pix2[4]];
+ s += sq[pix1[5] - pix2[5]];
+ s += sq[pix1[6] - pix2[6]];
+ s += sq[pix1[7] - pix2[7]];
+ pix1 += 8;
+ pix2 += 8;
+ }
+ pix1 += line_size - 16;
+ pix2 += line_size - 16;
+ }
+ return s;
+}
+
+static void no_motion_search(MpegEncContext * s,
+ int *mx_ptr, int *my_ptr)
+{
+ *mx_ptr = 16 * s->mb_x;
+ *my_ptr = 16 * s->mb_y;
+}
+
+static int full_motion_search(MpegEncContext * s,
+ int *mx_ptr, int *my_ptr, int range,
+ int xmin, int ymin, int xmax, int ymax)
+{
+ int x1, y1, x2, y2, xx, yy, x, y;
+ int mx, my, dmin, d;
+ UINT8 *pix;
+
+ xx = 16 * s->mb_x;
+ yy = 16 * s->mb_y;
+ x1 = xx - range + 1; /* we loose one pixel to avoid boundary pb with half pixel pred */
+ if (x1 < xmin)
+ x1 = xmin;
+ x2 = xx + range - 1;
+ if (x2 > xmax)
+ x2 = xmax;
+ y1 = yy - range + 1;
+ if (y1 < ymin)
+ y1 = ymin;
+ y2 = yy + range - 1;
+ if (y2 > ymax)
+ y2 = ymax;
+ pix = s->new_picture[0] + (yy * s->linesize) + xx;
+ dmin = 0x7fffffff;
+ mx = 0;
+ my = 0;
+ for (y = y1; y <= y2; y++) {
+ for (x = x1; x <= x2; x++) {
+ d = pix_abs16x16(pix, s->last_picture[0] + (y * s->linesize) + x,
+ s->linesize, 16);
+ if (d < dmin ||
+ (d == dmin &&
+ (abs(x - xx) + abs(y - yy)) <
+ (abs(mx - xx) + abs(my - yy)))) {
+ dmin = d;
+ mx = x;
+ my = y;
+ }
+ }
+ }
+
+ *mx_ptr = mx;
+ *my_ptr = my;
+
+#if 0
+ if (*mx_ptr < -(2 * range) || *mx_ptr >= (2 * range) ||
+ *my_ptr < -(2 * range) || *my_ptr >= (2 * range)) {
+ fprintf(stderr, "error %d %d\n", *mx_ptr, *my_ptr);
+ }
+#endif
+ return dmin;
+}
+
+
+static int log_motion_search(MpegEncContext * s,
+ int *mx_ptr, int *my_ptr, int range,
+ int xmin, int ymin, int xmax, int ymax)
+{
+ int x1, y1, x2, y2, xx, yy, x, y;
+ int mx, my, dmin, d;
+ UINT8 *pix;
+
+ xx = s->mb_x << 4;
+ yy = s->mb_y << 4;
+
+ /* Left limit */
+ x1 = xx - range;
+ if (x1 < xmin)
+ x1 = xmin;
+
+ /* Right limit */
+ x2 = xx + range;
+ if (x2 > xmax)
+ x2 = xmax;
+
+ /* Upper limit */
+ y1 = yy - range;
+ if (y1 < ymin)
+ y1 = ymin;
+
+ /* Lower limit */
+ y2 = yy + range;
+ if (y2 > ymax)
+ y2 = ymax;
+
+ pix = s->new_picture[0] + (yy * s->linesize) + xx;
+ dmin = 0x7fffffff;
+ mx = 0;
+ my = 0;
+
+ do {
+ for (y = y1; y <= y2; y += range) {
+ for (x = x1; x <= x2; x += range) {
+ d = pix_abs16x16(pix, s->last_picture[0] + (y * s->linesize) + x, s->linesize, 16);
+ if (d < dmin || (d == dmin && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) {
+ dmin = d;
+ mx = x;
+ my = y;
+ }
+ }
+ }
+
+ range = range >> 1;
+
+ x1 = mx - range;
+ if (x1 < xmin)
+ x1 = xmin;
+
+ x2 = mx + range;
+ if (x2 > xmax)
+ x2 = xmax;
+
+ y1 = my - range;
+ if (y1 < ymin)
+ y1 = ymin;
+
+ y2 = my + range;
+ if (y2 > ymax)
+ y2 = ymax;
+
+ } while (range >= 1);
+
+#ifdef DEBUG
+ fprintf(stderr, "log - MX: %d\tMY: %d\n", mx, my);
+#endif
+ *mx_ptr = mx;
+ *my_ptr = my;
+ return dmin;
+}
+
+static int phods_motion_search(MpegEncContext * s,
+ int *mx_ptr, int *my_ptr, int range,
+ int xmin, int ymin, int xmax, int ymax)
+{
+ int x1, y1, x2, y2, xx, yy, x, y, lastx, d;
+ int mx, my, dminx, dminy;
+ UINT8 *pix;
+
+ xx = s->mb_x << 4;
+ yy = s->mb_y << 4;
+
+ /* Left limit */
+ x1 = xx - range;
+ if (x1 < xmin)
+ x1 = xmin;
+
+ /* Right limit */
+ x2 = xx + range;
+ if (x2 > xmax)
+ x2 = xmax;
+
+ /* Upper limit */
+ y1 = yy - range;
+ if (y1 < ymin)
+ y1 = ymin;
+
+ /* Lower limit */
+ y2 = yy + range;
+ if (y2 > ymax)
+ y2 = ymax;
+
+ pix = s->new_picture[0] + (yy * s->linesize) + xx;
+ mx = 0;
+ my = 0;
+
+ x = xx;
+ y = yy;
+ do {
+ dminx = 0x7fffffff;
+ dminy = 0x7fffffff;
+
+ lastx = x;
+ for (x = x1; x <= x2; x += range) {
+ d = pix_abs16x16(pix, s->last_picture[0] + (y * s->linesize) + x, s->linesize, 16);
+ if (d < dminx || (d == dminx && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) {
+ dminx = d;
+ mx = x;
+ }
+ }
+
+ x = lastx;
+ for (y = y1; y <= y2; y += range) {
+ d = pix_abs16x16(pix, s->last_picture[0] + (y * s->linesize) + x, s->linesize, 16);
+ if (d < dminy || (d == dminy && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) {
+ dminy = d;
+ my = y;
+ }
+ }
+
+ range = range >> 1;
+
+ x = mx;
+ y = my;
+ x1 = mx - range;
+ if (x1 < xmin)
+ x1 = xmin;
+
+ x2 = mx + range;
+ if (x2 > xmax)
+ x2 = xmax;
+
+ y1 = my - range;
+ if (y1 < ymin)
+ y1 = ymin;
+
+ y2 = my + range;
+ if (y2 > ymax)
+ y2 = ymax;
+
+ } while (range >= 1);
+
+#ifdef DEBUG
+ fprintf(stderr, "phods - MX: %d\tMY: %d\n", mx, my);
+#endif
+
+ /* half pixel search */
+ *mx_ptr = mx;
+ *my_ptr = my;
+ return dminy;
+}
+
+/* The idea would be to make half pel ME after Inter/Intra decision to
+ save time. */
+static void halfpel_motion_search(MpegEncContext * s,
+ int *mx_ptr, int *my_ptr, int dmin,
+ int xmin, int ymin, int xmax, int ymax)
+{
+ int mx, my, mx1, my1, d, xx, yy, dminh;
+ UINT8 *pix;
+
+ mx = *mx_ptr << 1;
+ my = *my_ptr << 1;
+
+ xx = 16 * s->mb_x;
+ yy = 16 * s->mb_y;
+
+ dminh = dmin;
+
+ /* Half pixel search */
+ mx1 = mx;
+ my1 = my;
+
+ pix = s->new_picture[0] + (yy * s->linesize) + xx;
+
+ if ((mx > (xmin << 1)) && mx < (xmax << 1) &&
+ (my > (ymin << 1)) && my < (ymax << 1)) {
+ int dx, dy, px, py;
+ UINT8 *ptr;
+ for (dy = -1; dy <= 1; dy++) {
+ for (dx = -1; dx <= 1; dx++) {
+ if (dx != 0 || dy != 0) {
+ px = mx1 + dx;
+ py = my1 + dy;
+ ptr = s->last_picture[0] + ((py >> 1) * s->linesize) + (px >> 1);
+ switch (((py & 1) << 1) | (px & 1)) {
+ default:
+ case 0:
+ d = pix_abs16x16(pix, ptr, s->linesize, 16);
+ break;
+ case 1:
+ d = pix_abs16x16_x2(pix, ptr, s->linesize, 16);
+ break;
+ case 2:
+ d = pix_abs16x16_y2(pix, ptr, s->linesize, 16);
+ break;
+ case 3:
+ d = pix_abs16x16_xy2(pix, ptr, s->linesize, 16);
+ break;
+ }
+ if (d < dminh) {
+ dminh = d;
+ mx = px;
+ my = py;
+ }
+ }
+ }
+ }
+ }
+
+ *mx_ptr = mx - (xx << 1);
+ *my_ptr = my - (yy << 1);
+ //fprintf(stderr,"half - MX: %d\tMY: %d\n",*mx_ptr ,*my_ptr);
+}
+
+#ifndef CONFIG_TEST_MV_ENCODE
+
+int estimate_motion(MpegEncContext * s,
+ int mb_x, int mb_y,
+ int *mx_ptr, int *my_ptr)
+{
+ UINT8 *pix, *ppix;
+ int sum, varc, vard, mx, my, range, dmin, xx, yy;
+ int xmin, ymin, xmax, ymax;
+
+ range = 8 * (1 << (s->f_code - 1));
+ /* XXX: temporary kludge to avoid overflow for msmpeg4 */
+ if (s->out_format == FMT_H263 && !s->h263_msmpeg4)
+ range = range * 2;
+
+ if (s->unrestricted_mv) {
+ xmin = -16;
+ ymin = -16;
+ xmax = s->width;
+ ymax = s->height;
+ } else {
+ xmin = 0;
+ ymin = 0;
+ xmax = s->width - 16;
+ ymax = s->height - 16;
+ }
+
+ switch(s->full_search) {
+ case ME_ZERO:
+ default:
+ no_motion_search(s, &mx, &my);
+ dmin = 0;
+ break;
+ case ME_FULL:
+ dmin = full_motion_search(s, &mx, &my, range, xmin, ymin, xmax, ymax);
+ break;
+ case ME_LOG:
+ dmin = log_motion_search(s, &mx, &my, range / 2, xmin, ymin, xmax, ymax);
+ break;
+ case ME_PHODS:
+ dmin = phods_motion_search(s, &mx, &my, range / 2, xmin, ymin, xmax, ymax);
+ break;
+ }
+ emms_c();
+
+ /* intra / predictive decision */
+ xx = mb_x * 16;
+ yy = mb_y * 16;
+
+ pix = s->new_picture[0] + (yy * s->linesize) + xx;
+ /* At this point (mx,my) are full-pell and the absolute displacement */
+ ppix = s->last_picture[0] + (my * s->linesize) + mx;
+
+ sum = pix_sum(pix, s->linesize);
+ varc = pix_norm1(pix, s->linesize);
+ vard = pix_norm(pix, ppix, s->linesize);
+
+ vard = vard >> 8;
+ sum = sum >> 8;
+ varc = (varc >> 8) - (sum * sum);
+#if 0
+ printf("varc=%d (sum=%d) vard=%d mx=%d my=%d\n",
+ varc, sum, vard, mx - xx, my - yy);
+#endif
+ if (vard <= 64 || vard < varc) {
+ if (s->full_search != ME_ZERO) {
+ halfpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax);
+ } else {
+ mx -= 16 * s->mb_x;
+ my -= 16 * s->mb_y;
+ }
+ *mx_ptr = mx;
+ *my_ptr = my;
+ return 0;
+ } else {
+ *mx_ptr = 0;
+ *my_ptr = 0;
+ return 1;
+ }
+}
+
+#else
+
+/* test version which generates valid random vectors */
+int estimate_motion(MpegEncContext * s,
+ int mb_x, int mb_y,
+ int *mx_ptr, int *my_ptr)
+{
+ int xx, yy, x1, y1, x2, y2, range;
+
+ if ((random() % 10) >= 5) {
+ range = 8 * (1 << (s->f_code - 1));
+ if (s->out_format == FMT_H263 && !s->h263_msmpeg4)
+ range = range * 2;
+
+ xx = 16 * s->mb_x;
+ yy = 16 * s->mb_y;
+ x1 = xx - range;
+ if (x1 < 0)
+ x1 = 0;
+ x2 = xx + range - 1;
+ if (x2 > (s->width - 16))
+ x2 = s->width - 16;
+ y1 = yy - range;
+ if (y1 < 0)
+ y1 = 0;
+ y2 = yy + range - 1;
+ if (y2 > (s->height - 16))
+ y2 = s->height - 16;
+
+ *mx_ptr = (random() % (2 * (x2 - x1 + 1))) + 2 * (x1 - xx);
+ *my_ptr = (random() % (2 * (y2 - y1 + 1))) + 2 * (y1 - yy);
+ return 0;
+ } else {
+ *mx_ptr = 0;
+ *my_ptr = 0;
+ return 1;
+ }
+}
+
+#endif
diff --git a/src/libffmpeg/libavcodec/mpeg12.c b/src/libffmpeg/libavcodec/mpeg12.c
new file mode 100644
index 000000000..182c341e4
--- /dev/null
+++ b/src/libffmpeg/libavcodec/mpeg12.c
@@ -0,0 +1,1534 @@
+/*
+ * MPEG1 encoder / MPEG2 decoder
+ * Copyright (c) 2000,2001 Gerard Lantau.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "avcodec.h"
+#include "dsputil.h"
+#include "mpegvideo.h"
+
+#include "mpeg12data.h"
+
+#ifdef USE_FASTMEMCPY
+#include "fastmemcpy.h"
+#endif
+//#define DEBUG
+
+#ifdef DEBUG
+#define dprintf(fmt,args...) printf(fmt, ## args)
+#else
+#define dprintf(fmt,args...)
+#endif
+
+/* Start codes. */
+#define SEQ_END_CODE 0x000001b7
+#define SEQ_START_CODE 0x000001b3
+#define GOP_START_CODE 0x000001b8
+#define PICTURE_START_CODE 0x00000100
+#define SLICE_MIN_START_CODE 0x00000101
+#define SLICE_MAX_START_CODE 0x000001af
+#define EXT_START_CODE 0x000001b5
+#define USER_START_CODE 0x000001b2
+
+static void mpeg1_encode_block(MpegEncContext *s,
+ DCTELEM *block,
+ int component);
+static void mpeg1_encode_motion(MpegEncContext *s, int val);
+static void mpeg1_skip_picture(MpegEncContext *s, int pict_num);
+static int mpeg1_decode_block(MpegEncContext *s,
+ DCTELEM *block,
+ int n);
+static int mpeg2_decode_block_non_intra(MpegEncContext *s,
+ DCTELEM *block,
+ int n);
+static int mpeg2_decode_block_intra(MpegEncContext *s,
+ DCTELEM *block,
+ int n);
+static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred);
+
+static void put_header(MpegEncContext *s, int header)
+{
+ align_put_bits(&s->pb);
+ put_bits(&s->pb, 32, header);
+}
+
+/* put sequence header if needed */
+static void mpeg1_encode_sequence_header(MpegEncContext *s)
+{
+ unsigned int vbv_buffer_size;
+ unsigned int fps, v;
+ int n;
+ UINT64 time_code;
+
+ if ((s->picture_number % s->gop_size) == 0) {
+ /* mpeg1 header repeated every gop */
+ put_header(s, SEQ_START_CODE);
+
+ /* search closest frame rate */
+ {
+ int i, dmin, d;
+ s->frame_rate_index = 0;
+ dmin = 0x7fffffff;
+ for(i=1;i<9;i++) {
+ d = abs(s->frame_rate - frame_rate_tab[i]);
+ if (d < dmin) {
+ dmin = d;
+ s->frame_rate_index = i;
+ }
+ }
+ }
+
+ put_bits(&s->pb, 12, s->width);
+ put_bits(&s->pb, 12, s->height);
+ put_bits(&s->pb, 4, 1); /* 1/1 aspect ratio */
+ put_bits(&s->pb, 4, s->frame_rate_index);
+ v = s->bit_rate / 400;
+ if (v > 0x3ffff)
+ v = 0x3ffff;
+ put_bits(&s->pb, 18, v);
+ put_bits(&s->pb, 1, 1); /* marker */
+ /* vbv buffer size: slightly greater than an I frame. We add
+ some margin just in case */
+ vbv_buffer_size = (3 * s->I_frame_bits) / (2 * 8);
+ put_bits(&s->pb, 10, (vbv_buffer_size + 16383) / 16384);
+ put_bits(&s->pb, 1, 1); /* constrained parameter flag */
+ put_bits(&s->pb, 1, 0); /* no custom intra matrix */
+ put_bits(&s->pb, 1, 0); /* no custom non intra matrix */
+
+ put_header(s, GOP_START_CODE);
+ put_bits(&s->pb, 1, 0); /* do drop frame */
+ /* time code : we must convert from the real frame rate to a
+ fake mpeg frame rate in case of low frame rate */
+ fps = frame_rate_tab[s->frame_rate_index];
+ time_code = s->fake_picture_number * FRAME_RATE_BASE;
+ s->gop_picture_number = s->fake_picture_number;
+ put_bits(&s->pb, 5, (time_code / (fps * 3600)) % 24);
+ put_bits(&s->pb, 6, (time_code / (fps * 60)) % 60);
+ put_bits(&s->pb, 1, 1);
+ put_bits(&s->pb, 6, (time_code / fps) % 60);
+ put_bits(&s->pb, 6, (time_code % fps) / FRAME_RATE_BASE);
+ put_bits(&s->pb, 1, 1); /* closed gop */
+ put_bits(&s->pb, 1, 0); /* broken link */
+ }
+
+ if (s->frame_rate < (24 * FRAME_RATE_BASE) && s->picture_number > 0) {
+ /* insert empty P pictures to slow down to the desired
+ frame rate. Each fake pictures takes about 20 bytes */
+ fps = frame_rate_tab[s->frame_rate_index];
+ n = ((s->picture_number * fps) / s->frame_rate) - 1;
+ while (s->fake_picture_number < n) {
+ mpeg1_skip_picture(s, s->fake_picture_number -
+ s->gop_picture_number);
+ s->fake_picture_number++;
+ }
+
+ }
+ s->fake_picture_number++;
+}
+
+
+/* insert a fake P picture */
+static void mpeg1_skip_picture(MpegEncContext *s, int pict_num)
+{
+ unsigned int mb_incr;
+
+ /* mpeg1 picture header */
+ put_header(s, PICTURE_START_CODE);
+ /* temporal reference */
+ put_bits(&s->pb, 10, pict_num & 0x3ff);
+
+ put_bits(&s->pb, 3, P_TYPE);
+ put_bits(&s->pb, 16, 0xffff); /* non constant bit rate */
+
+ put_bits(&s->pb, 1, 1); /* integer coordinates */
+ put_bits(&s->pb, 3, 1); /* forward_f_code */
+
+ put_bits(&s->pb, 1, 0); /* extra bit picture */
+
+ /* only one slice */
+ put_header(s, SLICE_MIN_START_CODE);
+ put_bits(&s->pb, 5, 1); /* quantizer scale */
+ put_bits(&s->pb, 1, 0); /* slice extra information */
+
+ mb_incr = 1;
+ put_bits(&s->pb, mbAddrIncrTable[mb_incr - 1][1],
+ mbAddrIncrTable[mb_incr - 1][0]);
+
+ /* empty macroblock */
+ put_bits(&s->pb, 3, 1); /* motion only */
+
+ /* zero motion x & y */
+ put_bits(&s->pb, 1, 1);
+ put_bits(&s->pb, 1, 1);
+
+ /* output a number of empty slice */
+ mb_incr = s->mb_width * s->mb_height - 1;
+ while (mb_incr > 33) {
+ put_bits(&s->pb, 11, 0x008);
+ mb_incr -= 33;
+ }
+ put_bits(&s->pb, mbAddrIncrTable[mb_incr - 1][1],
+ mbAddrIncrTable[mb_incr - 1][0]);
+
+ /* empty macroblock */
+ put_bits(&s->pb, 3, 1); /* motion only */
+
+ /* zero motion x & y */
+ put_bits(&s->pb, 1, 1);
+ put_bits(&s->pb, 1, 1);
+}
+
+void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number)
+{
+ static int done;
+
+ if (!done) {
+ done = 1;
+ init_rl(&rl_mpeg1);
+ }
+ mpeg1_encode_sequence_header(s);
+
+ /* mpeg1 picture header */
+ put_header(s, PICTURE_START_CODE);
+ /* temporal reference */
+ put_bits(&s->pb, 10, (s->fake_picture_number -
+ s->gop_picture_number) & 0x3ff);
+
+ put_bits(&s->pb, 3, s->pict_type);
+ put_bits(&s->pb, 16, 0xffff); /* non constant bit rate */
+
+ if (s->pict_type == P_TYPE) {
+ put_bits(&s->pb, 1, 0); /* half pel coordinates */
+ put_bits(&s->pb, 3, s->f_code); /* forward_f_code */
+ }
+
+ put_bits(&s->pb, 1, 0); /* extra bit picture */
+
+ /* only one slice */
+ put_header(s, SLICE_MIN_START_CODE);
+ put_bits(&s->pb, 5, s->qscale); /* quantizer scale */
+ put_bits(&s->pb, 1, 0); /* slice extra information */
+}
+
+void mpeg1_encode_mb(MpegEncContext *s,
+ DCTELEM block[6][64],
+ int motion_x, int motion_y)
+{
+ int mb_incr, i, cbp, mb_x, mb_y;
+
+ mb_x = s->mb_x;
+ mb_y = s->mb_y;
+
+ /* compute cbp */
+ cbp = 0;
+ for(i=0;i<6;i++) {
+ if (s->block_last_index[i] >= 0)
+ cbp |= 1 << (5 - i);
+ }
+
+ /* skip macroblock, except if first or last macroblock of a slice */
+ if ((cbp | motion_x | motion_y) == 0 &&
+ (!((mb_x | mb_y) == 0 ||
+ (mb_x == s->mb_width - 1 && mb_y == s->mb_height - 1)))) {
+ s->mb_incr++;
+ } else {
+ /* output mb incr */
+ mb_incr = s->mb_incr;
+
+ while (mb_incr > 33) {
+ put_bits(&s->pb, 11, 0x008);
+ mb_incr -= 33;
+ }
+ put_bits(&s->pb, mbAddrIncrTable[mb_incr - 1][1],
+ mbAddrIncrTable[mb_incr - 1][0]);
+
+ if (s->pict_type == I_TYPE) {
+ put_bits(&s->pb, 1, 1); /* macroblock_type : macroblock_quant = 0 */
+ } else {
+ if (s->mb_intra) {
+ put_bits(&s->pb, 5, 0x03);
+ } else {
+ if (cbp != 0) {
+ if (motion_x == 0 && motion_y == 0) {
+ put_bits(&s->pb, 2, 1); /* macroblock_pattern only */
+ put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]);
+ } else {
+ put_bits(&s->pb, 1, 1); /* motion + cbp */
+ mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0]);
+ mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1]);
+ put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]);
+ }
+ } else {
+ put_bits(&s->pb, 3, 1); /* motion only */
+ mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0]);
+ mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1]);
+ }
+ }
+ }
+ for(i=0;i<6;i++) {
+ if (cbp & (1 << (5 - i))) {
+ mpeg1_encode_block(s, block[i], i);
+ }
+ }
+ s->mb_incr = 1;
+ }
+ s->last_mv[0][0][0] = motion_x;
+ s->last_mv[0][0][1] = motion_y;
+}
+
+static void mpeg1_encode_motion(MpegEncContext *s, int val)
+{
+ int code, bit_size, l, m, bits, range, sign;
+
+ if (val == 0) {
+ /* zero vector */
+ code = 0;
+ put_bits(&s->pb,
+ mbMotionVectorTable[0][1],
+ mbMotionVectorTable[0][0]);
+ } else {
+ bit_size = s->f_code - 1;
+ range = 1 << bit_size;
+ /* modulo encoding */
+ l = 16 * range;
+ m = 2 * l;
+ if (val < -l) {
+ val += m;
+ } else if (val >= l) {
+ val -= m;
+ }
+
+ if (val >= 0) {
+ val--;
+ code = (val >> bit_size) + 1;
+ bits = val & (range - 1);
+ sign = 0;
+ } else {
+ val = -val;
+ val--;
+ code = (val >> bit_size) + 1;
+ bits = val & (range - 1);
+ sign = 1;
+ }
+ put_bits(&s->pb,
+ mbMotionVectorTable[code][1],
+ mbMotionVectorTable[code][0]);
+ put_bits(&s->pb, 1, sign);
+ if (bit_size > 0) {
+ put_bits(&s->pb, bit_size, bits);
+ }
+ }
+}
+
+static inline void encode_dc(MpegEncContext *s, int diff, int component)
+{
+ int adiff, index;
+
+ adiff = abs(diff);
+ index = vlc_dc_table[adiff];
+ if (component == 0) {
+ put_bits(&s->pb, vlc_dc_lum_bits[index], vlc_dc_lum_code[index]);
+ } else {
+ put_bits(&s->pb, vlc_dc_chroma_bits[index], vlc_dc_chroma_code[index]);
+ }
+ if (diff > 0) {
+ put_bits(&s->pb, index, (diff & ((1 << index) - 1)));
+ } else if (diff < 0) {
+ put_bits(&s->pb, index, ((diff - 1) & ((1 << index) - 1)));
+ }
+}
+
+static void mpeg1_encode_block(MpegEncContext *s,
+ DCTELEM *block,
+ int n)
+{
+ int alevel, level, last_non_zero, dc, diff, i, j, run, last_index, sign;
+ int code, component;
+ RLTable *rl = &rl_mpeg1;
+
+ last_index = s->block_last_index[n];
+
+ /* DC coef */
+ if (s->mb_intra) {
+ component = (n <= 3 ? 0 : n - 4 + 1);
+ dc = block[0]; /* overflow is impossible */
+ diff = dc - s->last_dc[component];
+ encode_dc(s, diff, component);
+ s->last_dc[component] = dc;
+ i = 1;
+ } else {
+ /* encode the first coefficient : needs to be done here because
+ it is handled slightly differently */
+ level = block[0];
+ if (abs(level) == 1) {
+ code = ((UINT32)level >> 31); /* the sign bit */
+ put_bits(&s->pb, 2, code | 0x02);
+ i = 1;
+ } else {
+ i = 0;
+ last_non_zero = -1;
+ goto next_coef;
+ }
+ }
+
+ /* now quantify & encode AC coefs */
+ last_non_zero = i - 1;
+ for(;i<=last_index;i++) {
+ j = zigzag_direct[i];
+ level = block[j];
+ next_coef:
+#if 0
+ if (level != 0)
+ dprintf("level[%d]=%d\n", i, level);
+#endif
+ /* encode using VLC */
+ if (level != 0) {
+ run = i - last_non_zero - 1;
+ sign = 0;
+ alevel = level;
+ if (alevel < 0) {
+ sign = 1;
+ alevel = -alevel;
+ }
+ code = get_rl_index(rl, 0, run, alevel);
+ put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
+ if (code != rl->n) {
+ put_bits(&s->pb, 1, sign);
+ } else {
+ /* escape: only clip in this case */
+ put_bits(&s->pb, 6, run);
+ if (alevel < 128) {
+ put_bits(&s->pb, 8, level & 0xff);
+ } else {
+ if (level < 0) {
+ put_bits(&s->pb, 16, 0x8001 + level + 255);
+ } else {
+ put_bits(&s->pb, 16, level & 0xffff);
+ }
+ }
+ }
+ last_non_zero = i;
+ }
+ }
+ /* end of block */
+ put_bits(&s->pb, 2, 0x2);
+}
+
+/******************************************/
+/* decoding */
+
+static VLC dc_lum_vlc;
+static VLC dc_chroma_vlc;
+static VLC mv_vlc;
+static VLC mbincr_vlc;
+static VLC mb_ptype_vlc;
+static VLC mb_btype_vlc;
+static VLC mb_pat_vlc;
+
+void mpeg1_init_vlc(MpegEncContext *s)
+{
+ static int done = 0;
+
+ if (!done) {
+
+ init_vlc(&dc_lum_vlc, 9, 12,
+ vlc_dc_lum_bits, 1, 1,
+ vlc_dc_lum_code, 2, 2);
+ init_vlc(&dc_chroma_vlc, 9, 12,
+ vlc_dc_chroma_bits, 1, 1,
+ vlc_dc_chroma_code, 2, 2);
+ init_vlc(&mv_vlc, 9, 17,
+ &mbMotionVectorTable[0][1], 2, 1,
+ &mbMotionVectorTable[0][0], 2, 1);
+ init_vlc(&mbincr_vlc, 9, 34,
+ &mbAddrIncrTable[0][1], 2, 1,
+ &mbAddrIncrTable[0][0], 2, 1);
+ init_vlc(&mb_pat_vlc, 9, 63,
+ &mbPatTable[0][1], 2, 1,
+ &mbPatTable[0][0], 2, 1);
+
+ init_vlc(&mb_ptype_vlc, 6, 32,
+ &table_mb_ptype[0][1], 2, 1,
+ &table_mb_ptype[0][0], 2, 1);
+ init_vlc(&mb_btype_vlc, 6, 32,
+ &table_mb_btype[0][1], 2, 1,
+ &table_mb_btype[0][0], 2, 1);
+ init_rl(&rl_mpeg1);
+ init_rl(&rl_mpeg2);
+ /* cannot use generic init because we must add the EOB code */
+ init_vlc(&rl_mpeg1.vlc, 9, rl_mpeg1.n + 2,
+ &rl_mpeg1.table_vlc[0][1], 4, 2,
+ &rl_mpeg1.table_vlc[0][0], 4, 2);
+ init_vlc(&rl_mpeg2.vlc, 9, rl_mpeg2.n + 2,
+ &rl_mpeg2.table_vlc[0][1], 4, 2,
+ &rl_mpeg2.table_vlc[0][0], 4, 2);
+ }
+}
+
+static inline int get_dmv(MpegEncContext *s)
+{
+ if(get_bits1(&s->gb))
+ return 1 - (get_bits1(&s->gb) << 1);
+ else
+ return 0;
+}
+
+/* motion type (for mpeg2) */
+#define MT_FIELD 1
+#define MT_FRAME 2
+#define MT_16X8 2
+#define MT_DMV 3
+
+static int mpeg_decode_mb(MpegEncContext *s,
+ DCTELEM block[6][64])
+{
+ int i, j, k, cbp, val, code, mb_type, motion_type;
+
+ /* skip mb handling */
+ if (s->mb_incr == 0) {
+ /* read again increment */
+ s->mb_incr = 1;
+ for(;;) {
+ code = get_vlc(&s->gb, &mbincr_vlc);
+ if (code < 0)
+ return 1; /* error = end of slice */
+ if (code >= 33) {
+ if (code == 33) {
+ s->mb_incr += 33;
+ }
+ /* otherwise, stuffing, nothing to do */
+ } else {
+ s->mb_incr += code;
+ break;
+ }
+ }
+ }
+ if (++s->mb_x >= s->mb_width) {
+ s->mb_x = 0;
+ if (s->mb_y >= (s->mb_height - 1))
+ return -1;
+ s->mb_y++;
+ }
+ dprintf("decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y);
+
+ if (--s->mb_incr != 0) {
+ /* skip mb */
+ s->mb_intra = 0;
+ for(i=0;i<6;i++)
+ s->block_last_index[i] = -1;
+ s->mv_type = MV_TYPE_16X16;
+ if (s->pict_type == P_TYPE) {
+ /* if P type, zero motion vector is implied */
+ s->mv_dir = MV_DIR_FORWARD;
+ s->mv[0][0][0] = s->mv[0][0][1] = 0;
+ s->last_mv[0][0][0] = s->last_mv[0][0][1] = 0;
+ } else {
+ /* if B type, reuse previous vectors and directions */
+ s->mv[0][0][0] = s->last_mv[0][0][0];
+ s->mv[0][0][1] = s->last_mv[0][0][1];
+ s->mv[1][0][0] = s->last_mv[1][0][0];
+ s->mv[1][0][1] = s->last_mv[1][0][1];
+ }
+ s->mb_skiped = 1;
+ return 0;
+ }
+
+ switch(s->pict_type) {
+ default:
+ case I_TYPE:
+ if (get_bits1(&s->gb) == 0) {
+ if (get_bits1(&s->gb) == 0)
+ return -1;
+ mb_type = MB_QUANT | MB_INTRA;
+ } else {
+ mb_type = MB_INTRA;
+ }
+ break;
+ case P_TYPE:
+ mb_type = get_vlc(&s->gb, &mb_ptype_vlc);
+ if (mb_type < 0)
+ return -1;
+ break;
+ case B_TYPE:
+ mb_type = get_vlc(&s->gb, &mb_btype_vlc);
+ if (mb_type < 0)
+ return -1;
+ break;
+ }
+ dprintf("mb_type=%x\n", mb_type);
+ motion_type = 0; /* avoid warning */
+ if (mb_type & (MB_FOR|MB_BACK)) {
+ /* get additionnal motion vector type */
+ if (s->picture_structure == PICT_FRAME && s->frame_pred_frame_dct)
+ motion_type = MT_FRAME;
+ else
+ motion_type = get_bits(&s->gb, 2);
+ }
+ /* compute dct type */
+ if (s->picture_structure == PICT_FRAME &&
+ !s->frame_pred_frame_dct &&
+ (mb_type & (MB_PAT | MB_INTRA))) {
+ s->interlaced_dct = get_bits1(&s->gb);
+#ifdef DEBUG
+ if (s->interlaced_dct)
+ printf("interlaced_dct\n");
+#endif
+ } else {
+ s->interlaced_dct = 0; /* frame based */
+ }
+
+ if (mb_type & MB_QUANT) {
+ if (s->mpeg2) {
+ if (s->q_scale_type) {
+ s->qscale = non_linear_qscale[get_bits(&s->gb, 5)];
+ } else {
+ s->qscale = get_bits(&s->gb, 5) << 1;
+ }
+ } else {
+ /* for mpeg1, we use the generic unquant code */
+ s->qscale = get_bits(&s->gb, 5);
+ }
+ }
+ if (mb_type & MB_INTRA) {
+ if (s->concealment_motion_vectors) {
+ /* just parse them */
+ if (s->picture_structure != PICT_FRAME)
+ skip_bits1(&s->gb); /* field select */
+ mpeg_decode_motion(s, s->mpeg_f_code[0][0], 0);
+ mpeg_decode_motion(s, s->mpeg_f_code[0][1], 0);
+ }
+ s->mb_intra = 1;
+ cbp = 0x3f;
+ memset(s->last_mv, 0, sizeof(s->last_mv)); /* reset mv prediction */
+ } else {
+ s->mb_intra = 0;
+ cbp = 0;
+ }
+ /* special case of implicit zero motion vector */
+ if (s->pict_type == P_TYPE && !(mb_type & MB_FOR)) {
+ s->mv_dir = MV_DIR_FORWARD;
+ s->mv_type = MV_TYPE_16X16;
+ s->last_mv[0][0][0] = 0;
+ s->last_mv[0][0][1] = 0;
+ s->mv[0][0][0] = 0;
+ s->mv[0][0][1] = 0;
+ } else if (mb_type & (MB_FOR | MB_BACK)) {
+ /* motion vectors */
+ s->mv_dir = 0;
+ for(i=0;i<2;i++) {
+ if (mb_type & (MB_FOR >> i)) {
+ s->mv_dir |= (MV_DIR_FORWARD >> i);
+ dprintf("mv_type=%d\n", motion_type);
+ switch(motion_type) {
+ case MT_FRAME: /* or MT_16X8 */
+ if (s->picture_structure == PICT_FRAME) {
+ /* MT_FRAME */
+ s->mv_type = MV_TYPE_16X16;
+ for(k=0;k<2;k++) {
+ val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
+ s->last_mv[i][0][k]);
+ s->last_mv[i][0][k] = val;
+ s->last_mv[i][1][k] = val;
+ /* full_pel: only for mpeg1 */
+ if (s->full_pel[i])
+ val = val << 1;
+ s->mv[i][0][k] = val;
+ dprintf("mv%d: %d\n", k, val);
+ }
+ } else {
+ /* MT_16X8 */
+ s->mv_type = MV_TYPE_16X8;
+ for(j=0;j<2;j++) {
+ s->field_select[i][j] = get_bits1(&s->gb);
+ for(k=0;k<2;k++) {
+ val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
+ s->last_mv[i][j][k]);
+ s->last_mv[i][j][k] = val;
+ s->mv[i][j][k] = val;
+ }
+ }
+ }
+ break;
+ case MT_FIELD:
+ if (s->picture_structure == PICT_FRAME) {
+ s->mv_type = MV_TYPE_FIELD;
+ for(j=0;j<2;j++) {
+ s->field_select[i][j] = get_bits1(&s->gb);
+ val = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
+ s->last_mv[i][j][0]);
+ s->last_mv[i][j][0] = val;
+ s->mv[i][j][0] = val;
+ dprintf("fmx=%d\n", val);
+ val = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
+ s->last_mv[i][j][1] >> 1);
+ s->last_mv[i][j][1] = val << 1;
+ s->mv[i][j][1] = val;
+ dprintf("fmy=%d\n", val);
+ }
+ } else {
+ s->mv_type = MV_TYPE_16X16;
+ s->field_select[i][0] = get_bits1(&s->gb);
+ for(k=0;k<2;k++) {
+ val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
+ s->last_mv[i][0][k]);
+ s->last_mv[i][0][k] = val;
+ s->last_mv[i][1][k] = val;
+ s->mv[i][0][k] = val;
+ }
+ }
+ break;
+ case MT_DMV:
+ {
+ int dmx, dmy, mx, my, m;
+
+ mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
+ s->last_mv[i][0][0]);
+ s->last_mv[i][0][0] = mx;
+ s->last_mv[i][1][0] = mx;
+ dmx = get_dmv(s);
+ my = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
+ s->last_mv[i][0][1] >> 1);
+ dmy = get_dmv(s);
+ s->mv_type = MV_TYPE_DMV;
+ /* XXX: totally broken */
+ if (s->picture_structure == PICT_FRAME) {
+ s->last_mv[i][0][1] = my << 1;
+ s->last_mv[i][1][1] = my << 1;
+
+ m = s->top_field_first ? 1 : 3;
+ /* top -> top pred */
+ s->mv[i][0][0] = mx;
+ s->mv[i][0][1] = my << 1;
+ s->mv[i][1][0] = ((mx * m + (mx > 0)) >> 1) + dmx;
+ s->mv[i][1][1] = ((my * m + (my > 0)) >> 1) + dmy - 1;
+ m = 4 - m;
+ s->mv[i][2][0] = mx;
+ s->mv[i][2][1] = my << 1;
+ s->mv[i][3][0] = ((mx * m + (mx > 0)) >> 1) + dmx;
+ s->mv[i][3][1] = ((my * m + (my > 0)) >> 1) + dmy + 1;
+ } else {
+ s->last_mv[i][0][1] = my;
+ s->last_mv[i][1][1] = my;
+ s->mv[i][0][0] = mx;
+ s->mv[i][0][1] = my;
+ s->mv[i][1][0] = ((mx + (mx > 0)) >> 1) + dmx;
+ s->mv[i][1][1] = ((my + (my > 0)) >> 1) + dmy - 1
+ /* + 2 * cur_field */;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ if ((mb_type & MB_INTRA) && s->concealment_motion_vectors) {
+ skip_bits1(&s->gb); /* marker */
+ }
+
+ if (mb_type & MB_PAT) {
+ cbp = get_vlc(&s->gb, &mb_pat_vlc);
+ if (cbp < 0)
+ return -1;
+ cbp++;
+ }
+ dprintf("cbp=%x\n", cbp);
+
+ if (s->mpeg2) {
+ if (s->mb_intra) {
+ for(i=0;i<6;i++) {
+ if (cbp & (1 << (5 - i))) {
+ if (mpeg2_decode_block_intra(s, block[i], i) < 0)
+ return -1;
+ }
+ }
+ } else {
+ for(i=0;i<6;i++) {
+ if (cbp & (1 << (5 - i))) {
+ if (mpeg2_decode_block_non_intra(s, block[i], i) < 0)
+ return -1;
+ }
+ }
+ }
+ } else {
+ for(i=0;i<6;i++) {
+ if (cbp & (1 << (5 - i))) {
+ if (mpeg1_decode_block(s, block[i], i) < 0)
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
+/* as h263, but only 17 codes */
+static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred)
+{
+ int code, sign, val, m, l, shift;
+
+ code = get_vlc(&s->gb, &mv_vlc);
+ if (code < 0) {
+ return 0xffff;
+ }
+ if (code == 0) {
+ return pred;
+ }
+ sign = get_bits1(&s->gb);
+ shift = fcode - 1;
+ val = (code - 1) << shift;
+ if (shift > 0)
+ val |= get_bits(&s->gb, shift);
+ val++;
+ if (sign)
+ val = -val;
+ val += pred;
+
+ /* modulo decoding */
+ l = (1 << shift) * 16;
+ m = 2 * l;
+ if (val < -l) {
+ val += m;
+ } else if (val >= l) {
+ val -= m;
+ }
+ return val;
+}
+
+static inline int decode_dc(MpegEncContext *s, int component)
+{
+ int code, diff;
+
+ if (component == 0) {
+ code = get_vlc(&s->gb, &dc_lum_vlc);
+ } else {
+ code = get_vlc(&s->gb, &dc_chroma_vlc);
+ }
+ if (code < 0)
+ return 0xffff;
+ if (code == 0) {
+ diff = 0;
+ } else {
+ diff = get_bits(&s->gb, code);
+ if ((diff & (1 << (code - 1))) == 0)
+ diff = (-1 << code) | (diff + 1);
+ }
+ return diff;
+}
+
+static int mpeg1_decode_block(MpegEncContext *s,
+ DCTELEM *block,
+ int n)
+{
+ int level, dc, diff, i, j, run;
+ int code, component;
+ RLTable *rl = &rl_mpeg1;
+
+ if (s->mb_intra) {
+ /* DC coef */
+ component = (n <= 3 ? 0 : n - 4 + 1);
+ diff = decode_dc(s, component);
+ if (diff >= 0xffff)
+ return -1;
+ dc = s->last_dc[component];
+ dc += diff;
+ s->last_dc[component] = dc;
+ block[0] = dc;
+ dprintf("dc=%d diff=%d\n", dc, diff);
+ i = 1;
+ } else {
+ int bit_cnt, v;
+ UINT32 bit_buf;
+ UINT8 *buf_ptr;
+ i = 0;
+ /* special case for the first coef. no need to add a second vlc table */
+ SAVE_BITS(&s->gb);
+ SHOW_BITS(&s->gb, v, 2);
+ if (v & 2) {
+ run = 0;
+ level = 1 - ((v & 1) << 1);
+ FLUSH_BITS(2);
+ RESTORE_BITS(&s->gb);
+ goto add_coef;
+ }
+ RESTORE_BITS(&s->gb);
+ }
+
+ /* now quantify & encode AC coefs */
+ for(;;) {
+ code = get_vlc(&s->gb, &rl->vlc);
+ if (code < 0) {
+ return -1;
+ }
+ if (code == 112) {
+ break;
+ } else if (code == 111) {
+ /* escape */
+ run = get_bits(&s->gb, 6);
+ level = get_bits(&s->gb, 8);
+ level = (level << 24) >> 24;
+ if (level == -128) {
+ level = get_bits(&s->gb, 8) - 256;
+ } else if (level == 0) {
+ level = get_bits(&s->gb, 8);
+ }
+ } else {
+ run = rl->table_run[code];
+ level = rl->table_level[code];
+ if (get_bits1(&s->gb))
+ level = -level;
+ }
+ i += run;
+ if (i >= 64)
+ return -1;
+ add_coef:
+ dprintf("%d: run=%d level=%d\n", n, run, level);
+ j = zigzag_direct[i];
+ block[j] = level;
+ i++;
+ }
+ s->block_last_index[n] = i;
+ return 0;
+}
+
+/* Also does unquantization here, since I will never support mpeg2
+ encoding */
+static int mpeg2_decode_block_non_intra(MpegEncContext *s,
+ DCTELEM *block,
+ int n)
+{
+ int level, i, j, run;
+ int code;
+ RLTable *rl = &rl_mpeg1;
+ const UINT8 *scan_table;
+ const UINT16 *matrix;
+ int mismatch;
+
+ if (s->alternate_scan)
+ scan_table = ff_alternate_vertical_scan;
+ else
+ scan_table = zigzag_direct;
+ mismatch = 1;
+
+ {
+ int bit_cnt, v;
+ UINT32 bit_buf;
+ UINT8 *buf_ptr;
+ i = 0;
+ if (n < 4)
+ matrix = s->non_intra_matrix;
+ else
+ matrix = s->chroma_non_intra_matrix;
+
+ /* special case for the first coef. no need to add a second vlc table */
+ SAVE_BITS(&s->gb);
+ SHOW_BITS(&s->gb, v, 2);
+ if (v & 2) {
+ run = 0;
+ level = 1 - ((v & 1) << 1);
+ FLUSH_BITS(2);
+ RESTORE_BITS(&s->gb);
+ goto add_coef;
+ }
+ RESTORE_BITS(&s->gb);
+ }
+
+ /* now quantify & encode AC coefs */
+ for(;;) {
+ code = get_vlc(&s->gb, &rl->vlc);
+ if (code < 0)
+ return -1;
+ if (code == 112) {
+ break;
+ } else if (code == 111) {
+ /* escape */
+ run = get_bits(&s->gb, 6);
+ level = get_bits(&s->gb, 12);
+ level = (level << 20) >> 20;
+ } else {
+ run = rl->table_run[code];
+ level = rl->table_level[code];
+ if (get_bits1(&s->gb))
+ level = -level;
+ }
+ i += run;
+ if (i >= 64)
+ return -1;
+ add_coef:
+ j = scan_table[i];
+ dprintf("%d: run=%d level=%d\n", n, run, level);
+ level = ((level * 2 + 1) * s->qscale * matrix[j]) / 32;
+ /* XXX: is it really necessary to saturate since the encoder
+ knows whats going on ? */
+ mismatch ^= level;
+ block[j] = level;
+ i++;
+ }
+ block[63] ^= (mismatch & 1);
+ s->block_last_index[n] = i;
+ return 0;
+}
+
+static int mpeg2_decode_block_intra(MpegEncContext *s,
+ DCTELEM *block,
+ int n)
+{
+ int level, dc, diff, i, j, run;
+ int code, component;
+ RLTable *rl;
+ const UINT8 *scan_table;
+ const UINT16 *matrix;
+ int mismatch;
+
+ if (s->alternate_scan)
+ scan_table = ff_alternate_vertical_scan;
+ else
+ scan_table = zigzag_direct;
+ mismatch = 1;
+
+ /* DC coef */
+ component = (n <= 3 ? 0 : n - 4 + 1);
+ diff = decode_dc(s, component);
+ if (diff >= 0xffff)
+ return -1;
+ dc = s->last_dc[component];
+ dc += diff;
+ s->last_dc[component] = dc;
+ block[0] = dc << (3 - s->intra_dc_precision);
+ dprintf("dc=%d\n", block[0]);
+ i = 1;
+ if (s->intra_vlc_format)
+ rl = &rl_mpeg2;
+ else
+ rl = &rl_mpeg1;
+ if (n < 4)
+ matrix = s->intra_matrix;
+ else
+ matrix = s->chroma_intra_matrix;
+
+ /* now quantify & encode AC coefs */
+ for(;;) {
+ code = get_vlc(&s->gb, &rl->vlc);
+ if (code < 0)
+ return -1;
+ if (code == 112) {
+ break;
+ } else if (code == 111) {
+ /* escape */
+ run = get_bits(&s->gb, 6);
+ level = get_bits(&s->gb, 12);
+ level = (level << 20) >> 20;
+ } else {
+ run = rl->table_run[code];
+ level = rl->table_level[code];
+ if (get_bits1(&s->gb))
+ level = -level;
+ }
+ i += run;
+ if (i >= 64)
+ return -1;
+ j = scan_table[i];
+ dprintf("%d: run=%d level=%d\n", n, run, level);
+ level = (level * s->qscale * matrix[j]) / 16;
+ /* XXX: is it really necessary to saturate since the encoder
+ knows whats going on ? */
+ mismatch ^= level;
+ block[j] = level;
+ i++;
+ }
+ block[63] ^= (mismatch & 1);
+ s->block_last_index[n] = i;
+ return 0;
+}
+
+/* compressed picture size */
+#define PICTURE_BUFFER_SIZE 100000
+
+typedef struct Mpeg1Context {
+ MpegEncContext mpeg_enc_ctx;
+ UINT32 header_state;
+ int start_code; /* current start code */
+ UINT8 buffer[PICTURE_BUFFER_SIZE];
+ UINT8 *buf_ptr;
+ int buffer_size;
+ int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
+} Mpeg1Context;
+
+static int mpeg_decode_init(AVCodecContext *avctx)
+{
+ Mpeg1Context *s = avctx->priv_data;
+
+ s->header_state = 0xff;
+ s->mpeg_enc_ctx_allocated = 0;
+ s->buffer_size = PICTURE_BUFFER_SIZE;
+ s->start_code = -1;
+ s->buf_ptr = s->buffer;
+ s->mpeg_enc_ctx.picture_number = 0;
+ return 0;
+}
+
+/* return the 8 bit start code value and update the search
+ state. Return -1 if no start code found */
+static int find_start_code(UINT8 **pbuf_ptr, UINT8 *buf_end,
+ UINT32 *header_state)
+{
+ UINT8 *buf_ptr;
+ unsigned int state, v;
+ int val;
+
+ state = *header_state;
+ buf_ptr = *pbuf_ptr;
+ while (buf_ptr < buf_end) {
+ v = *buf_ptr++;
+ if (state == 0x000001) {
+ state = ((state << 8) | v) & 0xffffff;
+ val = state;
+ goto found;
+ }
+ state = ((state << 8) | v) & 0xffffff;
+ }
+ val = -1;
+ found:
+ *pbuf_ptr = buf_ptr;
+ *header_state = state;
+ return val;
+}
+
+static int mpeg1_decode_picture(AVCodecContext *avctx,
+ UINT8 *buf, int buf_size)
+{
+ Mpeg1Context *s1 = avctx->priv_data;
+ MpegEncContext *s = &s1->mpeg_enc_ctx;
+ int ref, f_code;
+
+ init_get_bits(&s->gb, buf, buf_size);
+
+ ref = get_bits(&s->gb, 10); /* temporal ref */
+ s->pict_type = get_bits(&s->gb, 3);
+ dprintf("pict_type=%d\n", s->pict_type);
+ skip_bits(&s->gb, 16);
+ if (s->pict_type == P_TYPE || s->pict_type == B_TYPE) {
+ s->full_pel[0] = get_bits1(&s->gb);
+ f_code = get_bits(&s->gb, 3);
+ if (f_code == 0)
+ return -1;
+ s->mpeg_f_code[0][0] = f_code;
+ s->mpeg_f_code[0][1] = f_code;
+ }
+ if (s->pict_type == B_TYPE) {
+ s->full_pel[1] = get_bits1(&s->gb);
+ f_code = get_bits(&s->gb, 3);
+ if (f_code == 0)
+ return -1;
+ s->mpeg_f_code[1][0] = f_code;
+ s->mpeg_f_code[1][1] = f_code;
+ }
+ s->y_dc_scale = 8;
+ s->c_dc_scale = 8;
+ s->first_slice = 1;
+ return 0;
+}
+
+static void mpeg_decode_sequence_extension(MpegEncContext *s)
+{
+ int horiz_size_ext, vert_size_ext;
+ int bit_rate_ext, vbv_buf_ext, low_delay;
+ int frame_rate_ext_n, frame_rate_ext_d;
+
+ skip_bits(&s->gb, 8); /* profil and level */
+ skip_bits(&s->gb, 1); /* progressive_sequence */
+ skip_bits(&s->gb, 2); /* chroma_format */
+ horiz_size_ext = get_bits(&s->gb, 2);
+ vert_size_ext = get_bits(&s->gb, 2);
+ s->width |= (horiz_size_ext << 12);
+ s->height |= (vert_size_ext << 12);
+ bit_rate_ext = get_bits(&s->gb, 12); /* XXX: handle it */
+ s->bit_rate = ((s->bit_rate / 400) | (bit_rate_ext << 12)) * 400;
+ skip_bits1(&s->gb); /* marker */
+ vbv_buf_ext = get_bits(&s->gb, 8);
+ low_delay = get_bits1(&s->gb);
+ frame_rate_ext_n = get_bits(&s->gb, 2);
+ frame_rate_ext_d = get_bits(&s->gb, 5);
+ if (frame_rate_ext_d >= 1)
+ s->frame_rate = (s->frame_rate * frame_rate_ext_n) / frame_rate_ext_d;
+ dprintf("sequence extension\n");
+ s->mpeg2 = 1;
+}
+
+static void mpeg_decode_quant_matrix_extension(MpegEncContext *s)
+{
+ int i, v;
+
+ if (get_bits1(&s->gb)) {
+ for(i=0;i<64;i++) {
+ v = get_bits(&s->gb, 8);
+ s->intra_matrix[i] = v;
+ s->chroma_intra_matrix[i] = v;
+ }
+ }
+ if (get_bits1(&s->gb)) {
+ for(i=0;i<64;i++) {
+ v = get_bits(&s->gb, 8);
+ s->non_intra_matrix[i] = v;
+ s->chroma_non_intra_matrix[i] = v;
+ }
+ }
+ if (get_bits1(&s->gb)) {
+ for(i=0;i<64;i++) {
+ v = get_bits(&s->gb, 8);
+ s->chroma_intra_matrix[i] = v;
+ }
+ }
+ if (get_bits1(&s->gb)) {
+ for(i=0;i<64;i++) {
+ v = get_bits(&s->gb, 8);
+ s->chroma_non_intra_matrix[i] = v;
+ }
+ }
+}
+
+static void mpeg_decode_picture_coding_extension(MpegEncContext *s)
+{
+ s->full_pel[0] = s->full_pel[1] = 0;
+ s->mpeg_f_code[0][0] = get_bits(&s->gb, 4);
+ s->mpeg_f_code[0][1] = get_bits(&s->gb, 4);
+ s->mpeg_f_code[1][0] = get_bits(&s->gb, 4);
+ s->mpeg_f_code[1][1] = get_bits(&s->gb, 4);
+ s->intra_dc_precision = get_bits(&s->gb, 2);
+ s->picture_structure = get_bits(&s->gb, 2);
+ s->top_field_first = get_bits1(&s->gb);
+ s->frame_pred_frame_dct = get_bits1(&s->gb);
+ s->concealment_motion_vectors = get_bits1(&s->gb);
+ s->q_scale_type = get_bits1(&s->gb);
+ s->intra_vlc_format = get_bits1(&s->gb);
+ s->alternate_scan = get_bits1(&s->gb);
+ s->repeat_first_field = get_bits1(&s->gb);
+ s->chroma_420_type = get_bits1(&s->gb);
+ s->progressive_frame = get_bits1(&s->gb);
+ /* composite display not parsed */
+ dprintf("dc_preci=%d\n", s->intra_dc_precision);
+ dprintf("pict_structure=%d\n", s->picture_structure);
+ dprintf("conceal=%d\n", s->concealment_motion_vectors);
+ dprintf("intrafmt=%d\n", s->intra_vlc_format);
+ dprintf("frame_pred_frame_dct=%d\n", s->frame_pred_frame_dct);
+}
+
+static void mpeg_decode_extension(AVCodecContext *avctx,
+ UINT8 *buf, int buf_size)
+{
+ Mpeg1Context *s1 = avctx->priv_data;
+ MpegEncContext *s = &s1->mpeg_enc_ctx;
+ int ext_type;
+
+ init_get_bits(&s->gb, buf, buf_size);
+
+ ext_type = get_bits(&s->gb, 4);
+ switch(ext_type) {
+ case 0x1:
+ /* sequence ext */
+ mpeg_decode_sequence_extension(s);
+ break;
+ case 0x3:
+ /* quant matrix extension */
+ mpeg_decode_quant_matrix_extension(s);
+ break;
+ case 0x8:
+ /* picture extension */
+ mpeg_decode_picture_coding_extension(s);
+ break;
+ }
+}
+
+/* return 1 if end of frame */
+static int mpeg_decode_slice(AVCodecContext *avctx,
+ AVPicture *pict,
+ int start_code,
+ UINT8 *buf, int buf_size)
+{
+ Mpeg1Context *s1 = avctx->priv_data;
+ MpegEncContext *s = &s1->mpeg_enc_ctx;
+ int ret;
+
+ start_code = (start_code - 1) & 0xff;
+ if (start_code >= s->mb_height)
+ return -1;
+ s->last_dc[0] = 1 << (7 + s->intra_dc_precision);
+ s->last_dc[1] = s->last_dc[0];
+ s->last_dc[2] = s->last_dc[0];
+ memset(s->last_mv, 0, sizeof(s->last_mv));
+ s->mb_x = -1;
+ s->mb_y = start_code;
+ s->mb_incr = 0;
+
+ /* start frame decoding */
+ if (s->first_slice) {
+ s->first_slice = 0;
+ MPV_frame_start(s);
+ }
+
+ init_get_bits(&s->gb, buf, buf_size);
+
+ s->qscale = get_bits(&s->gb, 5);
+ /* extra slice info */
+ while (get_bits1(&s->gb) != 0) {
+ skip_bits(&s->gb, 8);
+ }
+
+ for(;;) {
+ memset(s->block, 0, sizeof(s->block));
+ ret = mpeg_decode_mb(s, s->block);
+ dprintf("ret=%d\n", ret);
+ if (ret < 0)
+ return -1;
+ if (ret == 1)
+ break;
+ MPV_decode_mb(s, s->block);
+ }
+
+ /* end of slice reached */
+ if (s->mb_x == (s->mb_width - 1) &&
+ s->mb_y == (s->mb_height - 1)) {
+ /* end of image */
+ UINT8 **picture;
+
+ MPV_frame_end(s);
+
+ /* XXX: incorrect reported qscale for mpeg2 */
+ if (s->pict_type == B_TYPE) {
+ picture = s->current_picture;
+ avctx->quality = s->qscale;
+ } else {
+ /* latency of 1 frame for I and P frames */
+ /* XXX: use another variable than picture_number */
+ if (s->picture_number == 0) {
+ picture = NULL;
+ } else {
+ picture = s->last_picture;
+ avctx->quality = s->last_qscale;
+ }
+ s->last_qscale = s->qscale;
+ s->picture_number++;
+ }
+ if (picture) {
+ pict->data[0] = picture[0];
+ pict->data[1] = picture[1];
+ pict->data[2] = picture[2];
+ pict->linesize[0] = s->linesize;
+ pict->linesize[1] = s->linesize / 2;
+ pict->linesize[2] = s->linesize / 2;
+ return 1;
+ } else {
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+}
+
+static int mpeg1_decode_sequence(AVCodecContext *avctx,
+ UINT8 *buf, int buf_size)
+{
+ Mpeg1Context *s1 = avctx->priv_data;
+ MpegEncContext *s = &s1->mpeg_enc_ctx;
+ int width, height, i, v;
+
+ init_get_bits(&s->gb, buf, buf_size);
+
+ width = get_bits(&s->gb, 12);
+ height = get_bits(&s->gb, 12);
+ skip_bits(&s->gb, 4);
+ s->frame_rate_index = get_bits(&s->gb, 4);
+ if (s->frame_rate_index == 0)
+ return -1;
+ s->bit_rate = get_bits(&s->gb, 18) * 400;
+ if (get_bits1(&s->gb) == 0) /* marker */
+ return -1;
+ if (width <= 0 || height <= 0 ||
+ (width % 2) != 0 || (height % 2) != 0)
+ return -1;
+ if (width != s->width ||
+ height != s->height) {
+ /* start new mpeg1 context decoding */
+ s->out_format = FMT_MPEG1;
+ if (s1->mpeg_enc_ctx_allocated) {
+ MPV_common_end(s);
+ }
+ s->width = width;
+ s->height = height;
+ s->has_b_frames = 1;
+ avctx->width = width;
+ avctx->height = height;
+ avctx->frame_rate = frame_rate_tab[s->frame_rate_index];
+ avctx->bit_rate = s->bit_rate;
+
+ if (MPV_common_init(s) < 0)
+ return -1;
+ mpeg1_init_vlc(s);
+ s1->mpeg_enc_ctx_allocated = 1;
+ }
+
+ skip_bits(&s->gb, 10); /* vbv_buffer_size */
+ skip_bits(&s->gb, 1);
+
+ /* get matrix */
+ if (get_bits1(&s->gb)) {
+ for(i=0;i<64;i++) {
+ v = get_bits(&s->gb, 8);
+ s->intra_matrix[i] = v;
+ s->chroma_intra_matrix[i] = v;
+ }
+ } else {
+ for(i=0;i<64;i++) {
+ v = default_intra_matrix[i];
+ s->intra_matrix[i] = v;
+ s->chroma_intra_matrix[i] = v;
+ }
+ }
+ if (get_bits1(&s->gb)) {
+ for(i=0;i<64;i++) {
+ v = get_bits(&s->gb, 8);
+ s->non_intra_matrix[i] = v;
+ s->chroma_non_intra_matrix[i] = v;
+ }
+ } else {
+ for(i=0;i<64;i++) {
+ v = default_non_intra_matrix[i];
+ s->non_intra_matrix[i] = v;
+ s->chroma_non_intra_matrix[i] = v;
+ }
+ }
+
+ /* we set mpeg2 parameters so that it emulates mpeg1 */
+ s->progressive_sequence = 1;
+ s->progressive_frame = 1;
+ s->picture_structure = PICT_FRAME;
+ s->frame_pred_frame_dct = 1;
+ s->mpeg2 = 0;
+ return 0;
+}
+
+/* handle buffering and image synchronisation */
+static int mpeg_decode_frame(AVCodecContext *avctx,
+ void *data, int *data_size,
+ UINT8 *buf, int buf_size)
+{
+ Mpeg1Context *s = avctx->priv_data;
+ UINT8 *buf_end, *buf_ptr, *buf_start;
+ int len, start_code_found, ret, code, start_code, input_size;
+ AVPicture *picture = data;
+
+ dprintf("fill_buffer\n");
+
+ *data_size = 0;
+ /* special case for last picture */
+ if (buf_size == 0) {
+ MpegEncContext *s2 = &s->mpeg_enc_ctx;
+ if (s2->picture_number > 0) {
+ picture->data[0] = s2->next_picture[0];
+ picture->data[1] = s2->next_picture[1];
+ picture->data[2] = s2->next_picture[2];
+ picture->linesize[0] = s2->linesize;
+ picture->linesize[1] = s2->linesize / 2;
+ picture->linesize[2] = s2->linesize / 2;
+ *data_size = sizeof(AVPicture);
+ }
+ return 0;
+ }
+
+ buf_ptr = buf;
+ buf_end = buf + buf_size;
+ while (buf_ptr < buf_end) {
+ buf_start = buf_ptr;
+ /* find start next code */
+ code = find_start_code(&buf_ptr, buf_end, &s->header_state);
+ if (code >= 0) {
+ start_code_found = 1;
+ } else {
+ start_code_found = 0;
+ }
+ /* copy to buffer */
+ len = buf_ptr - buf_start;
+ if (len + (s->buf_ptr - s->buffer) > s->buffer_size) {
+ /* data too big : flush */
+ s->buf_ptr = s->buffer;
+ if (start_code_found)
+ s->start_code = code;
+ } else {
+ memcpy(s->buf_ptr, buf_start, len);
+ s->buf_ptr += len;
+
+ if (start_code_found) {
+ /* prepare data for next start code */
+ input_size = s->buf_ptr - s->buffer;
+ start_code = s->start_code;
+ s->buf_ptr = s->buffer;
+ s->start_code = code;
+ switch(start_code) {
+ case SEQ_START_CODE:
+ mpeg1_decode_sequence(avctx, s->buffer,
+ input_size);
+ break;
+
+ case PICTURE_START_CODE:
+ /* we have a complete image : we try to decompress it */
+ mpeg1_decode_picture(avctx,
+ s->buffer, input_size);
+ break;
+ case EXT_START_CODE:
+ mpeg_decode_extension(avctx,
+ s->buffer, input_size);
+ break;
+ default:
+ if (start_code >= SLICE_MIN_START_CODE &&
+ start_code <= SLICE_MAX_START_CODE) {
+ ret = mpeg_decode_slice(avctx, picture,
+ start_code, s->buffer, input_size);
+ if (ret == 1) {
+ /* got a picture: exit */
+ *data_size = sizeof(AVPicture);
+ goto the_end;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+ the_end:
+ return buf_ptr - buf;
+}
+
+static int mpeg_decode_end(AVCodecContext *avctx)
+{
+ Mpeg1Context *s = avctx->priv_data;
+
+ if (s->mpeg_enc_ctx_allocated)
+ MPV_common_end(&s->mpeg_enc_ctx);
+ return 0;
+}
+
+AVCodec mpeg_decoder = {
+ "mpegvideo",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_MPEG1VIDEO,
+ sizeof(Mpeg1Context),
+ mpeg_decode_init,
+ NULL,
+ mpeg_decode_end,
+ mpeg_decode_frame,
+};
diff --git a/src/libffmpeg/libavcodec/mpeg12data.h b/src/libffmpeg/libavcodec/mpeg12data.h
new file mode 100644
index 000000000..f397c4a17
--- /dev/null
+++ b/src/libffmpeg/libavcodec/mpeg12data.h
@@ -0,0 +1,363 @@
+/*
+ * MPEG1/2 tables
+ */
+
+const UINT8 default_intra_matrix[64] = {
+ 8, 16, 19, 22, 26, 27, 29, 34,
+ 16, 16, 22, 24, 27, 29, 34, 37,
+ 19, 22, 26, 27, 29, 34, 34, 38,
+ 22, 22, 26, 27, 29, 34, 37, 40,
+ 22, 26, 27, 29, 32, 35, 40, 48,
+ 26, 27, 29, 32, 35, 40, 48, 58,
+ 26, 27, 29, 34, 38, 46, 56, 69,
+ 27, 29, 35, 38, 46, 56, 69, 83
+};
+
+const UINT8 default_non_intra_matrix[64] = {
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+};
+
+const unsigned char vlc_dc_table[256] = {
+ 0, 1, 2, 2,
+ 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+};
+
+const UINT16 vlc_dc_lum_code[12] = {
+ 0x4, 0x0, 0x1, 0x5, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe, 0x1ff,
+};
+const unsigned char vlc_dc_lum_bits[12] = {
+ 3, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 9,
+};
+
+const UINT16 vlc_dc_chroma_code[12] = {
+ 0x0, 0x1, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe, 0x3fe, 0x3ff,
+};
+const unsigned char vlc_dc_chroma_bits[12] = {
+ 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10,
+};
+
+static const UINT16 mpeg1_vlc[113][2] = {
+ { 0x3, 2 }, { 0x4, 4 }, { 0x5, 5 }, { 0x6, 7 },
+ { 0x26, 8 }, { 0x21, 8 }, { 0xa, 10 }, { 0x1d, 12 },
+ { 0x18, 12 }, { 0x13, 12 }, { 0x10, 12 }, { 0x1a, 13 },
+ { 0x19, 13 }, { 0x18, 13 }, { 0x17, 13 }, { 0x1f, 14 },
+ { 0x1e, 14 }, { 0x1d, 14 }, { 0x1c, 14 }, { 0x1b, 14 },
+ { 0x1a, 14 }, { 0x19, 14 }, { 0x18, 14 }, { 0x17, 14 },
+ { 0x16, 14 }, { 0x15, 14 }, { 0x14, 14 }, { 0x13, 14 },
+ { 0x12, 14 }, { 0x11, 14 }, { 0x10, 14 }, { 0x18, 15 },
+ { 0x17, 15 }, { 0x16, 15 }, { 0x15, 15 }, { 0x14, 15 },
+ { 0x13, 15 }, { 0x12, 15 }, { 0x11, 15 }, { 0x10, 15 },
+ { 0x3, 3 }, { 0x6, 6 }, { 0x25, 8 }, { 0xc, 10 },
+ { 0x1b, 12 }, { 0x16, 13 }, { 0x15, 13 }, { 0x1f, 15 },
+ { 0x1e, 15 }, { 0x1d, 15 }, { 0x1c, 15 }, { 0x1b, 15 },
+ { 0x1a, 15 }, { 0x19, 15 }, { 0x13, 16 }, { 0x12, 16 },
+ { 0x11, 16 }, { 0x10, 16 }, { 0x5, 4 }, { 0x4, 7 },
+ { 0xb, 10 }, { 0x14, 12 }, { 0x14, 13 }, { 0x7, 5 },
+ { 0x24, 8 }, { 0x1c, 12 }, { 0x13, 13 }, { 0x6, 5 },
+ { 0xf, 10 }, { 0x12, 12 }, { 0x7, 6 }, { 0x9, 10 },
+ { 0x12, 13 }, { 0x5, 6 }, { 0x1e, 12 }, { 0x14, 16 },
+ { 0x4, 6 }, { 0x15, 12 }, { 0x7, 7 }, { 0x11, 12 },
+ { 0x5, 7 }, { 0x11, 13 }, { 0x27, 8 }, { 0x10, 13 },
+ { 0x23, 8 }, { 0x1a, 16 }, { 0x22, 8 }, { 0x19, 16 },
+ { 0x20, 8 }, { 0x18, 16 }, { 0xe, 10 }, { 0x17, 16 },
+ { 0xd, 10 }, { 0x16, 16 }, { 0x8, 10 }, { 0x15, 16 },
+ { 0x1f, 12 }, { 0x1a, 12 }, { 0x19, 12 }, { 0x17, 12 },
+ { 0x16, 12 }, { 0x1f, 13 }, { 0x1e, 13 }, { 0x1d, 13 },
+ { 0x1c, 13 }, { 0x1b, 13 }, { 0x1f, 16 }, { 0x1e, 16 },
+ { 0x1d, 16 }, { 0x1c, 16 }, { 0x1b, 16 },
+ { 0x1, 6 }, /* escape */
+ { 0x2, 2 }, /* EOB */
+};
+
+static const UINT16 mpeg2_vlc[113][2] = {
+ {0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5},
+ {0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7},
+ {0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8},
+ {0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14},
+ {0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14},
+ {0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14},
+ {0x16,14}, {0x15,14}, {0x14,14}, {0x13,14},
+ {0x12,14}, {0x11,14}, {0x10,14}, {0x18,15},
+ {0x17,15}, {0x16,15}, {0x15,15}, {0x14,15},
+ {0x13,15}, {0x12,15}, {0x11,15}, {0x10,15},
+ {0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8},
+ {0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15},
+ {0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15},
+ {0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16},
+ {0x11,16}, {0x10,16}, {0x05, 5}, {0x07, 7},
+ {0xfc, 8}, {0x0c,10}, {0x14,13}, {0x07, 5},
+ {0x26, 8}, {0x1c,12}, {0x13,13}, {0x06, 6},
+ {0xfd, 8}, {0x12,12}, {0x07, 6}, {0x04, 9},
+ {0x12,13}, {0x06, 7}, {0x1e,12}, {0x14,16},
+ {0x04, 7}, {0x15,12}, {0x05, 7}, {0x11,12},
+ {0x78, 7}, {0x11,13}, {0x7a, 7}, {0x10,13},
+ {0x21, 8}, {0x1a,16}, {0x25, 8}, {0x19,16},
+ {0x24, 8}, {0x18,16}, {0x05, 9}, {0x17,16},
+ {0x07, 9}, {0x16,16}, {0x0d,10}, {0x15,16},
+ {0x1f,12}, {0x1a,12}, {0x19,12}, {0x17,12},
+ {0x16,12}, {0x1f,13}, {0x1e,13}, {0x1d,13},
+ {0x1c,13}, {0x1b,13}, {0x1f,16}, {0x1e,16},
+ {0x1d,16}, {0x1c,16}, {0x1b,16},
+ {0x01,6}, /* escape */
+ {0x06,4}, /* EOB */
+};
+
+static const INT8 mpeg1_level[111] = {
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40,
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 1, 2, 3, 4, 5, 1,
+ 2, 3, 4, 1, 2, 3, 1, 2,
+ 3, 1, 2, 3, 1, 2, 1, 2,
+ 1, 2, 1, 2, 1, 2, 1, 2,
+ 1, 2, 1, 2, 1, 2, 1, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1,
+};
+
+static const INT8 mpeg1_run[111] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 2, 2, 2, 2, 2, 3,
+ 3, 3, 3, 4, 4, 4, 5, 5,
+ 5, 6, 6, 6, 7, 7, 8, 8,
+ 9, 9, 10, 10, 11, 11, 12, 12,
+ 13, 13, 14, 14, 15, 15, 16, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31,
+};
+
+static RLTable rl_mpeg1 = {
+ 111,
+ 111,
+ mpeg1_vlc,
+ mpeg1_run,
+ mpeg1_level,
+};
+
+static RLTable rl_mpeg2 = {
+ 111,
+ 111,
+ mpeg2_vlc,
+ mpeg1_run,
+ mpeg1_level,
+};
+
+static const UINT8 mbAddrIncrTable[35][2] = {
+ {0x1, 1},
+ {0x3, 3},
+ {0x2, 3},
+ {0x3, 4},
+ {0x2, 4},
+ {0x3, 5},
+ {0x2, 5},
+ {0x7, 7},
+ {0x6, 7},
+ {0xb, 8},
+ {0xa, 8},
+ {0x9, 8},
+ {0x8, 8},
+ {0x7, 8},
+ {0x6, 8},
+ {0x17, 10},
+ {0x16, 10},
+ {0x15, 10},
+ {0x14, 10},
+ {0x13, 10},
+ {0x12, 10},
+ {0x23, 11},
+ {0x22, 11},
+ {0x21, 11},
+ {0x20, 11},
+ {0x1f, 11},
+ {0x1e, 11},
+ {0x1d, 11},
+ {0x1c, 11},
+ {0x1b, 11},
+ {0x1a, 11},
+ {0x19, 11},
+ {0x18, 11},
+ {0x8, 11}, /* escape */
+ {0xf, 11}, /* stuffing */
+};
+
+static const UINT8 mbPatTable[63][2] = {
+ {0xb, 5},
+ {0x9, 5},
+ {0xd, 6},
+ {0xd, 4},
+ {0x17, 7},
+ {0x13, 7},
+ {0x1f, 8},
+ {0xc, 4},
+ {0x16, 7},
+ {0x12, 7},
+ {0x1e, 8},
+ {0x13, 5},
+ {0x1b, 8},
+ {0x17, 8},
+ {0x13, 8},
+ {0xb, 4},
+ {0x15, 7},
+ {0x11, 7},
+ {0x1d, 8},
+ {0x11, 5},
+ {0x19, 8},
+ {0x15, 8},
+ {0x11, 8},
+ {0xf, 6},
+ {0xf, 8},
+ {0xd, 8},
+ {0x3, 9},
+ {0xf, 5},
+ {0xb, 8},
+ {0x7, 8},
+ {0x7, 9},
+ {0xa, 4},
+ {0x14, 7},
+ {0x10, 7},
+ {0x1c, 8},
+ {0xe, 6},
+ {0xe, 8},
+ {0xc, 8},
+ {0x2, 9},
+ {0x10, 5},
+ {0x18, 8},
+ {0x14, 8},
+ {0x10, 8},
+ {0xe, 5},
+ {0xa, 8},
+ {0x6, 8},
+ {0x6, 9},
+ {0x12, 5},
+ {0x1a, 8},
+ {0x16, 8},
+ {0x12, 8},
+ {0xd, 5},
+ {0x9, 8},
+ {0x5, 8},
+ {0x5, 9},
+ {0xc, 5},
+ {0x8, 8},
+ {0x4, 8},
+ {0x4, 9},
+ {0x7, 3},
+ {0xa, 5},
+ {0x8, 5},
+ {0xc, 6}
+};
+
+#define MB_INTRA 0x01
+#define MB_PAT 0x02
+#define MB_BACK 0x04
+#define MB_FOR 0x08
+#define MB_QUANT 0x10
+
+static const UINT8 table_mb_ptype[32][2] = {
+ [ MB_FOR|MB_PAT ] { 1, 1 },
+ [ MB_PAT ] { 1, 2 },
+ [ MB_FOR ] { 1, 3 },
+ [ MB_INTRA ] { 3, 5 },
+ [ MB_QUANT|MB_FOR|MB_PAT ] { 2, 5 },
+ [ MB_QUANT|MB_PAT ] { 1, 5 },
+ [ MB_QUANT|MB_INTRA ] { 1, 6 },
+};
+
+static const UINT8 table_mb_btype[32][2] = {
+ [ MB_FOR|MB_BACK ] { 2, 2 },
+ [ MB_FOR|MB_BACK|MB_PAT ] { 3, 2 },
+ [ MB_BACK ] { 2, 3 },
+ [ MB_BACK|MB_PAT ] { 3, 3 },
+ [ MB_FOR ] { 2, 4 },
+ [ MB_FOR|MB_PAT ] { 3, 4 },
+ [ MB_INTRA ] { 3, 5 },
+ [ MB_QUANT|MB_FOR|MB_BACK|MB_PAT ] { 2, 5 },
+ [ MB_QUANT|MB_FOR|MB_PAT ] { 3, 6 },
+ [ MB_QUANT|MB_BACK|MB_PAT ] { 2, 6 },
+ [ MB_QUANT|MB_INTRA ] { 1, 6 },
+};
+
+static const UINT8 mbMotionVectorTable[17][2] = {
+{ 0x1, 1 },
+{ 0x1, 2 },
+{ 0x1, 3 },
+{ 0x1, 4 },
+{ 0x3, 6 },
+{ 0x5, 7 },
+{ 0x4, 7 },
+{ 0x3, 7 },
+{ 0xb, 9 },
+{ 0xa, 9 },
+{ 0x9, 9 },
+{ 0x11, 10 },
+{ 0x10, 10 },
+{ 0xf, 10 },
+{ 0xe, 10 },
+{ 0xd, 10 },
+{ 0xc, 10 },
+};
+
+//const
+UINT8 zigzag_direct[64] = {
+ 0, 1, 8, 16, 9, 2, 3, 10,
+ 17, 24, 32, 25, 18, 11, 4, 5,
+ 12, 19, 26, 33, 40, 48, 41, 34,
+ 27, 20, 13, 6, 7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36,
+ 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46,
+ 53, 60, 61, 54, 47, 55, 62, 63
+};
+
+static const int frame_rate_tab[9] = {
+ 0,
+ (int)(23.976 * FRAME_RATE_BASE),
+ (int)(24 * FRAME_RATE_BASE),
+ (int)(25 * FRAME_RATE_BASE),
+ (int)(29.97 * FRAME_RATE_BASE),
+ (int)(30 * FRAME_RATE_BASE),
+ (int)(50 * FRAME_RATE_BASE),
+ (int)(59.94 * FRAME_RATE_BASE),
+ (int)(60 * FRAME_RATE_BASE),
+};
+
+static const UINT8 non_linear_qscale[32] = {
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8,10,12,14,16,18,20,22,
+ 24,28,32,36,40,44,48,52,
+ 56,64,72,80,88,96,104,112,
+};
diff --git a/src/libffmpeg/libavcodec/mpeg4data.h b/src/libffmpeg/libavcodec/mpeg4data.h
new file mode 100644
index 000000000..54b93d97e
--- /dev/null
+++ b/src/libffmpeg/libavcodec/mpeg4data.h
@@ -0,0 +1,106 @@
+
+/* dc encoding for mpeg4 */
+static const UINT8 DCtab_lum[13][2] =
+{
+ {3,3}, {3,2}, {2,2}, {2,3}, {1,3}, {1,4}, {1,5}, {1,6}, {1,7},
+ {1,8}, {1,9}, {1,10}, {1,11},
+};
+
+static const UINT8 DCtab_chrom[13][2] =
+{
+ {3,2}, {2,2}, {1,2}, {1,3}, {1,4}, {1,5}, {1,6}, {1,7}, {1,8},
+ {1,9}, {1,10}, {1,11}, {1,12},
+};
+
+const UINT16 intra_vlc[103][2] = {
+{ 0x2, 2 },
+{ 0x6, 3 },{ 0xf, 4 },{ 0xd, 5 },{ 0xc, 5 },
+{ 0x15, 6 },{ 0x13, 6 },{ 0x12, 6 },{ 0x17, 7 },
+{ 0x1f, 8 },{ 0x1e, 8 },{ 0x1d, 8 },{ 0x25, 9 },
+{ 0x24, 9 },{ 0x23, 9 },{ 0x21, 9 },{ 0x21, 10 },
+{ 0x20, 10 },{ 0xf, 10 },{ 0xe, 10 },{ 0x7, 11 },
+{ 0x6, 11 },{ 0x20, 11 },{ 0x21, 11 },{ 0x50, 12 },
+{ 0x51, 12 },{ 0x52, 12 },{ 0xe, 4 },{ 0x14, 6 },
+{ 0x16, 7 },{ 0x1c, 8 },{ 0x20, 9 },{ 0x1f, 9 },
+{ 0xd, 10 },{ 0x22, 11 },{ 0x53, 12 },{ 0x55, 12 },
+{ 0xb, 5 },{ 0x15, 7 },{ 0x1e, 9 },{ 0xc, 10 },
+{ 0x56, 12 },{ 0x11, 6 },{ 0x1b, 8 },{ 0x1d, 9 },
+{ 0xb, 10 },{ 0x10, 6 },{ 0x22, 9 },{ 0xa, 10 },
+{ 0xd, 6 },{ 0x1c, 9 },{ 0x8, 10 },{ 0x12, 7 },
+{ 0x1b, 9 },{ 0x54, 12 },{ 0x14, 7 },{ 0x1a, 9 },
+{ 0x57, 12 },{ 0x19, 8 },{ 0x9, 10 },{ 0x18, 8 },
+{ 0x23, 11 },{ 0x17, 8 },{ 0x19, 9 },{ 0x18, 9 },
+{ 0x7, 10 },{ 0x58, 12 },{ 0x7, 4 },{ 0xc, 6 },
+{ 0x16, 8 },{ 0x17, 9 },{ 0x6, 10 },{ 0x5, 11 },
+{ 0x4, 11 },{ 0x59, 12 },{ 0xf, 6 },{ 0x16, 9 },
+{ 0x5, 10 },{ 0xe, 6 },{ 0x4, 10 },{ 0x11, 7 },
+{ 0x24, 11 },{ 0x10, 7 },{ 0x25, 11 },{ 0x13, 7 },
+{ 0x5a, 12 },{ 0x15, 8 },{ 0x5b, 12 },{ 0x14, 8 },
+{ 0x13, 8 },{ 0x1a, 8 },{ 0x15, 9 },{ 0x14, 9 },
+{ 0x13, 9 },{ 0x12, 9 },{ 0x11, 9 },{ 0x26, 11 },
+{ 0x27, 11 },{ 0x5c, 12 },{ 0x5d, 12 },{ 0x5e, 12 },
+{ 0x5f, 12 },{ 0x3, 7 },
+};
+
+const INT8 intra_level[102] = {
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 10, 1, 2, 3,
+ 4, 5, 1, 2, 3, 4, 1, 2,
+ 3, 1, 2, 3, 1, 2, 3, 1,
+ 2, 3, 1, 2, 1, 2, 1, 1,
+ 1, 1, 1, 1, 2, 3, 4, 5,
+ 6, 7, 8, 1, 2, 3, 1, 2,
+ 1, 2, 1, 2, 1, 2, 1, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1,
+};
+
+const INT8 intra_run[102] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 2, 2, 2,
+ 2, 2, 3, 3, 3, 3, 4, 4,
+ 4, 5, 5, 5, 6, 6, 6, 7,
+ 7, 7, 8, 8, 9, 9, 10, 11,
+ 12, 13, 14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 2, 2,
+ 3, 3, 4, 4, 5, 5, 6, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20,
+};
+
+static RLTable rl_intra = {
+ 102,
+ 67,
+ intra_vlc,
+ intra_run,
+ intra_level,
+};
+
+/* alternate scan orders used when doing AC prediction */
+UINT8 ff_alternate_horizontal_scan[64] = {
+ 0, 1, 2, 3, 8, 9, 16, 17,
+ 10, 11, 4, 5, 6, 7, 15, 14,
+ 13, 12, 19, 18, 24, 25, 32, 33,
+ 26, 27, 20, 21, 22, 23, 28, 29,
+ 30, 31, 34, 35, 40, 41, 48, 49,
+ 42, 43, 36, 37, 38, 39, 44, 45,
+ 46, 47, 50, 51, 56, 57, 58, 59,
+ 52, 53, 54, 55, 60, 61, 62, 63,
+};
+
+UINT8 ff_alternate_vertical_scan[64] = {
+ 0, 8, 16, 24, 1, 9, 2, 10,
+ 17, 25, 32, 40, 48, 56, 57, 49,
+ 41, 33, 26, 18, 3, 11, 4, 12,
+ 19, 27, 34, 42, 50, 58, 35, 43,
+ 51, 59, 20, 28, 5, 13, 6, 14,
+ 21, 29, 36, 44, 52, 60, 37, 45,
+ 53, 61, 22, 30, 7, 15, 23, 31,
+ 38, 46, 54, 62, 39, 47, 55, 63,
+};
diff --git a/src/libffmpeg/libavcodec/mpegvideo.c b/src/libffmpeg/libavcodec/mpegvideo.c
new file mode 100644
index 000000000..8a5745a8f
--- /dev/null
+++ b/src/libffmpeg/libavcodec/mpegvideo.c
@@ -0,0 +1,1357 @@
+/*
+ * The simplest mpeg encoder (well, it was the simplest!)
+ * Copyright (c) 2000,2001 Gerard Lantau.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include "avcodec.h"
+#include "dsputil.h"
+#include "mpegvideo.h"
+
+#ifdef USE_FASTMEMCPY
+#include "fastmemcpy.h"
+#endif
+
+/* FIXME */
+#ifdef ARCH_X86
+#define HAVE_MMX
+#endif
+
+static void encode_picture(MpegEncContext *s, int picture_number);
+static void rate_control_init(MpegEncContext *s);
+static int rate_estimate_qscale(MpegEncContext *s);
+static void dct_unquantize_mpeg1_c(MpegEncContext *s,
+ DCTELEM *block, int n, int qscale);
+static void dct_unquantize_h263_c(MpegEncContext *s,
+ DCTELEM *block, int n, int qscale);
+static int dct_quantize(MpegEncContext *s, DCTELEM *block, int n, int qscale);
+static int dct_quantize_mmx(MpegEncContext *s,
+ DCTELEM *block, int n,
+ int qscale);
+#define EDGE_WIDTH 16
+
+/* enable all paranoid tests for rounding, overflows, etc... */
+//#define PARANOID
+
+//#define DEBUG
+
+/* for jpeg fast DCT */
+#define CONST_BITS 14
+
+static const unsigned short aanscales[64] = {
+ /* precomputed values scaled up by 14 bits */
+ 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
+ 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
+ 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
+ 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
+ 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
+ 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
+ 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
+ 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
+};
+
+static UINT8 h263_chroma_roundtab[16] = {
+ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
+};
+
+/* default motion estimation */
+int motion_estimation_method = ME_LOG;
+
+/* XXX: should use variable shift ? */
+#define QMAT_SHIFT_MMX 19
+#define QMAT_SHIFT 25
+
+static void convert_matrix(int *qmat, const UINT16 *quant_matrix, int qscale)
+{
+ int i;
+
+ if (av_fdct == jpeg_fdct_ifast) {
+ for(i=0;i<64;i++) {
+ /* 16 <= qscale * quant_matrix[i] <= 7905 */
+ /* 19952 <= aanscales[i] * qscale * quant_matrix[i] <= 249205026 */
+
+ qmat[i] = (int)((1ULL << (QMAT_SHIFT + 11)) / (aanscales[i] * qscale * quant_matrix[i]));
+ }
+ } else {
+ for(i=0;i<64;i++) {
+ /* We can safely suppose that 16 <= quant_matrix[i] <= 255
+ So 16 <= qscale * quant_matrix[i] <= 7905
+ so (1 << QMAT_SHIFT) / 16 >= qmat[i] >= (1 << QMAT_SHIFT) / 7905
+ */
+ qmat[i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[i]);
+ }
+ }
+}
+
+/* init common structure for both encoder and decoder */
+int MPV_common_init(MpegEncContext *s)
+{
+ int c_size, i;
+ UINT8 *pict;
+
+ if (s->out_format == FMT_H263)
+ s->dct_unquantize = dct_unquantize_h263_c;
+ else
+ s->dct_unquantize = dct_unquantize_mpeg1_c;
+
+#ifdef HAVE_MMX
+ MPV_common_init_mmx(s);
+#endif
+ s->mb_width = (s->width + 15) / 16;
+ s->mb_height = (s->height + 15) / 16;
+ s->linesize = s->mb_width * 16 + 2 * EDGE_WIDTH;
+
+ for(i=0;i<3;i++) {
+ int w, h, shift, pict_start;
+
+ w = s->linesize;
+ h = s->mb_height * 16 + 2 * EDGE_WIDTH;
+ shift = (i == 0) ? 0 : 1;
+ c_size = (w >> shift) * (h >> shift);
+ pict_start = (w >> shift) * (EDGE_WIDTH >> shift) + (EDGE_WIDTH >> shift);
+
+ pict = av_mallocz(c_size);
+ if (pict == NULL)
+ goto fail;
+ s->last_picture_base[i] = pict;
+ s->last_picture[i] = pict + pict_start;
+
+ pict = av_mallocz(c_size);
+ if (pict == NULL)
+ goto fail;
+ s->next_picture_base[i] = pict;
+ s->next_picture[i] = pict + pict_start;
+
+ if (s->has_b_frames) {
+ pict = av_mallocz(c_size);
+ if (pict == NULL)
+ goto fail;
+ s->aux_picture_base[i] = pict;
+ s->aux_picture[i] = pict + pict_start;
+ }
+ }
+
+ if (s->out_format == FMT_H263) {
+ int size;
+ /* MV prediction */
+ size = (2 * s->mb_width + 2) * (2 * s->mb_height + 2);
+ s->motion_val = malloc(size * 2 * sizeof(INT16));
+ if (s->motion_val == NULL)
+ goto fail;
+ memset(s->motion_val, 0, size * 2 * sizeof(INT16));
+ }
+
+ if (s->h263_pred) {
+ int y_size, c_size, i, size;
+
+ /* dc values */
+
+ y_size = (2 * s->mb_width + 2) * (2 * s->mb_height + 2);
+ c_size = (s->mb_width + 2) * (s->mb_height + 2);
+ size = y_size + 2 * c_size;
+ s->dc_val[0] = malloc(size * sizeof(INT16));
+ if (s->dc_val[0] == NULL)
+ goto fail;
+ s->dc_val[1] = s->dc_val[0] + y_size;
+ s->dc_val[2] = s->dc_val[1] + c_size;
+ for(i=0;i<size;i++)
+ s->dc_val[0][i] = 1024;
+
+ /* ac values */
+ s->ac_val[0] = av_mallocz(size * sizeof(INT16) * 16);
+ if (s->ac_val[0] == NULL)
+ goto fail;
+ s->ac_val[1] = s->ac_val[0] + y_size;
+ s->ac_val[2] = s->ac_val[1] + c_size;
+
+ /* cbp values */
+ s->coded_block = av_mallocz(y_size);
+ if (!s->coded_block)
+ goto fail;
+ }
+ /* default structure is frame */
+ s->picture_structure = PICT_FRAME;
+
+ /* init default q matrix (only for mpeg and mjpeg) */
+ for(i=0;i<64;i++) {
+ s->intra_matrix[i] = default_intra_matrix[i];
+ s->chroma_intra_matrix[i] = default_intra_matrix[i];
+ s->non_intra_matrix[i] = default_non_intra_matrix[i];
+ s->chroma_non_intra_matrix[i] = default_non_intra_matrix[i];
+ }
+ /* init macroblock skip table */
+ if (!s->encoding) {
+ s->mbskip_table = av_mallocz(s->mb_width * s->mb_height);
+ if (!s->mbskip_table)
+ goto fail;
+ }
+
+ s->context_initialized = 1;
+ return 0;
+ fail:
+ if (s->motion_val)
+ free(s->motion_val);
+ if (s->dc_val[0])
+ free(s->dc_val[0]);
+ if (s->ac_val[0])
+ free(s->ac_val[0]);
+ if (s->coded_block)
+ free(s->coded_block);
+ if (s->mbskip_table)
+ free(s->mbskip_table);
+ for(i=0;i<3;i++) {
+ if (s->last_picture_base[i])
+ free(s->last_picture_base[i]);
+ if (s->next_picture_base[i])
+ free(s->next_picture_base[i]);
+ if (s->aux_picture_base[i])
+ free(s->aux_picture_base[i]);
+ }
+ return -1;
+}
+
+/* init common structure for both encoder and decoder */
+void MPV_common_end(MpegEncContext *s)
+{
+ int i;
+
+ if (s->motion_val)
+ free(s->motion_val);
+ if (s->h263_pred) {
+ free(s->dc_val[0]);
+ free(s->ac_val[0]);
+ free(s->coded_block);
+ }
+ if (s->mbskip_table)
+ free(s->mbskip_table);
+ for(i=0;i<3;i++) {
+ free(s->last_picture_base[i]);
+ free(s->next_picture_base[i]);
+ if (s->has_b_frames)
+ free(s->aux_picture_base[i]);
+ }
+ s->context_initialized = 0;
+}
+
+/* init video encoder */
+int MPV_encode_init(AVCodecContext *avctx)
+{
+ MpegEncContext *s = avctx->priv_data;
+
+ s->bit_rate = avctx->bit_rate;
+ s->frame_rate = avctx->frame_rate;
+ s->width = avctx->width;
+ s->height = avctx->height;
+ s->gop_size = avctx->gop_size;
+ if (s->gop_size <= 1) {
+ s->intra_only = 1;
+ s->gop_size = 12;
+ } else {
+ s->intra_only = 0;
+ }
+ s->full_search = motion_estimation_method;
+
+ s->fixed_qscale = (avctx->flags & CODEC_FLAG_QSCALE);
+
+ switch(avctx->codec->id) {
+ case CODEC_ID_MPEG1VIDEO:
+ s->out_format = FMT_MPEG1;
+ break;
+ case CODEC_ID_MJPEG:
+ s->out_format = FMT_MJPEG;
+ s->intra_only = 1; /* force intra only for jpeg */
+ if (mjpeg_init(s) < 0)
+ return -1;
+ break;
+ case CODEC_ID_H263:
+ if (h263_get_picture_format(s->width, s->height) == 7)
+ return -1;
+ s->out_format = FMT_H263;
+ break;
+ case CODEC_ID_H263P:
+ s->out_format = FMT_H263;
+ s->h263_plus = 1;
+ /* XXX: not unrectricted mv yet */
+ break;
+ case CODEC_ID_RV10:
+ s->out_format = FMT_H263;
+ s->h263_rv10 = 1;
+ break;
+ case CODEC_ID_OPENDIVX:
+ s->out_format = FMT_H263;
+ s->h263_pred = 1;
+ s->unrestricted_mv = 1;
+ break;
+ case CODEC_ID_MSMPEG4:
+ s->out_format = FMT_H263;
+ s->h263_msmpeg4 = 1;
+ s->h263_pred = 1;
+ s->unrestricted_mv = 1;
+ break;
+ default:
+ return -1;
+ }
+
+ if (s->out_format == FMT_H263)
+ h263_encode_init_vlc(s);
+
+ s->encoding = 1;
+
+ /* init */
+ if (MPV_common_init(s) < 0)
+ return -1;
+
+ /* rate control init */
+ rate_control_init(s);
+
+ s->picture_number = 0;
+ s->fake_picture_number = 0;
+ /* motion detector init */
+ s->f_code = 1;
+
+ return 0;
+}
+
+int MPV_encode_end(AVCodecContext *avctx)
+{
+ MpegEncContext *s = avctx->priv_data;
+
+#ifdef STATS
+ print_stats();
+#endif
+ MPV_common_end(s);
+ if (s->out_format == FMT_MJPEG)
+ mjpeg_close(s);
+ return 0;
+}
+
+/* draw the edges of width 'w' of an image of size width, height */
+static void draw_edges(UINT8 *buf, int wrap, int width, int height, int w)
+{
+ UINT8 *ptr, *last_line;
+ int i;
+
+ last_line = buf + (height - 1) * wrap;
+ for(i=0;i<w;i++) {
+ /* top and bottom */
+ memcpy(buf - (i + 1) * wrap, buf, width);
+ memcpy(last_line + (i + 1) * wrap, last_line, width);
+ }
+ /* left and right */
+ ptr = buf;
+ for(i=0;i<height;i++) {
+ memset(ptr - w, ptr[0], w);
+ memset(ptr + width, ptr[width-1], w);
+ ptr += wrap;
+ }
+ /* corners */
+ for(i=0;i<w;i++) {
+ memset(buf - (i + 1) * wrap - w, buf[0], w); /* top left */
+ memset(buf - (i + 1) * wrap + width, buf[width-1], w); /* top right */
+ memset(last_line + (i + 1) * wrap - w, last_line[0], w); /* top left */
+ memset(last_line + (i + 1) * wrap + width, last_line[width-1], w); /* top right */
+ }
+}
+
+/* generic function for encode/decode called before a frame is coded/decoded */
+void MPV_frame_start(MpegEncContext *s)
+{
+ int i;
+ UINT8 *tmp;
+
+ if (s->pict_type == B_TYPE) {
+ for(i=0;i<3;i++) {
+ s->current_picture[i] = s->aux_picture[i];
+ }
+ } else {
+ for(i=0;i<3;i++) {
+ /* swap next and last */
+ tmp = s->last_picture[i];
+ s->last_picture[i] = s->next_picture[i];
+ s->next_picture[i] = tmp;
+ s->current_picture[i] = tmp;
+ }
+ }
+}
+
+/* generic function for encode/decode called after a frame has been coded/decoded */
+void MPV_frame_end(MpegEncContext *s)
+{
+ /* draw edge for correct motion prediction if outside */
+ if (s->pict_type != B_TYPE) {
+ draw_edges(s->current_picture[0], s->linesize, s->width, s->height, EDGE_WIDTH);
+ draw_edges(s->current_picture[1], s->linesize/2, s->width/2, s->height/2, EDGE_WIDTH/2);
+ draw_edges(s->current_picture[2], s->linesize/2, s->width/2, s->height/2, EDGE_WIDTH/2);
+ }
+}
+
+int MPV_encode_picture(AVCodecContext *avctx,
+ unsigned char *buf, int buf_size, void *data)
+{
+ MpegEncContext *s = avctx->priv_data;
+ AVPicture *pict = data;
+ int i, j;
+
+ if (s->fixed_qscale)
+ s->qscale = avctx->quality;
+
+ init_put_bits(&s->pb, buf, buf_size, NULL, NULL);
+
+ if (!s->intra_only) {
+ /* first picture of GOP is intra */
+ if ((s->picture_number % s->gop_size) == 0)
+ s->pict_type = I_TYPE;
+ else
+ s->pict_type = P_TYPE;
+ } else {
+ s->pict_type = I_TYPE;
+ }
+ avctx->key_frame = (s->pict_type == I_TYPE);
+
+ MPV_frame_start(s);
+
+ for(i=0;i<3;i++) {
+ UINT8 *src = pict->data[i];
+ UINT8 *dest = s->current_picture[i];
+ int src_wrap = pict->linesize[i];
+ int dest_wrap = s->linesize;
+ int w = s->width;
+ int h = s->height;
+
+ if (i >= 1) {
+ dest_wrap >>= 1;
+ w >>= 1;
+ h >>= 1;
+ }
+
+ for(j=0;j<h;j++) {
+ memcpy(dest, src, w);
+ dest += dest_wrap;
+ src += src_wrap;
+ }
+ s->new_picture[i] = s->current_picture[i];
+ }
+
+ encode_picture(s, s->picture_number);
+
+ MPV_frame_end(s);
+ s->picture_number++;
+
+ if (s->out_format == FMT_MJPEG)
+ mjpeg_picture_trailer(s);
+
+ flush_put_bits(&s->pb);
+ s->total_bits += (s->pb.buf_ptr - s->pb.buf) * 8;
+ avctx->quality = s->qscale;
+ return s->pb.buf_ptr - s->pb.buf;
+}
+
+static inline int clip(int a, int amin, int amax)
+{
+ if (a < amin)
+ return amin;
+ else if (a > amax)
+ return amax;
+ else
+ return a;
+}
+
+/* apply one mpeg motion vector to the three components */
+static inline void mpeg_motion(MpegEncContext *s,
+ UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr,
+ int dest_offset,
+ UINT8 **ref_picture, int src_offset,
+ int field_based, op_pixels_func *pix_op,
+ int motion_x, int motion_y, int h)
+{
+ UINT8 *ptr;
+ int dxy, offset, mx, my, src_x, src_y, height, linesize;
+
+ dxy = ((motion_y & 1) << 1) | (motion_x & 1);
+ src_x = s->mb_x * 16 + (motion_x >> 1);
+ src_y = s->mb_y * (16 >> field_based) + (motion_y >> 1);
+
+ /* WARNING: do no forget half pels */
+ height = s->height >> field_based;
+ src_x = clip(src_x, -16, s->width);
+ if (src_x == s->width)
+ dxy &= ~1;
+ src_y = clip(src_y, -16, height);
+ if (src_y == height)
+ dxy &= ~2;
+ linesize = s->linesize << field_based;
+ ptr = ref_picture[0] + (src_y * linesize) + (src_x) + src_offset;
+ dest_y += dest_offset;
+ pix_op[dxy](dest_y, ptr, linesize, h);
+ pix_op[dxy](dest_y + 8, ptr + 8, linesize, h);
+
+ if (s->out_format == FMT_H263) {
+ dxy = 0;
+ if ((motion_x & 3) != 0)
+ dxy |= 1;
+ if ((motion_y & 3) != 0)
+ dxy |= 2;
+ mx = motion_x >> 2;
+ my = motion_y >> 2;
+ } else {
+ mx = motion_x / 2;
+ my = motion_y / 2;
+ dxy = ((my & 1) << 1) | (mx & 1);
+ mx >>= 1;
+ my >>= 1;
+ }
+
+ src_x = s->mb_x * 8 + mx;
+ src_y = s->mb_y * (8 >> field_based) + my;
+ src_x = clip(src_x, -8, s->width >> 1);
+ if (src_x == (s->width >> 1))
+ dxy &= ~1;
+ src_y = clip(src_y, -8, height >> 1);
+ if (src_y == (height >> 1))
+ dxy &= ~2;
+
+ offset = (src_y * (linesize >> 1)) + src_x + (src_offset >> 1);
+ ptr = ref_picture[1] + offset;
+ pix_op[dxy](dest_cb + (dest_offset >> 1), ptr, linesize >> 1, h >> 1);
+ ptr = ref_picture[2] + offset;
+ pix_op[dxy](dest_cr + (dest_offset >> 1), ptr, linesize >> 1, h >> 1);
+}
+
+static inline void MPV_motion(MpegEncContext *s,
+ UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr,
+ int dir, UINT8 **ref_picture,
+ op_pixels_func *pix_op)
+{
+ int dxy, offset, mx, my, src_x, src_y, motion_x, motion_y;
+ int mb_x, mb_y, i;
+ UINT8 *ptr, *dest;
+
+ mb_x = s->mb_x;
+ mb_y = s->mb_y;
+
+ switch(s->mv_type) {
+ case MV_TYPE_16X16:
+ mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,
+ ref_picture, 0,
+ 0, pix_op,
+ s->mv[dir][0][0], s->mv[dir][0][1], 16);
+ break;
+ case MV_TYPE_8X8:
+ for(i=0;i<4;i++) {
+ motion_x = s->mv[dir][i][0];
+ motion_y = s->mv[dir][i][1];
+
+ dxy = ((motion_y & 1) << 1) | (motion_x & 1);
+ src_x = mb_x * 16 + (motion_x >> 1) + (i & 1) * 8;
+ src_y = mb_y * 16 + (motion_y >> 1) + ((i >> 1) & 1) * 8;
+
+ /* WARNING: do no forget half pels */
+ src_x = clip(src_x, -16, s->width);
+ if (src_x == s->width)
+ dxy &= ~1;
+ src_y = clip(src_y, -16, s->height);
+ if (src_y == s->height)
+ dxy &= ~2;
+
+ ptr = ref_picture[0] + (src_y * s->linesize) + (src_x);
+ dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize;
+ pix_op[dxy](dest, ptr, s->linesize, 8);
+ }
+ /* In case of 8X8, we construct a single chroma motion vector
+ with a special rounding */
+ mx = 0;
+ my = 0;
+ for(i=0;i<4;i++) {
+ mx += s->mv[dir][i][0];
+ my += s->mv[dir][i][1];
+ }
+ if (mx >= 0)
+ mx = (h263_chroma_roundtab[mx & 0xf] + ((mx >> 3) & ~1));
+ else {
+ mx = -mx;
+ mx = -(h263_chroma_roundtab[mx & 0xf] + ((mx >> 3) & ~1));
+ }
+ if (my >= 0)
+ my = (h263_chroma_roundtab[my & 0xf] + ((my >> 3) & ~1));
+ else {
+ my = -my;
+ my = -(h263_chroma_roundtab[my & 0xf] + ((my >> 3) & ~1));
+ }
+ dxy = ((my & 1) << 1) | (mx & 1);
+ mx >>= 1;
+ my >>= 1;
+
+ src_x = mb_x * 8 + mx;
+ src_y = mb_y * 8 + my;
+ src_x = clip(src_x, -8, s->width/2);
+ if (src_x == s->width/2)
+ dxy &= ~1;
+ src_y = clip(src_y, -8, s->height/2);
+ if (src_y == s->height/2)
+ dxy &= ~2;
+
+ offset = (src_y * (s->linesize >> 1)) + src_x;
+ ptr = ref_picture[1] + offset;
+ pix_op[dxy](dest_cb, ptr, s->linesize >> 1, 8);
+ ptr = ref_picture[2] + offset;
+ pix_op[dxy](dest_cr, ptr, s->linesize >> 1, 8);
+ break;
+ case MV_TYPE_FIELD:
+ if (s->picture_structure == PICT_FRAME) {
+ /* top field */
+ mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,
+ ref_picture, s->field_select[dir][0] ? s->linesize : 0,
+ 1, pix_op,
+ s->mv[dir][0][0], s->mv[dir][0][1], 8);
+ /* bottom field */
+ mpeg_motion(s, dest_y, dest_cb, dest_cr, s->linesize,
+ ref_picture, s->field_select[dir][1] ? s->linesize : 0,
+ 1, pix_op,
+ s->mv[dir][1][0], s->mv[dir][1][1], 8);
+ } else {
+
+
+ }
+ break;
+ }
+}
+
+
+/* put block[] to dest[] */
+static inline void put_dct(MpegEncContext *s,
+ DCTELEM *block, int i, UINT8 *dest, int line_size)
+{
+ if (!s->mpeg2)
+ s->dct_unquantize(s, block, i, s->qscale);
+ ff_idct (block);
+ put_pixels_clamped(block, dest, line_size);
+}
+
+/* add block[] to dest[] */
+static inline void add_dct(MpegEncContext *s,
+ DCTELEM *block, int i, UINT8 *dest, int line_size)
+{
+ if (s->block_last_index[i] >= 0) {
+ if (!s->mpeg2)
+ s->dct_unquantize(s, block, i, s->qscale);
+ ff_idct (block);
+ add_pixels_clamped(block, dest, line_size);
+ }
+}
+
+/* generic function called after a macroblock has been parsed by the
+ decoder or after it has been encoded by the encoder.
+
+ Important variables used:
+ s->mb_intra : true if intra macroblock
+ s->mv_dir : motion vector direction
+ s->mv_type : motion vector type
+ s->mv : motion vector
+ s->interlaced_dct : true if interlaced dct used (mpeg2)
+ */
+void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
+{
+ int mb_x, mb_y, motion_x, motion_y;
+ int dct_linesize, dct_offset;
+ op_pixels_func *op_pix;
+
+ mb_x = s->mb_x;
+ mb_y = s->mb_y;
+
+ /* update DC predictors for P macroblocks */
+ if (!s->mb_intra) {
+ if (s->h263_pred) {
+ int wrap, x, y, v;
+ wrap = 2 * s->mb_width + 2;
+ v = 1024;
+ x = 2 * mb_x + 1;
+ y = 2 * mb_y + 1;
+ s->dc_val[0][(x) + (y) * wrap] = v;
+ s->dc_val[0][(x + 1) + (y) * wrap] = v;
+ s->dc_val[0][(x) + (y + 1) * wrap] = v;
+ s->dc_val[0][(x + 1) + (y + 1) * wrap] = v;
+ /* ac pred */
+ memset(s->ac_val[0][(x) + (y) * wrap], 0, 16 * sizeof(INT16));
+ memset(s->ac_val[0][(x + 1) + (y) * wrap], 0, 16 * sizeof(INT16));
+ memset(s->ac_val[0][(x) + (y + 1) * wrap], 0, 16 * sizeof(INT16));
+ memset(s->ac_val[0][(x + 1) + (y + 1) * wrap], 0, 16 * sizeof(INT16));
+ if (s->h263_msmpeg4) {
+ s->coded_block[(x) + (y) * wrap] = 0;
+ s->coded_block[(x + 1) + (y) * wrap] = 0;
+ s->coded_block[(x) + (y + 1) * wrap] = 0;
+ s->coded_block[(x + 1) + (y + 1) * wrap] = 0;
+ }
+ /* chroma */
+ wrap = s->mb_width + 2;
+ x = mb_x + 1;
+ y = mb_y + 1;
+ s->dc_val[1][(x) + (y) * wrap] = v;
+ s->dc_val[2][(x) + (y) * wrap] = v;
+ /* ac pred */
+ memset(s->ac_val[1][(x) + (y) * wrap], 0, 16 * sizeof(INT16));
+ memset(s->ac_val[2][(x) + (y) * wrap], 0, 16 * sizeof(INT16));
+ } else {
+ s->last_dc[0] = 128 << s->intra_dc_precision;
+ s->last_dc[1] = 128 << s->intra_dc_precision;
+ s->last_dc[2] = 128 << s->intra_dc_precision;
+ }
+ }
+
+ /* update motion predictor */
+ if (s->out_format == FMT_H263) {
+ int x, y, wrap;
+
+ x = 2 * mb_x + 1;
+ y = 2 * mb_y + 1;
+ wrap = 2 * s->mb_width + 2;
+ if (s->mb_intra) {
+ motion_x = 0;
+ motion_y = 0;
+ goto motion_init;
+ } else if (s->mv_type == MV_TYPE_16X16) {
+ motion_x = s->mv[0][0][0];
+ motion_y = s->mv[0][0][1];
+ motion_init:
+ /* no update if 8X8 because it has been done during parsing */
+ s->motion_val[(x) + (y) * wrap][0] = motion_x;
+ s->motion_val[(x) + (y) * wrap][1] = motion_y;
+ s->motion_val[(x + 1) + (y) * wrap][0] = motion_x;
+ s->motion_val[(x + 1) + (y) * wrap][1] = motion_y;
+ s->motion_val[(x) + (y + 1) * wrap][0] = motion_x;
+ s->motion_val[(x) + (y + 1) * wrap][1] = motion_y;
+ s->motion_val[(x + 1) + (y + 1) * wrap][0] = motion_x;
+ s->motion_val[(x + 1) + (y + 1) * wrap][1] = motion_y;
+ }
+ }
+
+ if (!s->intra_only) {
+ UINT8 *dest_y, *dest_cb, *dest_cr;
+ UINT8 *mbskip_ptr;
+
+ /* avoid copy if macroblock skipped in last frame too */
+ if (!s->encoding && s->pict_type != B_TYPE) {
+ mbskip_ptr = &s->mbskip_table[s->mb_y * s->mb_width + s->mb_x];
+ if (s->mb_skiped) {
+ s->mb_skiped = 0;
+ /* if previous was skipped too, then nothing to do ! */
+ if (*mbskip_ptr != 0)
+ goto the_end;
+ *mbskip_ptr = 1; /* indicate that this time we skiped it */
+ } else {
+ *mbskip_ptr = 0; /* not skipped */
+ }
+ }
+
+ dest_y = s->current_picture[0] + (mb_y * 16 * s->linesize) + mb_x * 16;
+ dest_cb = s->current_picture[1] + (mb_y * 8 * (s->linesize >> 1)) + mb_x * 8;
+ dest_cr = s->current_picture[2] + (mb_y * 8 * (s->linesize >> 1)) + mb_x * 8;
+
+ if (s->interlaced_dct) {
+ dct_linesize = s->linesize * 2;
+ dct_offset = s->linesize;
+ } else {
+ dct_linesize = s->linesize;
+ dct_offset = s->linesize * 8;
+ }
+
+ if (!s->mb_intra) {
+ /* motion handling */
+ if (!s->no_rounding)
+ op_pix = put_pixels_tab;
+ else
+ op_pix = put_no_rnd_pixels_tab;
+
+ if (s->mv_dir & MV_DIR_FORWARD) {
+ MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture, op_pix);
+ if (!s->no_rounding)
+ op_pix = avg_pixels_tab;
+ else
+ op_pix = avg_no_rnd_pixels_tab;
+ }
+ if (s->mv_dir & MV_DIR_BACKWARD) {
+ MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture, op_pix);
+ }
+
+ /* add dct residue */
+ add_dct(s, block[0], 0, dest_y, dct_linesize);
+ add_dct(s, block[1], 1, dest_y + 8, dct_linesize);
+ add_dct(s, block[2], 2, dest_y + dct_offset, dct_linesize);
+ add_dct(s, block[3], 3, dest_y + dct_offset + 8, dct_linesize);
+
+ add_dct(s, block[4], 4, dest_cb, dct_linesize >> 1);
+ add_dct(s, block[5], 5, dest_cr, dct_linesize >> 1);
+ } else {
+ /* dct only in intra block */
+ put_dct(s, block[0], 0, dest_y, dct_linesize);
+ put_dct(s, block[1], 1, dest_y + 8, dct_linesize);
+ put_dct(s, block[2], 2, dest_y + dct_offset, dct_linesize);
+ put_dct(s, block[3], 3, dest_y + dct_offset + 8, dct_linesize);
+
+ put_dct(s, block[4], 4, dest_cb, dct_linesize >> 1);
+ put_dct(s, block[5], 5, dest_cr, dct_linesize >> 1);
+ }
+ }
+ the_end:
+ emms_c();
+}
+
+static void encode_picture(MpegEncContext *s, int picture_number)
+{
+ int mb_x, mb_y, wrap;
+ UINT8 *ptr;
+ int i, motion_x, motion_y;
+
+ s->picture_number = picture_number;
+ if (!s->fixed_qscale)
+ s->qscale = rate_estimate_qscale(s);
+
+ /* precompute matrix */
+ if (s->out_format == FMT_MJPEG) {
+ /* for mjpeg, we do include qscale in the matrix */
+ s->intra_matrix[0] = default_intra_matrix[0];
+ for(i=1;i<64;i++)
+ s->intra_matrix[i] = (default_intra_matrix[i] * s->qscale) >> 3;
+ convert_matrix(s->q_intra_matrix, s->intra_matrix, 8);
+ } else {
+ convert_matrix(s->q_intra_matrix, s->intra_matrix, s->qscale);
+ convert_matrix(s->q_non_intra_matrix, s->non_intra_matrix, s->qscale);
+ }
+
+ switch(s->out_format) {
+ case FMT_MJPEG:
+ mjpeg_picture_header(s);
+ break;
+ case FMT_H263:
+ if (s->h263_msmpeg4)
+ msmpeg4_encode_picture_header(s, picture_number);
+ else if (s->h263_pred)
+ mpeg4_encode_picture_header(s, picture_number);
+ else if (s->h263_rv10)
+ rv10_encode_picture_header(s, picture_number);
+ else
+ h263_encode_picture_header(s, picture_number);
+ break;
+ case FMT_MPEG1:
+ mpeg1_encode_picture_header(s, picture_number);
+ break;
+ }
+
+ /* init last dc values */
+ /* note: quant matrix value (8) is implied here */
+ s->last_dc[0] = 128;
+ s->last_dc[1] = 128;
+ s->last_dc[2] = 128;
+ s->mb_incr = 1;
+ s->last_mv[0][0][0] = 0;
+ s->last_mv[0][0][1] = 0;
+ s->mv_type = MV_TYPE_16X16;
+ s->mv_dir = MV_DIR_FORWARD;
+
+ for(mb_y=0; mb_y < s->mb_height; mb_y++) {
+ for(mb_x=0; mb_x < s->mb_width; mb_x++) {
+
+ s->mb_x = mb_x;
+ s->mb_y = mb_y;
+
+ /* compute motion vector and macro block type (intra or non intra) */
+ motion_x = 0;
+ motion_y = 0;
+ if (s->pict_type == P_TYPE) {
+ s->mb_intra = estimate_motion(s, mb_x, mb_y,
+ &motion_x,
+ &motion_y);
+ } else {
+ s->mb_intra = 1;
+ }
+
+ /* get the pixels */
+ wrap = s->linesize;
+ ptr = s->new_picture[0] + (mb_y * 16 * wrap) + mb_x * 16;
+ get_pixels(s->block[0], ptr, wrap);
+ get_pixels(s->block[1], ptr + 8, wrap);
+ get_pixels(s->block[2], ptr + 8 * wrap, wrap);
+ get_pixels(s->block[3], ptr + 8 * wrap + 8, wrap);
+ wrap = s->linesize >> 1;
+ ptr = s->new_picture[1] + (mb_y * 8 * wrap) + mb_x * 8;
+ get_pixels(s->block[4], ptr, wrap);
+
+ wrap = s->linesize >> 1;
+ ptr = s->new_picture[2] + (mb_y * 8 * wrap) + mb_x * 8;
+ get_pixels(s->block[5], ptr, wrap);
+
+ /* subtract previous frame if non intra */
+ if (!s->mb_intra) {
+ int dxy, offset, mx, my;
+
+ dxy = ((motion_y & 1) << 1) | (motion_x & 1);
+ ptr = s->last_picture[0] +
+ ((mb_y * 16 + (motion_y >> 1)) * s->linesize) +
+ (mb_x * 16 + (motion_x >> 1));
+
+ sub_pixels_2(s->block[0], ptr, s->linesize, dxy);
+ sub_pixels_2(s->block[1], ptr + 8, s->linesize, dxy);
+ sub_pixels_2(s->block[2], ptr + s->linesize * 8, s->linesize, dxy);
+ sub_pixels_2(s->block[3], ptr + 8 + s->linesize * 8, s->linesize ,dxy);
+
+ if (s->out_format == FMT_H263) {
+ /* special rounding for h263 */
+ dxy = 0;
+ if ((motion_x & 3) != 0)
+ dxy |= 1;
+ if ((motion_y & 3) != 0)
+ dxy |= 2;
+ mx = motion_x >> 2;
+ my = motion_y >> 2;
+ } else {
+ mx = motion_x / 2;
+ my = motion_y / 2;
+ dxy = ((my & 1) << 1) | (mx & 1);
+ mx >>= 1;
+ my >>= 1;
+ }
+ offset = ((mb_y * 8 + my) * (s->linesize >> 1)) + (mb_x * 8 + mx);
+ ptr = s->last_picture[1] + offset;
+ sub_pixels_2(s->block[4], ptr, s->linesize >> 1, dxy);
+ ptr = s->last_picture[2] + offset;
+ sub_pixels_2(s->block[5], ptr, s->linesize >> 1, dxy);
+ }
+ emms_c();
+
+ /* DCT & quantize */
+ if (s->h263_msmpeg4) {
+ msmpeg4_dc_scale(s);
+ } else if (s->h263_pred) {
+ h263_dc_scale(s);
+ } else {
+ /* default quantization values */
+ s->y_dc_scale = 8;
+ s->c_dc_scale = 8;
+ }
+
+ for(i=0;i<6;i++) {
+ int last_index;
+ if (av_fdct == jpeg_fdct_ifast)
+ last_index = dct_quantize(s, s->block[i], i, s->qscale);
+ else
+ last_index = dct_quantize_mmx(s, s->block[i], i, s->qscale);
+ s->block_last_index[i] = last_index;
+ }
+
+ /* huffman encode */
+ switch(s->out_format) {
+ case FMT_MPEG1:
+ mpeg1_encode_mb(s, s->block, motion_x, motion_y);
+ break;
+ case FMT_H263:
+ if (s->h263_msmpeg4)
+ msmpeg4_encode_mb(s, s->block, motion_x, motion_y);
+ else
+ h263_encode_mb(s, s->block, motion_x, motion_y);
+ break;
+ case FMT_MJPEG:
+ mjpeg_encode_mb(s, s->block);
+ break;
+ }
+
+ /* decompress blocks so that we keep the state of the decoder */
+ s->mv[0][0][0] = motion_x;
+ s->mv[0][0][1] = motion_y;
+
+ MPV_decode_mb(s, s->block);
+ }
+ }
+}
+
+static int dct_quantize(MpegEncContext *s,
+ DCTELEM *block, int n,
+ int qscale)
+{
+ int i, j, level, last_non_zero, q;
+ const int *qmat;
+
+ av_fdct (block);
+
+ if (s->mb_intra) {
+ if (n < 4)
+ q = s->y_dc_scale;
+ else
+ q = s->c_dc_scale;
+ q = q << 3;
+
+ /* note: block[0] is assumed to be positive */
+ block[0] = (block[0] + (q >> 1)) / q;
+ i = 1;
+ last_non_zero = 0;
+ if (s->out_format == FMT_H263) {
+ qmat = s->q_non_intra_matrix;
+ } else {
+ qmat = s->q_intra_matrix;
+ }
+ } else {
+ i = 0;
+ last_non_zero = -1;
+ qmat = s->q_non_intra_matrix;
+ }
+
+ for(;i<64;i++) {
+ j = zigzag_direct[i];
+ level = block[j];
+ level = level * qmat[j];
+#ifdef PARANOID
+ {
+ static int count = 0;
+ int level1, level2, qmat1;
+ double val;
+ if (qmat == s->q_non_intra_matrix) {
+ qmat1 = default_non_intra_matrix[j] * s->qscale;
+ } else {
+ qmat1 = default_intra_matrix[j] * s->qscale;
+ }
+ if (av_fdct != jpeg_fdct_ifast)
+ val = ((double)block[j] * 8.0) / (double)qmat1;
+ else
+ val = ((double)block[j] * 8.0 * 2048.0) /
+ ((double)qmat1 * aanscales[j]);
+ level1 = (int)val;
+ level2 = level / (1 << (QMAT_SHIFT - 3));
+ if (level1 != level2) {
+ fprintf(stderr, "%d: quant error qlevel=%d wanted=%d level=%d qmat1=%d qmat=%d wantedf=%0.6f\n",
+ count, level2, level1, block[j], qmat1, qmat[j],
+ val);
+ count++;
+ }
+
+ }
+#endif
+ /* XXX: slight error for the low range. Test should be equivalent to
+ (level <= -(1 << (QMAT_SHIFT - 3)) || level >= (1 <<
+ (QMAT_SHIFT - 3)))
+ */
+ if (((level << (31 - (QMAT_SHIFT - 3))) >> (31 - (QMAT_SHIFT - 3))) !=
+ level) {
+ level = level / (1 << (QMAT_SHIFT - 3));
+ /* XXX: currently, this code is not optimal. the range should be:
+ mpeg1: -255..255
+ mpeg2: -2048..2047
+ h263: -128..127
+ mpeg4: -2048..2047
+ */
+ if (level > 127)
+ level = 127;
+ else if (level < -128)
+ level = -128;
+ block[j] = level;
+ last_non_zero = i;
+ } else {
+ block[j] = 0;
+ }
+ }
+ return last_non_zero;
+}
+
+static int dct_quantize_mmx(MpegEncContext *s,
+ DCTELEM *block, int n,
+ int qscale)
+{
+ int i, j, level, last_non_zero, q;
+ const int *qmat;
+
+ av_fdct (block);
+
+ if (s->mb_intra) {
+ if (n < 4)
+ q = s->y_dc_scale;
+ else
+ q = s->c_dc_scale;
+
+ /* note: block[0] is assumed to be positive */
+ block[0] = (block[0] + (q >> 1)) / q;
+ i = 1;
+ last_non_zero = 0;
+ if (s->out_format == FMT_H263) {
+ qmat = s->q_non_intra_matrix;
+ } else {
+ qmat = s->q_intra_matrix;
+ }
+ } else {
+ i = 0;
+ last_non_zero = -1;
+ qmat = s->q_non_intra_matrix;
+ }
+
+ for(;i<64;i++) {
+ j = zigzag_direct[i];
+ level = block[j];
+ level = level * qmat[j];
+ /* XXX: slight error for the low range. Test should be equivalent to
+ (level <= -(1 << (QMAT_SHIFT_MMX - 3)) || level >= (1 <<
+ (QMAT_SHIFT_MMX - 3)))
+ */
+ if (((level << (31 - (QMAT_SHIFT_MMX - 3))) >> (31 - (QMAT_SHIFT_MMX - 3))) !=
+ level) {
+ level = level / (1 << (QMAT_SHIFT_MMX - 3));
+ /* XXX: currently, this code is not optimal. the range should be:
+ mpeg1: -255..255
+ mpeg2: -2048..2047
+ h263: -128..127
+ mpeg4: -2048..2047
+ */
+ if (level > 127)
+ level = 127;
+ else if (level < -128)
+ level = -128;
+ block[j] = level;
+ last_non_zero = i;
+ } else {
+ block[j] = 0;
+ }
+ }
+ return last_non_zero;
+}
+
+static void dct_unquantize_mpeg1_c(MpegEncContext *s,
+ DCTELEM *block, int n, int qscale)
+{
+ int i, level;
+ const UINT16 *quant_matrix;
+
+ if (s->mb_intra) {
+ if (n < 4)
+ block[0] = block[0] * s->y_dc_scale;
+ else
+ block[0] = block[0] * s->c_dc_scale;
+ /* XXX: only mpeg1 */
+ quant_matrix = s->intra_matrix;
+ for(i=1;i<64;i++) {
+ level = block[i];
+ if (level) {
+ if (level < 0) {
+ level = -level;
+ level = (int)(level * qscale * quant_matrix[i]) >> 3;
+ level = (level - 1) | 1;
+ level = -level;
+ } else {
+ level = (int)(level * qscale * quant_matrix[i]) >> 3;
+ level = (level - 1) | 1;
+ }
+#ifdef PARANOID
+ if (level < -2048 || level > 2047)
+ fprintf(stderr, "unquant error %d %d\n", i, level);
+#endif
+ block[i] = level;
+ }
+ }
+ } else {
+ i = 0;
+ quant_matrix = s->non_intra_matrix;
+ for(;i<64;i++) {
+ level = block[i];
+ if (level) {
+ if (level < 0) {
+ level = -level;
+ level = (((level << 1) + 1) * qscale *
+ ((int) (quant_matrix[i]))) >> 4;
+ level = (level - 1) | 1;
+ level = -level;
+ } else {
+ level = (((level << 1) + 1) * qscale *
+ ((int) (quant_matrix[i]))) >> 4;
+ level = (level - 1) | 1;
+ }
+#ifdef PARANOID
+ if (level < -2048 || level > 2047)
+ fprintf(stderr, "unquant error %d %d\n", i, level);
+#endif
+ block[i] = level;
+ }
+ }
+ }
+}
+
+static void dct_unquantize_h263_c(MpegEncContext *s,
+ DCTELEM *block, int n, int qscale)
+{
+ int i, level, qmul, qadd;
+
+ if (s->mb_intra) {
+ if (n < 4)
+ block[0] = block[0] * s->y_dc_scale;
+ else
+ block[0] = block[0] * s->c_dc_scale;
+ i = 1;
+ } else {
+ i = 0;
+ }
+
+ qmul = s->qscale << 1;
+ qadd = (s->qscale - 1) | 1;
+
+ for(;i<64;i++) {
+ level = block[i];
+ if (level) {
+ if (level < 0) {
+ level = level * qmul - qadd;
+ } else {
+ level = level * qmul + qadd;
+ }
+#ifdef PARANOID
+ if (level < -2048 || level > 2047)
+ fprintf(stderr, "unquant error %d %d\n", i, level);
+#endif
+ block[i] = level;
+ }
+ }
+}
+
+/* rate control */
+
+/* an I frame is I_FRAME_SIZE_RATIO bigger than a P frame */
+#define I_FRAME_SIZE_RATIO 3.0
+#define QSCALE_K 20
+
+static void rate_control_init(MpegEncContext *s)
+{
+ s->wanted_bits = 0;
+
+ if (s->intra_only) {
+ s->I_frame_bits = ((INT64)s->bit_rate * FRAME_RATE_BASE) / s->frame_rate;
+ s->P_frame_bits = s->I_frame_bits;
+ } else {
+ s->P_frame_bits = (int) ((float)(s->gop_size * s->bit_rate) /
+ (float)((float)s->frame_rate / FRAME_RATE_BASE * (I_FRAME_SIZE_RATIO + s->gop_size - 1)));
+ s->I_frame_bits = (int)(s->P_frame_bits * I_FRAME_SIZE_RATIO);
+ }
+
+#if defined(DEBUG)
+ printf("I_frame_size=%d P_frame_size=%d\n",
+ s->I_frame_bits, s->P_frame_bits);
+#endif
+}
+
+
+/*
+ * This heuristic is rather poor, but at least we do not have to
+ * change the qscale at every macroblock.
+ */
+static int rate_estimate_qscale(MpegEncContext *s)
+{
+ long long total_bits = s->total_bits;
+ float q;
+ int qscale, diff, qmin;
+
+ if (s->pict_type == I_TYPE) {
+ s->wanted_bits += s->I_frame_bits;
+ } else {
+ s->wanted_bits += s->P_frame_bits;
+ }
+ diff = s->wanted_bits - total_bits;
+ q = 31.0 - (float)diff / (QSCALE_K * s->mb_height * s->mb_width);
+ /* adjust for I frame */
+ if (s->pict_type == I_TYPE && !s->intra_only) {
+ q /= I_FRAME_SIZE_RATIO;
+ }
+
+ /* using a too small Q scale leeds to problems in mpeg1 and h263
+ because AC coefficients are clamped to 255 or 127 */
+ qmin = 3;
+ if (q < qmin)
+ q = qmin;
+ else if (q > 31)
+ q = 31;
+ qscale = (int)(q + 0.5);
+#if defined(DEBUG)
+ printf("%d: total=%Ld br=%0.1f diff=%d qest=%0.1f\n",
+ s->picture_number,
+ total_bits,
+ (float)s->frame_rate / FRAME_RATE_BASE *
+ total_bits / s->picture_number,
+ diff, q);
+#endif
+ return qscale;
+}
+
+AVCodec mpeg1video_encoder = {
+ "mpeg1video",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_MPEG1VIDEO,
+ sizeof(MpegEncContext),
+ MPV_encode_init,
+ MPV_encode_picture,
+ MPV_encode_end,
+};
+
+AVCodec h263_encoder = {
+ "h263",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_H263,
+ sizeof(MpegEncContext),
+ MPV_encode_init,
+ MPV_encode_picture,
+ MPV_encode_end,
+};
+
+AVCodec h263p_encoder = {
+ "h263p",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_H263P,
+ sizeof(MpegEncContext),
+ MPV_encode_init,
+ MPV_encode_picture,
+ MPV_encode_end,
+};
+
+AVCodec rv10_encoder = {
+ "rv10",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_RV10,
+ sizeof(MpegEncContext),
+ MPV_encode_init,
+ MPV_encode_picture,
+ MPV_encode_end,
+};
+
+AVCodec mjpeg_encoder = {
+ "mjpeg",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_MJPEG,
+ sizeof(MpegEncContext),
+ MPV_encode_init,
+ MPV_encode_picture,
+ MPV_encode_end,
+};
+
+AVCodec opendivx_encoder = {
+ "opendivx",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_OPENDIVX,
+ sizeof(MpegEncContext),
+ MPV_encode_init,
+ MPV_encode_picture,
+ MPV_encode_end,
+};
+
+AVCodec msmpeg4_encoder = {
+ "msmpeg4",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_MSMPEG4,
+ sizeof(MpegEncContext),
+ MPV_encode_init,
+ MPV_encode_picture,
+ MPV_encode_end,
+};
diff --git a/src/libffmpeg/libavcodec/mpegvideo.h b/src/libffmpeg/libavcodec/mpegvideo.h
new file mode 100644
index 000000000..9f9307393
--- /dev/null
+++ b/src/libffmpeg/libavcodec/mpegvideo.h
@@ -0,0 +1,285 @@
+/*
+ * Generic DCT based hybrid video encoder
+ * Copyright (c) 2000,2001 Gerard Lantau.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Macros for picture code type. */
+#define I_TYPE 1
+#define P_TYPE 2
+#define B_TYPE 3
+
+enum OutputFormat {
+ FMT_MPEG1,
+ FMT_H263,
+ FMT_MJPEG,
+};
+
+#define MPEG_BUF_SIZE (16 * 1024)
+
+typedef struct MpegEncContext {
+ /* the following parameters must be initialized before encoding */
+ int width, height; /* picture size. must be a multiple of 16 */
+ int gop_size;
+ int frame_rate; /* number of frames per second */
+ int intra_only; /* if true, only intra pictures are generated */
+ int bit_rate; /* wanted bit rate */
+ enum OutputFormat out_format; /* output format */
+ int h263_plus; /* h263 plus headers */
+ int h263_rv10; /* use RV10 variation for H263 */
+ int h263_pred; /* use OpenDIVX (aka mpeg4) ac/dc predictions */
+ int h263_msmpeg4; /* generate MSMPEG4 compatible stream */
+ int h263_intel; /* use I263 intel h263 header */
+ int fixed_qscale; /* fixed qscale if non zero */
+ int encoding; /* true if we are encoding (vs decoding) */
+ /* the following fields are managed internally by the encoder */
+
+ /* bit output */
+ PutBitContext pb;
+
+ /* sequence parameters */
+ int context_initialized;
+ int picture_number;
+ int fake_picture_number; /* picture number at the bitstream frame rate */
+ int gop_picture_number; /* index of the first picture of a GOP */
+ int mb_width, mb_height;
+ int linesize; /* line size, in bytes, may be different from width */
+ UINT8 *new_picture[3]; /* picture to be compressed */
+ UINT8 *last_picture[3]; /* previous picture */
+ UINT8 *last_picture_base[3]; /* real start of the picture */
+ UINT8 *next_picture[3]; /* previous picture (for bidir pred) */
+ UINT8 *next_picture_base[3]; /* real start of the picture */
+ UINT8 *aux_picture[3]; /* aux picture (for B frames only) */
+ UINT8 *aux_picture_base[3]; /* real start of the picture */
+ UINT8 *current_picture[3]; /* buffer to store the decompressed current picture */
+ int last_dc[3]; /* last DC values for MPEG1 */
+ INT16 *dc_val[3]; /* used for mpeg4 DC prediction */
+ int y_dc_scale, c_dc_scale;
+ UINT8 *coded_block; /* used for coded block pattern prediction */
+ INT16 (*ac_val[3])[16]; /* used for for mpeg4 AC prediction */
+ int ac_pred;
+ int mb_skiped; /* MUST BE SET only during DECODING */
+ UINT8 *mbskip_table; /* used to avoid copy if macroblock
+ skipped (for black regions for example) */
+
+ int qscale;
+ int pict_type;
+ int frame_rate_index;
+ /* motion compensation */
+ int unrestricted_mv;
+ int h263_long_vectors; /* use horrible h263v1 long vector mode */
+
+ int f_code; /* resolution */
+ INT16 (*motion_val)[2]; /* used for MV prediction */
+ int full_search;
+ int mv_dir;
+#define MV_DIR_BACKWARD 1
+#define MV_DIR_FORWARD 2
+ int mv_type;
+#define MV_TYPE_16X16 0 /* 1 vector for the whole mb */
+#define MV_TYPE_8X8 1 /* 4 vectors (h263) */
+#define MV_TYPE_16X8 2 /* 2 vectors, one per 16x8 block */
+#define MV_TYPE_FIELD 3 /* 2 vectors, one per field */
+#define MV_TYPE_DMV 4 /* 2 vectors, special mpeg2 Dual Prime Vectors */
+ /* motion vectors for a macroblock
+ first coordinate : 0 = forward 1 = backward
+ second " : depend on type
+ third " : 0 = x, 1 = y
+ */
+ int mv[2][4][2];
+ int field_select[2][2];
+ int last_mv[2][2][2];
+
+ int has_b_frames;
+ int no_rounding; /* apply no rounding to motion estimation (MPEG4) */
+
+ /* macroblock layer */
+ int mb_x, mb_y;
+ int mb_incr;
+ int mb_intra;
+ /* matrix transmitted in the bitstream */
+ UINT16 intra_matrix[64];
+ UINT16 chroma_intra_matrix[64];
+ UINT16 non_intra_matrix[64];
+ UINT16 chroma_non_intra_matrix[64];
+ /* precomputed matrix (combine qscale and DCT renorm) */
+ int q_intra_matrix[64];
+ int q_non_intra_matrix[64];
+ int block_last_index[6]; /* last non zero coefficient in block */
+
+ void *opaque; /* private data for the user */
+
+ /* bit rate control */
+ int I_frame_bits; /* wanted number of bits per I frame */
+ int P_frame_bits; /* same for P frame */
+ long long wanted_bits;
+ long long total_bits;
+
+ /* mpeg4 specific */
+ int time_increment_bits;
+
+ /* RV10 specific */
+ int rv10_version; /* RV10 version: 0 or 3 */
+ int rv10_first_dc_coded[3];
+
+ /* MJPEG specific */
+ struct MJpegContext *mjpeg_ctx;
+
+ /* MSMPEG4 specific */
+ int mv_table_index;
+ int rl_table_index;
+ int rl_chroma_table_index;
+ int dc_table_index;
+ int use_skip_mb_code;
+ int slice_height; /* in macroblocks */
+ int first_slice_line;
+ /* decompression specific */
+ GetBitContext gb;
+
+ /* MPEG2 specific - I wish I had not to support this mess. */
+ int progressive_sequence;
+ int mpeg_f_code[2][2];
+ int picture_structure;
+/* picture type */
+#define PICT_TOP_FIELD 1
+#define PICT_BOTTOM_FIELD 2
+#define PICT_FRAME 3
+
+ int intra_dc_precision;
+ int frame_pred_frame_dct;
+ int top_field_first;
+ int concealment_motion_vectors;
+ int q_scale_type;
+ int intra_vlc_format;
+ int alternate_scan;
+ int repeat_first_field;
+ int chroma_420_type;
+ int progressive_frame;
+ int mpeg2;
+ int full_pel[2];
+ int interlaced_dct;
+ int last_qscale;
+ int first_slice;
+
+ DCTELEM block[6][64] __align8;
+ void (*dct_unquantize)(struct MpegEncContext *s,
+ DCTELEM *block, int n, int qscale);
+} MpegEncContext;
+
+//const
+extern UINT8 zigzag_direct[64];
+
+int MPV_common_init(MpegEncContext *s);
+void MPV_common_end(MpegEncContext *s);
+void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64]);
+void MPV_frame_start(MpegEncContext *s);
+void MPV_frame_end(MpegEncContext *s);
+#ifdef HAVE_MMX
+void MPV_common_init_mmx(MpegEncContext *s);
+#endif
+
+/* motion_est.c */
+
+int estimate_motion(MpegEncContext *s,
+ int mb_x, int mb_y,
+ int *mx_ptr, int *my_ptr);
+
+/* mpeg12.c */
+extern const UINT8 default_intra_matrix[64];
+extern const UINT8 default_non_intra_matrix[64];
+
+void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number);
+void mpeg1_encode_mb(MpegEncContext *s,
+ DCTELEM block[6][64],
+ int motion_x, int motion_y);
+
+/* h263enc.c */
+
+/* run length table */
+#define MAX_RUN 64
+#define MAX_LEVEL 64
+
+typedef struct RLTable {
+ int n; /* number of entries of table_vlc minus 1 */
+ int last; /* number of values for last = 0 */
+ const UINT16 (*table_vlc)[2];
+ const INT8 *table_run;
+ const INT8 *table_level;
+ UINT8 *index_run[2]; /* encoding only */
+ INT8 *max_level[2]; /* encoding & decoding */
+ INT8 *max_run[2]; /* encoding & decoding */
+ VLC vlc; /* decoding only */
+} RLTable;
+
+void init_rl(RLTable *rl);
+void init_vlc_rl(RLTable *rl);
+
+extern inline int get_rl_index(const RLTable *rl, int last, int run, int level)
+{
+ int index;
+ index = rl->index_run[last][run];
+ if (index >= rl->n)
+ return rl->n;
+ if (level > rl->max_level[last][run])
+ return rl->n;
+ return index + level - 1;
+}
+
+void h263_encode_mb(MpegEncContext *s,
+ DCTELEM block[6][64],
+ int motion_x, int motion_y);
+void h263_encode_picture_header(MpegEncContext *s, int picture_number);
+void h263_dc_scale(MpegEncContext *s);
+INT16 *h263_pred_motion(MpegEncContext * s, int block,
+ int *px, int *py);
+void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n,
+ int dir);
+void mpeg4_encode_picture_header(MpegEncContext *s, int picture_number);
+void h263_encode_init_vlc(MpegEncContext *s);
+
+void h263_decode_init_vlc(MpegEncContext *s);
+int h263_decode_picture_header(MpegEncContext *s);
+int mpeg4_decode_picture_header(MpegEncContext * s);
+int intel_h263_decode_picture_header(MpegEncContext *s);
+int h263_decode_mb(MpegEncContext *s,
+ DCTELEM block[6][64]);
+int h263_get_picture_format(int width, int height);
+extern UINT8 ff_alternate_horizontal_scan[64];
+extern UINT8 ff_alternate_vertical_scan[64];
+
+/* rv10.c */
+void rv10_encode_picture_header(MpegEncContext *s, int picture_number);
+int rv_decode_dc(MpegEncContext *s, int n);
+
+/* msmpeg4.c */
+void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number);
+void msmpeg4_encode_mb(MpegEncContext * s,
+ DCTELEM block[6][64],
+ int motion_x, int motion_y);
+void msmpeg4_dc_scale(MpegEncContext * s);
+int msmpeg4_decode_picture_header(MpegEncContext * s);
+int msmpeg4_decode_mb(MpegEncContext *s,
+ DCTELEM block[6][64]);
+int msmpeg4_decode_init_vlc(MpegEncContext *s);
+
+/* mjpegenc.c */
+
+int mjpeg_init(MpegEncContext *s);
+void mjpeg_close(MpegEncContext *s);
+void mjpeg_encode_mb(MpegEncContext *s,
+ DCTELEM block[6][64]);
+void mjpeg_picture_header(MpegEncContext *s);
+void mjpeg_picture_trailer(MpegEncContext *s);
diff --git a/src/libffmpeg/libavcodec/mpegvideo_mmx.c b/src/libffmpeg/libavcodec/mpegvideo_mmx.c
new file mode 100644
index 000000000..279e5ec22
--- /dev/null
+++ b/src/libffmpeg/libavcodec/mpegvideo_mmx.c
@@ -0,0 +1,232 @@
+/*
+ * The simplest mpeg encoder (well, it was the simplest!)
+ * Copyright (c) 2000,2001 Gerard Lantau.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Optimized for ia32 cpus by Nick Kurshev <nickols_k@mail.ru>
+ */
+
+#include "dsputil.h"
+#include "mpegvideo.h"
+#include "cpu_accel.h"
+
+#if 0
+
+/* XXX: GL: I don't understand why this function needs optimization
+ (it is called only once per frame!), so I disabled it */
+
+void MPV_frame_start(MpegEncContext *s)
+{
+ if (s->pict_type == B_TYPE) {
+ __asm __volatile(
+ "movl (%1), %%eax\n\t"
+ "movl 4(%1), %%edx\n\t"
+ "movl 8(%1), %%ecx\n\t"
+ "movl %%eax, (%0)\n\t"
+ "movl %%edx, 4(%0)\n\t"
+ "movl %%ecx, 8(%0)\n\t"
+ :
+ :"r"(s->current_picture), "r"(s->aux_picture)
+ :"eax","edx","ecx","memory");
+ } else {
+ /* swap next and last */
+ __asm __volatile(
+ "movl (%1), %%eax\n\t"
+ "movl 4(%1), %%edx\n\t"
+ "movl 8(%1), %%ecx\n\t"
+ "xchgl (%0), %%eax\n\t"
+ "xchgl 4(%0), %%edx\n\t"
+ "xchgl 8(%0), %%ecx\n\t"
+ "movl %%eax, (%1)\n\t"
+ "movl %%edx, 4(%1)\n\t"
+ "movl %%ecx, 8(%1)\n\t"
+ "movl %%eax, (%2)\n\t"
+ "movl %%edx, 4(%2)\n\t"
+ "movl %%ecx, 8(%2)\n\t"
+ :
+ :"r"(s->last_picture), "r"(s->next_picture), "r"(s->current_picture)
+ :"eax","edx","ecx","memory");
+ }
+}
+#endif
+
+static const unsigned long long int mm_wabs __attribute__ ((aligned(8))) = 0xffffffffffffffffULL;
+static const unsigned long long int mm_wone __attribute__ ((aligned(8))) = 0x0001000100010001ULL;
+
+/*
+ NK:
+ Note: looking at PARANOID:
+ "enable all paranoid tests for rounding, overflows, etc..."
+
+#ifdef PARANOID
+ if (level < -2048 || level > 2047)
+ fprintf(stderr, "unquant error %d %d\n", i, level);
+#endif
+ We can suppose that result of two multiplications can't be greate of 0xFFFF
+ i.e. is 16-bit, so we use here only PMULLW instruction and can avoid
+ a complex multiplication.
+=====================================================
+ Full formula for multiplication of 2 integer numbers
+ which are represent as high:low words:
+ input: value1 = high1:low1
+ value2 = high2:low2
+ output: value3 = value1*value2
+ value3=high3:low3 (on overflow: modulus 2^32 wrap-around)
+ this mean that for 0x123456 * 0x123456 correct result is 0x766cb0ce4
+ but this algorithm will compute only 0x66cb0ce4
+ this limited by 16-bit size of operands
+ ---------------------------------
+ tlow1 = high1*low2
+ tlow2 = high2*low1
+ tlow1 = tlow1 + tlow2
+ high3:low3 = low1*low2
+ high3 += tlow1
+*/
+static void dct_unquantize_mpeg1_mmx(MpegEncContext *s,
+ DCTELEM *block, int n, int qscale)
+{
+ int i, level;
+ const UINT16 *quant_matrix;
+ if (s->mb_intra) {
+ if (n < 4)
+ block[0] = block[0] * s->y_dc_scale;
+ else
+ block[0] = block[0] * s->c_dc_scale;
+ if (s->out_format == FMT_H263) {
+ i = 1;
+ goto unquant_even;
+ }
+ /* XXX: only mpeg1 */
+ quant_matrix = s->intra_matrix;
+ i=1;
+ /* Align on 4 elements boundary */
+ while(i&3)
+ {
+ level = block[i];
+ if (level) {
+ if (level < 0) level = -level;
+ level = (int)(level * qscale * quant_matrix[i]) >> 3;
+ level = (level - 1) | 1;
+ if (block[i] < 0) level = -level;
+ block[i] = level;
+ }
+ i++;
+ }
+ __asm __volatile(
+ "movd %0, %%mm6\n\t" /* mm6 = qscale | 0 */
+ "punpckldq %%mm6, %%mm6\n\t" /* mm6 = qscale | qscale */
+ "movq %2, %%mm4\n\t"
+ "movq %%mm6, %%mm7\n\t"
+ "movq %1, %%mm5\n\t"
+ "packssdw %%mm6, %%mm7\n\t" /* mm7 = qscale | qscale | qscale | qscale */
+ "pxor %%mm6, %%mm6\n\t"
+ ::"g"(qscale),"m"(mm_wone),"m"(mm_wabs):"memory");
+ for(;i<64;i+=4) {
+ __asm __volatile(
+ "movq %1, %%mm0\n\t"
+ "movq %%mm7, %%mm1\n\t"
+ "movq %%mm0, %%mm2\n\t"
+ "movq %%mm0, %%mm3\n\t"
+ "pcmpgtw %%mm6, %%mm2\n\t"
+ "pmullw %2, %%mm1\n\t"
+ "pandn %%mm4, %%mm2\n\t"
+ "por %%mm5, %%mm2\n\t"
+ "pmullw %%mm2, %%mm0\n\t" /* mm0 = abs(block[i]). */
+
+ "pcmpeqw %%mm6, %%mm3\n\t"
+ "pmullw %%mm0, %%mm1\n\t"
+ "psraw $3, %%mm1\n\t"
+ "psubw %%mm5, %%mm1\n\t" /* block[i] --; */
+ "pandn %%mm4, %%mm3\n\t" /* fake of pcmpneqw : mm0 != 0 then mm1 = -1 */
+ "por %%mm5, %%mm1\n\t" /* block[i] |= 1 */
+ "pmullw %%mm2, %%mm1\n\t" /* change signs again */
+
+ "pand %%mm3, %%mm1\n\t" /* nullify if was zero */
+ "movq %%mm1, %0"
+ :"=m"(block[i])
+ :"m"(block[i]), "m"(quant_matrix[i])
+ :"memory");
+ }
+ } else {
+ i = 0;
+ unquant_even:
+ quant_matrix = s->non_intra_matrix;
+ /* Align on 4 elements boundary */
+ while(i&3)
+ {
+ level = block[i];
+ if (level) {
+ if (level < 0) level = -level;
+ level = (((level << 1) + 1) * qscale *
+ ((int) quant_matrix[i])) >> 4;
+ level = (level - 1) | 1;
+ if(block[i] < 0) level = -level;
+ block[i] = level;
+ }
+ i++;
+ }
+ __asm __volatile(
+ "movd %0, %%mm6\n\t" /* mm6 = qscale | 0 */
+ "punpckldq %%mm6, %%mm6\n\t" /* mm6 = qscale | qscale */
+ "movq %2, %%mm4\n\t"
+ "movq %%mm6, %%mm7\n\t"
+ "movq %1, %%mm5\n\t"
+ "packssdw %%mm6, %%mm7\n\t" /* mm7 = qscale | qscale | qscale | qscale */
+ "pxor %%mm6, %%mm6\n\t"
+ ::"g"(qscale),"m"(mm_wone),"m"(mm_wabs):"memory");
+ for(;i<64;i+=4) {
+ __asm __volatile(
+ "movq %1, %%mm0\n\t"
+ "movq %%mm7, %%mm1\n\t"
+ "movq %%mm0, %%mm2\n\t"
+ "movq %%mm0, %%mm3\n\t"
+ "pcmpgtw %%mm6, %%mm2\n\t"
+ "pmullw %2, %%mm1\n\t"
+ "pandn %%mm4, %%mm2\n\t"
+ "por %%mm5, %%mm2\n\t"
+ "pmullw %%mm2, %%mm0\n\t" /* mm0 = abs(block[i]). */
+ "psllw $1, %%mm0\n\t" /* block[i] <<= 1 */
+ "paddw %%mm5, %%mm0\n\t" /* block[i] ++ */
+
+ "pmullw %%mm0, %%mm1\n\t"
+ "psraw $4, %%mm1\n\t"
+ "pcmpeqw %%mm6, %%mm3\n\t"
+ "psubw %%mm5, %%mm1\n\t" /* block[i] --; */
+ "pandn %%mm4, %%mm3\n\t" /* fake of pcmpneqw : mm0 != 0 then mm1 = -1 */
+ "por %%mm5, %%mm1\n\t" /* block[i] |= 1 */
+ "pmullw %%mm2, %%mm1\n\t" /* change signs again */
+
+ "pand %%mm3, %%mm1\n\t" /* nullify if was zero */
+ "movq %%mm1, %0"
+ :"=m"(block[i])
+ :"m"(block[i]), "m"(quant_matrix[i])
+ :"memory");
+ }
+ }
+}
+
+void MPV_common_init_mmx(MpegEncContext *s)
+{
+ int mm_flags;
+
+ mm_flags = mm_accel();
+
+ if (mm_flags & MM_ACCEL_X86_MMX) {
+ /* XXX: should include h263 optimization too. It would go even
+ faster! */
+ s->dct_unquantize = dct_unquantize_mpeg1_mmx;
+ }
+}
diff --git a/src/libffmpeg/libavcodec/msmpeg4.c b/src/libffmpeg/libavcodec/msmpeg4.c
new file mode 100644
index 000000000..885abc117
--- /dev/null
+++ b/src/libffmpeg/libavcodec/msmpeg4.c
@@ -0,0 +1,932 @@
+/*
+ * MSMPEG4 backend for ffmpeg encoder and decoder
+ * Copyright (c) 2001 Gerard Lantau.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include "common.h"
+#include "dsputil.h"
+#include "mpegvideo.h"
+
+/*
+ * You can also call this codec : MPEG4 with a twist !
+ *
+ * TODO:
+ * - (encoding) select best mv table (two choices)
+ * - (encoding) select best vlc/dc table
+ * - (decoding) handle slice indication
+ */
+//#define DEBUG
+
+/* motion vector table */
+typedef struct MVTable {
+ int n;
+ const UINT16 *table_mv_code;
+ const UINT8 *table_mv_bits;
+ const UINT8 *table_mvx;
+ const UINT8 *table_mvy;
+ UINT16 *table_mv_index; /* encoding: convert mv to index in table_mv */
+ VLC vlc; /* decoding: vlc */
+} MVTable;
+
+static void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n);
+static int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
+ int n, int coded);
+static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr);
+static int msmpeg4_decode_motion(MpegEncContext * s,
+ int *mx_ptr, int *my_ptr);
+
+#ifdef DEBUG
+int intra_count = 0;
+int frame_count = 0;
+#endif
+/* XXX: move it to mpegvideo.h */
+
+static int init_done = 0;
+
+#include "msmpeg4data.h"
+
+#ifdef STATS
+
+const char *st_names[ST_NB] = {
+ "unknown",
+ "dc",
+ "intra_ac",
+ "inter_ac",
+ "intra_mb",
+ "inter_mb",
+ "mv",
+};
+
+int st_current_index = 0;
+unsigned int st_bit_counts[ST_NB];
+unsigned int st_out_bit_counts[ST_NB];
+
+#define set_stat(var) st_current_index = var;
+
+void print_stats(void)
+{
+ unsigned int total;
+ int i;
+
+ printf("Input:\n");
+ total = 0;
+ for(i=0;i<ST_NB;i++)
+ total += st_bit_counts[i];
+ if (total == 0)
+ total = 1;
+ for(i=0;i<ST_NB;i++) {
+ printf("%-10s : %10.1f %5.1f%%\n",
+ st_names[i],
+ (double)st_bit_counts[i] / 8.0,
+ (double)st_bit_counts[i] * 100.0 / total);
+ }
+ printf("%-10s : %10.1f %5.1f%%\n",
+ "total",
+ (double)total / 8.0,
+ 100.0);
+
+ printf("Output:\n");
+ total = 0;
+ for(i=0;i<ST_NB;i++)
+ total += st_out_bit_counts[i];
+ if (total == 0)
+ total = 1;
+ for(i=0;i<ST_NB;i++) {
+ printf("%-10s : %10.1f %5.1f%%\n",
+ st_names[i],
+ (double)st_out_bit_counts[i] / 8.0,
+ (double)st_out_bit_counts[i] * 100.0 / total);
+ }
+ printf("%-10s : %10.1f %5.1f%%\n",
+ "total",
+ (double)total / 8.0,
+ 100.0);
+}
+
+#else
+
+#define set_stat(var)
+
+#endif
+
+/* build the table which associate a (x,y) motion vector to a vlc */
+static void init_mv_table(MVTable *tab)
+{
+ int i, x, y;
+
+ tab->table_mv_index = malloc(sizeof(UINT16) * 4096);
+ /* mark all entries as not used */
+ for(i=0;i<4096;i++)
+ tab->table_mv_index[i] = tab->n;
+
+ for(i=0;i<tab->n;i++) {
+ x = tab->table_mvx[i];
+ y = tab->table_mvy[i];
+ tab->table_mv_index[(x << 6) | y] = i;
+ }
+}
+
+static void code012(PutBitContext *pb, int n)
+{
+ if (n == 0) {
+ put_bits(pb, 1, 0);
+ } else {
+ put_bits(pb, 1, 1);
+ put_bits(pb, 1, (n >= 2));
+ }
+}
+
+/* write MSMPEG4 V3 compatible frame header */
+void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
+{
+ int i;
+
+ align_put_bits(&s->pb);
+
+ put_bits(&s->pb, 2, s->pict_type - 1);
+
+ put_bits(&s->pb, 5, s->qscale);
+
+ s->rl_table_index = 2;
+ s->rl_chroma_table_index = 1; /* only for I frame */
+ s->dc_table_index = 1;
+ s->mv_table_index = 1; /* only if P frame */
+ s->use_skip_mb_code = 1; /* only if P frame */
+
+ if (s->pict_type == I_TYPE) {
+ put_bits(&s->pb, 5, 0x17); /* indicate only one "slice" */
+
+ code012(&s->pb, s->rl_chroma_table_index);
+ code012(&s->pb, s->rl_table_index);
+
+ put_bits(&s->pb, 1, s->dc_table_index);
+ s->no_rounding = 1;
+ } else {
+ put_bits(&s->pb, 1, s->use_skip_mb_code);
+
+ s->rl_chroma_table_index = s->rl_table_index;
+ code012(&s->pb, s->rl_table_index);
+
+ put_bits(&s->pb, 1, s->dc_table_index);
+
+ put_bits(&s->pb, 1, s->mv_table_index);
+ s->no_rounding ^= 1;
+ }
+
+ if (!init_done) {
+ /* init various encoding tables */
+ init_done = 1;
+ init_mv_table(&mv_tables[0]);
+ init_mv_table(&mv_tables[1]);
+ for(i=0;i<NB_RL_TABLES;i++)
+ init_rl(&rl_table[i]);
+ }
+
+#ifdef DEBUG
+ intra_count = 0;
+ printf("*****frame %d:\n", frame_count++);
+#endif
+}
+
+/* predict coded block */
+static inline int coded_block_pred(MpegEncContext * s, int n, UINT8 **coded_block_ptr)
+{
+ int x, y, wrap, pred, a, b, c;
+
+ x = 2 * s->mb_x + 1 + (n & 1);
+ y = 2 * s->mb_y + 1 + ((n & 2) >> 1);
+ wrap = s->mb_width * 2 + 2;
+
+ /* B C
+ * A X
+ */
+ a = s->coded_block[(x - 1) + (y) * wrap];
+ b = s->coded_block[(x - 1) + (y - 1) * wrap];
+ c = s->coded_block[(x) + (y - 1) * wrap];
+
+ if (b == c) {
+ pred = a;
+ } else {
+ pred = c;
+ }
+
+ /* store value */
+ *coded_block_ptr = &s->coded_block[(x) + (y) * wrap];
+
+ return pred;
+}
+
+static void msmpeg4_encode_motion(MpegEncContext * s,
+ int mx, int my)
+{
+ int code;
+ MVTable *mv;
+
+ /* modulo encoding */
+ /* WARNING : you cannot reach all the MVs even with the modulo
+ encoding. This is a somewhat strange compromise they took !!! */
+ if (mx <= -64)
+ mx += 64;
+ else if (mx >= 64)
+ mx -= 64;
+ if (my <= -64)
+ my += 64;
+ else if (my >= 64)
+ my -= 64;
+
+ mx += 32;
+ my += 32;
+#if 0
+ if ((unsigned)mx >= 64 ||
+ (unsigned)my >= 64)
+ fprintf(stderr, "error mx=%d my=%d\n", mx, my);
+#endif
+ mv = &mv_tables[s->mv_table_index];
+
+ code = mv->table_mv_index[(mx << 6) | my];
+ set_stat(ST_MV);
+ put_bits(&s->pb,
+ mv->table_mv_bits[code],
+ mv->table_mv_code[code]);
+ if (code == mv->n) {
+ /* escape : code litterally */
+ put_bits(&s->pb, 6, mx);
+ put_bits(&s->pb, 6, my);
+ }
+}
+
+void msmpeg4_encode_mb(MpegEncContext * s,
+ DCTELEM block[6][64],
+ int motion_x, int motion_y)
+{
+ int cbp, coded_cbp, i;
+ int pred_x, pred_y;
+ UINT8 *coded_block;
+
+ if (!s->mb_intra) {
+ /* compute cbp */
+ set_stat(ST_INTER_MB);
+ cbp = 0;
+ for (i = 0; i < 6; i++) {
+ if (s->block_last_index[i] >= 0)
+ cbp |= 1 << (5 - i);
+ }
+ if (s->use_skip_mb_code && (cbp | motion_x | motion_y) == 0) {
+ /* skip macroblock */
+ put_bits(&s->pb, 1, 1);
+ return;
+ }
+ if (s->use_skip_mb_code)
+ put_bits(&s->pb, 1, 0); /* mb coded */
+
+ put_bits(&s->pb,
+ table_mb_non_intra[cbp + 64][1],
+ table_mb_non_intra[cbp + 64][0]);
+
+ /* motion vector */
+ h263_pred_motion(s, 0, &pred_x, &pred_y);
+ msmpeg4_encode_motion(s, motion_x - pred_x,
+ motion_y - pred_y);
+ } else {
+ /* compute cbp */
+ cbp = 0;
+ coded_cbp = 0;
+ for (i = 0; i < 6; i++) {
+ int val, pred;
+ val = (s->block_last_index[i] >= 1);
+ cbp |= val << (5 - i);
+ if (i < 4) {
+ /* predict value for close blocks only for luma */
+ pred = coded_block_pred(s, i, &coded_block);
+ *coded_block = val;
+ val = val ^ pred;
+ }
+ coded_cbp |= val << (5 - i);
+ }
+#if 0
+ if (coded_cbp)
+ printf("cbp=%x %x\n", cbp, coded_cbp);
+#endif
+
+ if (s->pict_type == I_TYPE) {
+ set_stat(ST_INTRA_MB);
+ put_bits(&s->pb,
+ table_mb_intra[coded_cbp][1], table_mb_intra[coded_cbp][0]);
+ } else {
+ if (s->use_skip_mb_code)
+ put_bits(&s->pb, 1, 0); /* mb coded */
+ put_bits(&s->pb,
+ table_mb_non_intra[cbp][1],
+ table_mb_non_intra[cbp][0]);
+ }
+ set_stat(ST_INTRA_MB);
+ put_bits(&s->pb, 1, 0); /* no AC prediction yet */
+ }
+
+ for (i = 0; i < 6; i++) {
+ msmpeg4_encode_block(s, block[i], i);
+ }
+}
+
+
+/* strongly inspirated from MPEG4, but not exactly the same ! */
+void msmpeg4_dc_scale(MpegEncContext * s)
+{
+ int scale;
+
+ if (s->qscale < 5)
+ scale = 8;
+ else if (s->qscale < 9)
+ scale = 2 * s->qscale;
+ else
+ scale = s->qscale + 8;
+ s->y_dc_scale = scale;
+ s->c_dc_scale = (s->qscale + 13) / 2;
+}
+
+/* dir = 0: left, dir = 1: top prediction */
+static int msmpeg4_pred_dc(MpegEncContext * s, int n,
+ INT16 **dc_val_ptr, int *dir_ptr)
+{
+ int a, b, c, x, y, wrap, pred, scale;
+ INT16 *dc_val;
+
+ /* find prediction */
+ if (n < 4) {
+ x = 2 * s->mb_x + 1 + (n & 1);
+ y = 2 * s->mb_y + 1 + ((n & 2) >> 1);
+ wrap = s->mb_width * 2 + 2;
+ dc_val = s->dc_val[0];
+ scale = s->y_dc_scale;
+ } else {
+ x = s->mb_x + 1;
+ y = s->mb_y + 1;
+ wrap = s->mb_width + 2;
+ dc_val = s->dc_val[n - 4 + 1];
+ scale = s->c_dc_scale;
+ }
+
+ /* B C
+ * A X
+ */
+ a = dc_val[(x - 1) + (y) * wrap];
+ b = dc_val[(x - 1) + (y - 1) * wrap];
+ c = dc_val[(x) + (y - 1) * wrap];
+
+ /* XXX: the following solution consumes divisions, but it does not
+ necessitate to modify mpegvideo.c. The problem comes from the
+ fact they decided to store the quantized DC (which would lead
+ to problems if Q could vary !) */
+ a = (a + (scale >> 1)) / scale;
+ b = (b + (scale >> 1)) / scale;
+ c = (c + (scale >> 1)) / scale;
+
+ /* XXX: WARNING: they did not choose the same test as MPEG4. This
+ is very important ! */
+ if (abs(a - b) <= abs(b - c)) {
+ pred = c;
+ *dir_ptr = 1;
+ } else {
+ pred = a;
+ *dir_ptr = 0;
+ }
+
+ /* update predictor */
+ *dc_val_ptr = &dc_val[(x) + (y) * wrap];
+ return pred;
+}
+
+#define DC_MAX 119
+
+static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr)
+{
+ int sign, code;
+ int pred;
+ INT16 *dc_val;
+
+ pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr);
+
+ /* update predictor */
+ if (n < 4) {
+ *dc_val = level * s->y_dc_scale;
+ } else {
+ *dc_val = level * s->c_dc_scale;
+ }
+
+ /* do the prediction */
+ level -= pred;
+
+ sign = 0;
+ if (level < 0) {
+ level = -level;
+ sign = 1;
+ }
+
+ code = level;
+ if (code > DC_MAX)
+ code = DC_MAX;
+
+ if (s->dc_table_index == 0) {
+ if (n < 4) {
+ put_bits(&s->pb, table0_dc_lum[code][1], table0_dc_lum[code][0]);
+ } else {
+ put_bits(&s->pb, table0_dc_chroma[code][1], table0_dc_chroma[code][0]);
+ }
+ } else {
+ if (n < 4) {
+ put_bits(&s->pb, table1_dc_lum[code][1], table1_dc_lum[code][0]);
+ } else {
+ put_bits(&s->pb, table1_dc_chroma[code][1], table1_dc_chroma[code][0]);
+ }
+ }
+
+ if (code == DC_MAX)
+ put_bits(&s->pb, 8, level);
+
+ if (level != 0) {
+ put_bits(&s->pb, 1, sign);
+ }
+}
+
+/* Encoding of a block. Very similar to MPEG4 except for a different
+ escape coding (same as H263) and more vlc tables.
+ */
+static void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n)
+{
+ int level, run, last, i, j, last_index;
+ int last_non_zero, sign, slevel;
+ int code, run_diff, dc_pred_dir;
+ const RLTable *rl;
+
+ if (s->mb_intra) {
+ set_stat(ST_DC);
+ msmpeg4_encode_dc(s, block[0], n, &dc_pred_dir);
+ i = 1;
+ if (n < 4) {
+ rl = &rl_table[s->rl_table_index];
+ } else {
+ rl = &rl_table[3 + s->rl_chroma_table_index];
+ }
+ run_diff = 0;
+ set_stat(ST_INTRA_AC);
+ } else {
+ i = 0;
+ rl = &rl_table[3 + s->rl_table_index];
+ run_diff = 1;
+ set_stat(ST_INTER_AC);
+ }
+
+ /* AC coefs */
+ last_index = s->block_last_index[n];
+ last_non_zero = i - 1;
+ for (; i <= last_index; i++) {
+ j = zigzag_direct[i];
+ level = block[j];
+ if (level) {
+ run = i - last_non_zero - 1;
+ last = (i == last_index);
+ sign = 0;
+ slevel = level;
+ if (level < 0) {
+ sign = 1;
+ level = -level;
+ }
+ code = get_rl_index(rl, last, run, level);
+ put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
+ if (code == rl->n) {
+ int level1, run1;
+
+ level1 = level - rl->max_level[last][run];
+ if (level1 < 1)
+ goto esc2;
+ code = get_rl_index(rl, last, run, level1);
+ if (code == rl->n) {
+ esc2:
+ put_bits(&s->pb, 1, 0);
+ if (level > MAX_LEVEL)
+ goto esc3;
+ run1 = run - rl->max_run[last][level] - run_diff;
+ if (run1 < 0)
+ goto esc3;
+ code = get_rl_index(rl, last, run1, level);
+ if (code == rl->n) {
+ esc3:
+ /* third escape */
+ put_bits(&s->pb, 1, 0);
+ put_bits(&s->pb, 1, last);
+ put_bits(&s->pb, 6, run);
+ put_bits(&s->pb, 8, slevel & 0xff);
+ } else {
+ /* second escape */
+ put_bits(&s->pb, 1, 1);
+ put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
+ put_bits(&s->pb, 1, sign);
+ }
+ } else {
+ /* first escape */
+ put_bits(&s->pb, 1, 1);
+ put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
+ put_bits(&s->pb, 1, sign);
+ }
+ } else {
+ put_bits(&s->pb, 1, sign);
+ }
+ last_non_zero = i;
+ }
+ }
+}
+
+/****************************************/
+/* decoding stuff */
+
+static VLC mb_non_intra_vlc;
+static VLC mb_intra_vlc;
+static VLC dc_lum_vlc[2];
+static VLC dc_chroma_vlc[2];
+
+/* init all vlc decoding tables */
+int msmpeg4_decode_init_vlc(MpegEncContext *s)
+{
+ int i;
+ MVTable *mv;
+
+ for(i=0;i<NB_RL_TABLES;i++) {
+ init_rl(&rl_table[i]);
+ init_vlc_rl(&rl_table[i]);
+ }
+ for(i=0;i<2;i++) {
+ mv = &mv_tables[i];
+ init_vlc(&mv->vlc, 9, mv->n + 1,
+ mv->table_mv_bits, 1, 1,
+ mv->table_mv_code, 2, 2);
+ }
+
+ init_vlc(&dc_lum_vlc[0], 9, 120,
+ &table0_dc_lum[0][1], 8, 4,
+ &table0_dc_lum[0][0], 8, 4);
+ init_vlc(&dc_chroma_vlc[0], 9, 120,
+ &table0_dc_chroma[0][1], 8, 4,
+ &table0_dc_chroma[0][0], 8, 4);
+ init_vlc(&dc_lum_vlc[1], 9, 120,
+ &table1_dc_lum[0][1], 8, 4,
+ &table1_dc_lum[0][0], 8, 4);
+ init_vlc(&dc_chroma_vlc[1], 9, 120,
+ &table1_dc_chroma[0][1], 8, 4,
+ &table1_dc_chroma[0][0], 8, 4);
+
+ init_vlc(&mb_non_intra_vlc, 9, 128,
+ &table_mb_non_intra[0][1], 8, 4,
+ &table_mb_non_intra[0][0], 8, 4);
+ init_vlc(&mb_intra_vlc, 9, 128,
+ &table_mb_intra[0][1], 4, 2,
+ &table_mb_intra[0][0], 4, 2);
+ return 0;
+}
+
+static int decode012(GetBitContext *gb)
+{
+ int n;
+ n = get_bits1(gb);
+ if (n == 0)
+ return 0;
+ else
+ return get_bits1(gb) + 1;
+}
+
+int msmpeg4_decode_picture_header(MpegEncContext * s)
+{
+ int code;
+
+ s->pict_type = get_bits(&s->gb, 2) + 1;
+ if (s->pict_type != I_TYPE &&
+ s->pict_type != P_TYPE)
+ return -1;
+
+ s->qscale = get_bits(&s->gb, 5);
+
+ if (s->pict_type == I_TYPE) {
+ code = get_bits(&s->gb, 5);
+ /* 0x17: one slice, 0x18: three slices */
+ /* XXX: implement it */
+ if (code < 0x17)
+ return -1;
+ s->slice_height = s->mb_height / (code - 0x16);
+ s->rl_chroma_table_index = decode012(&s->gb);
+ s->rl_table_index = decode012(&s->gb);
+
+ s->dc_table_index = get_bits1(&s->gb);
+ s->no_rounding = 1;
+ } else {
+ s->use_skip_mb_code = get_bits1(&s->gb);
+
+ s->rl_table_index = decode012(&s->gb);
+ s->rl_chroma_table_index = s->rl_table_index;
+
+ s->dc_table_index = get_bits1(&s->gb);
+
+ s->mv_table_index = get_bits1(&s->gb);
+ s->no_rounding ^= 1;
+ }
+#ifdef DEBUG
+ printf("*****frame %d:\n", frame_count++);
+#endif
+ return 0;
+}
+
+void memsetw(short *tab, int val, int n)
+{
+ int i;
+ for(i=0;i<n;i++)
+ tab[i] = val;
+}
+
+int msmpeg4_decode_mb(MpegEncContext *s,
+ DCTELEM block[6][64])
+{
+ int cbp, code, i;
+ int pred, val;
+ UINT8 *coded_val;
+
+ /* special slice handling */
+ if (s->mb_x == 0) {
+ if ((s->mb_y % s->slice_height) == 0) {
+ int wrap;
+ /* reset DC pred (set previous line to 1024) */
+ wrap = 2 * s->mb_width + 2;
+ memsetw(&s->dc_val[0][(1) + (2 * s->mb_y) * wrap],
+ 1024, 2 * s->mb_width);
+ wrap = s->mb_width + 2;
+ memsetw(&s->dc_val[1][(1) + (s->mb_y) * wrap],
+ 1024, s->mb_width);
+ memsetw(&s->dc_val[2][(1) + (s->mb_y) * wrap],
+ 1024, s->mb_width);
+
+ s->first_slice_line = 1;
+ } else {
+ s->first_slice_line = 0;
+ }
+ }
+
+ if (s->pict_type == P_TYPE) {
+ set_stat(ST_INTER_MB);
+ if (s->use_skip_mb_code) {
+ if (get_bits1(&s->gb)) {
+ /* skip mb */
+ s->mb_intra = 0;
+ for(i=0;i<6;i++)
+ s->block_last_index[i] = -1;
+ s->mv_dir = MV_DIR_FORWARD;
+ s->mv_type = MV_TYPE_16X16;
+ s->mv[0][0][0] = 0;
+ s->mv[0][0][1] = 0;
+ s->mb_skiped = 1;
+ return 0;
+ }
+ }
+
+ code = get_vlc(&s->gb, &mb_non_intra_vlc);
+ if (code < 0)
+ return -1;
+ if (code & 0x40)
+ s->mb_intra = 0;
+ else
+ s->mb_intra = 1;
+
+ cbp = code & 0x3f;
+ } else {
+ set_stat(ST_INTRA_MB);
+ s->mb_intra = 1;
+ code = get_vlc(&s->gb, &mb_intra_vlc);
+ if (code < 0)
+ return -1;
+ /* predict coded block pattern */
+ cbp = 0;
+ for(i=0;i<6;i++) {
+ val = ((code >> (5 - i)) & 1);
+ if (i < 4) {
+ pred = coded_block_pred(s, i, &coded_val);
+ val = val ^ pred;
+ *coded_val = val;
+ }
+ cbp |= val << (5 - i);
+ }
+ }
+
+ if (!s->mb_intra) {
+ int mx, my;
+ set_stat(ST_MV);
+ h263_pred_motion(s, 0, &mx, &my);
+ if (msmpeg4_decode_motion(s, &mx, &my) < 0)
+ return -1;
+ s->mv_dir = MV_DIR_FORWARD;
+ s->mv_type = MV_TYPE_16X16;
+ s->mv[0][0][0] = mx;
+ s->mv[0][0][1] = my;
+ } else {
+ set_stat(ST_INTRA_MB);
+ s->ac_pred = get_bits1(&s->gb);
+ }
+
+ for (i = 0; i < 6; i++) {
+ if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+static int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
+ int n, int coded)
+{
+ int code, level, i, j, last, run, run_diff;
+ int dc_pred_dir;
+ RLTable *rl;
+ const UINT8 *scan_table;
+
+ if (s->mb_intra) {
+ /* DC coef */
+ set_stat(ST_DC);
+ level = msmpeg4_decode_dc(s, n, &dc_pred_dir);
+ if (level < 0)
+ return -1;
+ block[0] = level;
+ if (n < 4) {
+ rl = &rl_table[s->rl_table_index];
+ } else {
+ rl = &rl_table[3 + s->rl_chroma_table_index];
+ }
+ run_diff = 0;
+ i = 1;
+ if (!coded) {
+ goto not_coded;
+ }
+ if (s->ac_pred) {
+ if (dc_pred_dir == 0)
+ scan_table = ff_alternate_vertical_scan; /* left */
+ else
+ scan_table = ff_alternate_horizontal_scan; /* top */
+ } else {
+ scan_table = zigzag_direct;
+ }
+ set_stat(ST_INTRA_AC);
+ } else {
+ i = 0;
+ rl = &rl_table[3 + s->rl_table_index];
+ run_diff = 1;
+ if (!coded) {
+ s->block_last_index[n] = i - 1;
+ return 0;
+ }
+ scan_table = zigzag_direct;
+ set_stat(ST_INTER_AC);
+ }
+
+ for(;;) {
+ code = get_vlc(&s->gb, &rl->vlc);
+ if (code < 0)
+ return -1;
+ if (code == rl->n) {
+ /* escape */
+ if (get_bits1(&s->gb) == 0) {
+ if (get_bits1(&s->gb) == 0) {
+ /* third escape */
+ last = get_bits1(&s->gb);
+ run = get_bits(&s->gb, 6);
+ level = get_bits(&s->gb, 8);
+ level = (level << 24) >> 24; /* sign extend */
+ } else {
+ /* second escape */
+ code = get_vlc(&s->gb, &rl->vlc);
+ if (code < 0 || code >= rl->n)
+ return -1;
+ run = rl->table_run[code];
+ level = rl->table_level[code];
+ last = code >= rl->last;
+ run += rl->max_run[last][level] + run_diff;
+ if (get_bits1(&s->gb))
+ level = -level;
+ }
+ } else {
+ /* first escape */
+ code = get_vlc(&s->gb, &rl->vlc);
+ if (code < 0 || code >= rl->n)
+ return -1;
+ run = rl->table_run[code];
+ level = rl->table_level[code];
+ last = code >= rl->last;
+ level += rl->max_level[last][run];
+ if (get_bits1(&s->gb))
+ level = -level;
+ }
+ } else {
+ run = rl->table_run[code];
+ level = rl->table_level[code];
+ last = code >= rl->last;
+ if (get_bits1(&s->gb))
+ level = -level;
+ }
+ i += run;
+ if (i >= 64)
+ return -1;
+ j = scan_table[i];
+ block[j] = level;
+ i++;
+ if (last)
+ break;
+ }
+ not_coded:
+ if (s->mb_intra) {
+ mpeg4_pred_ac(s, block, n, dc_pred_dir);
+ if (s->ac_pred) {
+ i = 64; /* XXX: not optimal */
+ }
+ }
+ s->block_last_index[n] = i - 1;
+
+ return 0;
+}
+
+static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
+{
+ int level, pred;
+ INT16 *dc_val;
+
+ if (n < 4) {
+ level = get_vlc(&s->gb, &dc_lum_vlc[s->dc_table_index]);
+ } else {
+ level = get_vlc(&s->gb, &dc_chroma_vlc[s->dc_table_index]);
+ }
+ if (level < 0)
+ return -1;
+
+ if (level == DC_MAX) {
+ level = get_bits(&s->gb, 8);
+ if (get_bits1(&s->gb))
+ level = -level;
+ } else if (level != 0) {
+ if (get_bits1(&s->gb))
+ level = -level;
+ }
+
+ pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr);
+ level += pred;
+
+ /* update predictor */
+ if (n < 4) {
+ *dc_val = level * s->y_dc_scale;
+ } else {
+ *dc_val = level * s->c_dc_scale;
+ }
+
+ return level;
+}
+
+static int msmpeg4_decode_motion(MpegEncContext * s,
+ int *mx_ptr, int *my_ptr)
+{
+ MVTable *mv;
+ int code, mx, my;
+
+ mv = &mv_tables[s->mv_table_index];
+
+ code = get_vlc(&s->gb, &mv->vlc);
+ if (code < 0)
+ return -1;
+ if (code == mv->n) {
+ mx = get_bits(&s->gb, 6);
+ my = get_bits(&s->gb, 6);
+ } else {
+ mx = mv->table_mvx[code];
+ my = mv->table_mvy[code];
+ }
+
+ mx += *mx_ptr - 32;
+ my += *my_ptr - 32;
+ /* WARNING : they do not do exactly modulo encoding */
+ if (mx <= -64)
+ mx += 64;
+ else if (mx >= 64)
+ mx -= 64;
+
+ if (my <= -64)
+ my += 64;
+ else if (my >= 64)
+ my -= 64;
+ *mx_ptr = mx;
+ *my_ptr = my;
+ return 0;
+}
diff --git a/src/libffmpeg/libavcodec/msmpeg4data.h b/src/libffmpeg/libavcodec/msmpeg4data.h
new file mode 100644
index 000000000..03a261211
--- /dev/null
+++ b/src/libffmpeg/libavcodec/msmpeg4data.h
@@ -0,0 +1,1767 @@
+/*
+ * MSMPEG4 data tables.
+ */
+
+/* intra picture macro block coded block pattern */
+const UINT16 table_mb_intra[64][2] = {
+{ 0x1, 1 },{ 0x17, 6 },{ 0x9, 5 },{ 0x5, 5 },
+{ 0x6, 5 },{ 0x47, 9 },{ 0x20, 7 },{ 0x10, 7 },
+{ 0x2, 5 },{ 0x7c, 9 },{ 0x3a, 7 },{ 0x1d, 7 },
+{ 0x2, 6 },{ 0xec, 9 },{ 0x77, 8 },{ 0x0, 8 },
+{ 0x3, 5 },{ 0xb7, 9 },{ 0x2c, 7 },{ 0x13, 7 },
+{ 0x1, 6 },{ 0x168, 10 },{ 0x46, 8 },{ 0x3f, 8 },
+{ 0x1e, 6 },{ 0x712, 13 },{ 0xb5, 9 },{ 0x42, 8 },
+{ 0x22, 7 },{ 0x1c5, 11 },{ 0x11e, 10 },{ 0x87, 9 },
+{ 0x6, 4 },{ 0x3, 9 },{ 0x1e, 7 },{ 0x1c, 6 },
+{ 0x12, 7 },{ 0x388, 12 },{ 0x44, 9 },{ 0x70, 9 },
+{ 0x1f, 6 },{ 0x23e, 11 },{ 0x39, 8 },{ 0x8e, 9 },
+{ 0x1, 7 },{ 0x1c6, 11 },{ 0xb6, 9 },{ 0x45, 9 },
+{ 0x14, 6 },{ 0x23f, 11 },{ 0x7d, 9 },{ 0x18, 9 },
+{ 0x7, 7 },{ 0x1c7, 11 },{ 0x86, 9 },{ 0x19, 9 },
+{ 0x15, 6 },{ 0x1db, 10 },{ 0x2, 9 },{ 0x46, 9 },
+{ 0xd, 8 },{ 0x713, 13 },{ 0x1da, 10 },{ 0x169, 10 },
+};
+
+/* non intra picture macro block coded block pattern + mb type */
+const UINT32 table_mb_non_intra[128][2] = {
+{ 0x40, 7 },{ 0x13c9, 13 },{ 0x9fd, 12 },{ 0x1fc, 15 },
+{ 0x9fc, 12 },{ 0xa83, 18 },{ 0x12d34, 17 },{ 0x83bc, 16 },
+{ 0x83a, 12 },{ 0x7f8, 17 },{ 0x3fd, 16 },{ 0x3ff, 16 },
+{ 0x79, 13 },{ 0xa82, 18 },{ 0x969d, 16 },{ 0x2a4, 16 },
+{ 0x978, 12 },{ 0x543, 17 },{ 0x41df, 15 },{ 0x7f9, 17 },
+{ 0x12f3, 13 },{ 0x25a6b, 18 },{ 0x25ef9, 18 },{ 0x3fa, 16 },
+{ 0x20ee, 14 },{ 0x969ab, 20 },{ 0x969c, 16 },{ 0x25ef8, 18 },
+{ 0x12d2, 13 },{ 0xa85, 18 },{ 0x969e, 16 },{ 0x4bc8, 15 },
+{ 0x3d, 12 },{ 0x12f7f, 17 },{ 0x2a2, 16 },{ 0x969f, 16 },
+{ 0x25ee, 14 },{ 0x12d355, 21 },{ 0x12f7d, 17 },{ 0x12f7e, 17 },
+{ 0x9e5, 12 },{ 0xa81, 18 },{ 0x4b4d4, 19 },{ 0x83bd, 16 },
+{ 0x78, 13 },{ 0x969b, 16 },{ 0x3fe, 16 },{ 0x2a5, 16 },
+{ 0x7e, 13 },{ 0xa80, 18 },{ 0x2a3, 16 },{ 0x3fb, 16 },
+{ 0x1076, 13 },{ 0xa84, 18 },{ 0x153, 15 },{ 0x4bc9, 15 },
+{ 0x55, 13 },{ 0x12d354, 21 },{ 0x4bde, 15 },{ 0x25e5, 14 },
+{ 0x25b, 10 },{ 0x4b4c, 15 },{ 0x96b, 12 },{ 0x96a, 12 },
+{ 0x1, 2 },{ 0x0, 7 },{ 0x26, 6 },{ 0x12b, 9 },
+{ 0x7, 3 },{ 0x20f, 10 },{ 0x4, 9 },{ 0x28, 12 },
+{ 0x6, 3 },{ 0x20a, 10 },{ 0x128, 9 },{ 0x2b, 12 },
+{ 0x11, 5 },{ 0x1b, 11 },{ 0x13a, 9 },{ 0x4ff, 11 },
+{ 0x3, 4 },{ 0x277, 10 },{ 0x106, 9 },{ 0x839, 12 },
+{ 0xb, 4 },{ 0x27b, 10 },{ 0x12c, 9 },{ 0x4bf, 11 },
+{ 0x9, 6 },{ 0x35, 12 },{ 0x27e, 10 },{ 0x13c8, 13 },
+{ 0x1, 6 },{ 0x4aa, 11 },{ 0x208, 10 },{ 0x29, 12 },
+{ 0x1, 4 },{ 0x254, 10 },{ 0x12e, 9 },{ 0x838, 12 },
+{ 0x24, 6 },{ 0x4f3, 11 },{ 0x276, 10 },{ 0x12f6, 13 },
+{ 0x1, 5 },{ 0x27a, 10 },{ 0x13e, 9 },{ 0x3e, 12 },
+{ 0x8, 6 },{ 0x413, 11 },{ 0xc, 10 },{ 0x4be, 11 },
+{ 0x14, 5 },{ 0x412, 11 },{ 0x253, 10 },{ 0x97a, 12 },
+{ 0x21, 6 },{ 0x4ab, 11 },{ 0x20b, 10 },{ 0x34, 12 },
+{ 0x15, 5 },{ 0x278, 10 },{ 0x252, 10 },{ 0x968, 12 },
+{ 0x5, 5 },{ 0xb, 10 },{ 0x9c, 8 },{ 0xe, 10 },
+};
+
+/* dc table 0 */
+
+static const UINT32 table0_dc_lum[120][2] = {
+{ 0x1, 1 },{ 0x1, 2 },{ 0x1, 4 },{ 0x1, 5 },
+{ 0x5, 5 },{ 0x7, 5 },{ 0x8, 6 },{ 0xc, 6 },
+{ 0x0, 7 },{ 0x2, 7 },{ 0x12, 7 },{ 0x1a, 7 },
+{ 0x3, 8 },{ 0x7, 8 },{ 0x27, 8 },{ 0x37, 8 },
+{ 0x5, 9 },{ 0x4c, 9 },{ 0x6c, 9 },{ 0x6d, 9 },
+{ 0x8, 10 },{ 0x19, 10 },{ 0x9b, 10 },{ 0x1b, 10 },
+{ 0x9a, 10 },{ 0x13, 11 },{ 0x34, 11 },{ 0x35, 11 },
+{ 0x61, 12 },{ 0x48, 13 },{ 0xc4, 13 },{ 0x4a, 13 },
+{ 0xc6, 13 },{ 0xc7, 13 },{ 0x92, 14 },{ 0x18b, 14 },
+{ 0x93, 14 },{ 0x183, 14 },{ 0x182, 14 },{ 0x96, 14 },
+{ 0x97, 14 },{ 0x180, 14 },{ 0x314, 15 },{ 0x315, 15 },
+{ 0x605, 16 },{ 0x604, 16 },{ 0x606, 16 },{ 0xc0e, 17 },
+{ 0x303cd, 23 },{ 0x303c9, 23 },{ 0x303c8, 23 },{ 0x303ca, 23 },
+{ 0x303cb, 23 },{ 0x303cc, 23 },{ 0x303ce, 23 },{ 0x303cf, 23 },
+{ 0x303d0, 23 },{ 0x303d1, 23 },{ 0x303d2, 23 },{ 0x303d3, 23 },
+{ 0x303d4, 23 },{ 0x303d5, 23 },{ 0x303d6, 23 },{ 0x303d7, 23 },
+{ 0x303d8, 23 },{ 0x303d9, 23 },{ 0x303da, 23 },{ 0x303db, 23 },
+{ 0x303dc, 23 },{ 0x303dd, 23 },{ 0x303de, 23 },{ 0x303df, 23 },
+{ 0x303e0, 23 },{ 0x303e1, 23 },{ 0x303e2, 23 },{ 0x303e3, 23 },
+{ 0x303e4, 23 },{ 0x303e5, 23 },{ 0x303e6, 23 },{ 0x303e7, 23 },
+{ 0x303e8, 23 },{ 0x303e9, 23 },{ 0x303ea, 23 },{ 0x303eb, 23 },
+{ 0x303ec, 23 },{ 0x303ed, 23 },{ 0x303ee, 23 },{ 0x303ef, 23 },
+{ 0x303f0, 23 },{ 0x303f1, 23 },{ 0x303f2, 23 },{ 0x303f3, 23 },
+{ 0x303f4, 23 },{ 0x303f5, 23 },{ 0x303f6, 23 },{ 0x303f7, 23 },
+{ 0x303f8, 23 },{ 0x303f9, 23 },{ 0x303fa, 23 },{ 0x303fb, 23 },
+{ 0x303fc, 23 },{ 0x303fd, 23 },{ 0x303fe, 23 },{ 0x303ff, 23 },
+{ 0x60780, 24 },{ 0x60781, 24 },{ 0x60782, 24 },{ 0x60783, 24 },
+{ 0x60784, 24 },{ 0x60785, 24 },{ 0x60786, 24 },{ 0x60787, 24 },
+{ 0x60788, 24 },{ 0x60789, 24 },{ 0x6078a, 24 },{ 0x6078b, 24 },
+{ 0x6078c, 24 },{ 0x6078d, 24 },{ 0x6078e, 24 },{ 0x6078f, 24 },
+};
+
+static const UINT32 table0_dc_chroma[120][2] = {
+{ 0x0, 2 },{ 0x1, 2 },{ 0x5, 3 },{ 0x9, 4 },
+{ 0xd, 4 },{ 0x11, 5 },{ 0x1d, 5 },{ 0x1f, 5 },
+{ 0x21, 6 },{ 0x31, 6 },{ 0x38, 6 },{ 0x33, 6 },
+{ 0x39, 6 },{ 0x3d, 6 },{ 0x61, 7 },{ 0x79, 7 },
+{ 0x80, 8 },{ 0xc8, 8 },{ 0xca, 8 },{ 0xf0, 8 },
+{ 0x81, 8 },{ 0xc0, 8 },{ 0xc9, 8 },{ 0x107, 9 },
+{ 0x106, 9 },{ 0x196, 9 },{ 0x183, 9 },{ 0x1e3, 9 },
+{ 0x1e2, 9 },{ 0x20a, 10 },{ 0x20b, 10 },{ 0x609, 11 },
+{ 0x412, 11 },{ 0x413, 11 },{ 0x60b, 11 },{ 0x411, 11 },
+{ 0x60a, 11 },{ 0x65f, 11 },{ 0x410, 11 },{ 0x65d, 11 },
+{ 0x65e, 11 },{ 0xcb8, 12 },{ 0xc10, 12 },{ 0xcb9, 12 },
+{ 0x1823, 13 },{ 0x3045, 14 },{ 0x6089, 15 },{ 0xc110, 16 },
+{ 0x304448, 22 },{ 0x304449, 22 },{ 0x30444a, 22 },{ 0x30444b, 22 },
+{ 0x30444c, 22 },{ 0x30444d, 22 },{ 0x30444e, 22 },{ 0x30444f, 22 },
+{ 0x304450, 22 },{ 0x304451, 22 },{ 0x304452, 22 },{ 0x304453, 22 },
+{ 0x304454, 22 },{ 0x304455, 22 },{ 0x304456, 22 },{ 0x304457, 22 },
+{ 0x304458, 22 },{ 0x304459, 22 },{ 0x30445a, 22 },{ 0x30445b, 22 },
+{ 0x30445c, 22 },{ 0x30445d, 22 },{ 0x30445e, 22 },{ 0x30445f, 22 },
+{ 0x304460, 22 },{ 0x304461, 22 },{ 0x304462, 22 },{ 0x304463, 22 },
+{ 0x304464, 22 },{ 0x304465, 22 },{ 0x304466, 22 },{ 0x304467, 22 },
+{ 0x304468, 22 },{ 0x304469, 22 },{ 0x30446a, 22 },{ 0x30446b, 22 },
+{ 0x30446c, 22 },{ 0x30446d, 22 },{ 0x30446e, 22 },{ 0x30446f, 22 },
+{ 0x304470, 22 },{ 0x304471, 22 },{ 0x304472, 22 },{ 0x304473, 22 },
+{ 0x304474, 22 },{ 0x304475, 22 },{ 0x304476, 22 },{ 0x304477, 22 },
+{ 0x304478, 22 },{ 0x304479, 22 },{ 0x30447a, 22 },{ 0x30447b, 22 },
+{ 0x30447c, 22 },{ 0x30447d, 22 },{ 0x30447e, 22 },{ 0x30447f, 22 },
+{ 0x608880, 23 },{ 0x608881, 23 },{ 0x608882, 23 },{ 0x608883, 23 },
+{ 0x608884, 23 },{ 0x608885, 23 },{ 0x608886, 23 },{ 0x608887, 23 },
+{ 0x608888, 23 },{ 0x608889, 23 },{ 0x60888a, 23 },{ 0x60888b, 23 },
+{ 0x60888c, 23 },{ 0x60888d, 23 },{ 0x60888e, 23 },{ 0x60888f, 23 },
+};
+
+/* dc table 1 */
+
+const UINT32 table1_dc_lum[120][2] = {
+{ 0x2, 2 },{ 0x3, 2 },{ 0x3, 3 },{ 0x2, 4 },
+{ 0x5, 4 },{ 0x1, 5 },{ 0x3, 5 },{ 0x8, 5 },
+{ 0x0, 6 },{ 0x5, 6 },{ 0xd, 6 },{ 0xf, 6 },
+{ 0x13, 6 },{ 0x8, 7 },{ 0x18, 7 },{ 0x1c, 7 },
+{ 0x24, 7 },{ 0x4, 8 },{ 0x6, 8 },{ 0x12, 8 },
+{ 0x32, 8 },{ 0x3b, 8 },{ 0x4a, 8 },{ 0x4b, 8 },
+{ 0xb, 9 },{ 0x26, 9 },{ 0x27, 9 },{ 0x66, 9 },
+{ 0x74, 9 },{ 0x75, 9 },{ 0x14, 10 },{ 0x1c, 10 },
+{ 0x1f, 10 },{ 0x1d, 10 },{ 0x2b, 11 },{ 0x3d, 11 },
+{ 0x19d, 11 },{ 0x19f, 11 },{ 0x54, 12 },{ 0x339, 12 },
+{ 0x338, 12 },{ 0x33d, 12 },{ 0xab, 13 },{ 0xf1, 13 },
+{ 0x678, 13 },{ 0xf2, 13 },{ 0x1e0, 14 },{ 0x1e1, 14 },
+{ 0x154, 14 },{ 0xcf2, 14 },{ 0x3cc, 15 },{ 0x2ab, 15 },
+{ 0x19e7, 15 },{ 0x3ce, 15 },{ 0x19e6, 15 },{ 0x554, 16 },
+{ 0x79f, 16 },{ 0x555, 16 },{ 0xf3d, 17 },{ 0xf37, 17 },
+{ 0xf3c, 17 },{ 0xf35, 17 },{ 0x1e6d, 18 },{ 0x1e68, 18 },
+{ 0x3cd8, 19 },{ 0x3cd3, 19 },{ 0x3cd9, 19 },{ 0x79a4, 20 },
+{ 0xf34ba, 25 },{ 0xf34b4, 25 },{ 0xf34b5, 25 },{ 0xf34b6, 25 },
+{ 0xf34b7, 25 },{ 0xf34b8, 25 },{ 0xf34b9, 25 },{ 0xf34bb, 25 },
+{ 0xf34bc, 25 },{ 0xf34bd, 25 },{ 0xf34be, 25 },{ 0xf34bf, 25 },
+{ 0x1e6940, 26 },{ 0x1e6941, 26 },{ 0x1e6942, 26 },{ 0x1e6943, 26 },
+{ 0x1e6944, 26 },{ 0x1e6945, 26 },{ 0x1e6946, 26 },{ 0x1e6947, 26 },
+{ 0x1e6948, 26 },{ 0x1e6949, 26 },{ 0x1e694a, 26 },{ 0x1e694b, 26 },
+{ 0x1e694c, 26 },{ 0x1e694d, 26 },{ 0x1e694e, 26 },{ 0x1e694f, 26 },
+{ 0x1e6950, 26 },{ 0x1e6951, 26 },{ 0x1e6952, 26 },{ 0x1e6953, 26 },
+{ 0x1e6954, 26 },{ 0x1e6955, 26 },{ 0x1e6956, 26 },{ 0x1e6957, 26 },
+{ 0x1e6958, 26 },{ 0x1e6959, 26 },{ 0x1e695a, 26 },{ 0x1e695b, 26 },
+{ 0x1e695c, 26 },{ 0x1e695d, 26 },{ 0x1e695e, 26 },{ 0x1e695f, 26 },
+{ 0x1e6960, 26 },{ 0x1e6961, 26 },{ 0x1e6962, 26 },{ 0x1e6963, 26 },
+{ 0x1e6964, 26 },{ 0x1e6965, 26 },{ 0x1e6966, 26 },{ 0x1e6967, 26 },
+};
+
+const UINT32 table1_dc_chroma[120][2] = {
+{ 0x0, 2 },{ 0x1, 2 },{ 0x4, 3 },{ 0x7, 3 },
+{ 0xb, 4 },{ 0xd, 4 },{ 0x15, 5 },{ 0x28, 6 },
+{ 0x30, 6 },{ 0x32, 6 },{ 0x52, 7 },{ 0x62, 7 },
+{ 0x66, 7 },{ 0xa6, 8 },{ 0xc6, 8 },{ 0xcf, 8 },
+{ 0x14f, 9 },{ 0x18e, 9 },{ 0x19c, 9 },{ 0x29d, 10 },
+{ 0x33a, 10 },{ 0x538, 11 },{ 0x63c, 11 },{ 0x63e, 11 },
+{ 0x63f, 11 },{ 0x676, 11 },{ 0xa73, 12 },{ 0xc7a, 12 },
+{ 0xcef, 12 },{ 0x14e5, 13 },{ 0x19dd, 13 },{ 0x29c8, 14 },
+{ 0x29c9, 14 },{ 0x63dd, 15 },{ 0x33b8, 14 },{ 0x33b9, 14 },
+{ 0xc7b6, 16 },{ 0x63d8, 15 },{ 0x63df, 15 },{ 0xc7b3, 16 },
+{ 0xc7b4, 16 },{ 0xc7b5, 16 },{ 0x63de, 15 },{ 0xc7b7, 16 },
+{ 0xc7b8, 16 },{ 0xc7b9, 16 },{ 0x18f65, 17 },{ 0x31ec8, 18 },
+{ 0xc7b248, 24 },{ 0xc7b249, 24 },{ 0xc7b24a, 24 },{ 0xc7b24b, 24 },
+{ 0xc7b24c, 24 },{ 0xc7b24d, 24 },{ 0xc7b24e, 24 },{ 0xc7b24f, 24 },
+{ 0xc7b250, 24 },{ 0xc7b251, 24 },{ 0xc7b252, 24 },{ 0xc7b253, 24 },
+{ 0xc7b254, 24 },{ 0xc7b255, 24 },{ 0xc7b256, 24 },{ 0xc7b257, 24 },
+{ 0xc7b258, 24 },{ 0xc7b259, 24 },{ 0xc7b25a, 24 },{ 0xc7b25b, 24 },
+{ 0xc7b25c, 24 },{ 0xc7b25d, 24 },{ 0xc7b25e, 24 },{ 0xc7b25f, 24 },
+{ 0xc7b260, 24 },{ 0xc7b261, 24 },{ 0xc7b262, 24 },{ 0xc7b263, 24 },
+{ 0xc7b264, 24 },{ 0xc7b265, 24 },{ 0xc7b266, 24 },{ 0xc7b267, 24 },
+{ 0xc7b268, 24 },{ 0xc7b269, 24 },{ 0xc7b26a, 24 },{ 0xc7b26b, 24 },
+{ 0xc7b26c, 24 },{ 0xc7b26d, 24 },{ 0xc7b26e, 24 },{ 0xc7b26f, 24 },
+{ 0xc7b270, 24 },{ 0xc7b271, 24 },{ 0xc7b272, 24 },{ 0xc7b273, 24 },
+{ 0xc7b274, 24 },{ 0xc7b275, 24 },{ 0xc7b276, 24 },{ 0xc7b277, 24 },
+{ 0xc7b278, 24 },{ 0xc7b279, 24 },{ 0xc7b27a, 24 },{ 0xc7b27b, 24 },
+{ 0xc7b27c, 24 },{ 0xc7b27d, 24 },{ 0xc7b27e, 24 },{ 0xc7b27f, 24 },
+{ 0x18f6480, 25 },{ 0x18f6481, 25 },{ 0x18f6482, 25 },{ 0x18f6483, 25 },
+{ 0x18f6484, 25 },{ 0x18f6485, 25 },{ 0x18f6486, 25 },{ 0x18f6487, 25 },
+{ 0x18f6488, 25 },{ 0x18f6489, 25 },{ 0x18f648a, 25 },{ 0x18f648b, 25 },
+{ 0x18f648c, 25 },{ 0x18f648d, 25 },{ 0x18f648e, 25 },{ 0x18f648f, 25 },
+};
+
+/* vlc table 0, for intra luma */
+
+static const UINT16 table0_vlc[133][2] = {
+{ 0x1, 2 },{ 0x6, 3 },{ 0xf, 4 },{ 0x16, 5 },
+{ 0x20, 6 },{ 0x18, 7 },{ 0x8, 8 },{ 0x9a, 8 },
+{ 0x56, 9 },{ 0x13e, 9 },{ 0xf0, 10 },{ 0x3a5, 10 },
+{ 0x77, 11 },{ 0x1ef, 11 },{ 0x9a, 12 },{ 0x5d, 13 },
+{ 0x1, 4 },{ 0x11, 5 },{ 0x2, 7 },{ 0xb, 8 },
+{ 0x12, 9 },{ 0x1d6, 9 },{ 0x27e, 10 },{ 0x191, 11 },
+{ 0xea, 12 },{ 0x3dc, 12 },{ 0x13b, 13 },{ 0x4, 5 },
+{ 0x14, 7 },{ 0x9e, 8 },{ 0x9, 10 },{ 0x1ac, 11 },
+{ 0x1e2, 11 },{ 0x3ca, 12 },{ 0x5f, 13 },{ 0x17, 5 },
+{ 0x4e, 7 },{ 0x5e, 9 },{ 0xf3, 10 },{ 0x1ad, 11 },
+{ 0xec, 12 },{ 0x5f0, 13 },{ 0xe, 6 },{ 0xe1, 8 },
+{ 0x3a4, 10 },{ 0x9c, 12 },{ 0x13d, 13 },{ 0x3b, 6 },
+{ 0x1c, 9 },{ 0x14, 11 },{ 0x9be, 12 },{ 0x6, 7 },
+{ 0x7a, 9 },{ 0x190, 11 },{ 0x137, 13 },{ 0x1b, 7 },
+{ 0x8, 10 },{ 0x75c, 11 },{ 0x71, 7 },{ 0xd7, 10 },
+{ 0x9bf, 12 },{ 0x7, 8 },{ 0xaf, 10 },{ 0x4cc, 11 },
+{ 0x34, 8 },{ 0x265, 10 },{ 0x9f, 12 },{ 0xe0, 8 },
+{ 0x16, 11 },{ 0x327, 12 },{ 0x15, 9 },{ 0x17d, 11 },
+{ 0xebb, 12 },{ 0x14, 9 },{ 0xf6, 10 },{ 0x1e4, 11 },
+{ 0xcb, 10 },{ 0x99d, 12 },{ 0xca, 10 },{ 0x2fc, 12 },
+{ 0x17f, 11 },{ 0x4cd, 11 },{ 0x2fd, 12 },{ 0x4fe, 11 },
+{ 0x13a, 13 },{ 0xa, 4 },{ 0x42, 7 },{ 0x1d3, 9 },
+{ 0x4dd, 11 },{ 0x12, 5 },{ 0xe8, 8 },{ 0x4c, 11 },
+{ 0x136, 13 },{ 0x39, 6 },{ 0x264, 10 },{ 0xeba, 12 },
+{ 0x0, 7 },{ 0xae, 10 },{ 0x99c, 12 },{ 0x1f, 7 },
+{ 0x4de, 11 },{ 0x43, 7 },{ 0x4dc, 11 },{ 0x3, 8 },
+{ 0x3cb, 12 },{ 0x6, 8 },{ 0x99e, 12 },{ 0x2a, 8 },
+{ 0x5f1, 13 },{ 0xf, 8 },{ 0x9fe, 12 },{ 0x33, 8 },
+{ 0x9ff, 12 },{ 0x98, 8 },{ 0x99f, 12 },{ 0xea, 8 },
+{ 0x13c, 13 },{ 0x2e, 8 },{ 0x192, 11 },{ 0x136, 9 },
+{ 0x6a, 9 },{ 0x15, 11 },{ 0x3af, 10 },{ 0x1e3, 11 },
+{ 0x74, 11 },{ 0xeb, 12 },{ 0x2f9, 12 },{ 0x5c, 13 },
+{ 0xed, 12 },{ 0x3dd, 12 },{ 0x326, 12 },{ 0x5e, 13 },
+{ 0x16, 7 },
+};
+
+const INT8 table0_level[132] = {
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16,
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 1, 2, 3, 4, 5,
+ 6, 7, 8, 1, 2, 3, 4, 5,
+ 6, 7, 1, 2, 3, 4, 5, 1,
+ 2, 3, 4, 1, 2, 3, 4, 1,
+ 2, 3, 1, 2, 3, 1, 2, 3,
+ 1, 2, 3, 1, 2, 3, 1, 2,
+ 3, 1, 2, 3, 1, 2, 1, 2,
+ 1, 1, 1, 1, 1, 1, 2, 3,
+ 4, 1, 2, 3, 4, 1, 2, 3,
+ 1, 2, 3, 1, 2, 1, 2, 1,
+ 2, 1, 2, 1, 2, 1, 2, 1,
+ 2, 1, 2, 1, 2, 1, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1,
+};
+
+const INT8 table0_run[132] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 2, 2, 2, 2, 2,
+ 2, 2, 2, 3, 3, 3, 3, 3,
+ 3, 3, 4, 4, 4, 4, 4, 5,
+ 5, 5, 5, 6, 6, 6, 6, 7,
+ 7, 7, 8, 8, 8, 9, 9, 9,
+ 10, 10, 10, 11, 11, 11, 12, 12,
+ 12, 13, 13, 13, 14, 14, 15, 15,
+ 16, 17, 18, 19, 20, 0, 0, 0,
+ 0, 1, 1, 1, 1, 2, 2, 2,
+ 3, 3, 3, 4, 4, 5, 5, 6,
+ 6, 7, 7, 8, 8, 9, 9, 10,
+ 10, 11, 11, 12, 12, 13, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26,
+};
+
+/* vlc table 1, for intra chroma and P macro blocks */
+
+const UINT16 table1_vlc[149][2] = {
+{ 0x4, 3 },{ 0x14, 5 },{ 0x17, 7 },{ 0x7f, 8 },
+{ 0x154, 9 },{ 0x1f2, 10 },{ 0xbf, 11 },{ 0x65, 12 },
+{ 0xaaa, 12 },{ 0x630, 13 },{ 0x1597, 13 },{ 0x3b7, 14 },
+{ 0x2b22, 14 },{ 0xbe6, 15 },{ 0xb, 4 },{ 0x37, 7 },
+{ 0x62, 9 },{ 0x7, 11 },{ 0x166, 12 },{ 0xce, 13 },
+{ 0x1590, 13 },{ 0x5f6, 14 },{ 0xbe7, 15 },{ 0x7, 5 },
+{ 0x6d, 8 },{ 0x3, 11 },{ 0x31f, 12 },{ 0x5f2, 14 },
+{ 0x2, 6 },{ 0x61, 9 },{ 0x55, 12 },{ 0x1df, 14 },
+{ 0x1a, 6 },{ 0x1e, 10 },{ 0xac9, 12 },{ 0x2b23, 14 },
+{ 0x1e, 6 },{ 0x1f, 10 },{ 0xac3, 12 },{ 0x2b2b, 14 },
+{ 0x6, 7 },{ 0x4, 11 },{ 0x2f8, 13 },{ 0x19, 7 },
+{ 0x6, 11 },{ 0x63d, 13 },{ 0x57, 7 },{ 0x182, 11 },
+{ 0x2aa2, 14 },{ 0x4, 8 },{ 0x180, 11 },{ 0x59c, 14 },
+{ 0x7d, 8 },{ 0x164, 12 },{ 0x76d, 15 },{ 0x2, 9 },
+{ 0x18d, 11 },{ 0x1581, 13 },{ 0xad, 8 },{ 0x60, 12 },
+{ 0xc67, 14 },{ 0x1c, 9 },{ 0xee, 13 },{ 0x3, 9 },
+{ 0x2cf, 13 },{ 0xd9, 9 },{ 0x1580, 13 },{ 0x2, 11 },
+{ 0x183, 11 },{ 0x57, 12 },{ 0x61, 12 },{ 0x31, 11 },
+{ 0x66, 12 },{ 0x631, 13 },{ 0x632, 13 },{ 0xac, 13 },
+{ 0x31d, 12 },{ 0x76, 12 },{ 0x3a, 11 },{ 0x165, 12 },
+{ 0xc66, 14 },{ 0x3, 2 },{ 0x54, 7 },{ 0x2ab, 10 },
+{ 0x16, 13 },{ 0x5f7, 14 },{ 0x5, 4 },{ 0xf8, 9 },
+{ 0xaa9, 12 },{ 0x5f, 15 },{ 0x4, 4 },{ 0x1c, 10 },
+{ 0x1550, 13 },{ 0x4, 5 },{ 0x77, 11 },{ 0x76c, 15 },
+{ 0xe, 5 },{ 0xa, 12 },{ 0xc, 5 },{ 0x562, 11 },
+{ 0x4, 6 },{ 0x31c, 12 },{ 0x6, 6 },{ 0xc8, 13 },
+{ 0xd, 6 },{ 0x1da, 13 },{ 0x7, 6 },{ 0xc9, 13 },
+{ 0x1, 7 },{ 0x2e, 14 },{ 0x14, 7 },{ 0x1596, 13 },
+{ 0xa, 7 },{ 0xac2, 12 },{ 0x16, 7 },{ 0x15b, 14 },
+{ 0x15, 7 },{ 0x15a, 14 },{ 0xf, 8 },{ 0x5e, 15 },
+{ 0x7e, 8 },{ 0xab, 8 },{ 0x2d, 9 },{ 0xd8, 9 },
+{ 0xb, 9 },{ 0x14, 10 },{ 0x2b3, 10 },{ 0x1f3, 10 },
+{ 0x3a, 10 },{ 0x0, 10 },{ 0x58, 10 },{ 0x2e, 9 },
+{ 0x5e, 10 },{ 0x563, 11 },{ 0xec, 12 },{ 0x54, 12 },
+{ 0xac1, 12 },{ 0x1556, 13 },{ 0x2fa, 13 },{ 0x181, 11 },
+{ 0x1557, 13 },{ 0x59d, 14 },{ 0x2aa3, 14 },{ 0x2b2a, 14 },
+{ 0x1de, 14 },{ 0x63c, 13 },{ 0xcf, 13 },{ 0x1594, 13 },
+{ 0xd, 9 },
+};
+
+const INT8 table1_level[148] = {
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 1, 2,
+ 3, 4, 5, 6, 7, 8, 9, 1,
+ 2, 3, 4, 5, 1, 2, 3, 4,
+ 1, 2, 3, 4, 1, 2, 3, 4,
+ 1, 2, 3, 1, 2, 3, 1, 2,
+ 3, 1, 2, 3, 1, 2, 3, 1,
+ 2, 3, 1, 2, 3, 1, 2, 1,
+ 2, 1, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 2, 3, 4, 5, 1, 2,
+ 3, 4, 1, 2, 3, 1, 2, 3,
+ 1, 2, 1, 2, 1, 2, 1, 2,
+ 1, 2, 1, 2, 1, 2, 1, 2,
+ 1, 2, 1, 2, 1, 2, 1, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1,
+};
+
+const INT8 table1_run[148] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 2,
+ 2, 2, 2, 2, 3, 3, 3, 3,
+ 4, 4, 4, 4, 5, 5, 5, 5,
+ 6, 6, 6, 7, 7, 7, 8, 8,
+ 8, 9, 9, 9, 10, 10, 10, 11,
+ 11, 11, 12, 12, 12, 13, 13, 14,
+ 14, 15, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 0, 0, 0, 0, 0, 1, 1,
+ 1, 1, 2, 2, 2, 3, 3, 3,
+ 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 9, 10, 10, 11, 11,
+ 12, 12, 13, 13, 14, 14, 15, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43,
+};
+
+/* third vlc table */
+
+const UINT16 table2_vlc[186][2] = {
+{ 0x1, 2 },{ 0x5, 3 },{ 0xd, 4 },{ 0x12, 5 },
+{ 0xe, 6 },{ 0x15, 7 },{ 0x13, 8 },{ 0x3f, 8 },
+{ 0x4b, 9 },{ 0x11f, 9 },{ 0xb8, 10 },{ 0x3e3, 10 },
+{ 0x172, 11 },{ 0x24d, 12 },{ 0x3da, 12 },{ 0x2dd, 13 },
+{ 0x1f55, 13 },{ 0x5b9, 14 },{ 0x3eae, 14 },{ 0x0, 4 },
+{ 0x10, 5 },{ 0x8, 7 },{ 0x20, 8 },{ 0x29, 9 },
+{ 0x1f4, 9 },{ 0x233, 10 },{ 0x1e0, 11 },{ 0x12a, 12 },
+{ 0x3dd, 12 },{ 0x50a, 13 },{ 0x1f29, 13 },{ 0xa42, 14 },
+{ 0x1272, 15 },{ 0x1737, 15 },{ 0x3, 5 },{ 0x11, 7 },
+{ 0xc4, 8 },{ 0x4b, 10 },{ 0xb4, 11 },{ 0x7d4, 11 },
+{ 0x345, 12 },{ 0x2d7, 13 },{ 0x7bf, 13 },{ 0x938, 14 },
+{ 0xbbb, 14 },{ 0x95e, 15 },{ 0x13, 5 },{ 0x78, 7 },
+{ 0x69, 9 },{ 0x232, 10 },{ 0x461, 11 },{ 0x3ec, 12 },
+{ 0x520, 13 },{ 0x1f2a, 13 },{ 0x3e50, 14 },{ 0x3e51, 14 },
+{ 0x1486, 15 },{ 0xc, 6 },{ 0x24, 9 },{ 0x94, 11 },
+{ 0x8c0, 12 },{ 0xf09, 14 },{ 0x1ef0, 15 },{ 0x3d, 6 },
+{ 0x53, 9 },{ 0x1a0, 11 },{ 0x2d6, 13 },{ 0xf08, 14 },
+{ 0x13, 7 },{ 0x7c, 9 },{ 0x7c1, 11 },{ 0x4ac, 14 },
+{ 0x1b, 7 },{ 0xa0, 10 },{ 0x344, 12 },{ 0xf79, 14 },
+{ 0x79, 7 },{ 0x3e1, 10 },{ 0x2d4, 13 },{ 0x2306, 14 },
+{ 0x21, 8 },{ 0x23c, 10 },{ 0xfae, 12 },{ 0x23de, 14 },
+{ 0x35, 8 },{ 0x175, 11 },{ 0x7b3, 13 },{ 0xc5, 8 },
+{ 0x174, 11 },{ 0x785, 13 },{ 0x48, 9 },{ 0x1a3, 11 },
+{ 0x49e, 13 },{ 0x2c, 9 },{ 0xfa, 10 },{ 0x7d6, 11 },
+{ 0x92, 10 },{ 0x5cc, 13 },{ 0x1ef1, 15 },{ 0xa3, 10 },
+{ 0x3ed, 12 },{ 0x93e, 14 },{ 0x1e2, 11 },{ 0x1273, 15 },
+{ 0x7c4, 11 },{ 0x1487, 15 },{ 0x291, 12 },{ 0x293, 12 },
+{ 0xf8a, 12 },{ 0x509, 13 },{ 0x508, 13 },{ 0x78d, 13 },
+{ 0x7be, 13 },{ 0x78c, 13 },{ 0x4ae, 14 },{ 0xbba, 14 },
+{ 0x2307, 14 },{ 0xb9a, 14 },{ 0x1736, 15 },{ 0xe, 4 },
+{ 0x45, 7 },{ 0x1f3, 9 },{ 0x47a, 11 },{ 0x5dc, 13 },
+{ 0x23df, 14 },{ 0x19, 5 },{ 0x28, 9 },{ 0x176, 11 },
+{ 0x49d, 13 },{ 0x23dd, 14 },{ 0x30, 6 },{ 0xa2, 10 },
+{ 0x2ef, 12 },{ 0x5b8, 14 },{ 0x3f, 6 },{ 0xa5, 10 },
+{ 0x3db, 12 },{ 0x93f, 14 },{ 0x44, 7 },{ 0x7cb, 11 },
+{ 0x95f, 15 },{ 0x63, 7 },{ 0x3c3, 12 },{ 0x15, 8 },
+{ 0x8f6, 12 },{ 0x17, 8 },{ 0x498, 13 },{ 0x2c, 8 },
+{ 0x7b2, 13 },{ 0x2f, 8 },{ 0x1f54, 13 },{ 0x8d, 8 },
+{ 0x7bd, 13 },{ 0x8e, 8 },{ 0x1182, 13 },{ 0xfb, 8 },
+{ 0x50b, 13 },{ 0x2d, 8 },{ 0x7c0, 11 },{ 0x79, 9 },
+{ 0x1f5f, 13 },{ 0x7a, 9 },{ 0x1f56, 13 },{ 0x231, 10 },
+{ 0x3e4, 10 },{ 0x1a1, 11 },{ 0x143, 11 },{ 0x1f7, 11 },
+{ 0x16f, 12 },{ 0x292, 12 },{ 0x2e7, 12 },{ 0x16c, 12 },
+{ 0x16d, 12 },{ 0x3dc, 12 },{ 0xf8b, 12 },{ 0x499, 13 },
+{ 0x3d8, 12 },{ 0x78e, 13 },{ 0x2d5, 13 },{ 0x1f5e, 13 },
+{ 0x1f2b, 13 },{ 0x78f, 13 },{ 0x4ad, 14 },{ 0x3eaf, 14 },
+{ 0x23dc, 14 },{ 0x4a, 9 },
+};
+
+const INT8 table2_level[185] = {
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 1, 2,
+ 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 1, 2, 3, 4, 5, 6, 1,
+ 2, 3, 4, 5, 1, 2, 3, 4,
+ 1, 2, 3, 4, 1, 2, 3, 4,
+ 1, 2, 3, 4, 1, 2, 3, 1,
+ 2, 3, 1, 2, 3, 1, 2, 3,
+ 1, 2, 3, 1, 2, 3, 1, 2,
+ 1, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 3, 4, 5, 6, 1, 2, 3,
+ 4, 5, 1, 2, 3, 4, 1, 2,
+ 3, 4, 1, 2, 3, 1, 2, 1,
+ 2, 1, 2, 1, 2, 1, 2, 1,
+ 2, 1, 2, 1, 2, 1, 2, 1,
+ 2, 1, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1,
+};
+
+const INT8 table2_run[185] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 4, 4, 4, 4, 4, 4, 5,
+ 5, 5, 5, 5, 6, 6, 6, 6,
+ 7, 7, 7, 7, 8, 8, 8, 8,
+ 9, 9, 9, 9, 10, 10, 10, 11,
+ 11, 11, 12, 12, 12, 13, 13, 13,
+ 14, 14, 14, 15, 15, 15, 16, 16,
+ 17, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 0,
+ 0, 0, 0, 0, 0, 1, 1, 1,
+ 1, 1, 2, 2, 2, 2, 3, 3,
+ 3, 3, 4, 4, 4, 5, 5, 6,
+ 6, 7, 7, 8, 8, 9, 9, 10,
+ 10, 11, 11, 12, 12, 13, 13, 14,
+ 14, 15, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36,
+ 37,
+};
+
+/* second non intra vlc table */
+const UINT16 table4_vlc[169][2] = {
+{ 0x0, 3 },{ 0x3, 4 },{ 0xb, 5 },{ 0x14, 6 },
+{ 0x3f, 6 },{ 0x5d, 7 },{ 0xa2, 8 },{ 0xac, 9 },
+{ 0x16e, 9 },{ 0x20a, 10 },{ 0x2e2, 10 },{ 0x432, 11 },
+{ 0x5c9, 11 },{ 0x827, 12 },{ 0xb54, 12 },{ 0x4e6, 13 },
+{ 0x105f, 13 },{ 0x172a, 13 },{ 0x20b2, 14 },{ 0x2d4e, 14 },
+{ 0x39f0, 14 },{ 0x4175, 15 },{ 0x5a9e, 15 },{ 0x4, 4 },
+{ 0x1e, 5 },{ 0x42, 7 },{ 0xb6, 8 },{ 0x173, 9 },
+{ 0x395, 10 },{ 0x72e, 11 },{ 0xb94, 12 },{ 0x16a4, 13 },
+{ 0x20b3, 14 },{ 0x2e45, 14 },{ 0x5, 5 },{ 0x40, 7 },
+{ 0x49, 9 },{ 0x28f, 10 },{ 0x5cb, 11 },{ 0x48a, 13 },
+{ 0x9dd, 14 },{ 0x73e2, 15 },{ 0x18, 5 },{ 0x25, 8 },
+{ 0x8a, 10 },{ 0x51b, 11 },{ 0xe5f, 12 },{ 0x9c9, 14 },
+{ 0x139c, 15 },{ 0x29, 6 },{ 0x4f, 9 },{ 0x412, 11 },
+{ 0x48d, 13 },{ 0x2e41, 14 },{ 0x38, 6 },{ 0x10e, 9 },
+{ 0x5a8, 11 },{ 0x105c, 13 },{ 0x39f2, 14 },{ 0x58, 7 },
+{ 0x21f, 10 },{ 0xe7e, 12 },{ 0x39ff, 14 },{ 0x23, 8 },
+{ 0x2e3, 10 },{ 0x4e5, 13 },{ 0x2e40, 14 },{ 0xa1, 8 },
+{ 0x5be, 11 },{ 0x9c8, 14 },{ 0x83, 8 },{ 0x13a, 11 },
+{ 0x1721, 13 },{ 0x44, 9 },{ 0x276, 12 },{ 0x39f6, 14 },
+{ 0x8b, 10 },{ 0x4ef, 13 },{ 0x5a9b, 15 },{ 0x208, 10 },
+{ 0x1cfe, 13 },{ 0x399, 10 },{ 0x1cb4, 13 },{ 0x39e, 10 },
+{ 0x39f3, 14 },{ 0x5ab, 11 },{ 0x73e3, 15 },{ 0x737, 11 },
+{ 0x5a9f, 15 },{ 0x82d, 12 },{ 0xe69, 12 },{ 0xe68, 12 },
+{ 0x433, 11 },{ 0xb7b, 12 },{ 0x2df8, 14 },{ 0x2e56, 14 },
+{ 0x2e57, 14 },{ 0x39f7, 14 },{ 0x51a5, 15 },{ 0x3, 3 },
+{ 0x2a, 6 },{ 0xe4, 8 },{ 0x28e, 10 },{ 0x735, 11 },
+{ 0x1058, 13 },{ 0x1cfa, 13 },{ 0x2df9, 14 },{ 0x4174, 15 },
+{ 0x9, 4 },{ 0x54, 8 },{ 0x398, 10 },{ 0x48b, 13 },
+{ 0x139d, 15 },{ 0xd, 4 },{ 0xad, 9 },{ 0x826, 12 },
+{ 0x2d4c, 14 },{ 0x11, 5 },{ 0x16b, 9 },{ 0xb7f, 12 },
+{ 0x51a4, 15 },{ 0x19, 5 },{ 0x21b, 10 },{ 0x16fd, 13 },
+{ 0x1d, 5 },{ 0x394, 10 },{ 0x28d3, 14 },{ 0x2b, 6 },
+{ 0x5bc, 11 },{ 0x5a9a, 15 },{ 0x2f, 6 },{ 0x247, 12 },
+{ 0x10, 7 },{ 0xa35, 12 },{ 0x3e, 6 },{ 0xb7a, 12 },
+{ 0x59, 7 },{ 0x105e, 13 },{ 0x26, 8 },{ 0x9cf, 14 },
+{ 0x55, 8 },{ 0x1cb5, 13 },{ 0x57, 8 },{ 0xe5b, 12 },
+{ 0xa0, 8 },{ 0x1468, 13 },{ 0x170, 9 },{ 0x90, 10 },
+{ 0x1ce, 9 },{ 0x21a, 10 },{ 0x218, 10 },{ 0x168, 9 },
+{ 0x21e, 10 },{ 0x244, 12 },{ 0x736, 11 },{ 0x138, 11 },
+{ 0x519, 11 },{ 0xe5e, 12 },{ 0x72c, 11 },{ 0xb55, 12 },
+{ 0x9dc, 14 },{ 0x20bb, 14 },{ 0x48c, 13 },{ 0x1723, 13 },
+{ 0x2e44, 14 },{ 0x16a5, 13 },{ 0x518, 11 },{ 0x39fe, 14 },
+{ 0x169, 9 },
+};
+
+const INT8 table4_level[168] = {
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 1, 2, 3, 4, 5, 6,
+ 7, 8, 1, 2, 3, 4, 5, 6,
+ 7, 1, 2, 3, 4, 5, 1, 2,
+ 3, 4, 5, 1, 2, 3, 4, 1,
+ 2, 3, 4, 1, 2, 3, 1, 2,
+ 3, 1, 2, 3, 1, 2, 3, 1,
+ 2, 1, 2, 1, 2, 1, 2, 1,
+ 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 1, 2, 3, 4,
+ 5, 1, 2, 3, 4, 1, 2, 3,
+ 4, 1, 2, 3, 1, 2, 3, 1,
+ 2, 3, 1, 2, 1, 2, 1, 2,
+ 1, 2, 1, 2, 1, 2, 1, 2,
+ 1, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+};
+
+const INT8 table4_run[168] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 2, 2, 2, 2, 2, 2,
+ 2, 2, 3, 3, 3, 3, 3, 3,
+ 3, 4, 4, 4, 4, 4, 5, 5,
+ 5, 5, 5, 6, 6, 6, 6, 7,
+ 7, 7, 7, 8, 8, 8, 9, 9,
+ 9, 10, 10, 10, 11, 11, 11, 12,
+ 12, 13, 13, 14, 14, 15, 15, 16,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 3, 3, 3,
+ 3, 4, 4, 4, 5, 5, 5, 6,
+ 6, 6, 7, 7, 8, 8, 9, 9,
+ 10, 10, 11, 11, 12, 12, 13, 13,
+ 14, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36,
+};
+
+extern const UINT16 inter_vlc[103][2];
+extern const INT8 inter_level[102];
+extern const INT8 inter_run[102];
+
+extern const UINT16 intra_vlc[103][2];
+extern const INT8 intra_level[102];
+extern const INT8 intra_run[102];
+
+#define NB_RL_TABLES 6
+
+static RLTable rl_table[NB_RL_TABLES] = {
+ /* intra luminance tables */
+ {
+ 132,
+ 85,
+ table0_vlc,
+ table0_run,
+ table0_level,
+ },
+ {
+ 185,
+ 119,
+ table2_vlc,
+ table2_run,
+ table2_level,
+ },
+ {
+ 102,
+ 67,
+ intra_vlc,
+ intra_run,
+ intra_level,
+ },
+ /* intra chrominance / non intra tables */
+ {
+ 148,
+ 81,
+ table1_vlc,
+ table1_run,
+ table1_level,
+ },
+ {
+ 168,
+ 99,
+ table4_vlc,
+ table4_run,
+ table4_level,
+ },
+ {
+ 102,
+ 58,
+ inter_vlc,
+ inter_run,
+ inter_level,
+ },
+};
+
+/* motion vector table 0 */
+
+const UINT16 table0_mv_code[1100] = {
+ 0x0001, 0x0003, 0x0005, 0x0007, 0x0003, 0x0008, 0x000c, 0x0001,
+ 0x0002, 0x001b, 0x0006, 0x000b, 0x0015, 0x0002, 0x000e, 0x000f,
+ 0x0014, 0x0020, 0x0022, 0x0025, 0x0027, 0x0029, 0x002d, 0x004b,
+ 0x004d, 0x0003, 0x0022, 0x0023, 0x0025, 0x0027, 0x0042, 0x0048,
+ 0x0049, 0x0050, 0x005c, 0x0091, 0x009f, 0x000e, 0x0043, 0x004c,
+ 0x0054, 0x0056, 0x008c, 0x0098, 0x009a, 0x009b, 0x00b1, 0x00b2,
+ 0x0120, 0x0121, 0x0126, 0x0133, 0x0139, 0x01a1, 0x01a4, 0x01a5,
+ 0x01a6, 0x01a7, 0x01ae, 0x01af, 0x000b, 0x0019, 0x0085, 0x0090,
+ 0x009b, 0x00aa, 0x00af, 0x010c, 0x010e, 0x011c, 0x011e, 0x0133,
+ 0x0144, 0x0160, 0x0174, 0x0175, 0x0177, 0x0178, 0x0249, 0x024b,
+ 0x0252, 0x0261, 0x0265, 0x0270, 0x0352, 0x0353, 0x0355, 0x0359,
+ 0x0010, 0x0011, 0x0013, 0x0034, 0x0035, 0x0036, 0x0037, 0x003d,
+ 0x003e, 0x0109, 0x0126, 0x0156, 0x021a, 0x021e, 0x023a, 0x023e,
+ 0x028e, 0x028f, 0x02cf, 0x0491, 0x0494, 0x049f, 0x04a0, 0x04a3,
+ 0x04a6, 0x04a7, 0x04ad, 0x04ae, 0x04c0, 0x04c4, 0x04c6, 0x04c8,
+ 0x04c9, 0x04f5, 0x04f6, 0x04f7, 0x0680, 0x0682, 0x0683, 0x0688,
+ 0x0689, 0x068d, 0x068e, 0x068f, 0x06a2, 0x06a3, 0x06a9, 0x06b0,
+ 0x06b1, 0x06b4, 0x06b5, 0x0024, 0x0060, 0x0063, 0x0078, 0x0079,
+ 0x0211, 0x0244, 0x0245, 0x0247, 0x0248, 0x0249, 0x024a, 0x024b,
+ 0x026b, 0x02af, 0x02b8, 0x02bb, 0x0436, 0x0476, 0x0477, 0x047e,
+ 0x04c8, 0x04c9, 0x04ca, 0x0514, 0x0586, 0x0587, 0x0598, 0x059d,
+ 0x05d9, 0x05da, 0x0920, 0x0921, 0x093b, 0x093c, 0x093d, 0x0942,
+ 0x0943, 0x0944, 0x0945, 0x0959, 0x095e, 0x095f, 0x0982, 0x0983,
+ 0x098e, 0x098f, 0x09c4, 0x09e7, 0x09e8, 0x09e9, 0x0d02, 0x0d17,
+ 0x0d18, 0x0d19, 0x0d41, 0x0d42, 0x0d43, 0x0d50, 0x0d5f, 0x0d6d,
+ 0x0d6e, 0x0d6f, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
+ 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x041e, 0x041f, 0x0420, 0x0421,
+ 0x048c, 0x048d, 0x04d3, 0x04d4, 0x04d5, 0x055c, 0x055d, 0x0572,
+ 0x0573, 0x0574, 0x0575, 0x08de, 0x08df, 0x08fe, 0x08ff, 0x0996,
+ 0x0a36, 0x0a37, 0x0b08, 0x0b09, 0x0b0a, 0x0b0b, 0x0b32, 0x0b33,
+ 0x0b34, 0x0b35, 0x0b36, 0x0b37, 0x0b38, 0x0b39, 0x0bb0, 0x0bf7,
+ 0x0bf8, 0x0bf9, 0x0bfa, 0x0bfb, 0x0bfc, 0x0bfd, 0x0bfe, 0x0bff,
+ 0x1254, 0x1255, 0x1256, 0x1257, 0x1270, 0x1271, 0x1272, 0x1273,
+ 0x1274, 0x1275, 0x12ab, 0x12ac, 0x12ad, 0x12ae, 0x12af, 0x12b0,
+ 0x12b1, 0x1315, 0x1316, 0x1317, 0x13bf, 0x13c0, 0x13c1, 0x13c2,
+ 0x13c3, 0x13c4, 0x13c5, 0x13c6, 0x13c7, 0x13c8, 0x13c9, 0x13ca,
+ 0x13cb, 0x13cc, 0x13cd, 0x1a06, 0x1a07, 0x1a28, 0x1a29, 0x1a2a,
+ 0x1a2b, 0x1a2c, 0x1a2d, 0x1a80, 0x1abb, 0x1abc, 0x1abd, 0x1ad8,
+ 0x1ad9, 0x0094, 0x0095, 0x0096, 0x0097, 0x00a0, 0x00a1, 0x00a2,
+ 0x00a3, 0x0831, 0x0832, 0x0833, 0x0834, 0x0835, 0x0836, 0x0837,
+ 0x0838, 0x0839, 0x083a, 0x083b, 0x0939, 0x093a, 0x093b, 0x093c,
+ 0x093d, 0x093e, 0x093f, 0x09a0, 0x09a1, 0x09a2, 0x09a3, 0x09a4,
+ 0x09a5, 0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2,
+ 0x11b3, 0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba,
+ 0x11bb, 0x132f, 0x1454, 0x1455, 0x1456, 0x1457, 0x1458, 0x1459,
+ 0x145a, 0x145b, 0x145c, 0x145d, 0x145e, 0x145f, 0x1460, 0x1461,
+ 0x1462, 0x1463, 0x1464, 0x1465, 0x1466, 0x1467, 0x1468, 0x1469,
+ 0x146a, 0x146b, 0x17de, 0x17df, 0x17e0, 0x17e1, 0x17e2, 0x17e3,
+ 0x17e4, 0x17e5, 0x17e6, 0x17e7, 0x17e8, 0x17e9, 0x17ea, 0x17eb,
+ 0x17ec, 0x17ed, 0x2540, 0x2541, 0x2542, 0x2543, 0x2544, 0x2545,
+ 0x2546, 0x2547, 0x2548, 0x2549, 0x254a, 0x254b, 0x254c, 0x254d,
+ 0x254e, 0x254f, 0x2550, 0x2551, 0x2552, 0x2553, 0x2554, 0x2555,
+ 0x2628, 0x2766, 0x2767, 0x2768, 0x2769, 0x276a, 0x276b, 0x276c,
+ 0x276d, 0x276e, 0x276f, 0x2770, 0x2771, 0x2772, 0x2773, 0x2774,
+ 0x2775, 0x2776, 0x2777, 0x2778, 0x2779, 0x277a, 0x277b, 0x277c,
+ 0x277d, 0x3503, 0x3544, 0x3545, 0x3546, 0x3547, 0x3560, 0x3561,
+ 0x3562, 0x3563, 0x3564, 0x3565, 0x3566, 0x3567, 0x3568, 0x3569,
+ 0x356a, 0x356b, 0x356c, 0x356d, 0x356e, 0x356f, 0x3570, 0x3571,
+ 0x3572, 0x3573, 0x3574, 0x3575, 0x03f0, 0x103d, 0x103e, 0x103f,
+ 0x1040, 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047,
+ 0x1048, 0x1049, 0x104a, 0x104b, 0x104c, 0x104d, 0x104e, 0x104f,
+ 0x1050, 0x1051, 0x1052, 0x1053, 0x1054, 0x1055, 0x1056, 0x1057,
+ 0x1058, 0x1059, 0x105a, 0x105b, 0x105c, 0x105d, 0x105e, 0x105f,
+ 0x1060, 0x1061, 0x1270, 0x1271, 0x21b8, 0x21b9, 0x21ba, 0x21bb,
+ 0x21bc, 0x21bd, 0x21be, 0x21bf, 0x21f0, 0x21f1, 0x21f2, 0x21f3,
+ 0x21f4, 0x21f5, 0x21f6, 0x21f7, 0x21f8, 0x21f9, 0x21fa, 0x21fb,
+ 0x21fc, 0x21fd, 0x21fe, 0x21ff, 0x2340, 0x2341, 0x2342, 0x2343,
+ 0x2344, 0x2345, 0x2346, 0x2347, 0x2348, 0x2349, 0x234a, 0x234b,
+ 0x234c, 0x234d, 0x234e, 0x234f, 0x2350, 0x2351, 0x2352, 0x2353,
+ 0x2354, 0x2355, 0x2356, 0x2357, 0x265c, 0x2f88, 0x2f89, 0x2f8a,
+ 0x2f8b, 0x2f8c, 0x2f8d, 0x2f8e, 0x2f8f, 0x2f90, 0x2f91, 0x2f92,
+ 0x2f93, 0x2f94, 0x2f95, 0x2f96, 0x2f97, 0x2f98, 0x2f99, 0x2f9a,
+ 0x2f9b, 0x2f9c, 0x2f9d, 0x2f9e, 0x2f9f, 0x2fa0, 0x2fa1, 0x2fa2,
+ 0x2fa3, 0x2fa4, 0x2fa5, 0x2fa6, 0x2fa7, 0x2fa8, 0x2fa9, 0x2faa,
+ 0x2fab, 0x2fac, 0x2fad, 0x2fae, 0x2faf, 0x2fb0, 0x2fb1, 0x2fb2,
+ 0x2fb3, 0x2fb4, 0x2fb5, 0x2fb6, 0x2fb7, 0x2fb8, 0x2fb9, 0x2fba,
+ 0x2fbb, 0x4c52, 0x4c53, 0x4e28, 0x4e29, 0x4e2a, 0x4e2b, 0x4e2c,
+ 0x4e2d, 0x4e2e, 0x4e2f, 0x4e30, 0x4e31, 0x4e32, 0x4e33, 0x4e34,
+ 0x4e35, 0x4e36, 0x4e37, 0x4e38, 0x4e39, 0x4e3a, 0x4e3b, 0x4e3c,
+ 0x4e3d, 0x4e3e, 0x4e3f, 0x4e80, 0x4e81, 0x4e82, 0x4e83, 0x4e84,
+ 0x4e85, 0x4e86, 0x4e87, 0x4e88, 0x4e89, 0x4e8a, 0x4e8b, 0x4e8c,
+ 0x4e8d, 0x4e8e, 0x4e8f, 0x4e90, 0x4e91, 0x4e92, 0x4e93, 0x4e94,
+ 0x4e95, 0x4e96, 0x4e97, 0x4e98, 0x4e99, 0x4e9a, 0x4e9b, 0x4e9c,
+ 0x4e9d, 0x4e9e, 0x4e9f, 0x4ea0, 0x4ea1, 0x4ea2, 0x4ea3, 0x4ea4,
+ 0x4ea5, 0x4ea6, 0x4ea7, 0x4ea8, 0x4ea9, 0x4eaa, 0x4eab, 0x4eac,
+ 0x4ead, 0x4eae, 0x4eaf, 0x4eb0, 0x4eb1, 0x4eb2, 0x4eb3, 0x4eb4,
+ 0x4eb5, 0x4eb6, 0x4eb7, 0x4eb8, 0x4eb9, 0x4eba, 0x4ebb, 0x4ebc,
+ 0x4ebd, 0x4ebe, 0x4ebf, 0x4ec0, 0x4ec1, 0x4ec2, 0x4ec3, 0x4ec4,
+ 0x4ec5, 0x4ec6, 0x4ec7, 0x4ec8, 0x4ec9, 0x4eca, 0x4ecb, 0x6a04,
+ 0x6a05, 0x07e2, 0x07e3, 0x07e4, 0x07e5, 0x07e6, 0x07e7, 0x07e8,
+ 0x07e9, 0x07ea, 0x07eb, 0x07ec, 0x07ed, 0x07ee, 0x07ef, 0x07f0,
+ 0x07f1, 0x07f2, 0x07f3, 0x07f4, 0x07f5, 0x07f6, 0x07f7, 0x07f8,
+ 0x07f9, 0x07fa, 0x07fb, 0x07fc, 0x07fd, 0x07fe, 0x07ff, 0x2000,
+ 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008,
+ 0x2009, 0x200a, 0x200b, 0x200c, 0x200d, 0x200e, 0x200f, 0x2010,
+ 0x2011, 0x2012, 0x2013, 0x2014, 0x2015, 0x2016, 0x2017, 0x2018,
+ 0x2019, 0x201a, 0x201b, 0x201c, 0x201d, 0x201e, 0x201f, 0x2020,
+ 0x2021, 0x2022, 0x2023, 0x2024, 0x2025, 0x2026, 0x2027, 0x2028,
+ 0x2029, 0x202a, 0x202b, 0x202c, 0x202d, 0x202e, 0x202f, 0x2030,
+ 0x2031, 0x2032, 0x2033, 0x2034, 0x2035, 0x2036, 0x2037, 0x2038,
+ 0x2039, 0x203a, 0x203b, 0x203c, 0x203d, 0x203e, 0x203f, 0x2040,
+ 0x2041, 0x2042, 0x2043, 0x2044, 0x2045, 0x2046, 0x2047, 0x2048,
+ 0x2049, 0x204a, 0x204b, 0x204c, 0x204d, 0x204e, 0x204f, 0x2050,
+ 0x2051, 0x2052, 0x2053, 0x2054, 0x2055, 0x2056, 0x2057, 0x2058,
+ 0x2059, 0x205a, 0x205b, 0x205c, 0x205d, 0x205e, 0x205f, 0x2060,
+ 0x2061, 0x2062, 0x2063, 0x2064, 0x2065, 0x2066, 0x2067, 0x2068,
+ 0x2069, 0x206a, 0x206b, 0x206c, 0x206d, 0x206e, 0x206f, 0x2070,
+ 0x2071, 0x2072, 0x2073, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078,
+ 0x2079, 0x4cba, 0x4cbb, 0x5d88, 0x5d89, 0x5d8a, 0x5d8b, 0x5d8c,
+ 0x5d8d, 0x5d8e, 0x5d8f, 0x5db0, 0x5db1, 0x5db2, 0x5db3, 0x5db4,
+ 0x5db5, 0x5db6, 0x5db7, 0x5db8, 0x5db9, 0x5dba, 0x5dbb, 0x5dbc,
+ 0x5dbd, 0x5dbe, 0x5dbf, 0x5e40, 0x5e41, 0x5e42, 0x5e43, 0x5e44,
+ 0x5e45, 0x5e46, 0x5e47, 0x5e48, 0x5e49, 0x5e4a, 0x5e4b, 0x5e4c,
+ 0x5e4d, 0x5e4e, 0x5e4f, 0x5e50, 0x5e51, 0x5e52, 0x5e53, 0x5e54,
+ 0x5e55, 0x5e56, 0x5e57, 0x5e58, 0x5e59, 0x5e5a, 0x5e5b, 0x5e5c,
+ 0x5e5d, 0x5e5e, 0x5e5f, 0x5e60, 0x5e61, 0x5e62, 0x5e63, 0x5e64,
+ 0x5e65, 0x5e66, 0x5e67, 0x5e68, 0x5e69, 0x5e6a, 0x5e6b, 0x5e6c,
+ 0x5e6d, 0x5e6e, 0x5e6f, 0x5e70, 0x5e71, 0x5e72, 0x5e73, 0x5e74,
+ 0x5e75, 0x5e76, 0x5e77, 0x5e78, 0x5e79, 0x5e7a, 0x5e7b, 0x5e7c,
+ 0x5e7d, 0x5e7e, 0x5e7f, 0x5e80, 0x5e81, 0x5e82, 0x5e83, 0x5e84,
+ 0x5e85, 0x5e86, 0x5e87, 0x5e88, 0x5e89, 0x5e8a, 0x5e8b, 0x5e8c,
+ 0x5e8d, 0x5e8e, 0x5e8f, 0x5e90, 0x5e91, 0x5e92, 0x5e93, 0x5e94,
+ 0x5e95, 0x5e96, 0x5e97, 0x5e98, 0x5e99, 0x5e9a, 0x5e9b, 0x5e9c,
+ 0x5e9d, 0x5e9e, 0x5e9f, 0x5ea0, 0x5ea1, 0x5ea2, 0x5ea3, 0x5ea4,
+ 0x5ea5, 0x5ea6, 0x5ea7, 0x5ea8, 0x5ea9, 0x5eaa, 0x5eab, 0x5eac,
+ 0x5ead, 0x5eae, 0x5eaf, 0x5eb0, 0x5eb1, 0x5eb2, 0x5eb3, 0x5eb4,
+ 0x5eb5, 0x5eb6, 0x5eb7, 0x5eb8, 0x5eb9, 0x5eba, 0x5ebb, 0x5ebc,
+ 0x5ebd, 0x5ebe, 0x5ebf, 0x5ec0, 0x5ec1, 0x5ec2, 0x5ec3, 0x5ec4,
+ 0x5ec5, 0x5ec6, 0x5ec7, 0x5ec8, 0x5ec9, 0x5eca, 0x5ecb, 0x5ecc,
+ 0x5ecd, 0x5ece, 0x5ecf, 0x5ed0, 0x5ed1, 0x5ed2, 0x5ed3, 0x5ed4,
+ 0x5ed5, 0x5ed6, 0x5ed7, 0x5ed8, 0x5ed9, 0x5eda, 0x5edb, 0x5edc,
+ 0x5edd, 0x5ede, 0x5edf, 0x5ee0, 0x5ee1, 0x5ee2, 0x5ee3, 0x5ee4,
+ 0x5ee5, 0x5ee6, 0x5ee7, 0x5ee8, 0x5ee9, 0x5eea, 0x5eeb, 0x5eec,
+ 0x5eed, 0x5eee, 0x5eef, 0x5ef0, 0x5ef1, 0x5ef2, 0x5ef3, 0x5ef4,
+ 0x5ef5, 0x5ef6, 0x5ef7, 0x5ef8, 0x5ef9, 0x5efa, 0x5efb, 0x5efc,
+ 0x5efd, 0x5efe, 0x5eff, 0x5f00, 0x5f01, 0x5f02, 0x5f03, 0x5f04,
+ 0x5f05, 0x5f06, 0x5f07, 0x5f08, 0x5f09, 0x5f0a, 0x5f0b, 0x5f0c,
+ 0x5f0d, 0x5f0e, 0x5f0f, 0x0000,
+};
+
+const UINT8 table0_mv_bits[1100] = {
+ 1, 4, 4, 4, 5, 5, 5, 6,
+ 6, 6, 7, 7, 7, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 8,
+};
+
+const UINT8 table0_mvx[1099] = {
+ 32, 32, 31, 32, 33, 31, 33, 31,
+ 33, 32, 34, 32, 30, 32, 31, 34,
+ 35, 32, 34, 33, 29, 33, 30, 30,
+ 31, 31, 35, 29, 33, 35, 33, 34,
+ 31, 29, 30, 34, 30, 36, 28, 32,
+ 34, 37, 30, 27, 32, 25, 39, 32,
+ 34, 32, 35, 35, 35, 31, 35, 29,
+ 32, 29, 30, 29, 37, 27, 36, 38,
+ 37, 33, 32, 31, 29, 31, 28, 36,
+ 33, 30, 34, 33, 33, 28, 27, 25,
+ 31, 26, 39, 32, 32, 31, 33, 39,
+ 31, 38, 28, 36, 21, 23, 43, 36,
+ 34, 41, 30, 25, 28, 31, 30, 34,
+ 38, 35, 61, 34, 28, 30, 37, 37,
+ 35, 27, 36, 3, 59, 38, 37, 32,
+ 31, 29, 26, 33, 37, 33, 27, 27,
+ 35, 34, 34, 40, 42, 33, 32, 29,
+ 4, 5, 28, 24, 25, 35, 39, 38,
+ 32, 23, 27, 32, 30, 35, 26, 34,
+ 60, 36, 29, 22, 26, 41, 7, 30,
+ 38, 30, 36, 29, 30, 41, 26, 25,
+ 32, 34, 24, 39, 1, 25, 39, 32,
+ 28, 29, 32, 38, 26, 36, 28, 63,
+ 28, 39, 23, 21, 26, 35, 31, 35,
+ 57, 31, 29, 29, 28, 30, 27, 35,
+ 2, 38, 40, 34, 37, 29, 38, 43,
+ 26, 32, 33, 42, 24, 40, 28, 32,
+ 32, 32, 36, 32, 43, 25, 21, 31,
+ 30, 31, 41, 29, 33, 37, 26, 37,
+ 27, 59, 23, 33, 35, 31, 31, 37,
+ 38, 39, 32, 23, 32, 27, 37, 36,
+ 31, 40, 25, 27, 38, 31, 36, 28,
+ 31, 36, 25, 45, 3, 34, 38, 39,
+ 40, 38, 30, 32, 19, 24, 25, 26,
+ 45, 20, 24, 33, 33, 31, 41, 34,
+ 39, 47, 40, 58, 59, 41, 33, 3,
+ 17, 61, 42, 30, 26, 29, 36, 61,
+ 33, 37, 62, 28, 25, 38, 25, 38,
+ 17, 23, 34, 33, 21, 33, 49, 27,
+ 32, 23, 27, 22, 24, 22, 39, 43,
+ 27, 37, 6, 42, 47, 26, 30, 31,
+ 41, 39, 33, 22, 45, 36, 32, 45,
+ 19, 22, 30, 5, 5, 17, 29, 22,
+ 31, 31, 43, 37, 27, 32, 32, 32,
+ 33, 34, 43, 35, 29, 26, 22, 32,
+ 19, 32, 25, 31, 41, 49, 28, 34,
+ 28, 39, 34, 19, 37, 38, 29, 21,
+ 36, 42, 24, 48, 16, 28, 49, 22,
+ 34, 31, 38, 39, 44, 11, 35, 30,
+ 33, 33, 23, 28, 33, 46, 15, 13,
+ 24, 41, 24, 34, 34, 30, 26, 24,
+ 14, 60, 21, 29, 39, 23, 35, 37,
+ 63, 45, 33, 34, 47, 41, 22, 42,
+ 35, 35, 23, 32, 35, 43, 32, 7,
+ 31, 41, 20, 31, 16, 13, 63, 25,
+ 30, 32, 35, 30, 30, 31, 42, 47,
+ 39, 38, 40, 40, 51, 55, 56, 18,
+ 21, 39, 39, 33, 17, 41, 23, 24,
+ 43, 25, 31, 20, 19, 45, 1, 34,
+ 31, 22, 35, 15, 46, 46, 35, 31,
+ 28, 29, 29, 23, 41, 27, 14, 53,
+ 53, 27, 24, 32, 57, 32, 17, 42,
+ 37, 29, 33, 1, 25, 32, 32, 63,
+ 26, 40, 44, 36, 31, 39, 20, 20,
+ 44, 23, 33, 34, 35, 33, 33, 28,
+ 41, 23, 41, 41, 29, 25, 26, 49,
+ 29, 24, 37, 49, 50, 51, 51, 26,
+ 39, 25, 26, 15, 39, 18, 42, 17,
+ 4, 31, 32, 32, 60, 1, 42, 32,
+ 0, 12, 19, 35, 21, 41, 17, 26,
+ 20, 45, 46, 32, 37, 22, 47, 29,
+ 31, 27, 29, 30, 21, 33, 35, 18,
+ 25, 33, 50, 51, 42, 2, 15, 51,
+ 53, 33, 25, 29, 55, 37, 38, 33,
+ 38, 59, 38, 33, 39, 13, 32, 40,
+ 61, 61, 32, 9, 44, 3, 31, 29,
+ 25, 31, 27, 23, 9, 25, 9, 29,
+ 20, 30, 30, 42, 18, 28, 25, 28,
+ 28, 21, 29, 43, 29, 43, 26, 44,
+ 44, 21, 38, 21, 24, 45, 45, 35,
+ 39, 22, 35, 36, 34, 34, 45, 34,
+ 29, 31, 46, 25, 46, 16, 17, 31,
+ 20, 32, 47, 47, 47, 32, 49, 49,
+ 49, 31, 1, 27, 28, 39, 39, 21,
+ 36, 23, 51, 2, 40, 51, 32, 53,
+ 24, 30, 24, 30, 21, 40, 57, 57,
+ 31, 41, 58, 32, 12, 4, 32, 34,
+ 59, 31, 32, 13, 9, 35, 26, 35,
+ 37, 61, 37, 63, 26, 29, 41, 38,
+ 23, 20, 41, 26, 41, 42, 42, 42,
+ 26, 26, 26, 26, 1, 26, 37, 37,
+ 37, 23, 34, 42, 27, 43, 34, 27,
+ 31, 24, 33, 16, 3, 31, 24, 33,
+ 24, 4, 44, 44, 11, 44, 31, 13,
+ 13, 44, 45, 13, 25, 22, 38, 26,
+ 38, 38, 39, 32, 30, 39, 30, 22,
+ 32, 26, 30, 47, 47, 47, 19, 47,
+ 30, 31, 35, 8, 23, 47, 47, 27,
+ 35, 47, 31, 48, 35, 19, 36, 49,
+ 49, 33, 31, 39, 27, 39, 49, 49,
+ 50, 50, 50, 39, 31, 51, 51, 39,
+ 28, 33, 33, 21, 40, 31, 52, 53,
+ 40, 53, 9, 33, 31, 53, 54, 54,
+ 54, 55, 55, 34, 15, 56, 25, 56,
+ 21, 21, 40, 40, 25, 40, 58, 36,
+ 5, 41, 41, 12, 60, 41, 41, 37,
+ 22, 61, 18, 29, 29, 30, 61, 30,
+ 61, 62, 62, 30, 30, 63, 18, 13,
+ 30, 23, 19, 20, 20, 41, 13, 2,
+ 5, 5, 1, 5, 32, 6, 32, 35,
+ 20, 35, 27, 35, 35, 36, 36, 13,
+ 36, 41, 41, 41, 3, 30, 42, 27,
+ 20, 30, 27, 28, 30, 21, 33, 33,
+ 14, 24, 30, 42, 24, 33, 25, 42,
+ 43, 14, 43, 43, 14, 43, 7, 36,
+ 37, 37, 37, 37, 7, 14, 25, 43,
+ 43, 44, 15, 37, 7, 7, 3, 1,
+ 8, 15, 15, 8, 44, 44, 44, 45,
+ 45, 45, 45, 8, 8, 45, 21, 45,
+ 28, 28, 28, 21, 28, 28, 22, 37,
+ 46, 46, 37, 8, 29, 37, 29, 22,
+ 46, 37, 22, 29, 47, 47, 38, 38,
+ 16, 38, 38, 33, 38, 22, 47, 47,
+ 29, 25, 16, 0, 48, 1, 34, 48,
+ 48, 34, 25, 26, 26, 49, 49, 26,
+ 1, 49, 4, 26, 4, 49, 1, 9,
+ 49, 49, 49, 10, 49, 17, 38, 17,
+ 17, 50, 38, 50, 50, 22, 38, 51,
+ 38, 38, 51, 39, 39, 18, 22, 39,
+ 51, 22, 52, 52, 52, 39, 53, 53,
+ 10, 23, 18, 29, 10, 53, 29, 54,
+ 11, 54, 11, 11, 55, 1, 18, 55,
+ 55, 55, 55, 55, 55, 29, 34, 18,
+ 29, 56, 56, 34, 57, 34, 34, 29,
+ 29, 57, 57, 35, 35, 35, 35, 35,
+ 39, 35, 59, 59, 18, 59, 39, 30,
+ 18, 40, 60, 60, 61, 30, 18, 61,
+ 61, 19, 19,
+};
+
+const UINT8 table0_mvy[1099] = {
+ 32, 31, 32, 33, 32, 31, 31, 33,
+ 33, 34, 32, 30, 32, 35, 34, 31,
+ 32, 29, 33, 30, 32, 34, 33, 31,
+ 30, 35, 31, 31, 29, 33, 35, 30,
+ 29, 33, 34, 34, 30, 32, 32, 36,
+ 29, 32, 35, 32, 28, 32, 32, 27,
+ 35, 37, 34, 29, 30, 36, 35, 34,
+ 25, 30, 29, 35, 33, 31, 31, 32,
+ 31, 28, 39, 28, 29, 37, 31, 33,
+ 27, 36, 28, 36, 37, 33, 33, 31,
+ 27, 32, 31, 38, 26, 25, 25, 33,
+ 39, 31, 34, 30, 32, 32, 32, 34,
+ 36, 32, 28, 33, 30, 38, 37, 27,
+ 33, 28, 32, 37, 35, 38, 29, 34,
+ 27, 29, 29, 32, 32, 34, 35, 3,
+ 26, 36, 31, 38, 30, 26, 35, 34,
+ 37, 26, 25, 32, 32, 39, 23, 37,
+ 32, 32, 29, 32, 29, 36, 29, 30,
+ 41, 31, 30, 21, 39, 25, 34, 38,
+ 32, 35, 39, 32, 33, 33, 32, 27,
+ 29, 25, 28, 27, 26, 31, 30, 35,
+ 24, 24, 31, 34, 32, 30, 35, 40,
+ 28, 38, 5, 35, 29, 36, 36, 32,
+ 38, 30, 33, 31, 35, 26, 23, 38,
+ 32, 41, 28, 25, 37, 40, 37, 39,
+ 32, 36, 33, 39, 25, 26, 28, 31,
+ 28, 42, 23, 31, 33, 31, 39, 1,
+ 59, 22, 27, 4, 33, 34, 33, 24,
+ 41, 3, 35, 41, 41, 28, 36, 36,
+ 28, 33, 35, 21, 23, 21, 22, 37,
+ 27, 27, 43, 29, 60, 39, 27, 25,
+ 59, 34, 27, 27, 26, 40, 37, 27,
+ 61, 26, 39, 33, 31, 22, 37, 25,
+ 30, 25, 24, 61, 31, 34, 25, 38,
+ 32, 32, 30, 3, 61, 43, 29, 23,
+ 28, 32, 28, 32, 31, 34, 5, 33,
+ 32, 33, 33, 42, 37, 23, 38, 31,
+ 40, 26, 32, 26, 37, 38, 36, 24,
+ 29, 30, 20, 22, 29, 24, 32, 41,
+ 2, 34, 25, 33, 29, 31, 39, 35,
+ 36, 24, 32, 30, 33, 27, 44, 60,
+ 30, 36, 19, 34, 31, 24, 16, 35,
+ 32, 38, 21, 33, 31, 31, 21, 35,
+ 5, 17, 29, 38, 38, 18, 58, 19,
+ 43, 41, 30, 41, 43, 39, 29, 7,
+ 29, 17, 28, 19, 28, 31, 25, 19,
+ 40, 26, 21, 33, 39, 23, 40, 30,
+ 39, 34, 35, 32, 32, 24, 33, 30,
+ 40, 47, 39, 37, 32, 33, 24, 23,
+ 45, 47, 27, 23, 42, 32, 32, 33,
+ 36, 37, 37, 17, 18, 22, 40, 38,
+ 32, 31, 35, 24, 17, 25, 17, 23,
+ 33, 34, 51, 42, 31, 36, 36, 29,
+ 21, 22, 37, 44, 43, 25, 47, 33,
+ 45, 27, 31, 58, 31, 32, 31, 38,
+ 43, 20, 47, 45, 54, 1, 26, 34,
+ 38, 14, 22, 24, 33, 34, 32, 32,
+ 37, 21, 23, 49, 35, 23, 28, 39,
+ 39, 23, 55, 33, 30, 30, 63, 16,
+ 42, 28, 13, 33, 33, 35, 19, 46,
+ 43, 17, 19, 36, 39, 24, 31, 32,
+ 33, 26, 28, 62, 33, 63, 33, 39,
+ 19, 49, 17, 31, 43, 13, 15, 29,
+ 25, 35, 33, 23, 49, 41, 28, 29,
+ 34, 38, 7, 61, 11, 50, 13, 41,
+ 19, 47, 25, 26, 15, 42, 41, 29,
+ 45, 27, 17, 35, 32, 29, 32, 24,
+ 13, 26, 26, 31, 24, 33, 28, 30,
+ 31, 11, 45, 46, 33, 33, 35, 57,
+ 32, 32, 35, 45, 34, 11, 37, 42,
+ 39, 37, 31, 49, 21, 27, 29, 47,
+ 53, 40, 51, 16, 26, 1, 40, 30,
+ 41, 44, 34, 25, 27, 31, 35, 35,
+ 31, 15, 49, 1, 35, 40, 5, 58,
+ 21, 29, 22, 59, 45, 31, 9, 26,
+ 9, 29, 11, 32, 30, 3, 13, 20,
+ 18, 20, 11, 3, 29, 40, 31, 53,
+ 30, 17, 20, 37, 31, 42, 47, 47,
+ 54, 38, 9, 34, 13, 37, 21, 25,
+ 27, 43, 42, 45, 40, 25, 27, 46,
+ 22, 25, 53, 20, 2, 14, 39, 15,
+ 22, 44, 34, 21, 38, 33, 27, 48,
+ 34, 52, 35, 47, 49, 54, 2, 13,
+ 23, 52, 29, 45, 22, 49, 54, 21,
+ 40, 42, 31, 30, 29, 34, 0, 25,
+ 23, 51, 24, 59, 28, 38, 29, 31,
+ 2, 13, 31, 8, 31, 33, 12, 45,
+ 41, 7, 14, 30, 25, 18, 43, 20,
+ 43, 35, 44, 1, 49, 42, 42, 18,
+ 41, 38, 41, 44, 53, 11, 20, 25,
+ 45, 46, 47, 48, 39, 52, 46, 49,
+ 63, 55, 44, 38, 13, 13, 57, 22,
+ 51, 16, 12, 28, 35, 57, 25, 20,
+ 26, 28, 28, 29, 32, 31, 62, 34,
+ 35, 35, 19, 49, 48, 39, 40, 18,
+ 43, 46, 11, 6, 48, 19, 49, 41,
+ 10, 23, 58, 17, 21, 23, 34, 30,
+ 60, 0, 44, 34, 26, 37, 46, 43,
+ 49, 59, 4, 34, 59, 37, 22, 25,
+ 28, 46, 6, 40, 59, 42, 36, 61,
+ 28, 30, 31, 43, 10, 22, 23, 47,
+ 20, 52, 55, 36, 25, 16, 1, 11,
+ 27, 29, 5, 63, 18, 41, 31, 34,
+ 38, 1, 5, 13, 28, 31, 17, 38,
+ 39, 41, 36, 37, 22, 39, 33, 43,
+ 43, 15, 17, 49, 30, 21, 22, 20,
+ 10, 17, 25, 54, 57, 3, 34, 8,
+ 36, 25, 31, 14, 15, 19, 29, 25,
+ 18, 39, 53, 22, 27, 20, 29, 33,
+ 41, 42, 35, 62, 50, 29, 53, 50,
+ 35, 55, 42, 61, 63, 4, 7, 42,
+ 21, 46, 47, 49, 27, 46, 17, 55,
+ 41, 50, 63, 4, 56, 18, 8, 10,
+ 18, 51, 63, 36, 55, 18, 5, 55,
+ 9, 29, 17, 21, 30, 27, 1, 59,
+ 7, 11, 12, 15, 5, 42, 24, 41,
+ 43, 7, 27, 22, 25, 31, 30, 37,
+ 22, 39, 53, 29, 36, 37, 48, 0,
+ 5, 13, 17, 31, 32, 26, 46, 28,
+ 44, 45, 46, 53, 49, 51, 3, 41,
+ 3, 22, 42, 33, 5, 45, 7, 22,
+ 40, 53, 24, 14, 25, 27, 10, 12,
+ 34, 16, 17, 53, 20, 26, 39, 45,
+ 18, 45, 35, 33, 31, 49, 4, 39,
+ 42, 11, 51, 5, 13, 26, 27, 17,
+ 52, 30, 0, 22, 12, 34, 62, 36,
+ 38, 41, 47, 30, 63, 38, 41, 43,
+ 59, 33, 45, 37, 38, 40, 47, 24,
+ 48, 49, 30, 1, 10, 22, 49, 15,
+ 39, 59, 31, 32, 33, 18, 13, 15,
+ 31, 21, 27, 44, 42, 39, 46, 17,
+ 26, 32, 30, 31, 0, 30, 34, 9,
+ 12, 13, 25, 31, 32, 55, 43, 35,
+ 61, 33, 35, 46, 25, 47, 48, 62,
+ 63, 38, 61, 1, 2, 5, 7, 9,
+ 46, 10, 34, 35, 36, 55, 51, 7,
+ 40, 23, 34, 37, 5, 13, 42, 18,
+ 25, 27, 28,
+};
+
+/* motion vector table 1 */
+const UINT16 table1_mv_code[1100] = {
+ 0x0000, 0x0007, 0x0009, 0x000f, 0x000a, 0x0011, 0x001a, 0x001c,
+ 0x0011, 0x0031, 0x0025, 0x002d, 0x002f, 0x006f, 0x0075, 0x0041,
+ 0x004c, 0x004e, 0x005c, 0x0060, 0x0062, 0x0066, 0x0068, 0x0069,
+ 0x006b, 0x00a6, 0x00c1, 0x00cb, 0x00cc, 0x00ce, 0x00da, 0x00e8,
+ 0x00ee, 0x0087, 0x0090, 0x009e, 0x009f, 0x00ba, 0x00ca, 0x00d8,
+ 0x00db, 0x00df, 0x0104, 0x0109, 0x010c, 0x0143, 0x0145, 0x014a,
+ 0x0156, 0x015c, 0x01b3, 0x01d3, 0x01da, 0x0103, 0x0109, 0x010b,
+ 0x0122, 0x0127, 0x0134, 0x0161, 0x0164, 0x0176, 0x0184, 0x018d,
+ 0x018e, 0x018f, 0x0190, 0x0193, 0x0196, 0x019d, 0x019e, 0x019f,
+ 0x01a9, 0x01b2, 0x01b4, 0x01ba, 0x01bb, 0x01bc, 0x0201, 0x0202,
+ 0x0205, 0x0207, 0x020d, 0x0210, 0x0211, 0x0215, 0x021b, 0x021f,
+ 0x0281, 0x0285, 0x0290, 0x029c, 0x029d, 0x02a2, 0x02a7, 0x02a8,
+ 0x02aa, 0x02b0, 0x02b1, 0x02b4, 0x02bc, 0x02bf, 0x0320, 0x0326,
+ 0x0327, 0x0329, 0x032a, 0x0336, 0x0360, 0x0362, 0x0363, 0x0372,
+ 0x03b2, 0x03bc, 0x03bd, 0x0203, 0x0205, 0x021a, 0x0249, 0x024a,
+ 0x024c, 0x02c7, 0x02ca, 0x02ce, 0x02ef, 0x030d, 0x0322, 0x0325,
+ 0x0338, 0x0373, 0x037a, 0x0409, 0x0415, 0x0416, 0x0418, 0x0428,
+ 0x042d, 0x042f, 0x0434, 0x0508, 0x0509, 0x0510, 0x0511, 0x051c,
+ 0x051e, 0x0524, 0x0541, 0x0543, 0x0546, 0x0547, 0x054d, 0x0557,
+ 0x055f, 0x056a, 0x056c, 0x056d, 0x056f, 0x0576, 0x0577, 0x057a,
+ 0x057b, 0x057c, 0x057d, 0x0600, 0x0601, 0x0603, 0x0614, 0x0616,
+ 0x0617, 0x061c, 0x061f, 0x0642, 0x0648, 0x0649, 0x064a, 0x064b,
+ 0x0657, 0x0668, 0x0669, 0x066b, 0x066e, 0x067f, 0x06c2, 0x06c8,
+ 0x06cb, 0x06de, 0x06df, 0x06e2, 0x06e3, 0x06ef, 0x0748, 0x074b,
+ 0x076e, 0x076f, 0x077c, 0x0409, 0x0423, 0x0428, 0x0429, 0x042a,
+ 0x042b, 0x0432, 0x0433, 0x0496, 0x049a, 0x04d5, 0x04db, 0x0581,
+ 0x0582, 0x058b, 0x058c, 0x058d, 0x0598, 0x0599, 0x059a, 0x059e,
+ 0x05dd, 0x0619, 0x0632, 0x0633, 0x0648, 0x0672, 0x06a1, 0x06a2,
+ 0x06a3, 0x06af, 0x06e2, 0x06e3, 0x06e4, 0x0800, 0x0801, 0x0802,
+ 0x0803, 0x081a, 0x081b, 0x0829, 0x082f, 0x0832, 0x083e, 0x083f,
+ 0x0852, 0x0853, 0x0858, 0x086b, 0x0877, 0x0878, 0x0879, 0x087a,
+ 0x087b, 0x0a00, 0x0a01, 0x0a0d, 0x0a0e, 0x0a0f, 0x0a24, 0x0a37,
+ 0x0a3a, 0x0a3b, 0x0a3e, 0x0a46, 0x0a47, 0x0a4a, 0x0a4b, 0x0a5f,
+ 0x0a79, 0x0a7a, 0x0a7b, 0x0a80, 0x0a81, 0x0a84, 0x0a85, 0x0a99,
+ 0x0aa5, 0x0aa6, 0x0ab8, 0x0aba, 0x0abb, 0x0abc, 0x0abd, 0x0ac8,
+ 0x0ace, 0x0acf, 0x0ad7, 0x0adc, 0x0aeb, 0x0c04, 0x0c25, 0x0c26,
+ 0x0c27, 0x0c2a, 0x0c2b, 0x0c3a, 0x0c3b, 0x0c3c, 0x0c3d, 0x0ca0,
+ 0x0cad, 0x0cd4, 0x0cd5, 0x0cfc, 0x0cfd, 0x0d86, 0x0d92, 0x0d93,
+ 0x0d94, 0x0d95, 0x0db0, 0x0db8, 0x0db9, 0x0dba, 0x0dbb, 0x0dc0,
+ 0x0dc2, 0x0dc3, 0x0dda, 0x0ddb, 0x0ddc, 0x0ddd, 0x0e92, 0x0e93,
+ 0x0e94, 0x0e95, 0x0ec7, 0x0ecc, 0x0ece, 0x0ecf, 0x0ed8, 0x0ed9,
+ 0x0eda, 0x0edb, 0x0808, 0x0809, 0x080a, 0x0810, 0x0811, 0x0844,
+ 0x0845, 0x0861, 0x0862, 0x0863, 0x086c, 0x0922, 0x0923, 0x092e,
+ 0x092f, 0x0936, 0x0937, 0x09b1, 0x09b2, 0x09b3, 0x09b4, 0x09b5,
+ 0x09b8, 0x09b9, 0x09ba, 0x09bb, 0x09bc, 0x09bd, 0x09be, 0x09bf,
+ 0x0b00, 0x0b15, 0x0b2c, 0x0b2d, 0x0b2e, 0x0b2f, 0x0b36, 0x0bb9,
+ 0x0c28, 0x0c2a, 0x0c2b, 0x0c2c, 0x0c2d, 0x0c2e, 0x0c2f, 0x0c30,
+ 0x0c31, 0x0c38, 0x0c60, 0x0c61, 0x0c62, 0x0c63, 0x0c8d, 0x0c8e,
+ 0x0c8f, 0x0c92, 0x0cbe, 0x0cbf, 0x0ce6, 0x0ce7, 0x0d40, 0x0d41,
+ 0x0d57, 0x0d58, 0x0d59, 0x0d5a, 0x0d5b, 0x0d5c, 0x0d5d, 0x0d98,
+ 0x0d99, 0x0d9a, 0x0d9b, 0x0d9c, 0x0d9d, 0x0dad, 0x0dae, 0x0daf,
+ 0x0dc0, 0x0dc1, 0x0dc2, 0x0dc3, 0x0dca, 0x0dcb, 0x0dec, 0x0ded,
+ 0x0dee, 0x0def, 0x1018, 0x1022, 0x1023, 0x1030, 0x1031, 0x1032,
+ 0x1033, 0x1050, 0x1051, 0x105c, 0x1074, 0x1075, 0x1076, 0x1077,
+ 0x1078, 0x1079, 0x107a, 0x107b, 0x10b2, 0x10b3, 0x10b8, 0x10b9,
+ 0x10ba, 0x10bb, 0x10d4, 0x10ea, 0x10eb, 0x10ec, 0x10ed, 0x1404,
+ 0x1405, 0x1406, 0x1407, 0x1410, 0x1411, 0x1412, 0x1413, 0x1414,
+ 0x1415, 0x1416, 0x1417, 0x1418, 0x1419, 0x1466, 0x1467, 0x1468,
+ 0x1469, 0x146a, 0x146b, 0x146c, 0x146d, 0x147e, 0x147f, 0x1488,
+ 0x1489, 0x148a, 0x148b, 0x14b6, 0x14b7, 0x14b8, 0x14b9, 0x14ba,
+ 0x14bb, 0x14bc, 0x14bd, 0x14f0, 0x14f1, 0x14f8, 0x14f9, 0x14fa,
+ 0x14fb, 0x14fc, 0x14fd, 0x14fe, 0x14ff, 0x152a, 0x152b, 0x152c,
+ 0x152d, 0x152e, 0x152f, 0x1530, 0x1531, 0x1548, 0x1549, 0x154e,
+ 0x154f, 0x1558, 0x1559, 0x155a, 0x155b, 0x1572, 0x159a, 0x159b,
+ 0x15ac, 0x15ba, 0x15bb, 0x15d0, 0x15d1, 0x15d2, 0x15d3, 0x15d4,
+ 0x15d5, 0x181d, 0x181e, 0x181f, 0x1840, 0x1841, 0x1842, 0x1843,
+ 0x1844, 0x1845, 0x1846, 0x1847, 0x1848, 0x1849, 0x1861, 0x1862,
+ 0x1863, 0x1864, 0x1865, 0x1866, 0x1867, 0x1868, 0x1869, 0x186a,
+ 0x186b, 0x186c, 0x186d, 0x186e, 0x191b, 0x191c, 0x191d, 0x191e,
+ 0x191f, 0x1942, 0x1943, 0x1944, 0x1945, 0x1946, 0x1947, 0x1958,
+ 0x1959, 0x19ed, 0x19ee, 0x19ef, 0x19f0, 0x19f1, 0x19f2, 0x19f3,
+ 0x19f4, 0x19f5, 0x19f6, 0x19f7, 0x1b0e, 0x1b0f, 0x1b62, 0x1b63,
+ 0x1b64, 0x1b65, 0x1b66, 0x1b67, 0x1b68, 0x1b69, 0x1b6a, 0x1b6b,
+ 0x1b6c, 0x1b6d, 0x1b6e, 0x1b6f, 0x1b82, 0x1ba8, 0x1ba9, 0x1baa,
+ 0x1bab, 0x1bac, 0x1bad, 0x1bae, 0x1baf, 0x1bb0, 0x1bb1, 0x1bb2,
+ 0x1bb3, 0x1d80, 0x1d81, 0x1d82, 0x1d83, 0x1d84, 0x1d85, 0x1d86,
+ 0x1d87, 0x1d88, 0x1d89, 0x1d8a, 0x1d8b, 0x1d8c, 0x1d8d, 0x1007,
+ 0x1008, 0x1009, 0x100a, 0x100b, 0x100c, 0x100d, 0x100e, 0x100f,
+ 0x1016, 0x1080, 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086,
+ 0x1087, 0x10c0, 0x123a, 0x123b, 0x123c, 0x123d, 0x123e, 0x123f,
+ 0x1240, 0x1241, 0x1242, 0x1243, 0x1350, 0x1352, 0x1353, 0x1358,
+ 0x1359, 0x135a, 0x135b, 0x135c, 0x135d, 0x135e, 0x135f, 0x1360,
+ 0x1361, 0x1602, 0x1603, 0x160c, 0x160d, 0x160e, 0x160f, 0x1620,
+ 0x1621, 0x1622, 0x1623, 0x1624, 0x1625, 0x1626, 0x1627, 0x1628,
+ 0x1629, 0x166e, 0x166f, 0x167c, 0x167d, 0x167e, 0x167f, 0x1770,
+ 0x1771, 0x1852, 0x1853, 0x1872, 0x1873, 0x1874, 0x1875, 0x1876,
+ 0x1877, 0x1878, 0x1879, 0x187a, 0x187b, 0x187c, 0x187d, 0x187e,
+ 0x187f, 0x1918, 0x1919, 0x1926, 0x1927, 0x1970, 0x1971, 0x1972,
+ 0x1973, 0x1974, 0x1975, 0x1976, 0x1977, 0x1978, 0x1979, 0x197a,
+ 0x197b, 0x1aa0, 0x1aa1, 0x1aa2, 0x1aa3, 0x1aa4, 0x1aa5, 0x1aa6,
+ 0x1aa7, 0x1aa8, 0x1aa9, 0x1aaa, 0x1aab, 0x1aac, 0x1aad, 0x1b3c,
+ 0x1b3d, 0x1b3e, 0x1b3f, 0x1b50, 0x1b51, 0x1b52, 0x1b53, 0x1b54,
+ 0x1b55, 0x1b56, 0x1b57, 0x1b58, 0x1b59, 0x2032, 0x2033, 0x2034,
+ 0x2035, 0x2036, 0x2037, 0x2038, 0x2039, 0x203a, 0x203b, 0x203c,
+ 0x203d, 0x203e, 0x203f, 0x2040, 0x2041, 0x2042, 0x2043, 0x20ba,
+ 0x20bb, 0x20cc, 0x20cd, 0x20ce, 0x20cf, 0x20e0, 0x20e1, 0x20e2,
+ 0x20e3, 0x20e4, 0x20e5, 0x20e6, 0x20e7, 0x21aa, 0x21ab, 0x21c0,
+ 0x21c1, 0x21c2, 0x21c3, 0x21c4, 0x21c5, 0x21c6, 0x21c7, 0x21c8,
+ 0x21c9, 0x21ca, 0x21cb, 0x21cc, 0x21cd, 0x21ce, 0x21cf, 0x21d0,
+ 0x21d1, 0x21d2, 0x21d3, 0x2894, 0x2895, 0x2896, 0x2897, 0x2898,
+ 0x2899, 0x289a, 0x289b, 0x289c, 0x289d, 0x289e, 0x289f, 0x28c0,
+ 0x28c1, 0x28c2, 0x28c3, 0x28c4, 0x28c5, 0x28c6, 0x28c7, 0x28c8,
+ 0x28c9, 0x28ca, 0x28cb, 0x2930, 0x2931, 0x2932, 0x2933, 0x2934,
+ 0x2935, 0x2936, 0x2937, 0x2938, 0x2939, 0x293a, 0x293b, 0x293c,
+ 0x293d, 0x293e, 0x293f, 0x2960, 0x2961, 0x2962, 0x2963, 0x2964,
+ 0x2965, 0x2966, 0x2967, 0x2968, 0x2969, 0x296a, 0x296b, 0x2a40,
+ 0x2a41, 0x2a42, 0x2a43, 0x2a44, 0x2a45, 0x2a46, 0x2a47, 0x2a48,
+ 0x2a49, 0x2a4a, 0x2a4b, 0x2a4c, 0x2a4d, 0x2a4e, 0x2a4f, 0x2a50,
+ 0x2a51, 0x2a52, 0x2a53, 0x2ae6, 0x2ae7, 0x2b24, 0x2b25, 0x2b26,
+ 0x2b27, 0x2b28, 0x2b29, 0x2b2a, 0x2b2b, 0x2b2c, 0x2b2d, 0x2b2e,
+ 0x2b2f, 0x2b30, 0x2b31, 0x2b32, 0x2b33, 0x2b5a, 0x2b5b, 0x3014,
+ 0x3015, 0x3016, 0x3017, 0x3020, 0x3021, 0x3022, 0x3023, 0x3024,
+ 0x3025, 0x3026, 0x3027, 0x3028, 0x3029, 0x302a, 0x302b, 0x302c,
+ 0x302d, 0x302e, 0x302f, 0x3030, 0x3031, 0x3032, 0x3033, 0x3034,
+ 0x3035, 0x3036, 0x3037, 0x3038, 0x3039, 0x30c0, 0x30c1, 0x30de,
+ 0x30df, 0x3218, 0x3219, 0x321a, 0x321b, 0x321c, 0x321d, 0x321e,
+ 0x321f, 0x3220, 0x3221, 0x3222, 0x3223, 0x3224, 0x3225, 0x3226,
+ 0x3227, 0x3228, 0x3229, 0x322a, 0x322b, 0x322c, 0x322d, 0x322e,
+ 0x322f, 0x3230, 0x3231, 0x3232, 0x3233, 0x3234, 0x3235, 0x3378,
+ 0x3379, 0x337a, 0x337b, 0x337c, 0x337d, 0x337e, 0x337f, 0x33c0,
+ 0x33c1, 0x33c2, 0x33c3, 0x33c4, 0x33c5, 0x33c6, 0x33c7, 0x33c8,
+ 0x33c9, 0x33ca, 0x33cb, 0x33cc, 0x33cd, 0x33ce, 0x33cf, 0x33d0,
+ 0x33d1, 0x33d2, 0x33d3, 0x33d4, 0x33d5, 0x33d6, 0x33d7, 0x33d8,
+ 0x33d9, 0x3706, 0x3707, 0x3730, 0x3731, 0x3732, 0x3733, 0x3734,
+ 0x3735, 0x3736, 0x3737, 0x3738, 0x3739, 0x373a, 0x373b, 0x373c,
+ 0x373d, 0x373e, 0x373f, 0x3740, 0x3741, 0x3742, 0x3743, 0x3744,
+ 0x3745, 0x3746, 0x3747, 0x3748, 0x3749, 0x374a, 0x374b, 0x374c,
+ 0x374d, 0x374e, 0x374f, 0x3b34, 0x3b35, 0x3b36, 0x3b37, 0x3be8,
+ 0x3be9, 0x3bea, 0x3beb, 0x3bec, 0x3bed, 0x3bee, 0x3bef, 0x3bf0,
+ 0x3bf1, 0x3bf2, 0x3bf3, 0x3bf4, 0x3bf5, 0x3bf6, 0x3bf7, 0x3bf8,
+ 0x3bf9, 0x3bfa, 0x3bfb, 0x3bfc, 0x3bfd, 0x3bfe, 0x3bff, 0x2000,
+ 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008,
+ 0x2009, 0x200a, 0x200b, 0x200c, 0x200d, 0x202e, 0x202f, 0x2182,
+ 0x2183, 0x21b4, 0x21b5, 0x21b6, 0x21b7, 0x21b8, 0x21b9, 0x21ba,
+ 0x21bb, 0x21bc, 0x21bd, 0x21be, 0x21bf, 0x2460, 0x2461, 0x2462,
+ 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, 0x246a,
+ 0x246b, 0x246c, 0x246d, 0x246e, 0x246f, 0x2470, 0x2471, 0x2472,
+ 0x2473, 0x26a2, 0x26a3, 0x000b,
+};
+
+const UINT8 table1_mv_bits[1100] = {
+ 2, 4, 4, 4, 5, 5, 5, 5,
+ 6, 6, 7, 7, 7, 7, 7, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 4,
+};
+
+const UINT8 table1_mvx[1099] = {
+ 32, 31, 32, 31, 33, 32, 33, 33,
+ 31, 34, 30, 32, 32, 34, 35, 32,
+ 34, 33, 29, 30, 30, 32, 31, 31,
+ 33, 35, 35, 33, 31, 29, 29, 33,
+ 34, 30, 31, 28, 36, 30, 34, 32,
+ 32, 37, 32, 32, 25, 27, 39, 32,
+ 32, 32, 38, 35, 36, 32, 37, 61,
+ 26, 32, 34, 35, 3, 35, 27, 28,
+ 29, 34, 28, 37, 31, 36, 32, 27,
+ 31, 30, 29, 39, 33, 29, 33, 35,
+ 25, 25, 29, 33, 31, 31, 31, 33,
+ 32, 30, 32, 32, 41, 39, 33, 36,
+ 32, 28, 34, 36, 38, 24, 60, 31,
+ 23, 28, 32, 33, 59, 32, 40, 30,
+ 5, 34, 32, 38, 32, 30, 43, 4,
+ 32, 32, 42, 31, 31, 32, 26, 38,
+ 26, 22, 21, 37, 61, 63, 37, 31,
+ 32, 33, 2, 1, 23, 33, 41, 27,
+ 35, 30, 38, 23, 33, 3, 28, 34,
+ 34, 27, 41, 29, 39, 35, 36, 29,
+ 32, 27, 30, 32, 24, 61, 37, 26,
+ 59, 25, 35, 27, 36, 37, 30, 31,
+ 34, 40, 3, 28, 34, 39, 32, 31,
+ 32, 30, 24, 28, 35, 36, 26, 32,
+ 31, 33, 29, 33, 39, 25, 30, 24,
+ 35, 59, 29, 34, 25, 30, 21, 35,
+ 43, 40, 32, 29, 5, 28, 31, 62,
+ 33, 33, 25, 31, 21, 31, 43, 31,
+ 34, 33, 20, 40, 39, 31, 31, 57,
+ 38, 32, 42, 33, 32, 31, 32, 29,
+ 30, 44, 5, 31, 22, 34, 36, 17,
+ 38, 58, 38, 35, 32, 60, 35, 24,
+ 32, 38, 16, 45, 42, 32, 31, 29,
+ 4, 30, 17, 40, 46, 48, 63, 32,
+ 42, 19, 41, 22, 28, 36, 45, 33,
+ 33, 32, 29, 7, 41, 42, 18, 33,
+ 33, 32, 22, 37, 1, 26, 22, 23,
+ 49, 28, 26, 27, 32, 33, 27, 23,
+ 28, 36, 15, 6, 34, 27, 31, 26,
+ 23, 2, 33, 32, 34, 41, 28, 32,
+ 41, 0, 36, 38, 34, 31, 47, 32,
+ 17, 31, 39, 33, 37, 51, 30, 47,
+ 32, 50, 32, 19, 63, 30, 25, 27,
+ 33, 62, 24, 31, 27, 30, 37, 31,
+ 45, 32, 39, 20, 46, 47, 35, 19,
+ 34, 1, 49, 21, 21, 14, 51, 26,
+ 23, 31, 36, 35, 58, 29, 29, 21,
+ 20, 42, 13, 28, 12, 40, 31, 33,
+ 39, 60, 32, 44, 33, 31, 28, 37,
+ 29, 32, 30, 49, 43, 28, 39, 25,
+ 32, 48, 2, 15, 20, 25, 31, 28,
+ 21, 24, 25, 15, 31, 17, 37, 43,
+ 18, 32, 33, 24, 33, 36, 13, 33,
+ 31, 39, 11, 31, 33, 32, 39, 37,
+ 32, 32, 29, 17, 44, 46, 36, 35,
+ 26, 37, 58, 32, 34, 38, 8, 38,
+ 38, 22, 29, 25, 16, 35, 32, 35,
+ 33, 43, 18, 46, 38, 50, 33, 18,
+ 53, 60, 13, 32, 36, 33, 51, 36,
+ 43, 45, 27, 42, 29, 24, 30, 25,
+ 31, 52, 31, 35, 38, 9, 22, 34,
+ 4, 17, 28, 55, 42, 25, 17, 20,
+ 47, 34, 33, 16, 40, 25, 16, 30,
+ 53, 29, 10, 11, 14, 26, 33, 4,
+ 35, 44, 26, 16, 31, 26, 34, 38,
+ 29, 31, 30, 24, 22, 61, 32, 9,
+ 45, 34, 31, 19, 9, 31, 46, 31,
+ 35, 54, 29, 57, 30, 50, 3, 31,
+ 63, 34, 47, 41, 51, 18, 31, 14,
+ 37, 38, 31, 24, 32, 31, 50, 33,
+ 31, 54, 27, 9, 33, 23, 19, 32,
+ 29, 29, 33, 28, 47, 49, 30, 47,
+ 33, 27, 25, 54, 44, 45, 50, 58,
+ 51, 48, 33, 59, 33, 34, 57, 13,
+ 26, 33, 13, 48, 30, 11, 7, 56,
+ 34, 55, 26, 0, 26, 35, 1, 51,
+ 33, 53, 31, 45, 12, 29, 29, 51,
+ 31, 48, 2, 6, 34, 30, 28, 33,
+ 60, 40, 27, 46, 31, 9, 35, 29,
+ 31, 39, 55, 46, 19, 37, 62, 34,
+ 30, 16, 19, 49, 41, 41, 39, 37,
+ 14, 5, 13, 35, 55, 30, 40, 40,
+ 42, 8, 20, 25, 45, 35, 33, 36,
+ 54, 38, 27, 37, 62, 40, 15, 59,
+ 49, 31, 29, 34, 34, 39, 24, 29,
+ 25, 29, 21, 29, 10, 61, 33, 49,
+ 35, 34, 3, 38, 39, 29, 7, 41,
+ 1, 35, 4, 23, 15, 23, 11, 37,
+ 28, 35, 30, 30, 24, 1, 43, 56,
+ 8, 34, 42, 24, 45, 30, 20, 23,
+ 8, 38, 22, 33, 17, 52, 34, 22,
+ 53, 43, 44, 1, 27, 31, 41, 43,
+ 41, 30, 31, 36, 30, 5, 55, 31,
+ 33, 30, 40, 23, 15, 29, 34, 34,
+ 59, 34, 30, 11, 13, 38, 5, 0,
+ 30, 42, 5, 30, 29, 34, 10, 44,
+ 30, 63, 35, 12, 3, 26, 15, 17,
+ 25, 34, 43, 39, 34, 56, 29, 23,
+ 30, 12, 30, 10, 35, 9, 24, 58,
+ 10, 12, 54, 33, 37, 20, 41, 35,
+ 29, 18, 61, 30, 40, 24, 39, 53,
+ 62, 26, 29, 33, 34, 53, 49, 21,
+ 27, 11, 63, 20, 26, 23, 7, 13,
+ 6, 47, 29, 30, 9, 51, 22, 34,
+ 21, 25, 33, 56, 57, 30, 38, 51,
+ 51, 38, 63, 28, 40, 35, 33, 18,
+ 33, 33, 24, 58, 58, 34, 49, 29,
+ 43, 4, 1, 4, 42, 35, 35, 30,
+ 17, 5, 56, 61, 25, 37, 36, 55,
+ 28, 35, 29, 50, 48, 52, 2, 42,
+ 34, 40, 46, 46, 43, 35, 29, 48,
+ 20, 29, 31, 41, 7, 30, 35, 19,
+ 14, 21, 8, 39, 39, 40, 46, 55,
+ 34, 6, 30, 34, 37, 25, 37, 33,
+ 22, 44, 52, 17, 35, 29, 36, 35,
+ 40, 37, 28, 30, 50, 14, 28, 55,
+ 6, 23, 19, 14, 30, 3, 30, 28,
+ 28, 61, 61, 47, 45, 48, 40, 40,
+ 34, 34, 25, 30, 29, 35, 4, 26,
+ 53, 50, 26, 41, 27, 59, 27, 38,
+ 39, 3, 50, 43, 47, 23, 33, 55,
+ 35, 21, 23, 35, 61, 33, 46, 52,
+ 35, 34, 24, 30, 43, 16, 37, 21,
+ 2, 24, 45, 34, 30, 55, 55, 1,
+ 29, 29, 26, 28, 25, 31, 36, 22,
+ 17, 30, 52, 2, 44, 44, 57, 26,
+ 62, 41, 39, 57, 26, 46, 49, 11,
+ 16, 19, 5, 59, 38, 39, 58, 38,
+ 25, 49, 50, 22, 28, 59, 9, 59,
+ 7, 28, 55, 17, 4, 35, 50, 21,
+ 29, 44, 47, 18, 24, 19, 25, 42,
+ 35, 3, 51, 35, 16, 35, 30, 63,
+ 57, 39, 39, 25, 35, 38, 9, 16,
+ 36, 45, 31, 60, 14, 34, 42, 24,
+ 0, 37, 18, 61, 57, 37, 28, 53,
+ 20, 46, 14, 47, 38, 38, 38, 9,
+ 34, 39, 43, 17, 39, 59, 5, 27,
+ 0, 12, 27,
+};
+
+const UINT8 table1_mvy[1099] = {
+ 32, 32, 31, 31, 32, 33, 31, 33,
+ 33, 32, 32, 30, 34, 31, 32, 29,
+ 33, 30, 32, 33, 31, 35, 34, 30,
+ 34, 31, 33, 29, 29, 31, 33, 35,
+ 30, 30, 35, 32, 32, 34, 34, 28,
+ 25, 32, 36, 27, 32, 32, 32, 37,
+ 39, 3, 32, 30, 31, 26, 31, 32,
+ 32, 38, 29, 29, 32, 34, 31, 31,
+ 34, 35, 33, 33, 28, 33, 1, 33,
+ 27, 29, 30, 31, 28, 29, 37, 35,
+ 31, 33, 35, 27, 36, 37, 25, 25,
+ 61, 35, 4, 5, 32, 33, 36, 30,
+ 23, 30, 28, 34, 31, 32, 32, 39,
+ 32, 34, 21, 39, 32, 59, 32, 28,
+ 32, 36, 60, 33, 24, 36, 32, 32,
+ 41, 2, 32, 38, 26, 22, 33, 30,
+ 31, 32, 32, 30, 31, 32, 29, 3,
+ 40, 38, 32, 32, 33, 26, 31, 34,
+ 28, 38, 34, 31, 3, 31, 35, 38,
+ 27, 35, 33, 28, 29, 27, 29, 27,
+ 43, 29, 37, 63, 31, 33, 34, 30,
+ 31, 30, 37, 30, 35, 35, 26, 41,
+ 37, 31, 33, 28, 26, 30, 42, 24,
+ 7, 27, 33, 29, 36, 28, 34, 57,
+ 23, 41, 36, 23, 35, 34, 25, 30,
+ 25, 33, 25, 25, 29, 24, 33, 39,
+ 33, 33, 0, 37, 31, 36, 21, 32,
+ 61, 24, 35, 61, 31, 5, 31, 59,
+ 39, 21, 32, 30, 34, 22, 40, 32,
+ 29, 16, 31, 5, 62, 2, 20, 39,
+ 39, 32, 33, 1, 31, 24, 36, 32,
+ 36, 32, 28, 26, 6, 31, 38, 34,
+ 58, 35, 32, 33, 33, 17, 43, 26,
+ 31, 40, 31, 34, 32, 32, 31, 19,
+ 30, 32, 29, 33, 38, 38, 32, 59,
+ 40, 18, 38, 32, 35, 34, 32, 17,
+ 1, 15, 30, 28, 31, 28, 34, 29,
+ 32, 27, 35, 27, 49, 22, 37, 34,
+ 37, 26, 32, 32, 22, 28, 45, 29,
+ 30, 31, 43, 46, 41, 30, 26, 13,
+ 34, 32, 27, 38, 42, 42, 33, 47,
+ 33, 60, 27, 42, 25, 32, 22, 32,
+ 48, 32, 45, 33, 33, 41, 27, 25,
+ 19, 31, 35, 19, 36, 42, 27, 17,
+ 31, 44, 28, 33, 33, 31, 23, 31,
+ 40, 33, 31, 34, 30, 32, 33, 36,
+ 35, 47, 37, 41, 31, 23, 41, 29,
+ 30, 35, 32, 25, 32, 28, 58, 2,
+ 37, 33, 14, 33, 49, 20, 39, 36,
+ 21, 9, 23, 33, 35, 24, 39, 37,
+ 11, 33, 30, 31, 31, 28, 51, 40,
+ 35, 29, 25, 33, 46, 35, 37, 30,
+ 30, 8, 63, 28, 15, 40, 33, 45,
+ 49, 25, 32, 4, 47, 51, 36, 39,
+ 53, 10, 24, 29, 30, 31, 25, 40,
+ 38, 38, 33, 56, 23, 27, 32, 37,
+ 26, 29, 43, 36, 33, 24, 55, 43,
+ 9, 29, 34, 34, 24, 33, 18, 33,
+ 33, 30, 31, 50, 24, 60, 30, 39,
+ 34, 30, 39, 28, 22, 38, 2, 26,
+ 63, 32, 57, 21, 39, 33, 28, 18,
+ 30, 34, 22, 33, 29, 41, 30, 34,
+ 35, 21, 13, 34, 35, 39, 30, 46,
+ 32, 42, 32, 31, 33, 26, 11, 33,
+ 22, 31, 25, 31, 53, 27, 43, 25,
+ 40, 50, 21, 36, 38, 30, 12, 31,
+ 34, 20, 15, 29, 32, 62, 30, 13,
+ 17, 32, 19, 31, 20, 31, 30, 7,
+ 1, 17, 34, 37, 31, 31, 44, 34,
+ 26, 40, 16, 37, 52, 48, 30, 20,
+ 18, 33, 38, 29, 7, 25, 30, 54,
+ 45, 47, 46, 41, 29, 29, 16, 30,
+ 14, 26, 38, 34, 34, 29, 34, 30,
+ 29, 30, 57, 30, 4, 46, 33, 29,
+ 39, 44, 30, 31, 50, 33, 31, 32,
+ 19, 32, 40, 31, 37, 47, 1, 35,
+ 16, 31, 0, 35, 33, 1, 17, 34,
+ 9, 34, 33, 31, 49, 43, 42, 51,
+ 34, 29, 23, 29, 14, 30, 45, 49,
+ 11, 24, 31, 28, 35, 41, 30, 44,
+ 18, 29, 34, 35, 36, 25, 26, 21,
+ 31, 30, 34, 19, 34, 44, 36, 38,
+ 25, 31, 28, 23, 37, 3, 55, 41,
+ 30, 22, 41, 24, 33, 26, 35, 35,
+ 30, 55, 51, 47, 48, 38, 24, 15,
+ 21, 50, 25, 46, 30, 29, 10, 34,
+ 42, 45, 29, 42, 22, 3, 33, 27,
+ 34, 1, 34, 28, 34, 36, 35, 23,
+ 23, 13, 58, 3, 26, 63, 25, 31,
+ 34, 61, 38, 39, 25, 61, 29, 37,
+ 30, 41, 26, 48, 28, 33, 50, 35,
+ 30, 37, 29, 29, 40, 6, 39, 28,
+ 28, 19, 8, 22, 45, 34, 35, 10,
+ 58, 17, 37, 39, 30, 18, 54, 14,
+ 29, 16, 59, 30, 35, 23, 35, 30,
+ 47, 36, 29, 55, 20, 12, 31, 35,
+ 14, 29, 18, 34, 34, 24, 29, 26,
+ 22, 2, 27, 23, 8, 30, 55, 38,
+ 60, 31, 4, 34, 49, 34, 27, 34,
+ 33, 30, 31, 54, 42, 35, 38, 46,
+ 44, 26, 27, 9, 39, 25, 21, 29,
+ 28, 42, 13, 0, 5, 34, 37, 28,
+ 24, 29, 63, 26, 22, 27, 29, 25,
+ 33, 25, 61, 0, 35, 25, 36, 15,
+ 27, 40, 53, 33, 3, 10, 16, 37,
+ 38, 18, 30, 46, 27, 9, 6, 29,
+ 62, 8, 42, 28, 29, 3, 25, 16,
+ 26, 29, 35, 28, 27, 51, 61, 48,
+ 37, 9, 34, 7, 49, 45, 20, 29,
+ 21, 5, 5, 29, 28, 34, 29, 24,
+ 10, 24, 35, 36, 38, 55, 11, 36,
+ 38, 53, 54, 26, 30, 49, 20, 27,
+ 30, 39, 33, 41, 49, 22, 38, 38,
+ 4, 30, 8, 9, 3, 24, 22, 50,
+ 37, 36, 31, 27, 2, 9, 42, 63,
+ 25, 19, 44, 1, 28, 28, 48, 30,
+ 34, 41, 41, 38, 12, 27, 15, 0,
+ 16, 34, 35, 38, 28, 29, 40, 42,
+ 51, 52, 45, 54, 59, 59, 42, 44,
+ 37, 26, 46, 24, 15, 39, 22, 46,
+ 19, 35, 38, 17, 37, 23, 52, 55,
+ 50, 37, 26, 11, 37, 12, 24, 30,
+ 16, 13, 22, 13, 36, 35, 40, 41,
+ 34, 41, 26, 53, 51, 5, 21, 30,
+ 2, 63, 41, 20, 1, 56, 21, 24,
+ 25, 5, 28, 35, 26, 28, 30, 18,
+ 29, 23, 40, 34, 20, 42, 39, 34,
+ 28, 61, 38, 27, 62, 9, 36, 17,
+ 9, 49, 24, 25, 54, 34, 39, 37,
+ 3, 1, 25, 38, 38, 44, 35, 36,
+ 12, 60, 36, 38, 40, 25, 43, 39,
+ 53, 28, 39, 57, 46, 10, 52, 27,
+ 35, 42, 45, 59, 15, 60, 38, 24,
+ 23, 39, 12, 29, 24, 0, 20, 16,
+ 28, 43, 35, 28, 1, 49, 4, 21,
+ 42, 39, 29, 3, 44, 21, 53, 55,
+ 11, 5, 3, 39, 53, 28, 25, 19,
+ 34, 28, 21,
+};
+
+static MVTable mv_tables[2] = {
+ {
+ 1099,
+ table0_mv_code,
+ table0_mv_bits,
+ table0_mvx,
+ table0_mvy,
+ },
+ {
+ 1099,
+ table1_mv_code,
+ table1_mv_bits,
+ table1_mvx,
+ table1_mvy,
+ }
+};
diff --git a/src/libffmpeg/libavcodec/rv10.c b/src/libffmpeg/libavcodec/rv10.c
new file mode 100644
index 000000000..b03cd0293
--- /dev/null
+++ b/src/libffmpeg/libavcodec/rv10.c
@@ -0,0 +1,487 @@
+/*
+ * RV10 codec
+ * Copyright (c) 2000,2001 Gerard Lantau.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "common.h"
+#include "dsputil.h"
+#include "avcodec.h"
+#include "mpegvideo.h"
+
+//#define DEBUG
+
+static const UINT16 rv_lum_code[256] =
+{
+ 0x3e7f, 0x0f00, 0x0f01, 0x0f02, 0x0f03, 0x0f04, 0x0f05, 0x0f06,
+ 0x0f07, 0x0f08, 0x0f09, 0x0f0a, 0x0f0b, 0x0f0c, 0x0f0d, 0x0f0e,
+ 0x0f0f, 0x0f10, 0x0f11, 0x0f12, 0x0f13, 0x0f14, 0x0f15, 0x0f16,
+ 0x0f17, 0x0f18, 0x0f19, 0x0f1a, 0x0f1b, 0x0f1c, 0x0f1d, 0x0f1e,
+ 0x0f1f, 0x0f20, 0x0f21, 0x0f22, 0x0f23, 0x0f24, 0x0f25, 0x0f26,
+ 0x0f27, 0x0f28, 0x0f29, 0x0f2a, 0x0f2b, 0x0f2c, 0x0f2d, 0x0f2e,
+ 0x0f2f, 0x0f30, 0x0f31, 0x0f32, 0x0f33, 0x0f34, 0x0f35, 0x0f36,
+ 0x0f37, 0x0f38, 0x0f39, 0x0f3a, 0x0f3b, 0x0f3c, 0x0f3d, 0x0f3e,
+ 0x0f3f, 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0386,
+ 0x0387, 0x0388, 0x0389, 0x038a, 0x038b, 0x038c, 0x038d, 0x038e,
+ 0x038f, 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396,
+ 0x0397, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e,
+ 0x039f, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6,
+ 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce,
+ 0x00cf, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056,
+ 0x0057, 0x0020, 0x0021, 0x0022, 0x0023, 0x000c, 0x000d, 0x0004,
+ 0x0000, 0x0005, 0x000e, 0x000f, 0x0024, 0x0025, 0x0026, 0x0027,
+ 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
+ 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
+ 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
+ 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7,
+ 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af,
+ 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
+ 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
+ 0x0f40, 0x0f41, 0x0f42, 0x0f43, 0x0f44, 0x0f45, 0x0f46, 0x0f47,
+ 0x0f48, 0x0f49, 0x0f4a, 0x0f4b, 0x0f4c, 0x0f4d, 0x0f4e, 0x0f4f,
+ 0x0f50, 0x0f51, 0x0f52, 0x0f53, 0x0f54, 0x0f55, 0x0f56, 0x0f57,
+ 0x0f58, 0x0f59, 0x0f5a, 0x0f5b, 0x0f5c, 0x0f5d, 0x0f5e, 0x0f5f,
+ 0x0f60, 0x0f61, 0x0f62, 0x0f63, 0x0f64, 0x0f65, 0x0f66, 0x0f67,
+ 0x0f68, 0x0f69, 0x0f6a, 0x0f6b, 0x0f6c, 0x0f6d, 0x0f6e, 0x0f6f,
+ 0x0f70, 0x0f71, 0x0f72, 0x0f73, 0x0f74, 0x0f75, 0x0f76, 0x0f77,
+ 0x0f78, 0x0f79, 0x0f7a, 0x0f7b, 0x0f7c, 0x0f7d, 0x0f7e, 0x0f7f,
+};
+
+static const UINT8 rv_lum_bits[256] =
+{
+ 14, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 7, 7, 7, 7, 7, 7, 7,
+ 7, 6, 6, 6, 6, 5, 5, 4,
+ 2, 4, 5, 5, 6, 6, 6, 6,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+};
+
+static const UINT16 rv_chrom_code[256] =
+{
+ 0xfe7f, 0x3f00, 0x3f01, 0x3f02, 0x3f03, 0x3f04, 0x3f05, 0x3f06,
+ 0x3f07, 0x3f08, 0x3f09, 0x3f0a, 0x3f0b, 0x3f0c, 0x3f0d, 0x3f0e,
+ 0x3f0f, 0x3f10, 0x3f11, 0x3f12, 0x3f13, 0x3f14, 0x3f15, 0x3f16,
+ 0x3f17, 0x3f18, 0x3f19, 0x3f1a, 0x3f1b, 0x3f1c, 0x3f1d, 0x3f1e,
+ 0x3f1f, 0x3f20, 0x3f21, 0x3f22, 0x3f23, 0x3f24, 0x3f25, 0x3f26,
+ 0x3f27, 0x3f28, 0x3f29, 0x3f2a, 0x3f2b, 0x3f2c, 0x3f2d, 0x3f2e,
+ 0x3f2f, 0x3f30, 0x3f31, 0x3f32, 0x3f33, 0x3f34, 0x3f35, 0x3f36,
+ 0x3f37, 0x3f38, 0x3f39, 0x3f3a, 0x3f3b, 0x3f3c, 0x3f3d, 0x3f3e,
+ 0x3f3f, 0x0f80, 0x0f81, 0x0f82, 0x0f83, 0x0f84, 0x0f85, 0x0f86,
+ 0x0f87, 0x0f88, 0x0f89, 0x0f8a, 0x0f8b, 0x0f8c, 0x0f8d, 0x0f8e,
+ 0x0f8f, 0x0f90, 0x0f91, 0x0f92, 0x0f93, 0x0f94, 0x0f95, 0x0f96,
+ 0x0f97, 0x0f98, 0x0f99, 0x0f9a, 0x0f9b, 0x0f9c, 0x0f9d, 0x0f9e,
+ 0x0f9f, 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6,
+ 0x03c7, 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce,
+ 0x03cf, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6,
+ 0x00e7, 0x0030, 0x0031, 0x0032, 0x0033, 0x0008, 0x0009, 0x0002,
+ 0x0000, 0x0003, 0x000a, 0x000b, 0x0034, 0x0035, 0x0036, 0x0037,
+ 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+ 0x03d0, 0x03d1, 0x03d2, 0x03d3, 0x03d4, 0x03d5, 0x03d6, 0x03d7,
+ 0x03d8, 0x03d9, 0x03da, 0x03db, 0x03dc, 0x03dd, 0x03de, 0x03df,
+ 0x0fa0, 0x0fa1, 0x0fa2, 0x0fa3, 0x0fa4, 0x0fa5, 0x0fa6, 0x0fa7,
+ 0x0fa8, 0x0fa9, 0x0faa, 0x0fab, 0x0fac, 0x0fad, 0x0fae, 0x0faf,
+ 0x0fb0, 0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7,
+ 0x0fb8, 0x0fb9, 0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf,
+ 0x3f40, 0x3f41, 0x3f42, 0x3f43, 0x3f44, 0x3f45, 0x3f46, 0x3f47,
+ 0x3f48, 0x3f49, 0x3f4a, 0x3f4b, 0x3f4c, 0x3f4d, 0x3f4e, 0x3f4f,
+ 0x3f50, 0x3f51, 0x3f52, 0x3f53, 0x3f54, 0x3f55, 0x3f56, 0x3f57,
+ 0x3f58, 0x3f59, 0x3f5a, 0x3f5b, 0x3f5c, 0x3f5d, 0x3f5e, 0x3f5f,
+ 0x3f60, 0x3f61, 0x3f62, 0x3f63, 0x3f64, 0x3f65, 0x3f66, 0x3f67,
+ 0x3f68, 0x3f69, 0x3f6a, 0x3f6b, 0x3f6c, 0x3f6d, 0x3f6e, 0x3f6f,
+ 0x3f70, 0x3f71, 0x3f72, 0x3f73, 0x3f74, 0x3f75, 0x3f76, 0x3f77,
+ 0x3f78, 0x3f79, 0x3f7a, 0x3f7b, 0x3f7c, 0x3f7d, 0x3f7e, 0x3f7f,
+};
+
+static const UINT8 rv_chrom_bits[256] =
+{
+ 16, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 8, 8, 8, 8, 8, 8, 8,
+ 8, 6, 6, 6, 6, 4, 4, 3,
+ 2, 3, 4, 4, 6, 6, 6, 6,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+};
+
+static VLC rv_dc_lum, rv_dc_chrom;
+
+int rv_decode_dc(MpegEncContext *s, int n)
+{
+ int code;
+
+ if (n < 4) {
+ code = get_vlc(&s->gb, &rv_dc_lum);
+ if (code < 0) {
+ /* XXX: I don't understand why they use LONGER codes than
+ necessary. The following code would be completely useless
+ if they had thought about it !!! */
+ code = get_bits(&s->gb, 7);
+ if (code == 0x7c) {
+ code = (INT8)(get_bits(&s->gb, 7) + 1);
+ } else if (code == 0x7d) {
+ code = -128 + get_bits(&s->gb, 7);
+ } else if (code == 0x7e) {
+ if (get_bits(&s->gb, 1) == 0)
+ code = (INT8)(get_bits(&s->gb, 8) + 1);
+ else
+ code = (INT8)(get_bits(&s->gb, 8));
+ } else if (code == 0x7f) {
+ get_bits(&s->gb, 11);
+ code = 1;
+ }
+ } else {
+ code -= 128;
+ }
+ } else {
+ code = get_vlc(&s->gb, &rv_dc_chrom);
+ /* same remark */
+ if (code < 0) {
+ code = get_bits(&s->gb, 9);
+ if (code == 0x1fc) {
+ code = (INT8)(get_bits(&s->gb, 7) + 1);
+ } else if (code == 0x1fd) {
+ code = -128 + get_bits(&s->gb, 7);
+ } else if (code == 0x1fe) {
+ get_bits(&s->gb, 9);
+ code = 1;
+ } else {
+ return 0xffff;
+ }
+ } else {
+ code -= 128;
+ }
+ }
+ return -code;
+}
+
+/* write RV 1.0 compatible frame header */
+void rv10_encode_picture_header(MpegEncContext *s, int picture_number)
+{
+ align_put_bits(&s->pb);
+
+ put_bits(&s->pb, 1, 1); /* marker */
+
+ put_bits(&s->pb, 1, (s->pict_type == P_TYPE));
+
+ put_bits(&s->pb, 1, 0); /* not PB frame */
+
+ put_bits(&s->pb, 5, s->qscale);
+
+ if (s->pict_type == I_TYPE) {
+ /* specific MPEG like DC coding not used */
+ }
+ /* if multiple packets per frame are sent, the position at which
+ to display the macro blocks is coded here */
+ put_bits(&s->pb, 6, 0); /* mb_x */
+ put_bits(&s->pb, 6, 0); /* mb_y */
+ put_bits(&s->pb, 12, s->mb_width * s->mb_height);
+
+ put_bits(&s->pb, 3, 0); /* ignored */
+}
+
+static int get_num(GetBitContext *gb)
+{
+ int n, n1;
+
+ n = get_bits(gb, 16);
+ if (n >= 0x4000) {
+ return n - 0x4000;
+ } else {
+ n1 = get_bits(gb, 16);
+ return (n << 16) | n1;
+ }
+}
+
+/* read RV 1.0 compatible frame header */
+static int rv10_decode_picture_header(MpegEncContext *s)
+{
+ int mb_count, pb_frame, marker, h, full_frame;
+
+ /* skip packet header */
+ h = get_bits(&s->gb, 8);
+ if ((h & 0xc0) == 0xc0) {
+ int len, pos;
+ full_frame = 1;
+ len = get_num(&s->gb);
+ pos = get_num(&s->gb);
+ } else {
+ int seq, frame_size, pos;
+ full_frame = 0;
+ seq = get_bits(&s->gb, 8);
+ frame_size = get_num(&s->gb);
+ pos = get_num(&s->gb);
+ }
+ /* picture number */
+ get_bits(&s->gb, 8);
+
+ marker = get_bits(&s->gb, 1);
+
+ if (get_bits(&s->gb, 1))
+ s->pict_type = P_TYPE;
+ else
+ s->pict_type = I_TYPE;
+
+ pb_frame = get_bits(&s->gb, 1);
+
+#ifdef DEBUG
+ printf("pict_type=%d pb_frame=%d\n", s->pict_type, pb_frame);
+#endif
+
+ if (pb_frame)
+ return -1;
+
+ s->qscale = get_bits(&s->gb, 5);
+
+ if (s->pict_type == I_TYPE) {
+ if (s->rv10_version == 3) {
+ /* specific MPEG like DC coding not used */
+ s->last_dc[0] = get_bits(&s->gb, 8);
+ s->last_dc[1] = get_bits(&s->gb, 8);
+ s->last_dc[2] = get_bits(&s->gb, 8);
+#ifdef DEBUG
+ printf("DC:%d %d %d\n",
+ s->last_dc[0],
+ s->last_dc[1],
+ s->last_dc[2]);
+#endif
+ }
+ }
+ /* if multiple packets per frame are sent, the position at which
+ to display the macro blocks is coded here */
+ if (!full_frame) {
+ s->mb_x = get_bits(&s->gb, 6); /* mb_x */
+ s->mb_y = get_bits(&s->gb, 6); /* mb_y */
+ mb_count = get_bits(&s->gb, 12);
+ } else {
+ s->mb_x = 0;
+ s->mb_y = 0;
+ mb_count = s->mb_width * s->mb_height;
+ }
+
+ get_bits(&s->gb, 3); /* ignored */
+ s->f_code = 1;
+ s->unrestricted_mv = 1;
+#if 0
+ s->h263_long_vectors = 1;
+#endif
+ return mb_count;
+}
+
+static int rv10_decode_init(AVCodecContext *avctx)
+{
+ MpegEncContext *s = avctx->priv_data;
+ static int done;
+
+ s->out_format = FMT_H263;
+
+ s->width = avctx->width;
+ s->height = avctx->height;
+
+ s->h263_rv10 = 1;
+ s->rv10_version = avctx->sub_id;
+
+ if (MPV_common_init(s) < 0)
+ return -1;
+
+ h263_decode_init_vlc(s);
+
+ /* init rv vlc */
+ if (!done) {
+ init_vlc(&rv_dc_lum, 9, 256,
+ rv_lum_bits, 1, 1,
+ rv_lum_code, 2, 2);
+ init_vlc(&rv_dc_chrom, 9, 256,
+ rv_chrom_bits, 1, 1,
+ rv_chrom_code, 2, 2);
+ done = 1;
+ }
+
+ return 0;
+}
+
+static int rv10_decode_end(AVCodecContext *avctx)
+{
+ MpegEncContext *s = avctx->priv_data;
+
+ MPV_common_end(s);
+ return 0;
+}
+
+static int rv10_decode_frame(AVCodecContext *avctx,
+ void *data, int *data_size,
+ UINT8 *buf, int buf_size)
+{
+ MpegEncContext *s = avctx->priv_data;
+ int i, mb_count, mb_pos, left;
+ DCTELEM block[6][64];
+ AVPicture *pict = data;
+
+#ifdef DEBUG
+ printf("*****frame %d size=%d\n", avctx->frame_number, buf_size);
+#endif
+
+ /* no supplementary picture */
+ if (buf_size == 0) {
+ *data_size = 0;
+ return 0;
+ }
+
+ init_get_bits(&s->gb, buf, buf_size);
+
+ mb_count = rv10_decode_picture_header(s);
+ if (mb_count < 0) {
+#ifdef DEBUG
+ printf("HEADER ERROR\n");
+#endif
+ return -1;
+ }
+
+ if (s->mb_x >= s->mb_width ||
+ s->mb_y >= s->mb_height) {
+#ifdef DEBUG
+ printf("POS ERROR %d %d\n", s->mb_x, s->mb_y);
+#endif
+ return -1;
+ }
+ mb_pos = s->mb_y * s->mb_width + s->mb_x;
+ left = s->mb_width * s->mb_height - mb_pos;
+ if (mb_count > left) {
+#ifdef DEBUG
+ printf("COUNT ERROR\n");
+#endif
+ return -1;
+ }
+
+ if (s->mb_x == 0 && s->mb_y == 0) {
+ MPV_frame_start(s);
+ }
+
+#ifdef DEBUG
+ printf("qscale=%d\n", s->qscale);
+#endif
+
+ /* default quantization values */
+ s->y_dc_scale = 8;
+ s->c_dc_scale = 8;
+ s->rv10_first_dc_coded[0] = 0;
+ s->rv10_first_dc_coded[1] = 0;
+ s->rv10_first_dc_coded[2] = 0;
+
+ /* decode each macroblock */
+ for(i=0;i<mb_count;i++) {
+#ifdef DEBUG
+ printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y);
+#endif
+
+ memset(block, 0, sizeof(block));
+ s->mv_dir = MV_DIR_FORWARD;
+ s->mv_type = MV_TYPE_16X16;
+ if (h263_decode_mb(s, block) < 0) {
+#ifdef DEBUG
+ printf("ERROR\n");
+#endif
+ return -1;
+ }
+ MPV_decode_mb(s, block);
+ if (++s->mb_x == s->mb_width) {
+ s->mb_x = 0;
+ s->mb_y++;
+ }
+ }
+
+ if (s->mb_x == 0 &&
+ s->mb_y == s->mb_height) {
+ MPV_frame_end(s);
+
+ pict->data[0] = s->current_picture[0];
+ pict->data[1] = s->current_picture[1];
+ pict->data[2] = s->current_picture[2];
+ pict->linesize[0] = s->linesize;
+ pict->linesize[1] = s->linesize / 2;
+ pict->linesize[2] = s->linesize / 2;
+
+ avctx->quality = s->qscale;
+ *data_size = sizeof(AVPicture);
+ } else {
+ *data_size = 0;
+ }
+ return buf_size;
+}
+
+AVCodec rv10_decoder = {
+ "rv10",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_RV10,
+ sizeof(MpegEncContext),
+ rv10_decode_init,
+ NULL,
+ rv10_decode_end,
+ rv10_decode_frame,
+};
diff --git a/src/libffmpeg/libavcodec/sad_mmx.s b/src/libffmpeg/libavcodec/sad_mmx.s
new file mode 100644
index 000000000..42c7ade59
--- /dev/null
+++ b/src/libffmpeg/libavcodec/sad_mmx.s
@@ -0,0 +1,799 @@
+# MMX/SSE optimized routines for SAD of 16*16 macroblocks
+# Copyright (C) Juan J. Sierralta P. <juanjo@atmlab.utfsm.cl>
+#
+# dist1_* Original Copyright (C) 2000 Chris Atenasio <chris@crud.net>
+# Enhancements and rest Copyright (C) 2000 Andrew Stevens <as@comlab.ox.ac.uk>
+
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+.global pix_abs16x16_mmx
+
+# int pix_abs16x16_mmx(unsigned char *pix1,unsigned char *pix2, int lx, int h);
+# esi = p1 (init: blk1)
+# edi = p2 (init: blk2)
+# ecx = rowsleft (init: h)
+# edx = lx;
+
+# mm0 = distance accumulators (4 words)
+# mm1 = distance accumulators (4 words)
+# mm2 = temp
+# mm3 = temp
+# mm4 = temp
+# mm5 = temp
+# mm6 = 0
+# mm7 = temp
+
+
+.align 32
+pix_abs16x16_mmx:
+ pushl %ebp # save frame pointer
+ movl %esp,%ebp
+
+ pushl %ebx # Saves registers (called saves convention in
+ pushl %ecx # x86 GCC it seems)
+ pushl %edx #
+ pushl %esi
+ pushl %edi
+
+ pxor %mm0,%mm0 # zero acculumators
+ pxor %mm1,%mm1
+ pxor %mm6,%mm6
+ movl 8(%ebp),%esi # get pix1
+ movl 12(%ebp),%edi # get pix2
+ movl 16(%ebp),%edx # get lx
+ movl 20(%ebp),%ecx # get rowsleft
+ jmp pix_abs16x16_mmx.nextrow
+.align 32
+
+pix_abs16x16_mmx.nextrow:
+ # First 8 bytes of the row
+
+ movq (%edi),%mm4 # load first 8 bytes of pix2 row
+ movq (%esi),%mm5 # load first 8 bytes of pix1 row
+ movq %mm4,%mm3 # mm4 := abs(mm4-mm5)
+ movq 8(%esi),%mm2 # load last 8 bytes of pix1 row
+ psubusb %mm5,%mm4
+ movq 8(%edi),%mm7 # load last 8 bytes of pix2 row
+ psubusb %mm3,%mm5
+ por %mm5,%mm4
+
+ # Last 8 bytes of the row
+
+ movq %mm7,%mm3 # mm7 := abs(mm7-mm2)
+ psubusb %mm2,%mm7
+ psubusb %mm3,%mm2
+ por %mm2,%mm7
+
+ # Now mm4 and mm7 have 16 absdiffs to add
+
+ # First 8 bytes of the row2
+
+
+ addl %edx,%edi
+ movq (%edi),%mm2 # load first 8 bytes of pix2 row
+ addl %edx,%esi
+ movq (%esi),%mm5 # load first 8 bytes of pix1 row
+
+
+
+ movq %mm2,%mm3 # mm2 := abs(mm2-mm5)
+ psubusb %mm5,%mm2
+ movq 8(%esi),%mm6 # load last 8 bytes of pix1 row
+ psubusb %mm3,%mm5
+ por %mm5,%mm2
+
+ # Last 8 bytes of the row2
+
+ movq 8(%edi),%mm5 # load last 8 bytes of pix2 row
+
+
+ movq %mm5,%mm3 # mm5 := abs(mm5-mm6)
+ psubusb %mm6,%mm5
+ psubusb %mm3,%mm6
+ por %mm6,%mm5
+
+ # Now mm2, mm4, mm5, mm7 have 32 absdiffs
+
+ movq %mm7,%mm3
+
+ pxor %mm6,%mm6 # Zero mm6
+
+ punpcklbw %mm6,%mm3 # Unpack to words and add
+ punpckhbw %mm6,%mm7
+ paddusw %mm3,%mm7
+
+ movq %mm5,%mm3
+
+ punpcklbw %mm6,%mm3 # Unpack to words and add
+ punpckhbw %mm6,%mm5
+ paddusw %mm3,%mm5
+
+ paddusw %mm7,%mm0 # Add to the acumulator (mm0)
+ paddusw %mm5,%mm1 # Add to the acumulator (mm1)
+
+ movq %mm4,%mm3
+
+ punpcklbw %mm6,%mm3 # Unpack to words and add
+ punpckhbw %mm6,%mm4
+ movq %mm2,%mm5
+ paddusw %mm3,%mm4
+
+
+
+ punpcklbw %mm6,%mm5 # Unpack to words and add
+ punpckhbw %mm6,%mm2
+ paddusw %mm5,%mm2
+
+ # Loop termination
+
+ addl %edx,%esi # update pointers to next row
+ paddusw %mm4,%mm0 # Add to the acumulator (mm0)
+ addl %edx,%edi
+ subl $2,%ecx
+ paddusw %mm2,%mm1 # Add to the acumulator (mm1)
+ testl %ecx,%ecx # check rowsleft
+ jnz pix_abs16x16_mmx.nextrow
+
+ paddusw %mm1,%mm0
+ movq %mm0,%mm2 # Copy mm0 to mm2
+ psrlq $32,%mm2
+ paddusw %mm2,%mm0 # Add
+ movq %mm0,%mm3
+ psrlq $16,%mm3
+ paddusw %mm3,%mm0
+ movd %mm0,%eax # Store return value
+ andl $0xffff,%eax
+
+ popl %edi
+ popl %esi
+ popl %edx
+ popl %ecx
+ popl %ebx
+
+ popl %ebp # restore stack pointer
+
+ #emms ; clear mmx registers
+ ret # return
+
+.global pix_abs16x16_sse
+
+# int pix_abs16x16_mmx(unsigned char *pix1,unsigned char *pix2, int lx, int h);
+# esi = p1 (init: blk1)
+# edi = p2 (init: blk2)
+# ecx = rowsleft (init: h)
+# edx = lx;
+
+# mm0 = distance accumulators (4 words)
+# mm1 = distance accumulators (4 words)
+# mm2 = temp
+# mm3 = temp
+# mm4 = temp
+# mm5 = temp
+# mm6 = temp
+# mm7 = temp
+
+
+.align 32
+pix_abs16x16_sse:
+ pushl %ebp # save frame pointer
+ movl %esp,%ebp
+
+ pushl %ebx # Saves registers (called saves convention in
+ pushl %ecx # x86 GCC it seems)
+ pushl %edx #
+ pushl %esi
+ pushl %edi
+
+ pxor %mm0,%mm0 # zero acculumators
+ pxor %mm1,%mm1
+ movl 8(%ebp),%esi # get pix1
+ movl 12(%ebp),%edi # get pix2
+ movl 16(%ebp),%edx # get lx
+ movl 20(%ebp),%ecx # get rowsleft
+ jmp pix_abs16x16_sse.next4row
+.align 32
+
+pix_abs16x16_sse.next4row:
+ # First row
+
+ movq (%edi),%mm4 # load first 8 bytes of pix2 row
+ movq 8(%edi),%mm5 # load last 8 bytes of pix2 row
+ psadbw (%esi),%mm4 # SAD of first 8 bytes
+ psadbw 8(%esi),%mm5 # SAD of last 8 bytes
+ paddw %mm4,%mm0 # Add to acumulators
+ paddw %mm5,%mm1
+
+ # Second row
+
+ addl %edx,%edi #
+ addl %edx,%esi #
+
+ movq (%edi),%mm6 # load first 8 bytes of pix2 row
+ movq 8(%edi),%mm7 # load last 8 bytes of pix2 row
+ psadbw (%esi),%mm6 # SAD of first 8 bytes
+ psadbw 8(%esi),%mm7 # SAD of last 8 bytes
+ paddw %mm6,%mm0 # Add to acumulators
+ paddw %mm7,%mm1
+
+ # Third row
+
+ addl %edx,%edi #
+ addl %edx,%esi #
+
+ movq (%edi),%mm4 # load first 8 bytes of pix2 row
+ movq 8(%edi),%mm5 # load last 8 bytes of pix2 row
+ psadbw (%esi),%mm4 # SAD of first 8 bytes
+ psadbw 8(%esi),%mm5 # SAD of last 8 bytes
+ paddw %mm4,%mm0 # Add to acumulators
+ paddw %mm5,%mm1
+
+ # Fourth row
+
+ addl %edx,%edi #
+ addl %edx,%esi #
+
+ movq (%edi),%mm6 # load first 8 bytes of pix2 row
+ movq 8(%edi),%mm7 # load last 8 bytes of pix2 row
+ psadbw (%esi),%mm6 # SAD of first 8 bytes
+ psadbw 8(%esi),%mm7 # SAD of last 8 bytes
+ paddw %mm6,%mm0 # Add to acumulators
+ paddw %mm7,%mm1
+
+ # Loop termination
+
+ addl %edx,%esi # update pointers to next row
+ addl %edx,%edi
+ subl $4,%ecx
+ testl %ecx,%ecx # check rowsleft
+ jnz pix_abs16x16_sse.next4row
+
+ paddd %mm1,%mm0 # Sum acumulators
+ movd %mm0,%eax # Store return value
+
+ popl %edi
+ popl %esi
+ popl %edx
+ popl %ecx
+ popl %ebx
+
+ popl %ebp # restore stack pointer
+
+ #emms ; clear mmx registers
+ ret # return
+
+.global pix_abs16x16_x2_mmx
+
+# int pix_abs16x16_x2_mmx(unsigned char *pix1,unsigned char *pix2, int lx, int h);
+# esi = p1 (init: blk1)
+# edi = p2 (init: blk2)
+# ecx = rowsleft (init: h)
+# edx = lx;
+
+# mm0 = distance accumulators (4 words)
+# mm1 = distance accumulators (4 words)
+# mm2 = temp
+# mm3 = temp
+# mm4 = temp
+# mm5 = temp
+# mm6 = 0
+# mm7 = temp
+
+
+.align 32
+pix_abs16x16_x2_mmx:
+ pushl %ebp # save frame pointer
+ movl %esp,%ebp
+
+ pushl %ebx # Saves registers (called saves convention in
+ pushl %ecx # x86 GCC it seems)
+ pushl %edx #
+ pushl %esi
+ pushl %edi
+
+ pxor %mm0,%mm0 # zero acculumators
+ pxor %mm1,%mm1
+ pxor %mm6,%mm6
+ movl 8(%ebp),%esi # get pix1
+ movl 12(%ebp),%edi # get pix2
+ movl 16(%ebp),%edx # get lx
+ movl 20(%ebp),%ecx # get rowsleft
+ jmp pix_abs16x16_x2_mmx.nextrow_x2
+.align 32
+
+pix_abs16x16_x2_mmx.nextrow_x2:
+ # First 8 bytes of the row
+
+ movq (%edi),%mm4 # load first 8 bytes of pix2 row
+ movq 1(%edi),%mm5 # load bytes 1-8 of pix2 row
+
+ movq %mm4,%mm2 # copy mm4 on mm2
+ movq %mm5,%mm3 # copy mm5 on mm3
+ punpcklbw %mm6,%mm4 # first 4 bytes of [edi] on mm4
+ punpcklbw %mm6,%mm5 # first 4 bytes of [edi+1] on mm5
+ paddusw %mm5,%mm4 # mm4 := first 4 bytes interpolated in words
+ psrlw $1,%mm4
+
+ punpckhbw %mm6,%mm2 # last 4 bytes of [edi] on mm2
+ punpckhbw %mm6,%mm3 # last 4 bytes of [edi+1] on mm3
+ paddusw %mm3,%mm2 # mm2 := last 4 bytes interpolated in words
+ psrlw $1,%mm2
+
+ packuswb %mm2,%mm4 # pack 8 bytes interpolated on mm4
+ movq (%esi),%mm5 # load first 8 bytes of pix1 row
+
+ movq %mm4,%mm3 # mm4 := abs(mm4-mm5)
+ psubusb %mm5,%mm4
+ psubusb %mm3,%mm5
+ por %mm5,%mm4
+
+ # Last 8 bytes of the row
+
+ movq 8(%edi),%mm7 # load last 8 bytes of pix2 row
+ movq 9(%edi),%mm5 # load bytes 10-17 of pix2 row
+
+ movq %mm7,%mm2 # copy mm7 on mm2
+ movq %mm5,%mm3 # copy mm5 on mm3
+ punpcklbw %mm6,%mm7 # first 4 bytes of [edi+8] on mm7
+ punpcklbw %mm6,%mm5 # first 4 bytes of [edi+9] on mm5
+ paddusw %mm5,%mm7 # mm1 := first 4 bytes interpolated in words
+ psrlw $1,%mm7
+
+ punpckhbw %mm6,%mm2 # last 4 bytes of [edi] on mm2
+ punpckhbw %mm6,%mm3 # last 4 bytes of [edi+1] on mm3
+ paddusw %mm3,%mm2 # mm2 := last 4 bytes interpolated in words
+ psrlw $1,%mm2
+
+ packuswb %mm2,%mm7 # pack 8 bytes interpolated on mm1
+ movq 8(%esi),%mm5 # load last 8 bytes of pix1 row
+
+ movq %mm7,%mm3 # mm7 := abs(mm1-mm5)
+ psubusb %mm5,%mm7
+ psubusb %mm3,%mm5
+ por %mm5,%mm7
+
+ # Now mm4 and mm7 have 16 absdiffs to add
+
+ movq %mm4,%mm3 # Make copies of these bytes
+ movq %mm7,%mm2
+
+ punpcklbw %mm6,%mm4 # Unpack to words and add
+ punpcklbw %mm6,%mm7
+ paddusw %mm7,%mm4
+ paddusw %mm4,%mm0 # Add to the acumulator (mm0)
+
+ punpckhbw %mm6,%mm3 # Unpack to words and add
+ punpckhbw %mm6,%mm2
+ paddusw %mm2,%mm3
+ paddusw %mm3,%mm1 # Add to the acumulator (mm1)
+
+ # Loop termination
+
+ addl %edx,%esi # update pointers to next row
+ addl %edx,%edi
+
+ subl $1,%ecx
+ testl %ecx,%ecx # check rowsleft
+ jnz pix_abs16x16_x2_mmx.nextrow_x2
+
+ paddusw %mm1,%mm0
+
+ movq %mm0,%mm1 # Copy mm0 to mm1
+ psrlq $32,%mm1
+ paddusw %mm1,%mm0 # Add
+ movq %mm0,%mm2
+ psrlq $16,%mm2
+ paddusw %mm2,%mm0
+ movd %mm0,%eax # Store return value
+ andl $0xffff,%eax
+
+ popl %edi
+ popl %esi
+ popl %edx
+ popl %ecx
+ popl %ebx
+
+ popl %ebp # restore stack pointer
+
+ emms # clear mmx registers
+ ret # return
+
+.global pix_abs16x16_y2_mmx
+
+# int pix_abs16x16_y2_mmx(unsigned char *pix1,unsigned char *pix2, int lx, int h);
+# esi = p1 (init: blk1)
+# edi = p2 (init: blk2)
+# ebx = p2 + lx
+# ecx = rowsleft (init: h)
+# edx = lx;
+
+# mm0 = distance accumulators (4 words)
+# mm1 = distance accumulators (4 words)
+# mm2 = temp
+# mm3 = temp
+# mm4 = temp
+# mm5 = temp
+# mm6 = 0
+# mm7 = temp
+
+
+.align 32
+pix_abs16x16_y2_mmx:
+ pushl %ebp # save frame pointer
+ movl %esp,%ebp
+
+ pushl %ebx # Saves registers (called saves convention in
+ pushl %ecx # x86 GCC it seems)
+ pushl %edx #
+ pushl %esi
+ pushl %edi
+
+ pxor %mm0,%mm0 # zero acculumators
+ pxor %mm1,%mm1
+ pxor %mm6,%mm6
+ movl 8(%ebp),%esi # get pix1
+ movl 12(%ebp),%edi # get pix2
+ movl 16(%ebp),%edx # get lx
+ movl 20(%ebp),%ecx # get rowsleft
+ movl %edi,%ebx
+ addl %edx,%ebx
+ jmp pix_abs16x16_y2_mmx.nextrow_y2
+.align 32
+
+pix_abs16x16_y2_mmx.nextrow_y2:
+ # First 8 bytes of the row
+
+ movq (%edi),%mm4 # load first 8 bytes of pix2 row
+ movq (%ebx),%mm5 # load bytes 1-8 of pix2 row
+
+ movq %mm4,%mm2 # copy mm4 on mm2
+ movq %mm5,%mm3 # copy mm5 on mm3
+ punpcklbw %mm6,%mm4 # first 4 bytes of [edi] on mm4
+ punpcklbw %mm6,%mm5 # first 4 bytes of [ebx] on mm5
+ paddusw %mm5,%mm4 # mm4 := first 4 bytes interpolated in words
+ psrlw $1,%mm4
+
+ punpckhbw %mm6,%mm2 # last 4 bytes of [edi] on mm2
+ punpckhbw %mm6,%mm3 # last 4 bytes of [edi+1] on mm3
+ paddusw %mm3,%mm2 # mm2 := last 4 bytes interpolated in words
+ psrlw $1,%mm2
+
+ packuswb %mm2,%mm4 # pack 8 bytes interpolated on mm4
+ movq (%esi),%mm5 # load first 8 bytes of pix1 row
+
+ movq %mm4,%mm3 # mm4 := abs(mm4-mm5)
+ psubusb %mm5,%mm4
+ psubusb %mm3,%mm5
+ por %mm5,%mm4
+
+ # Last 8 bytes of the row
+
+ movq 8(%edi),%mm7 # load last 8 bytes of pix2 row
+ movq 8(%ebx),%mm5 # load bytes 10-17 of pix2 row
+
+ movq %mm7,%mm2 # copy mm7 on mm2
+ movq %mm5,%mm3 # copy mm5 on mm3
+ punpcklbw %mm6,%mm7 # first 4 bytes of [edi+8] on mm7
+ punpcklbw %mm6,%mm5 # first 4 bytes of [ebx+8] on mm5
+ paddusw %mm5,%mm7 # mm1 := first 4 bytes interpolated in words
+ psrlw $1,%mm7
+
+ punpckhbw %mm6,%mm2 # last 4 bytes of [edi+8] on mm2
+ punpckhbw %mm6,%mm3 # last 4 bytes of [ebx+8] on mm3
+ paddusw %mm3,%mm2 # mm2 := last 4 bytes interpolated in words
+ psrlw $1,%mm2
+
+ packuswb %mm2,%mm7 # pack 8 bytes interpolated on mm1
+ movq 8(%esi),%mm5 # load last 8 bytes of pix1 row
+
+ movq %mm7,%mm3 # mm7 := abs(mm1-mm5)
+ psubusb %mm5,%mm7
+ psubusb %mm3,%mm5
+ por %mm5,%mm7
+
+ # Now mm4 and mm7 have 16 absdiffs to add
+
+ movq %mm4,%mm3 # Make copies of these bytes
+ movq %mm7,%mm2
+
+ punpcklbw %mm6,%mm4 # Unpack to words and add
+ punpcklbw %mm6,%mm7
+ paddusw %mm7,%mm4
+ paddusw %mm4,%mm0 # Add to the acumulator (mm0)
+
+ punpckhbw %mm6,%mm3 # Unpack to words and add
+ punpckhbw %mm6,%mm2
+ paddusw %mm2,%mm3
+ paddusw %mm3,%mm1 # Add to the acumulator (mm1)
+
+ # Loop termination
+
+ addl %edx,%esi # update pointers to next row
+ addl %edx,%edi
+ addl %edx,%ebx
+ subl $1,%ecx
+ testl %ecx,%ecx # check rowsleft
+ jnz pix_abs16x16_y2_mmx.nextrow_y2
+
+ paddusw %mm1,%mm0
+
+ movq %mm0,%mm1 # Copy mm0 to mm1
+ psrlq $32,%mm1
+ paddusw %mm1,%mm0 # Add
+ movq %mm0,%mm2
+ psrlq $16,%mm2
+ paddusw %mm2,%mm0
+ movd %mm0,%eax # Store return value
+ andl $0xffff,%eax
+
+ popl %edi
+ popl %esi
+ popl %edx
+ popl %ecx
+ popl %ebx
+
+ popl %ebp # restore stack pointer
+
+ emms # clear mmx registers
+ ret # return
+
+.global pix_abs16x16_xy2_mmx
+
+# int pix_abs16x16_xy2_mmx(unsigned char *p1,unsigned char *p2,int lx,int h);
+
+# esi = p1 (init: blk1)
+# edi = p2 (init: blk2)
+# ebx = p1+lx
+# ecx = rowsleft (init: h)
+# edx = lx;
+
+# mm0 = distance accumulators (4 words)
+# mm1 = bytes p2
+# mm2 = bytes p1
+# mm3 = bytes p1+lx
+# I'd love to find someplace to stash p1+1 and p1+lx+1's bytes
+# but I don't think thats going to happen in iA32-land...
+# mm4 = temp 4 bytes in words interpolating p1, p1+1
+# mm5 = temp 4 bytes in words from p2
+# mm6 = temp comparison bit mask p1,p2
+# mm7 = temp comparison bit mask p2,p1
+
+
+.align 32
+pix_abs16x16_xy2_mmx:
+ pushl %ebp # save stack pointer
+ movl %esp,%ebp # so that we can do this
+
+ pushl %ebx # Saves registers (called saves convention in
+ pushl %ecx # x86 GCC it seems)
+ pushl %edx #
+ pushl %esi
+ pushl %edi
+
+ pxor %mm0,%mm0 # zero acculumators
+
+ movl 12(%ebp),%esi # get p1
+ movl 8(%ebp),%edi # get p2
+ movl 16(%ebp),%edx # get lx
+ movl 20(%ebp),%ecx # rowsleft := h
+ movl %esi,%ebx
+ addl %edx,%ebx
+ jmp pix_abs16x16_xy2_mmx.nextrowmm11 # snap to it
+.align 32
+pix_abs16x16_xy2_mmx.nextrowmm11:
+
+ ##
+ ## First 8 bytes of row
+ ##
+
+ ## First 4 bytes of 8
+
+ movq (%esi),%mm4 # mm4 := first 4 bytes p1
+ pxor %mm7,%mm7
+ movq %mm4,%mm2 # mm2 records all 8 bytes
+ punpcklbw %mm7,%mm4 # First 4 bytes p1 in Words...
+
+ movq (%ebx),%mm6 # mm6 := first 4 bytes p1+lx
+ movq %mm6,%mm3 # mm3 records all 8 bytes
+ punpcklbw %mm7,%mm6
+ paddw %mm6,%mm4
+
+
+ movq 1(%esi),%mm5 # mm5 := first 4 bytes p1+1
+ punpcklbw %mm7,%mm5 # First 4 bytes p1 in Words...
+ paddw %mm5,%mm4
+ movq 1(%ebx),%mm6 # mm6 := first 4 bytes p1+lx+1
+ punpcklbw %mm7,%mm6
+ paddw %mm6,%mm4
+
+ psrlw $2,%mm4 # mm4 := First 4 bytes interpolated in words
+
+ movq (%edi),%mm5 # mm5:=first 4 bytes of p2 in words
+ movq %mm5,%mm1
+ punpcklbw %mm7,%mm5
+
+ movq %mm4,%mm7
+ pcmpgtw %mm5,%mm7 # mm7 := [i : W0..3,mm4>mm5]
+
+ movq %mm4,%mm6 # mm6 := [i : W0..3, (mm4-mm5)*(mm4-mm5 > 0)]
+ psubw %mm5,%mm6
+ pand %mm7,%mm6
+
+ paddw %mm6,%mm0 # Add to accumulator
+
+ movq %mm5,%mm6 # mm6 := [i : W0..3,mm5>mm4]
+ pcmpgtw %mm4,%mm6
+ psubw %mm4,%mm5 # mm5 := [i : B0..7, (mm5-mm4)*(mm5-mm4 > 0)]
+ pand %mm6,%mm5
+
+ paddw %mm5,%mm0 # Add to accumulator
+
+ ## Second 4 bytes of 8
+
+ movq %mm2,%mm4 # mm4 := Second 4 bytes p1 in words
+ pxor %mm7,%mm7
+ punpckhbw %mm7,%mm4
+ movq %mm3,%mm6 # mm6 := Second 4 bytes p1+1 in words
+ punpckhbw %mm7,%mm6
+ paddw %mm6,%mm4
+
+ movq 1(%esi),%mm5 # mm5 := first 4 bytes p1+1
+ punpckhbw %mm7,%mm5 # First 4 bytes p1 in Words...
+ paddw %mm5,%mm4
+ movq 1(%ebx),%mm6 # mm6 := first 4 bytes p1+lx+1
+ punpckhbw %mm7,%mm6
+ paddw %mm6,%mm4
+
+ psrlw $2,%mm4 # mm4 := First 4 bytes interpolated in words
+
+ movq %mm1,%mm5 # mm5:= second 4 bytes of p2 in words
+ punpckhbw %mm7,%mm5
+
+ movq %mm4,%mm7
+ pcmpgtw %mm5,%mm7 # mm7 := [i : W0..3,mm4>mm5]
+
+ movq %mm4,%mm6 # mm6 := [i : W0..3, (mm4-mm5)*(mm4-mm5 > 0)]
+ psubw %mm5,%mm6
+ pand %mm7,%mm6
+
+ paddw %mm6,%mm0 # Add to accumulator
+
+ movq %mm5,%mm6 # mm6 := [i : W0..3,mm5>mm4]
+ pcmpgtw %mm4,%mm6
+ psubw %mm4,%mm5 # mm5 := [i : B0..7, (mm5-mm4)*(mm5-mm4 > 0)]
+ pand %mm6,%mm5
+
+ paddw %mm5,%mm0 # Add to accumulator
+
+
+ ##
+ ## Second 8 bytes of row
+ ##
+ ## First 4 bytes of 8
+
+ movq 8(%esi),%mm4 # mm4 := first 4 bytes p1+8
+ pxor %mm7,%mm7
+ movq %mm4,%mm2 # mm2 records all 8 bytes
+ punpcklbw %mm7,%mm4 # First 4 bytes p1 in Words...
+
+ movq 8(%ebx),%mm6 # mm6 := first 4 bytes p1+lx+8
+ movq %mm6,%mm3 # mm3 records all 8 bytes
+ punpcklbw %mm7,%mm6
+ paddw %mm6,%mm4
+
+
+ movq 9(%esi),%mm5 # mm5 := first 4 bytes p1+9
+ punpcklbw %mm7,%mm5 # First 4 bytes p1 in Words...
+ paddw %mm5,%mm4
+ movq 9(%ebx),%mm6 # mm6 := first 4 bytes p1+lx+9
+ punpcklbw %mm7,%mm6
+ paddw %mm6,%mm4
+
+ psrlw $2,%mm4 # mm4 := First 4 bytes interpolated in words
+
+ movq 8(%edi),%mm5 # mm5:=first 4 bytes of p2+8 in words
+ movq %mm5,%mm1
+ punpcklbw %mm7,%mm5
+
+ movq %mm4,%mm7
+ pcmpgtw %mm5,%mm7 # mm7 := [i : W0..3,mm4>mm5]
+
+ movq %mm4,%mm6 # mm6 := [i : W0..3, (mm4-mm5)*(mm4-mm5 > 0)]
+ psubw %mm5,%mm6
+ pand %mm7,%mm6
+
+ paddw %mm6,%mm0 # Add to accumulator
+
+ movq %mm5,%mm6 # mm6 := [i : W0..3,mm5>mm4]
+ pcmpgtw %mm4,%mm6
+ psubw %mm4,%mm5 # mm5 := [i : B0..7, (mm5-mm4)*(mm5-mm4 > 0)]
+ pand %mm6,%mm5
+
+ paddw %mm5,%mm0 # Add to accumulator
+
+ ## Second 4 bytes of 8
+
+ movq %mm2,%mm4 # mm4 := Second 4 bytes p1 in words
+ pxor %mm7,%mm7
+ punpckhbw %mm7,%mm4
+ movq %mm3,%mm6 # mm6 := Second 4 bytes p1+1 in words
+ punpckhbw %mm7,%mm6
+ paddw %mm6,%mm4
+
+ movq 9(%esi),%mm5 # mm5 := first 4 bytes p1+1
+ punpckhbw %mm7,%mm5 # First 4 bytes p1 in Words...
+ paddw %mm5,%mm4
+ movq 9(%ebx),%mm6 # mm6 := first 4 bytes p1+lx+1
+ punpckhbw %mm7,%mm6
+ paddw %mm6,%mm4
+
+ psrlw $2,%mm4 # mm4 := First 4 bytes interpolated in words
+
+ movq %mm1,%mm5 # mm5:= second 4 bytes of p2 in words
+ punpckhbw %mm7,%mm5
+
+ movq %mm4,%mm7
+ pcmpgtw %mm5,%mm7 # mm7 := [i : W0..3,mm4>mm5]
+
+ movq %mm4,%mm6 # mm6 := [i : W0..3, (mm4-mm5)*(mm4-mm5 > 0)]
+ psubw %mm5,%mm6
+ pand %mm7,%mm6
+
+ paddw %mm6,%mm0 # Add to accumulator
+
+ movq %mm5,%mm6 # mm6 := [i : W0..3,mm5>mm4]
+ pcmpgtw %mm4,%mm6
+ psubw %mm4,%mm5 # mm5 := [i : B0..7, (mm5-mm4)*(mm5-mm4 > 0)]
+ pand %mm6,%mm5
+
+ paddw %mm5,%mm0 # Add to accumulator
+
+
+ ##
+ ## Loop termination condition... and stepping
+ ##
+
+ addl %edx,%esi # update pointer to next row
+ addl %edx,%edi # ditto
+ addl %edx,%ebx
+
+ subl $1,%ecx
+ testl %ecx,%ecx # check rowsleft
+ jnz pix_abs16x16_xy2_mmx.nextrowmm11
+
+ ## Sum the Accumulators
+ movq %mm0,%mm4
+ psrlq $32,%mm4
+ paddw %mm4,%mm0
+ movq %mm0,%mm6
+ psrlq $16,%mm6
+ paddw %mm6,%mm0
+ movd %mm0,%eax # store return value
+ andl $0xffff,%eax
+
+ popl %edi
+ popl %esi
+ popl %edx
+ popl %ecx
+ popl %ebx
+
+ popl %ebp # restore stack pointer
+
+ emms # clear mmx registers
+ ret # we now return you to your regular programming
+
+
+
diff --git a/src/libffmpeg/libavcodec/utils.c b/src/libffmpeg/libavcodec/utils.c
new file mode 100644
index 000000000..958f6d32d
--- /dev/null
+++ b/src/libffmpeg/libavcodec/utils.c
@@ -0,0 +1,319 @@
+/*
+ * utils for libavcodec
+ * Copyright (c) 2001 Gerard Lantau.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "common.h"
+#include "dsputil.h"
+#include "avcodec.h"
+
+/* memory alloc */
+void *av_mallocz(int size)
+{
+ void *ptr;
+ ptr = malloc(size);
+ if (!ptr)
+ return NULL;
+ memset(ptr, 0, size);
+ return ptr;
+}
+
+/* encoder management */
+AVCodec *first_avcodec;
+
+void register_avcodec(AVCodec *format)
+{
+ AVCodec **p;
+ p = &first_avcodec;
+ while (*p != NULL) p = &(*p)->next;
+ *p = format;
+ format->next = NULL;
+}
+
+int avcodec_open(AVCodecContext *avctx, AVCodec *codec)
+{
+ int ret;
+
+ avctx->codec = codec;
+ avctx->frame_number = 0;
+ avctx->priv_data = av_mallocz(codec->priv_data_size);
+ if (!avctx->priv_data)
+ return -ENOMEM;
+ ret = avctx->codec->init(avctx);
+ if (ret < 0) {
+ free(avctx->priv_data);
+ avctx->priv_data = NULL;
+ return ret;
+ }
+ return 0;
+}
+
+int avcodec_encode_audio(AVCodecContext *avctx, UINT8 *buf, int buf_size,
+ const short *samples)
+{
+ int ret;
+
+ ret = avctx->codec->encode(avctx, buf, buf_size, (void *)samples);
+ avctx->frame_number++;
+ return ret;
+}
+
+int avcodec_encode_video(AVCodecContext *avctx, UINT8 *buf, int buf_size,
+ const AVPicture *pict)
+{
+ int ret;
+
+ ret = avctx->codec->encode(avctx, buf, buf_size, (void *)pict);
+ avctx->frame_number++;
+ return ret;
+}
+
+/* decode a frame. return -1 if error, otherwise return the number of
+ bytes used. If no frame could be decompressed, *got_picture_ptr is
+ zero. Otherwise, it is non zero */
+int avcodec_decode_video(AVCodecContext *avctx, AVPicture *picture,
+ int *got_picture_ptr,
+ UINT8 *buf, int buf_size)
+{
+ int ret;
+
+ ret = avctx->codec->decode(avctx, picture, got_picture_ptr,
+ buf, buf_size);
+ avctx->frame_number++;
+ return ret;
+}
+
+/* decode an audio frame. return -1 if error, otherwise return the
+ *number of bytes used. If no frame could be decompressed,
+ *frame_size_ptr is zero. Otherwise, it is the decompressed frame
+ *size in BYTES. */
+int avcodec_decode_audio(AVCodecContext *avctx, INT16 *samples,
+ int *frame_size_ptr,
+ UINT8 *buf, int buf_size)
+{
+ int ret;
+
+ ret = avctx->codec->decode(avctx, samples, frame_size_ptr,
+ buf, buf_size);
+ avctx->frame_number++;
+ return ret;
+}
+
+int avcodec_close(AVCodecContext *avctx)
+{
+ if (avctx->codec->close)
+ avctx->codec->close(avctx);
+ free(avctx->priv_data);
+ avctx->priv_data = NULL;
+ avctx->codec = NULL;
+ return 0;
+}
+
+AVCodec *avcodec_find_encoder(enum CodecID id)
+{
+ AVCodec *p;
+ p = first_avcodec;
+ while (p) {
+ if (p->encode != NULL && p->id == id)
+ return p;
+ p = p->next;
+ }
+ return NULL;
+}
+
+AVCodec *avcodec_find_decoder(enum CodecID id)
+{
+ AVCodec *p;
+ p = first_avcodec;
+ while (p) {
+ if (p->decode != NULL && p->id == id)
+ return p;
+ p = p->next;
+ }
+ return NULL;
+}
+
+AVCodec *avcodec_find_decoder_by_name(const char *name)
+{
+ AVCodec *p;
+ p = first_avcodec;
+ while (p) {
+ if (p->decode != NULL && strcmp(name,p->name) == 0)
+ return p;
+ p = p->next;
+ }
+ return NULL;
+}
+
+AVCodec *avcodec_find(enum CodecID id)
+{
+ AVCodec *p;
+ p = first_avcodec;
+ while (p) {
+ if (p->id == id)
+ return p;
+ p = p->next;
+ }
+ return NULL;
+}
+
+void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
+{
+ const char *codec_name;
+ AVCodec *p;
+ char buf1[32];
+
+ if (encode)
+ p = avcodec_find_encoder(enc->codec_id);
+ else
+ p = avcodec_find_decoder(enc->codec_id);
+
+ if (p) {
+ codec_name = p->name;
+ } else if (enc->codec_name[0] != '\0') {
+ codec_name = enc->codec_name;
+ } else {
+ /* output avi tags */
+ if (enc->codec_type == CODEC_TYPE_VIDEO) {
+ snprintf(buf1, sizeof(buf1), "%c%c%c%c",
+ enc->codec_tag & 0xff,
+ (enc->codec_tag >> 8) & 0xff,
+ (enc->codec_tag >> 16) & 0xff,
+ (enc->codec_tag >> 24) & 0xff);
+ } else {
+ snprintf(buf1, sizeof(buf1), "0x%04x", enc->codec_tag);
+ }
+ codec_name = buf1;
+ }
+
+ switch(enc->codec_type) {
+ case CODEC_TYPE_VIDEO:
+ snprintf(buf, buf_size,
+ "Video: %s%s",
+ codec_name, enc->flags & CODEC_FLAG_HQ ? " (hq)" : "");
+ if (enc->width) {
+ snprintf(buf + strlen(buf), buf_size - strlen(buf),
+ ", %dx%d, %0.2f fps",
+ enc->width, enc->height,
+ (float)enc->frame_rate / FRAME_RATE_BASE);
+ }
+ break;
+ case CODEC_TYPE_AUDIO:
+ snprintf(buf, buf_size,
+ "Audio: %s",
+ codec_name);
+ if (enc->sample_rate) {
+ snprintf(buf + strlen(buf), buf_size - strlen(buf),
+ ", %d Hz, %s",
+ enc->sample_rate,
+ enc->channels == 2 ? "stereo" : "mono");
+ }
+ break;
+ default:
+ abort();
+ }
+ if (enc->bit_rate != 0) {
+ snprintf(buf + strlen(buf), buf_size - strlen(buf),
+ ", %d kb/s", enc->bit_rate / 1000);
+ }
+}
+
+/* must be called before any other functions */
+void avcodec_init(void)
+{
+ dsputil_init();
+}
+
+/* simple call to use all the codecs */
+void avcodec_register_all(void)
+{
+ /* encoders */
+#ifdef CONFIG_ENCODERS
+ register_avcodec(&ac3_encoder);
+ register_avcodec(&mp2_encoder);
+ register_avcodec(&mpeg1video_encoder);
+ register_avcodec(&h263_encoder);
+ register_avcodec(&h263p_encoder);
+ register_avcodec(&rv10_encoder);
+ register_avcodec(&mjpeg_encoder);
+ register_avcodec(&opendivx_encoder);
+ register_avcodec(&msmpeg4_encoder);
+#endif /* CONFIG_ENCODERS */
+ register_avcodec(&pcm_codec);
+ register_avcodec(&rawvideo_codec);
+
+ /* decoders */
+#ifdef CONFIG_DECODERS
+ register_avcodec(&h263_decoder);
+ register_avcodec(&opendivx_decoder);
+ register_avcodec(&msmpeg4_decoder);
+ register_avcodec(&mpeg_decoder);
+ register_avcodec(&h263i_decoder);
+ register_avcodec(&rv10_decoder);
+ register_avcodec(&mjpeg_decoder);
+#ifdef CONFIG_MPGLIB
+ register_avcodec(&mp3_decoder);
+#endif
+#ifdef CONFIG_AC3
+ register_avcodec(&ac3_decoder);
+#endif
+#endif /* CONFIG_DECODERS */
+}
+
+static int encode_init(AVCodecContext *s)
+{
+ return 0;
+}
+
+static int decode_frame(AVCodecContext *avctx,
+ void *data, int *data_size,
+ UINT8 *buf, int buf_size)
+{
+ return -1;
+}
+
+static int encode_frame(AVCodecContext *avctx,
+ unsigned char *frame, int buf_size, void *data)
+{
+ return -1;
+}
+
+/* dummy pcm codec */
+AVCodec pcm_codec = {
+ "pcm",
+ CODEC_TYPE_AUDIO,
+ CODEC_ID_PCM,
+ 0,
+ encode_init,
+ encode_frame,
+ NULL,
+ decode_frame,
+};
+
+AVCodec rawvideo_codec = {
+ "rawvideo",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_RAWVIDEO,
+ 0,
+ encode_init,
+ encode_frame,
+ NULL,
+ decode_frame,
+};
diff --git a/src/libffmpeg/xine_decoder.c b/src/libffmpeg/xine_decoder.c
new file mode 100644
index 000000000..8a6166a7c
--- /dev/null
+++ b/src/libffmpeg/xine_decoder.c
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: xine_decoder.c,v 1.1 2001/08/07 12:41:46 guenter Exp $
+ *
+ * xine decoder plugin using ffmpeg
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include <xine/video_out.h>
+#include <xine/buffer.h>
+#include <xine/metronom.h>
+
+#include "libavcodec/avcodec.h"
+
+/* this def is taken from xine_internal.h */
+typedef struct video_decoder_s video_decoder_t;
+struct video_decoder_s {
+ int interface_version;
+ int (*can_handle) (video_decoder_t *this, int buf_type);
+ void (*init) (video_decoder_t *this, vo_instance_t *video_out);
+ void (*decode_data) (video_decoder_t *this, buf_element_t *buf);
+ void (*close) (video_decoder_t *this);
+ char* (*get_identifier) (void);
+ int priority;
+ metronom_t *metronom;
+};
+
+/* now this is ripped of wine's vfw.h */
+typedef struct {
+ long biSize;
+ long biWidth;
+ long biHeight;
+ short biPlanes;
+ short biBitCount;
+ long biCompression;
+ long biSizeImage;
+ long biXPelsPerMeter;
+ long biYPelsPerMeter;
+ long biClrUsed;
+ long biClrImportant;
+} BITMAPINFOHEADER;
+#ifndef mmioFOURCC
+#define mmioFOURCC( ch0, ch1, ch2, ch3 ) \
+ ( (long)(unsigned char)(ch0) | ( (long)(unsigned char)(ch1) << 8 ) | \
+ ( (long)(unsigned char)(ch2) << 16 ) | ( (long)(unsigned char)(ch3) << 24 ) )
+#endif
+
+typedef struct ff_decoder_s {
+ video_decoder_t video_decoder;
+
+ vo_instance_t *video_out;
+ int video_step;
+ int decoder_ok;
+
+ BITMAPINFOHEADER bih;
+ unsigned char buf[128*1024];
+ int size;
+
+ AVPicture av_picture;
+ AVCodecContext context;
+} ff_decoder_t;
+
+
+#define IMGFMT_YUY2 mmioFOURCC('Y','U','Y','2')
+#define IMGFMT_YV12 mmioFOURCC('Y','V','1','2')
+
+static int ff_can_handle (video_decoder_t *this_gen, int buf_type) {
+ return ((buf_type & 0xFFFF0000) == BUF_VIDEO_AVI) ;
+}
+
+static void ff_init (video_decoder_t *this_gen, vo_instance_t *video_out) {
+
+ ff_decoder_t *this = (ff_decoder_t *) this_gen;
+
+ this->video_out = video_out;
+ this->decoder_ok = 0;
+}
+
+static void ff_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
+ ff_decoder_t *this = (ff_decoder_t *) this_gen;
+
+ /*
+ printf ("ffmpeg: processing packet type = %08x, buf : %d, buf->decoder_info[0]=%d\n",
+ buf->type, buf, buf->decoder_info[0]);
+ */
+
+ if (buf->decoder_info[0] == 0) {
+
+ AVCodec *codec = NULL;
+
+ /* init package containing bih */
+
+ memcpy ( &this->bih, buf->content, sizeof (BITMAPINFOHEADER));
+ this->video_step = buf->decoder_info[1];
+
+ /* init codec */
+
+ /*
+ if (this->bih.biCompression == mmioFOURCC('D', 'I', 'V', 'X')) {
+ printf ("ffmpeg: mpeg4 (opendivx) format detected\n");
+
+ codec = avcodec_find_decoder (CODEC_ID_OPENDIVX);
+ } else {
+ printf ("ffmpeg: ms mpeg4 format detected\n");
+ codec = avcodec_find_decoder (CODEC_ID_MSMPEG4);
+ }
+ */
+
+ switch (this->bih.biCompression) {
+ case mmioFOURCC('M', 'P', 'G', '4'):
+ case mmioFOURCC('m', 'p', 'g', '4'):
+ case mmioFOURCC('M', 'P', '4', '2'):
+ case mmioFOURCC('m', 'p', '4', '2'):
+ case mmioFOURCC('M', 'P', '4', '3'):
+ case mmioFOURCC('m', 'p', '4', '3'):
+ case mmioFOURCC('D', 'I', 'V', '3'):
+ case mmioFOURCC('d', 'i', 'v', '3'):
+ case mmioFOURCC('D', 'I', 'V', '4'):
+ case mmioFOURCC('d', 'i', 'v', '4'):
+ case mmioFOURCC('M', 'P', '4', '1'):
+ case mmioFOURCC('m', 'p', '4', '1'):
+ printf ("ffmpeg: ms mpeg4 format detected\n");
+ codec = avcodec_find_decoder (CODEC_ID_MSMPEG4);
+ break;
+ case mmioFOURCC('D', 'I', 'V', 'X'):
+ case mmioFOURCC('d', 'i', 'v', 'x'):
+ case mmioFOURCC('D', 'i', 'v', 'x'):
+ case mmioFOURCC('D', 'i', 'v', 'X'):
+ printf ("ffmpeg: mpeg4 (opendivx) format detected\n");
+ codec = avcodec_find_decoder (CODEC_ID_OPENDIVX);
+ break;
+ case mmioFOURCC('d', 'm', 'b', '1'):
+ printf ("ffmpeg: motion jpeg format detected\n");
+ codec = avcodec_find_decoder (CODEC_ID_MJPEG);
+ break;
+ default:
+ printf ("ffmpeg: unknown video format 0x%08X\n",
+ this->bih.biCompression);
+ }
+
+ if (!codec) {
+ printf ("ffmpeg: couldn't find decoder\n");
+ return;
+ }
+
+ memset(&this->context, 0, sizeof(this->context));
+ this->context.width = this->bih.biWidth;
+ this->context.height = this->bih.biHeight;
+
+ if (avcodec_open (&this->context, codec) < 0) {
+ printf ("ffmpeg: couldn't open decoder\n");
+ return;
+ }
+
+ this->decoder_ok = 1;
+ this->video_out->open (this->video_out);
+
+ } else if (this->decoder_ok) {
+
+ memcpy (&this->buf[this->size], buf->content, buf->size);
+
+ this->size += buf->size;
+
+ if (buf->decoder_info[0] == 2) {
+
+ vo_frame_t *img;
+ int got_picture, len, y;
+ uint8_t *dy, *du, *dv, *sy, *su, *sv;
+
+ /* decoder video frame */
+
+ /* this->bih.biSizeImage = this->size; */
+
+ len = avcodec_decode_video (&this->context, &this->av_picture,
+ &got_picture, this->buf,
+ this->size);
+
+ img = this->video_out->get_frame (this->video_out,
+ /* this->av_picture.linesize[0], */
+ this->bih.biWidth,
+ this->bih.biHeight,
+ 42,
+ IMGFMT_YV12,
+ this->video_step,
+ VO_BOTH_FIELDS);
+
+ img->PTS = buf->PTS;
+ if (len<0) {
+ printf ("ffmpeg: error decompressing frame\n");
+ img->bFrameBad = 1;
+ } else
+ img->bFrameBad = 0;
+
+ dy = img->base[0];
+ du = img->base[1];
+ dv = img->base[2];
+ sy = this->av_picture.data[0];
+ su = this->av_picture.data[1];
+ sv = this->av_picture.data[2];
+
+ for (y=0; y<this->bih.biHeight; y++) {
+
+ memcpy (dy, sy, this->bih.biWidth);
+
+ dy += this->bih.biWidth;
+
+ sy += this->av_picture.linesize[0];
+ }
+
+ for (y=0; y<(this->bih.biHeight/2); y++) {
+
+ memcpy (du, su, this->bih.biWidth/2);
+ memcpy (dv, sv, this->bih.biWidth/2);
+
+ du += this->bih.biWidth/2;
+ dv += this->bih.biWidth/2;
+
+ su += this->av_picture.linesize[1];
+ sv += this->av_picture.linesize[2];
+ }
+ /*
+ memcpy (img->base[0], this->av_picture.data[0],
+ this->context.height * this->av_picture.linesize[0]);
+ memcpy (img->base[1], this->av_picture.data[1],
+ this->context.height * this->av_picture.linesize[1]/2);
+ memcpy (img->base[2], this->av_picture.data[2],
+ this->context.height * this->av_picture.linesize[2]/2);
+ */
+
+ if (img->copy) {
+
+ int height = abs(this->bih.biHeight);
+ int stride = this->bih.biWidth;
+ uint8_t* src[3];
+
+ src[0] = img->base[0];
+ src[2] = src[0] + height * this->bih.biWidth;
+ src[1] = src[2] + height * this->bih.biWidth / 4;
+ while ((height -= 16) >= 0) {
+ img->copy(img, src);
+ src[0] += 16 * stride;
+ src[1] += 4 * stride;
+ src[2] += 4 * stride;
+ }
+ }
+
+ img->draw(img);
+ img->free(img);
+
+ this->size = 0;
+ }
+ }
+}
+
+static void ff_close (video_decoder_t *this_gen) {
+
+ ff_decoder_t *this = (ff_decoder_t *) this_gen;
+
+ avcodec_close (&this->context);
+ this->video_out->close(this->video_out);
+}
+
+static char *ff_get_id(void) {
+ return "ffmpeg video decoder";
+}
+
+
+video_decoder_t *init_video_decoder_plugin (int iface_version, config_values_t *cfg) {
+
+ ff_decoder_t *this ;
+
+ if (iface_version != 2) {
+ printf( "ffmpeg: plugin doesn't support plugin API version %d.\n"
+ "ffmpeg: this means there's a version mismatch between xine and this "
+ "ffmpeg: decoder plugin.\nInstalling current plugins should help.\n",
+ iface_version);
+
+ return NULL;
+ }
+
+ this = (ff_decoder_t *) malloc (sizeof (ff_decoder_t));
+
+ this->video_decoder.interface_version = 2;
+ this->video_decoder.can_handle = ff_can_handle;
+ this->video_decoder.init = ff_init;
+ this->video_decoder.decode_data = ff_decode_data;
+ this->video_decoder.close = ff_close;
+ this->video_decoder.get_identifier = ff_get_id;
+ this->video_decoder.priority = cfg->lookup_int (cfg, "ff_priority", 0);
+
+ avcodec_init();
+ avcodec_register_all();
+
+ return (video_decoder_t *) this;
+}
+
+
diff --git a/src/xine-engine/cpu_accel.c b/src/xine-engine/cpu_accel.c
index 81adb7a12..d2254084e 100644
--- a/src/xine-engine/cpu_accel.c
+++ b/src/xine-engine/cpu_accel.c
@@ -111,3 +111,8 @@ uint32_t mm_accel (void)
#endif
#endif
}
+
+uint32_t mm_support (void)
+{
+ return mm_accel();
+}
diff --git a/src/xine-engine/cpu_accel.h b/src/xine-engine/cpu_accel.h
index d563787eb..ca2713ff4 100644
--- a/src/xine-engine/cpu_accel.h
+++ b/src/xine-engine/cpu_accel.h
@@ -44,8 +44,14 @@ extern "C" {
#define MM_ACCEL_X86_MMX 0x80000000
#define MM_ACCEL_X86_3DNOW 0x40000000
#define MM_ACCEL_X86_MMXEXT 0x20000000
+#define MM_MMX 0x80000000
+#define MM_3DNOW 0x40000000
+#define MM_MMXEXT 0x20000000
+#define MM_SSE 0x00000000
+#define MM_SSE2 0x00000000
uint32_t mm_accel (void) ;
+uint32_t mm_support (void) ;
#ifdef ARCH_X86