summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Roitzsch <mroi@users.sourceforge.net>2004-05-30 19:24:17 +0000
committerMichael Roitzsch <mroi@users.sourceforge.net>2004-05-30 19:24:17 +0000
commitdf5fbeb013e70f14090cec1998a5f923d6713a1d (patch)
treede31c29919f53b88f27bdb7add18706b1b51ddcc
parent26de73d1e48ab23af83e352cdc6e9eac41bf8c3b (diff)
downloadxine-lib-df5fbeb013e70f14090cec1998a5f923d6713a1d.tar.gz
xine-lib-df5fbeb013e70f14090cec1998a5f923d6713a1d.tar.bz2
merge ffmpeg to fix compiler warnings
CVS patchset: 6612 CVS date: 2004/05/30 19:24:17
-rw-r--r--CREDITS2
-rw-r--r--src/libffmpeg/diff_to_ffmpeg_cvs.txt142
-rw-r--r--src/libffmpeg/libavcodec/4xm.c2
-rw-r--r--src/libffmpeg/libavcodec/Makefile.am13
-rw-r--r--src/libffmpeg/libavcodec/adpcm.c2
-rw-r--r--src/libffmpeg/libavcodec/armv4l/Makefile.am2
-rw-r--r--src/libffmpeg/libavcodec/armv4l/simple_idct_arm.S485
-rw-r--r--src/libffmpeg/libavcodec/asv1.c2
-rw-r--r--src/libffmpeg/libavcodec/avcodec.h22
-rw-r--r--src/libffmpeg/libavcodec/cabac.c2
-rw-r--r--src/libffmpeg/libavcodec/cabac.h6
-rw-r--r--src/libffmpeg/libavcodec/cljr.c159
-rw-r--r--src/libffmpeg/libavcodec/common.h12
-rw-r--r--src/libffmpeg/libavcodec/cyuv.c2
-rw-r--r--src/libffmpeg/libavcodec/dsputil.h5
-rw-r--r--src/libffmpeg/libavcodec/dv.c7
-rw-r--r--src/libffmpeg/libavcodec/faandct.c2
-rw-r--r--src/libffmpeg/libavcodec/ffv1.c1035
-rw-r--r--src/libffmpeg/libavcodec/flac.c770
-rw-r--r--src/libffmpeg/libavcodec/g726.c422
-rw-r--r--src/libffmpeg/libavcodec/h263.c57
-rw-r--r--src/libffmpeg/libavcodec/h263dec.c2
-rw-r--r--src/libffmpeg/libavcodec/h264.c2
-rw-r--r--src/libffmpeg/libavcodec/huffyuv.c2
-rw-r--r--src/libffmpeg/libavcodec/i386/dsputil_mmx.c2
-rw-r--r--src/libffmpeg/libavcodec/i386/dsputil_mmx_avg.h4
-rw-r--r--src/libffmpeg/libavcodec/i386/dsputil_mmx_rnd.h4
-rw-r--r--src/libffmpeg/libavcodec/i386/fdct_mmx.c1
-rw-r--r--src/libffmpeg/libavcodec/i386/idct_mmx.c3
-rw-r--r--src/libffmpeg/libavcodec/i386/mpegvideo_mmx.c2
-rw-r--r--src/libffmpeg/libavcodec/i386/simple_idct_mmx.c1
-rw-r--r--src/libffmpeg/libavcodec/indeo3.c1
-rw-r--r--src/libffmpeg/libavcodec/libpostproc/Makefile.am2
-rw-r--r--src/libffmpeg/libavcodec/libpostproc/postprocess.c82
-rw-r--r--src/libffmpeg/libavcodec/libpostproc/postprocess.h1
-rw-r--r--src/libffmpeg/libavcodec/libpostproc/postprocess_altivec_template.c713
-rw-r--r--src/libffmpeg/libavcodec/libpostproc/postprocess_template.c21
-rw-r--r--src/libffmpeg/libavcodec/mace.c1
-rw-r--r--src/libffmpeg/libavcodec/mangle.h18
-rw-r--r--src/libffmpeg/libavcodec/mdec.c2
-rw-r--r--src/libffmpeg/libavcodec/mjpeg.c6
-rw-r--r--src/libffmpeg/libavcodec/motion_est.c427
-rw-r--r--src/libffmpeg/libavcodec/motion_est_template.c132
-rw-r--r--src/libffmpeg/libavcodec/mpeg12.c8
-rw-r--r--src/libffmpeg/libavcodec/mpegaudiodec.c1
-rw-r--r--src/libffmpeg/libavcodec/mpegvideo.c44
-rw-r--r--src/libffmpeg/libavcodec/mpegvideo.h14
-rw-r--r--src/libffmpeg/libavcodec/msmpeg4.c17
-rw-r--r--src/libffmpeg/libavcodec/os_support.h37
-rw-r--r--src/libffmpeg/libavcodec/parser.c14
-rw-r--r--src/libffmpeg/libavcodec/pcm.c1
-rw-r--r--src/libffmpeg/libavcodec/ra288.c4
-rw-r--r--src/libffmpeg/libavcodec/raw.c175
-rw-r--r--src/libffmpeg/libavcodec/roqvideo.c2
-rw-r--r--src/libffmpeg/libavcodec/rpza.c2
-rw-r--r--src/libffmpeg/libavcodec/rv10.c11
-rw-r--r--src/libffmpeg/libavcodec/svq1.c782
-rw-r--r--src/libffmpeg/libavcodec/svq1_cb.h4
-rw-r--r--src/libffmpeg/libavcodec/svq1_vlc.h22
-rw-r--r--src/libffmpeg/libavcodec/svq3.c2
-rw-r--r--src/libffmpeg/libavcodec/truemotion1.c2
-rw-r--r--src/libffmpeg/libavcodec/utils.c13
-rw-r--r--src/libffmpeg/libavcodec/vcr1.c2
-rw-r--r--src/libffmpeg/libavcodec/vmdav.c1
-rw-r--r--src/libffmpeg/libavcodec/vp3.c4
-rw-r--r--src/libffmpeg/libavcodec/vp3data.h12
-rw-r--r--src/libffmpeg/libavcodec/vp3dsp.c1
-rw-r--r--src/libffmpeg/libavcodec/wmadec.c6
-rw-r--r--src/libffmpeg/libavcodec/wmv2.c6
69 files changed, 4576 insertions, 1191 deletions
diff --git a/CREDITS b/CREDITS
index 1db0abe73..74a00c4a6 100644
--- a/CREDITS
+++ b/CREDITS
@@ -12,7 +12,7 @@ updates (the word 'maintainer' is intentionally avoided here).
project version mediator
-----------------------------------------------------------------------
-ffmpeg build 4713 Mike Melanson
+ffmpeg build 4715 Mike Melanson
goom 1.9dev5
gsm610 1.0.10 Mike Melanson
liba52 0.7.4
diff --git a/src/libffmpeg/diff_to_ffmpeg_cvs.txt b/src/libffmpeg/diff_to_ffmpeg_cvs.txt
index 864c8c365..f54735d20 100644
--- a/src/libffmpeg/diff_to_ffmpeg_cvs.txt
+++ b/src/libffmpeg/diff_to_ffmpeg_cvs.txt
@@ -1,5 +1,5 @@
---- avcodec.h 2004-05-12 18:40:32.000000000 +0200
-+++ avcodec.h 2004-05-10 01:31:59.000000000 +0200
+--- avcodec.h 2004-05-28 18:20:57.000000000 +0200
++++ avcodec.h 2004-05-28 18:25:10.000000000 +0200
@@ -15,6 +15,13 @@
#include "rational.h"
#include <sys/types.h> /* size_t */
@@ -13,9 +13,23 @@
+
#define FFMPEG_VERSION_INT 0x000408
#define FFMPEG_VERSION "0.4.8"
- #define LIBAVCODEC_BUILD 4713
---- common.h 2004-05-12 18:37:00.000000000 +0200
-+++ common.h 2004-05-10 01:31:59.000000000 +0200
+ #define LIBAVCODEC_BUILD 4715
+@@ -2177,6 +2184,13 @@
+ ((uint8_t*)(x))[0])
+ #endif
+
++/* unused static macro */
++#if defined(__GNUC__) && !defined(DEBUG)
++/* since we do not compile the encoder part of ffmpeg, some static
++ * functions will be unused; this is ok, the compiler will take care */
++# define static static __attribute__((__unused__))
++#endif
++
+ #ifdef __cplusplus
+ }
+ #endif
+--- common.h 2004-05-28 18:20:57.000000000 +0200
++++ common.h 2004-05-28 18:22:54.000000000 +0200
@@ -6,6 +6,11 @@
#ifndef COMMON_H
#define COMMON_H
@@ -28,8 +42,18 @@
#if defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
# define CONFIG_WIN32
#endif
---- dsputil.h 2004-04-27 05:58:06.000000000 +0200
-+++ dsputil.h 2004-05-10 01:32:00.000000000 +0200
+@@ -213,7 +218,9 @@
+ /* debug stuff */
+
+ # ifndef DEBUG
++# ifndef NDEBUG
+ # define NDEBUG
++# endif
+ # endif
+ # include <assert.h>
+
+--- dsputil.h 2004-05-28 18:20:57.000000000 +0200
++++ dsputil.h 2004-05-28 18:22:54.000000000 +0200
@@ -31,6 +31,9 @@
#include "common.h"
#include "avcodec.h"
@@ -40,8 +64,8 @@
//#define DEBUG
/* dct code */
---- mlib/dsputil_mlib.c 2004-03-15 02:21:01.000000000 +0100
-+++ mlib/dsputil_mlib.c 2004-03-15 02:22:22.000000000 +0100
+--- mlib/dsputil_mlib.c 2004-05-28 18:20:57.000000000 +0200
++++ mlib/dsputil_mlib.c 2004-05-28 18:22:54.000000000 +0200
@@ -20,6 +20,8 @@
#include "../dsputil.h"
#include "../mpegvideo.h"
@@ -78,15 +102,33 @@
}
+ }
}
---- mpeg12.c 2004-04-30 15:44:29.000000000 +0200
-+++ mpeg12.c 2004-05-10 01:32:01.000000000 +0200
+--- motion_est.c 2004-05-30 20:16:44.000000000 +0200
++++ motion_est.c 2004-05-10 23:21:24.000000000 +0200
+@@ -20,6 +20,9 @@
+ *
+ * new Motion Estimation (X1/EPZS) by Michael Niedermayer <michaelni@gmx.at>
+ */
++
++/* motion estimation only needed for encoders */
++#ifdef CONFIG_ENCODERS
+
+ /**
+ * @file motion_est.c
+@@ -1998,3 +2001,5 @@
+ }
+ }
+ }
++
++#endif /* CONFIG_ENCODERS */
+--- mpeg12.c 2004-05-28 18:20:57.000000000 +0200
++++ mpeg12.c 2004-05-28 18:22:54.000000000 +0200
@@ -34,6 +34,13 @@
//#include <assert.h>
+/* if xine's MPEG encoder is enabled, enable the encoding features in
+ * this particular module */
-+#ifdef XINE_MPEG_ENCODER
++#if defined(XINE_MPEG_ENCODER) && !defined(CONFIG_ENCODERS)
+#define CONFIG_ENCODERS
+#endif
+
@@ -94,16 +136,16 @@
/* Start codes. */
#define SEQ_END_CODE 0x000001b7
#define SEQ_START_CODE 0x000001b3
---- mpegvideo.c 2004-05-12 18:37:00.000000000 +0200
-+++ mpegvideo.c 2004-05-10 01:32:01.000000000 +0200
-@@ -39,6 +39,14 @@
+--- mpegvideo.c 2004-05-28 18:20:57.000000000 +0200
++++ mpegvideo.c 2004-05-28 18:22:54.000000000 +0200
+@@ -38,6 +38,14 @@
//#undef NDEBUG
//#include <assert.h>
+
+/* if xine's MPEG encoder is enabled, enable the encoding features in
+ * this particular module */
-+#ifdef XINE_MPEG_ENCODER
++#if defined(XINE_MPEG_ENCODER) && !defined(CONFIG_ENCODERS)
+#define CONFIG_ENCODERS
+#endif
+
@@ -111,7 +153,7 @@
#ifdef CONFIG_ENCODERS
static void encode_picture(MpegEncContext *s, int picture_number);
#endif //CONFIG_ENCODERS
-@@ -1033,6 +1041,8 @@
+@@ -1032,6 +1040,8 @@
s->low_delay= 0; //s->max_b_frames ? 0 : 1;
avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1);
break;
@@ -120,7 +162,7 @@
case CODEC_ID_MPEG2VIDEO:
s->out_format = FMT_MPEG1;
s->low_delay= 0; //s->max_b_frames ? 0 : 1;
-@@ -1154,6 +1164,7 @@
+@@ -1153,6 +1163,7 @@
s->low_delay=1;
break;
#endif
@@ -128,7 +170,7 @@
default:
return -1;
}
-@@ -1172,13 +1183,22 @@
+@@ -1171,13 +1182,22 @@
ff_set_cmp(&s->dsp, s->dsp.ildct_cmp, s->avctx->ildct_cmp);
@@ -151,7 +193,7 @@
if (s->out_format == FMT_MPEG1)
ff_mpeg1_encode_init(s);
#endif
-@@ -1230,9 +1250,12 @@
+@@ -1229,9 +1249,12 @@
ff_rate_control_uninit(s);
@@ -164,7 +206,7 @@
av_freep(&avctx->extradata);
-@@ -2136,8 +2159,11 @@
+@@ -2135,8 +2158,11 @@
MPV_frame_end(s);
@@ -176,7 +218,7 @@
if(s->flags&CODEC_FLAG_PASS1)
ff_write_pass1_stats(s);
-@@ -3674,6 +3700,8 @@
+@@ -3673,6 +3699,8 @@
case CODEC_ID_MPEG1VIDEO:
case CODEC_ID_MPEG2VIDEO:
mpeg1_encode_mb(s, s->block, motion_x, motion_y); break;
@@ -185,7 +227,7 @@
#ifdef CONFIG_RISKY
case CODEC_ID_MPEG4:
mpeg4_encode_mb(s, s->block, motion_x, motion_y); break;
-@@ -3691,6 +3719,7 @@
+@@ -3690,6 +3718,7 @@
#endif
case CODEC_ID_MJPEG:
mjpeg_encode_mb(s, s->block); break;
@@ -193,7 +235,7 @@
default:
assert(0);
}
-@@ -3965,6 +3994,8 @@
+@@ -3964,6 +3993,8 @@
}
static void write_slice_end(MpegEncContext *s){
@@ -202,7 +244,7 @@
if(s->codec_id==CODEC_ID_MPEG4){
if(s->partitioned_frame){
ff_mpeg4_merge_partitions(s);
-@@ -3974,6 +4005,7 @@
+@@ -3973,6 +4004,7 @@
}else if(s->out_format == FMT_MJPEG){
ff_mjpeg_stuffing(&s->pb);
}
@@ -210,7 +252,7 @@
align_put_bits(&s->pb);
flush_put_bits(&s->pb);
-@@ -4025,10 +4057,13 @@
+@@ -4024,10 +4056,13 @@
case CODEC_ID_FLV1:
s->gob_index = ff_h263_get_gob_height(s);
break;
@@ -224,7 +266,7 @@
}
#endif
-@@ -4082,9 +4117,12 @@
+@@ -4081,9 +4116,12 @@
if(s->start_mb_y != mb_y || mb_x!=0){
write_slice_end(s);
@@ -237,8 +279,8 @@
}
assert((put_bits_count(&s->pb)&7) == 0);
-@@ -4106,19 +4144,25 @@
- s->avctx->rtp_callback(s->ptr_lastgob, current_packet_size, 0);
+@@ -4105,19 +4143,25 @@
+ s->avctx->rtp_callback(s->avctx, s->ptr_lastgob, current_packet_size, 0);
switch(s->codec_id){
+/* xine: do not need this for decode or MPEG-1 encoding modes */
@@ -263,7 +305,7 @@
}
if(s->flags&CODEC_FLAG_PASS1){
-@@ -4232,9 +4276,12 @@
+@@ -4231,9 +4275,12 @@
s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
s->mb_intra= 0;
@@ -276,7 +318,7 @@
encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_DIRECT, pb, pb2, tex_pb,
&dmin, &next_block, mx, my);
}
-@@ -4422,9 +4469,12 @@
+@@ -4421,9 +4468,12 @@
s->mb_intra= 0;
motion_x=s->b_direct_mv_table[xy][0];
motion_y=s->b_direct_mv_table[xy][1];
@@ -289,7 +331,7 @@
break;
case CANDIDATE_MB_TYPE_BIDIR:
s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
-@@ -4531,11 +4581,14 @@
+@@ -4530,11 +4580,14 @@
}
}
@@ -304,9 +346,9 @@
write_slice_end(s);
-@@ -4598,12 +4651,15 @@
- s->mb_var_sum_temp =
- s->mc_mb_var_sum_temp = 0;
+@@ -4597,12 +4650,15 @@
+ s->me.mb_var_sum_temp =
+ s->me.mc_mb_var_sum_temp = 0;
+/* xine: do not need this for decode or MPEG-1 encoding modes */
+#if 0
@@ -318,9 +360,27 @@
#endif
+#endif /* #if 0 */
- s->scene_change_score=0;
+ s->me.scene_change_score=0;
-@@ -4657,6 +4713,8 @@
+@@ -4621,6 +4677,8 @@
+ ff_update_duplicate_context(s->thread_context[i], s);
+ }
+
++/* xine: do not need this for decode or MPEG-1 encoding modes */
++#if 0
+ ff_init_me(s);
+
+ /* Estimate motion for every MB */
+@@ -4633,6 +4691,8 @@
+
+ s->avctx->execute(s->avctx, estimate_motion_thread, (void**)&(s->thread_context[0]), NULL, s->avctx->thread_count);
+ }else /* if(s->pict_type == I_TYPE) */{
++#endif /* #if 0 */
++ {
+ /* I-Frame */
+ for(i=0; i<s->mb_stride*s->mb_height; i++)
+ s->mb_type[i]= CANDIDATE_MB_TYPE_INTRA;
+@@ -4656,6 +4716,8 @@
//printf("Scene change detected, encoding as I Frame %d %d\n", s->current_picture.mb_var_sum, s->current_picture.mc_mb_var_sum);
}
@@ -329,7 +389,7 @@
if(!s->umvplus){
if(s->pict_type==P_TYPE || s->pict_type==S_TYPE) {
s->f_code= ff_get_best_fcode(s, s->p_mv_table, CANDIDATE_MB_TYPE_INTER);
-@@ -4709,11 +4767,14 @@
+@@ -4709,11 +4771,14 @@
}
}
}
@@ -344,7 +404,7 @@
#ifdef CONFIG_RISKY
switch(s->codec_id){
case CODEC_ID_MPEG4:
-@@ -4726,6 +4787,7 @@
+@@ -4726,6 +4791,7 @@
break;
}
#endif
@@ -352,7 +412,7 @@
s->lambda= s->lambda_table[0];
//FIXME broken
-@@ -4759,6 +4821,8 @@
+@@ -4759,6 +4825,8 @@
s->last_bits= put_bits_count(&s->pb);
switch(s->out_format) {
@@ -361,7 +421,7 @@
case FMT_MJPEG:
mjpeg_picture_header(s);
break;
-@@ -4778,11 +4842,15 @@
+@@ -4778,11 +4846,15 @@
h263_encode_picture_header(s, picture_number);
break;
#endif
diff --git a/src/libffmpeg/libavcodec/4xm.c b/src/libffmpeg/libavcodec/4xm.c
index 50dc4a55b..fd84f8968 100644
--- a/src/libffmpeg/libavcodec/4xm.c
+++ b/src/libffmpeg/libavcodec/4xm.c
@@ -600,8 +600,6 @@ static int decode_frame(AVCodecContext *avctx,
AVFrame *p, temp;
int i, frame_4cc, frame_size;
- *data_size = 0;
-
/* special case for last picture */
if (buf_size == 0) {
return 0;
diff --git a/src/libffmpeg/libavcodec/Makefile.am b/src/libffmpeg/libavcodec/Makefile.am
index 8b3a7f634..78752e5fe 100644
--- a/src/libffmpeg/libavcodec/Makefile.am
+++ b/src/libffmpeg/libavcodec/Makefile.am
@@ -2,11 +2,14 @@ include $(top_srcdir)/misc/Makefile.common
SUBDIRS = armv4l i386 mlib alpha ppc sparc libpostproc
-## some files here are #included by others... go figure.
-EXTRA_DIST = fdctref.c motion_est_template.c svq3.c wmv2.c \
- imgresample.c mdec.c
+# some of ffmpeg's decoders are not used by xine yet
+EXTRA_DIST = motion_est_template.c imgresample.c \
+ cljr.c fdctref.c ffv1.c flac.c g726.c mdec.c raw.c svq3.c wmv2.c
-AM_CFLAGS = $(LIBFFMPEG_CFLAGS)
+# we need to compile everything in debug mode, including the encoders,
+# otherwise we get unresolved symbols, because some unsatisfied function calls
+# are not optimized away with debug optimization
+AM_CFLAGS = $(LIBFFMPEG_CFLAGS) `test "$(CFLAGS)" = "$(DEBUG_CFLAGS)" && echo -DCONFIG_ENCODERS`
ASFLAGS =
noinst_LTLIBRARIES = libavcodec.la
@@ -101,7 +104,6 @@ noinst_HEADERS = \
integer.h \
h263data.h \
h264data.h \
- mangle.h \
mpeg4data.h \
mpeg12data.h \
mpegaudio.h \
@@ -109,7 +111,6 @@ noinst_HEADERS = \
mpegaudiotab.h \
mpegvideo.h \
msmpeg4data.h \
- os_support.h \
ra144.h \
ra288.h \
rational.h \
diff --git a/src/libffmpeg/libavcodec/adpcm.c b/src/libffmpeg/libavcodec/adpcm.c
index 2ce7dc87f..0755e24fe 100644
--- a/src/libffmpeg/libavcodec/adpcm.c
+++ b/src/libffmpeg/libavcodec/adpcm.c
@@ -568,7 +568,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
if(st) { /* handle stereo interlacing */
c->channel = (channel + 1) % 2; /* we get one packet for left, then one for right data */
if(channel == 1) { /* wait for the other packet before outputing anything */
- *data_size = 0;
return src - buf;
}
}
@@ -842,7 +841,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
}
break;
default:
- *data_size = 0;
return -1;
}
*data_size = (uint8_t *)samples - (uint8_t *)data;
diff --git a/src/libffmpeg/libavcodec/armv4l/Makefile.am b/src/libffmpeg/libavcodec/armv4l/Makefile.am
index 123978087..194cba8eb 100644
--- a/src/libffmpeg/libavcodec/armv4l/Makefile.am
+++ b/src/libffmpeg/libavcodec/armv4l/Makefile.am
@@ -5,7 +5,7 @@ ASFLAGS =
noinst_LTLIBRARIES = libavcodec_armv4l.la
-libavcodec_armv4l_src = dsputil_arm.c jrevdct_arm.S mpegvideo_arm.c
+libavcodec_armv4l_src = dsputil_arm.c jrevdct_arm.S mpegvideo_arm.c simple_idct_arm.S
libavcodec_armv4l_dummy = libavcodec_armv4l_dummy.c
EXTRA_DIST = $(libavcodec_armv4l_src) $(libavcodec_armv4l_dummy)
diff --git a/src/libffmpeg/libavcodec/armv4l/simple_idct_arm.S b/src/libffmpeg/libavcodec/armv4l/simple_idct_arm.S
new file mode 100644
index 000000000..95ac0dee4
--- /dev/null
+++ b/src/libffmpeg/libavcodec/armv4l/simple_idct_arm.S
@@ -0,0 +1,485 @@
+/*
+ * simple_idct_arm.S
+ * Copyright (C) 2002 Frederic 'dilb' Boulay.
+ * All Rights Reserved.
+ *
+ * Author: Frederic Boulay <dilb@handhelds.org>
+ *
+ * You can redistribute this file and/or modify
+ * it under the terms of the GNU General Public License (version 2)
+ * as published by the Free Software Foundation.
+ *
+ * This file 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ * The function defined in this file, is derived from the simple_idct function
+ * from the libavcodec library part of the ffmpeg project.
+ */
+
+/* useful constants for the algorithm, they are save in __constant_ptr__ at */
+/* the end of the source code.*/
+#define W1 22725
+#define W2 21407
+#define W3 19266
+#define W4 16383
+#define W5 12873
+#define W6 8867
+#define W7 4520
+#define MASK_MSHW 0xFFFF0000
+
+/* offsets of the constants in the vector */
+#define offW1 0
+#define offW2 4
+#define offW3 8
+#define offW4 12
+#define offW5 16
+#define offW6 20
+#define offW7 24
+#define offMASK_MSHW 28
+
+#define ROW_SHIFT 11
+#define ROW_SHIFT2MSHW (16-11)
+#define COL_SHIFT 20
+#define ROW_SHIFTED_1 1024 /* 1<< (ROW_SHIFT-1) */
+#define COL_SHIFTED_1 524288 /* 1<< (COL_SHIFT-1) */
+
+
+ .text
+ .align
+ .global simple_idct_ARM
+
+simple_idct_ARM:
+ @@ void simple_idct_ARM(int16_t *block)
+ @@ save stack for reg needed (take all of them),
+ @@ R0-R3 are scratch regs, so no need to save them, but R0 contains the pointer to block
+ @@ so it must not be overwritten, if it is not saved!!
+ @@ R12 is another scratch register, so it should not be saved too
+ @@ save all registers
+ stmfd sp!, {r4-r11, r14} @ R14 is also called LR
+ @@ at this point, R0=block, other registers are free.
+ add r14, r0, #112 @ R14=&block[8*7], better start from the last row, and decrease the value until row=0, i.e. R12=block.
+ add r12, pc, #(__constant_ptr__-.-8) @ R12=__constant_ptr__, the vector containing the constants, probably not necessary to reserve a register for it
+ @@ add 2 temporary variables in the stack: R0 and R14
+ sub sp, sp, #8 @ allow 2 local variables
+ str r0, [sp, #0] @ save block in sp[0]
+ @@ stack status
+ @@ sp+4 free
+ @@ sp+0 R0 (block)
+
+
+ @@ at this point, R0=block, R14=&block[56], R12=__const_ptr_, R1-R11 free
+
+
+__row_loop:
+ @@ read the row and check if it is null, almost null, or not, according to strongarm specs, it is not necessary to optimise ldr accesses (i.e. split 32bits in 2 16bits words), at least it gives more usable registers :)
+ ldr r1, [r14, #0] @ R1=(int32)(R12)[0]=ROWr32[0] (relative row cast to a 32b pointer)
+ ldr r2, [r14, #4] @ R2=(int32)(R12)[1]=ROWr32[1]
+ ldr r3, [r14, #8] @ R3=ROWr32[2]
+ ldr r4, [r14, #12] @ R4=ROWr32[3]
+ @@ check if the words are null, if all of them are null, then proceed with next row (branch __end_row_loop),
+ @@ if ROWr16[0] is the only one not null, then proceed with this special case (branch __almost_empty_row)
+ @@ else follow the complete algorithm.
+ @@ at this point, R0=block, R14=&block[n], R12=__const_ptr_, R1=ROWr32[0], R2=ROWr32[1],
+ @@ R3=ROWr32[2], R4=ROWr32[3], R5-R11 free
+ orr r5, r4, r3 @ R5=R4 | R3
+ orr r5, r5, r2 @ R5=R4 | R3 | R2
+ orrs r6, r5, r1 @ Test R5 | R1 (the aim is to check if everything is null)
+ beq __end_row_loop
+ mov r7, r1, asr #16 @ R7=R1>>16=ROWr16[1] (evaluate it now, as it could be useful later)
+ ldrsh r6, [r14, #0] @ R6=ROWr16[0]
+ orrs r5, r5, r7 @ R5=R4 | R3 | R2 | R7
+ beq __almost_empty_row
+
+__b_evaluation:
+ @@ at this point, R0=block (temp), R1(free), R2=ROWr32[1], R3=ROWr32[2], R4=ROWr32[3],
+ @@ R5=(temp), R6=ROWr16[0], R7=ROWr16[1], R8-R11 free,
+ @@ R12=__const_ptr_, R14=&block[n]
+ @@ to save some registers/calls, proceed with b0-b3 first, followed by a0-a3
+
+ @@ MUL16(b0, W1, row[1]);
+ @@ MUL16(b1, W3, row[1]);
+ @@ MUL16(b2, W5, row[1]);
+ @@ MUL16(b3, W7, row[1]);
+ @@ MAC16(b0, W3, row[3]);
+ @@ MAC16(b1, -W7, row[3]);
+ @@ MAC16(b2, -W1, row[3]);
+ @@ MAC16(b3, -W5, row[3]);
+ ldr r8, [r12, #offW1] @ R8=W1
+ mov r2, r2, asr #16 @ R2=ROWr16[3]
+ mul r0, r8, r7 @ R0=W1*ROWr16[1]=b0 (ROWr16[1] must be the second arg, to have the possibility to save 1 cycle)
+ ldr r9, [r12, #offW3] @ R9=W3
+ ldr r10, [r12, #offW5] @ R10=W5
+ mul r1, r9, r7 @ R1=W3*ROWr16[1]=b1 (ROWr16[1] must be the second arg, to have the possibility to save 1 cycle)
+ ldr r11, [r12, #offW7] @ R11=W7
+ mul r5, r10, r7 @ R5=W5*ROWr16[1]=b2 (ROWr16[1] must be the second arg, to have the possibility to save 1 cycle)
+ mul r7, r11, r7 @ R7=W7*ROWr16[1]=b3 (ROWr16[1] must be the second arg, to have the possibility to save 1 cycle)
+ teq r2, #0 @ if null avoid muls
+ mlane r0, r9, r2, r0 @ R0+=W3*ROWr16[3]=b0 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle)
+ rsbne r2, r2, #0 @ R2=-ROWr16[3]
+ mlane r1, r11, r2, r1 @ R1-=W7*ROWr16[3]=b1 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle)
+ mlane r5, r8, r2, r5 @ R5-=W1*ROWr16[3]=b2 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle)
+ mlane r7, r10, r2, r7 @ R7-=W5*ROWr16[3]=b3 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle)
+
+ @@ at this point, R0=b0, R1=b1, R2 (free), R3=ROWr32[2], R4=ROWr32[3],
+ @@ R5=b2, R6=ROWr16[0], R7=b3, R8=W1, R9=W3, R10=W5, R11=W7,
+ @@ R12=__const_ptr_, R14=&block[n]
+ @@ temp = ((uint32_t*)row)[2] | ((uint32_t*)row)[3];
+ @@ if (temp != 0) {}
+ orrs r2, r3, r4 @ R2=ROWr32[2] | ROWr32[3]
+ beq __end_b_evaluation
+
+ @@ at this point, R0=b0, R1=b1, R2 (free), R3=ROWr32[2], R4=ROWr32[3],
+ @@ R5=b2, R6=ROWr16[0], R7=b3, R8=W1, R9=W3, R10=W5, R11=W7,
+ @@ R12=__const_ptr_, R14=&block[n]
+ @@ MAC16(b0, W5, row[5]);
+ @@ MAC16(b2, W7, row[5]);
+ @@ MAC16(b3, W3, row[5]);
+ @@ MAC16(b1, -W1, row[5]);
+ @@ MAC16(b0, W7, row[7]);
+ @@ MAC16(b2, W3, row[7]);
+ @@ MAC16(b3, -W1, row[7]);
+ @@ MAC16(b1, -W5, row[7]);
+ mov r3, r3, asr #16 @ R3=ROWr16[5]
+ teq r3, #0 @ if null avoid muls
+ mlane r0, r10, r3, r0 @ R0+=W5*ROWr16[5]=b0
+ mov r4, r4, asr #16 @ R4=ROWr16[7]
+ mlane r5, r11, r3, r5 @ R5+=W7*ROWr16[5]=b2
+ mlane r7, r9, r3, r7 @ R7+=W3*ROWr16[5]=b3
+ rsbne r3, r3, #0 @ R3=-ROWr16[5]
+ mlane r1, r8, r3, r1 @ R7-=W1*ROWr16[5]=b1
+ @@ R3 is free now
+ teq r4, #0 @ if null avoid muls
+ mlane r0, r11, r4, r0 @ R0+=W7*ROWr16[7]=b0
+ mlane r5, r9, r4, r5 @ R5+=W3*ROWr16[7]=b2
+ rsbne r4, r4, #0 @ R4=-ROWr16[7]
+ mlane r7, r8, r4, r7 @ R7-=W1*ROWr16[7]=b3
+ mlane r1, r10, r4, r1 @ R1-=W5*ROWr16[7]=b1
+ @@ R4 is free now
+__end_b_evaluation:
+ @@ at this point, R0=b0, R1=b1, R2=ROWr32[2] | ROWr32[3] (tmp), R3 (free), R4 (free),
+ @@ R5=b2, R6=ROWr16[0], R7=b3, R8 (free), R9 (free), R10 (free), R11 (free),
+ @@ R12=__const_ptr_, R14=&block[n]
+
+__a_evaluation:
+ @@ a0 = (W4 * row[0]) + (1 << (ROW_SHIFT - 1));
+ @@ a1 = a0 + W6 * row[2];
+ @@ a2 = a0 - W6 * row[2];
+ @@ a3 = a0 - W2 * row[2];
+ @@ a0 = a0 + W2 * row[2];
+ ldr r9, [r12, #offW4] @ R9=W4
+ mul r6, r9, r6 @ R6=W4*ROWr16[0]
+ ldr r10, [r12, #offW6] @ R10=W6
+ ldrsh r4, [r14, #4] @ R4=ROWr16[2] (a3 not defined yet)
+ add r6, r6, #ROW_SHIFTED_1 @ R6=W4*ROWr16[0] + 1<<(ROW_SHIFT-1) (a0)
+
+ mul r11, r10, r4 @ R11=W6*ROWr16[2]
+ ldr r8, [r12, #offW2] @ R8=W2
+ sub r3, r6, r11 @ R3=a0-W6*ROWr16[2] (a2)
+ @@ temp = ((uint32_t*)row)[2] | ((uint32_t*)row)[3];
+ @@ if (temp != 0) {}
+ teq r2, #0
+ beq __end_bef_a_evaluation
+
+ add r2, r6, r11 @ R2=a0+W6*ROWr16[2] (a1)
+ mul r11, r8, r4 @ R11=W2*ROWr16[2]
+ sub r4, r6, r11 @ R4=a0-W2*ROWr16[2] (a3)
+ add r6, r6, r11 @ R6=a0+W2*ROWr16[2] (a0)
+
+
+ @@ at this point, R0=b0, R1=b1, R2=a1, R3=a2, R4=a3,
+ @@ R5=b2, R6=a0, R7=b3, R8=W2, R9=W4, R10=W6, R11 (free),
+ @@ R12=__const_ptr_, R14=&block[n]
+
+
+ @@ a0 += W4*row[4]
+ @@ a1 -= W4*row[4]
+ @@ a2 -= W4*row[4]
+ @@ a3 += W4*row[4]
+ ldrsh r11, [r14, #8] @ R11=ROWr16[4]
+ teq r11, #0 @ if null avoid muls
+ mulne r11, r9, r11 @ R11=W4*ROWr16[4]
+ @@ R9 is free now
+ ldrsh r9, [r14, #12] @ R9=ROWr16[6]
+ addne r6, r6, r11 @ R6+=W4*ROWr16[4] (a0)
+ subne r2, r2, r11 @ R2-=W4*ROWr16[4] (a1)
+ subne r3, r3, r11 @ R3-=W4*ROWr16[4] (a2)
+ addne r4, r4, r11 @ R4+=W4*ROWr16[4] (a3)
+ @@ W6 alone is no more useful, save W2*ROWr16[6] in it instead
+ teq r9, #0 @ if null avoid muls
+ mulne r11, r10, r9 @ R11=W6*ROWr16[6]
+ addne r6, r6, r11 @ R6+=W6*ROWr16[6] (a0)
+ mulne r10, r8, r9 @ R10=W2*ROWr16[6]
+ @@ a0 += W6*row[6];
+ @@ a3 -= W6*row[6];
+ @@ a1 -= W2*row[6];
+ @@ a2 += W2*row[6];
+ subne r4, r4, r11 @ R4-=W6*ROWr16[6] (a3)
+ subne r2, r2, r10 @ R2-=W2*ROWr16[6] (a1)
+ addne r3, r3, r10 @ R3+=W2*ROWr16[6] (a2)
+
+__end_a_evaluation:
+ @@ at this point, R0=b0, R1=b1, R2=a1, R3=a2, R4=a3,
+ @@ R5=b2, R6=a0, R7=b3, R8 (free), R9 (free), R10 (free), R11 (free),
+ @@ R12=__const_ptr_, R14=&block[n]
+ @@ row[0] = (a0 + b0) >> ROW_SHIFT;
+ @@ row[1] = (a1 + b1) >> ROW_SHIFT;
+ @@ row[2] = (a2 + b2) >> ROW_SHIFT;
+ @@ row[3] = (a3 + b3) >> ROW_SHIFT;
+ @@ row[4] = (a3 - b3) >> ROW_SHIFT;
+ @@ row[5] = (a2 - b2) >> ROW_SHIFT;
+ @@ row[6] = (a1 - b1) >> ROW_SHIFT;
+ @@ row[7] = (a0 - b0) >> ROW_SHIFT;
+ add r8, r6, r0 @ R8=a0+b0
+ add r9, r2, r1 @ R9=a1+b1
+ @@ put 2 16 bits half-words in a 32bits word
+ @@ ROWr32[0]=ROWr16[0] | (ROWr16[1]<<16) (only Little Endian compliant then!!!)
+ ldr r10, [r12, #offMASK_MSHW] @ R10=0xFFFF0000
+ and r9, r10, r9, lsl #ROW_SHIFT2MSHW @ R9=0xFFFF0000 & ((a1+b1)<<5)
+ mvn r11, r10 @ R11= NOT R10= 0x0000FFFF
+ and r8, r11, r8, asr #ROW_SHIFT @ R8=0x0000FFFF & ((a0+b0)>>11)
+ orr r8, r8, r9
+ str r8, [r14, #0]
+
+ add r8, r3, r5 @ R8=a2+b2
+ add r9, r4, r7 @ R9=a3+b3
+ and r9, r10, r9, lsl #ROW_SHIFT2MSHW @ R9=0xFFFF0000 & ((a3+b3)<<5)
+ and r8, r11, r8, asr #ROW_SHIFT @ R8=0x0000FFFF & ((a2+b2)>>11)
+ orr r8, r8, r9
+ str r8, [r14, #4]
+
+ sub r8, r4, r7 @ R8=a3-b3
+ sub r9, r3, r5 @ R9=a2-b2
+ and r9, r10, r9, lsl #ROW_SHIFT2MSHW @ R9=0xFFFF0000 & ((a2-b2)<<5)
+ and r8, r11, r8, asr #ROW_SHIFT @ R8=0x0000FFFF & ((a3-b3)>>11)
+ orr r8, r8, r9
+ str r8, [r14, #8]
+
+ sub r8, r2, r1 @ R8=a1-b1
+ sub r9, r6, r0 @ R9=a0-b0
+ and r9, r10, r9, lsl #ROW_SHIFT2MSHW @ R9=0xFFFF0000 & ((a0-b0)<<5)
+ and r8, r11, r8, asr #ROW_SHIFT @ R8=0x0000FFFF & ((a1-b1)>>11)
+ orr r8, r8, r9
+ str r8, [r14, #12]
+
+ bal __end_row_loop
+
+__almost_empty_row:
+ @@ the row was empty, except ROWr16[0], now, management of this special case
+ @@ at this point, R0=block, R14=&block[n], R12=__const_ptr_, R1=ROWr32[0], R2=ROWr32[1],
+ @@ R3=ROWr32[2], R4=ROWr32[3], R5=(temp), R6=ROWr16[0], R7=ROWr16[1],
+ @@ R8=0xFFFF (temp), R9-R11 free
+ mov r8, #0x10000 @ R8=0xFFFF (2 steps needed!) it saves a ldr call (because of delay run).
+ sub r8, r8, #1 @ R8 is now ready.
+ and r5, r8, r6, lsl #3 @ R5=R8 & (R6<<3)= (ROWr16[0]<<3) & 0xFFFF
+ orr r5, r5, r5, lsl #16 @ R5=R5 | (R5<<16)
+ str r5, [r14, #0] @ R14[0]=ROWr32[0]=R5
+ str r5, [r14, #4] @ R14[4]=ROWr32[1]=R5
+ str r5, [r14, #8] @ R14[8]=ROWr32[2]=R5
+ str r5, [r14, #12] @ R14[12]=ROWr32[3]=R5
+
+__end_row_loop:
+ @@ at this point, R0-R11 (free)
+ @@ R12=__const_ptr_, R14=&block[n]
+ ldr r0, [sp, #0] @ R0=block
+ teq r0, r14 @ compare current &block[8*n] to block, when block is reached, the loop is finished.
+ sub r14, r14, #16
+ bne __row_loop
+
+
+
+ @@ at this point, R0=block, R1-R11 (free)
+ @@ R12=__const_ptr_, R14=&block[n]
+ add r14, r0, #14 @ R14=&block[7], better start from the last col, and decrease the value until col=0, i.e. R14=block.
+__col_loop:
+
+__b_evaluation2:
+ @@ at this point, R0=block (temp), R1-R11 (free)
+ @@ R12=__const_ptr_, R14=&block[n]
+ @@ proceed with b0-b3 first, followed by a0-a3
+ @@ MUL16(b0, W1, col[8x1]);
+ @@ MUL16(b1, W3, col[8x1]);
+ @@ MUL16(b2, W5, col[8x1]);
+ @@ MUL16(b3, W7, col[8x1]);
+ @@ MAC16(b0, W3, col[8x3]);
+ @@ MAC16(b1, -W7, col[8x3]);
+ @@ MAC16(b2, -W1, col[8x3]);
+ @@ MAC16(b3, -W5, col[8x3]);
+ ldr r8, [r12, #offW1] @ R8=W1
+ ldrsh r7, [r14, #16]
+ mul r0, r8, r7 @ R0=W1*ROWr16[1]=b0 (ROWr16[1] must be the second arg, to have the possibility to save 1 cycle)
+ ldr r9, [r12, #offW3] @ R9=W3
+ ldr r10, [r12, #offW5] @ R10=W5
+ mul r1, r9, r7 @ R1=W3*ROWr16[1]=b1 (ROWr16[1] must be the second arg, to have the possibility to save 1 cycle)
+ ldr r11, [r12, #offW7] @ R11=W7
+ mul r5, r10, r7 @ R5=W5*ROWr16[1]=b2 (ROWr16[1] must be the second arg, to have the possibility to save 1 cycle)
+ ldrsh r2, [r14, #48]
+ mul r7, r11, r7 @ R7=W7*ROWr16[1]=b3 (ROWr16[1] must be the second arg, to have the possibility to save 1 cycle)
+ teq r2, #0 @ if 0, then avoid muls
+ mlane r0, r9, r2, r0 @ R0+=W3*ROWr16[3]=b0 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle)
+ rsbne r2, r2, #0 @ R2=-ROWr16[3]
+ mlane r1, r11, r2, r1 @ R1-=W7*ROWr16[3]=b1 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle)
+ mlane r5, r8, r2, r5 @ R5-=W1*ROWr16[3]=b2 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle)
+ mlane r7, r10, r2, r7 @ R7-=W5*ROWr16[3]=b3 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle)
+
+ @@ at this point, R0=b0, R1=b1, R2 (free), R3 (free), R4 (free),
+ @@ R5=b2, R6 (free), R7=b3, R8=W1, R9=W3, R10=W5, R11=W7,
+ @@ R12=__const_ptr_, R14=&block[n]
+ @@ MAC16(b0, W5, col[5x8]);
+ @@ MAC16(b2, W7, col[5x8]);
+ @@ MAC16(b3, W3, col[5x8]);
+ @@ MAC16(b1, -W1, col[5x8]);
+ @@ MAC16(b0, W7, col[7x8]);
+ @@ MAC16(b2, W3, col[7x8]);
+ @@ MAC16(b3, -W1, col[7x8]);
+ @@ MAC16(b1, -W5, col[7x8]);
+ ldrsh r3, [r14, #80] @ R3=COLr16[5x8]
+ teq r3, #0 @ if 0 then avoid muls
+ mlane r0, r10, r3, r0 @ R0+=W5*ROWr16[5x8]=b0
+ mlane r5, r11, r3, r5 @ R5+=W7*ROWr16[5x8]=b2
+ mlane r7, r9, r3, r7 @ R7+=W3*ROWr16[5x8]=b3
+ rsbne r3, r3, #0 @ R3=-ROWr16[5x8]
+ ldrsh r4, [r14, #112] @ R4=COLr16[7x8]
+ mlane r1, r8, r3, r1 @ R7-=W1*ROWr16[5x8]=b1
+ @@ R3 is free now
+ teq r4, #0 @ if 0 then avoid muls
+ mlane r0, r11, r4, r0 @ R0+=W7*ROWr16[7x8]=b0
+ mlane r5, r9, r4, r5 @ R5+=W3*ROWr16[7x8]=b2
+ rsbne r4, r4, #0 @ R4=-ROWr16[7x8]
+ mlane r7, r8, r4, r7 @ R7-=W1*ROWr16[7x8]=b3
+ mlane r1, r10, r4, r1 @ R1-=W5*ROWr16[7x8]=b1
+ @@ R4 is free now
+__end_b_evaluation2:
+ @@ at this point, R0=b0, R1=b1, R2 (free), R3 (free), R4 (free),
+ @@ R5=b2, R6 (free), R7=b3, R8 (free), R9 (free), R10 (free), R11 (free),
+ @@ R12=__const_ptr_, R14=&block[n]
+
+__a_evaluation2:
+ @@ a0 = (W4 * col[8x0]) + (1 << (COL_SHIFT - 1));
+ @@ a1 = a0 + W6 * row[2];
+ @@ a2 = a0 - W6 * row[2];
+ @@ a3 = a0 - W2 * row[2];
+ @@ a0 = a0 + W2 * row[2];
+ ldrsh r6, [r14, #0]
+ ldr r9, [r12, #offW4] @ R9=W4
+ mul r6, r9, r6 @ R6=W4*ROWr16[0]
+ ldr r10, [r12, #offW6] @ R10=W6
+ ldrsh r4, [r14, #32] @ R4=ROWr16[2] (a3 not defined yet)
+ add r6, r6, #COL_SHIFTED_1 @ R6=W4*ROWr16[0] + 1<<(COL_SHIFT-1) (a0)
+ mul r11, r10, r4 @ R11=W6*ROWr16[2]
+ ldr r8, [r12, #offW2] @ R8=W2
+ add r2, r6, r11 @ R2=a0+W6*ROWr16[2] (a1)
+ sub r3, r6, r11 @ R3=a0-W6*ROWr16[2] (a2)
+ mul r11, r8, r4 @ R11=W2*ROWr16[2]
+ sub r4, r6, r11 @ R4=a0-W2*ROWr16[2] (a3)
+ add r6, r6, r11 @ R6=a0+W2*ROWr16[2] (a0)
+
+ @@ at this point, R0=b0, R1=b1, R2=a1, R3=a2, R4=a3,
+ @@ R5=b2, R6=a0, R7=b3, R8=W2, R9=W4, R10=W6, R11 (free),
+ @@ R12=__const_ptr_, R14=&block[n]
+ @@ a0 += W4*row[4]
+ @@ a1 -= W4*row[4]
+ @@ a2 -= W4*row[4]
+ @@ a3 += W4*row[4]
+ ldrsh r11, [r14, #64] @ R11=ROWr16[4]
+ teq r11, #0 @ if null avoid muls
+ mulne r11, r9, r11 @ R11=W4*ROWr16[4]
+ @@ R9 is free now
+ addne r6, r6, r11 @ R6+=W4*ROWr16[4] (a0)
+ subne r2, r2, r11 @ R2-=W4*ROWr16[4] (a1)
+ subne r3, r3, r11 @ R3-=W4*ROWr16[4] (a2)
+ ldrsh r9, [r14, #96] @ R9=ROWr16[6]
+ addne r4, r4, r11 @ R4+=W4*ROWr16[4] (a3)
+ @@ W6 alone is no more useful, save W2*ROWr16[6] in it instead
+ teq r9, #0 @ if null avoid muls
+ mulne r11, r10, r9 @ R11=W6*ROWr16[6]
+ addne r6, r6, r11 @ R6+=W6*ROWr16[6] (a0)
+ mulne r10, r8, r9 @ R10=W2*ROWr16[6]
+ @@ a0 += W6*row[6];
+ @@ a3 -= W6*row[6];
+ @@ a1 -= W2*row[6];
+ @@ a2 += W2*row[6];
+ subne r4, r4, r11 @ R4-=W6*ROWr16[6] (a3)
+ subne r2, r2, r10 @ R2-=W2*ROWr16[6] (a1)
+ addne r3, r3, r10 @ R3+=W2*ROWr16[6] (a2)
+__end_a_evaluation2:
+ @@ at this point, R0=b0, R1=b1, R2=a1, R3=a2, R4=a3,
+ @@ R5=b2, R6=a0, R7=b3, R8 (free), R9 (free), R10 (free), R11 (free),
+ @@ R12=__const_ptr_, R14=&block[n]
+ @@ col[0 ] = ((a0 + b0) >> COL_SHIFT);
+ @@ col[8 ] = ((a1 + b1) >> COL_SHIFT);
+ @@ col[16] = ((a2 + b2) >> COL_SHIFT);
+ @@ col[24] = ((a3 + b3) >> COL_SHIFT);
+ @@ col[32] = ((a3 - b3) >> COL_SHIFT);
+ @@ col[40] = ((a2 - b2) >> COL_SHIFT);
+ @@ col[48] = ((a1 - b1) >> COL_SHIFT);
+ @@ col[56] = ((a0 - b0) >> COL_SHIFT);
+ @@@@@ no optimisation here @@@@@
+ add r8, r6, r0 @ R8=a0+b0
+ add r9, r2, r1 @ R9=a1+b1
+ mov r8, r8, asr #COL_SHIFT
+ mov r9, r9, asr #COL_SHIFT
+ strh r8, [r14, #0]
+ strh r9, [r14, #16]
+ add r8, r3, r5 @ R8=a2+b2
+ add r9, r4, r7 @ R9=a3+b3
+ mov r8, r8, asr #COL_SHIFT
+ mov r9, r9, asr #COL_SHIFT
+ strh r8, [r14, #32]
+ strh r9, [r14, #48]
+ sub r8, r4, r7 @ R8=a3-b3
+ sub r9, r3, r5 @ R9=a2-b2
+ mov r8, r8, asr #COL_SHIFT
+ mov r9, r9, asr #COL_SHIFT
+ strh r8, [r14, #64]
+ strh r9, [r14, #80]
+ sub r8, r2, r1 @ R8=a1-b1
+ sub r9, r6, r0 @ R9=a0-b0
+ mov r8, r8, asr #COL_SHIFT
+ mov r9, r9, asr #COL_SHIFT
+ strh r8, [r14, #96]
+ strh r9, [r14, #112]
+
+__end_col_loop:
+ @@ at this point, R0-R11 (free)
+ @@ R12=__const_ptr_, R14=&block[n]
+ ldr r0, [sp, #0] @ R0=block
+ teq r0, r14 @ compare current &block[n] to block, when block is reached, the loop is finished.
+ sub r14, r14, #2
+ bne __col_loop
+
+
+
+
+__end_simple_idct_ARM:
+ @@ restore registers to previous status!
+ add sp, sp, #8 @@ the local variables!
+ ldmfd sp!, {r4-r11, r15} @@ update PC with LR content.
+
+
+
+@@ kind of sub-function, here not to overload the common case.
+__end_bef_a_evaluation:
+ add r2, r6, r11 @ R2=a0+W6*ROWr16[2] (a1)
+ mul r11, r8, r4 @ R11=W2*ROWr16[2]
+ sub r4, r6, r11 @ R4=a0-W2*ROWr16[2] (a3)
+ add r6, r6, r11 @ R6=a0+W2*ROWr16[2] (a0)
+ bal __end_a_evaluation
+
+
+__constant_ptr__: @@ see #defines at the beginning of the source code for values.
+ .align
+ .word W1
+ .word W2
+ .word W3
+ .word W4
+ .word W5
+ .word W6
+ .word W7
+ .word MASK_MSHW
diff --git a/src/libffmpeg/libavcodec/asv1.c b/src/libffmpeg/libavcodec/asv1.c
index 24916590f..2ab729c17 100644
--- a/src/libffmpeg/libavcodec/asv1.c
+++ b/src/libffmpeg/libavcodec/asv1.c
@@ -403,8 +403,6 @@ static int decode_frame(AVCodecContext *avctx,
AVFrame * const p= (AVFrame*)&a->picture;
int mb_x, mb_y;
- *data_size = 0;
-
/* special case for last picture */
if (buf_size == 0) {
return 0;
diff --git a/src/libffmpeg/libavcodec/avcodec.h b/src/libffmpeg/libavcodec/avcodec.h
index d071e0891..26fee27ef 100644
--- a/src/libffmpeg/libavcodec/avcodec.h
+++ b/src/libffmpeg/libavcodec/avcodec.h
@@ -24,7 +24,7 @@ extern "C" {
#define FFMPEG_VERSION_INT 0x000408
#define FFMPEG_VERSION "0.4.8"
-#define LIBAVCODEC_BUILD 4713
+#define LIBAVCODEC_BUILD 4715
#define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT
#define LIBAVCODEC_VERSION FFMPEG_VERSION
@@ -799,7 +799,7 @@ typedef struct AVCodecContext {
/* every time the encoder as a packet to send */
/* Depends on the encoder if the data starts */
/* with a Start Code (it should) H.263 does */
- void (*rtp_callback)(void *data, int size, int packet_number);
+ void (*rtp_callback)(struct AVCodecContext *avctx, void *data, int size, int packet_number);
/* statistics, used for 2-pass encoding */
int mv_bits;
@@ -904,7 +904,8 @@ typedef struct AVCodecContext {
/**
* called at the beginning of each frame to get a buffer for it.
* if pic.reference is set then the frame will be read later by lavc
- * width and height should be rounded up to the next multiple of 16
+ * avcodec_align_dimensions() should be used to find the required width and
+ * height, as they normally need to be rounded up to the next multiple of 16
* - encoding: unused
* - decoding: set by lavc, user can override
*/
@@ -1665,6 +1666,7 @@ typedef struct AVCodec {
struct AVCodec *next;
void (*flush)(AVCodecContext *);
const AVRational *supported_framerates; ///array of supported framerates, or NULL if any, array is terminated by {0,0}
+ const enum PixelFormat *pix_fmts; ///array of supported pixel formats, or NULL if unknown, array is terminanted by -1
} AVCodec;
/**
@@ -1944,10 +1946,14 @@ AVFrame *avcodec_alloc_frame(void);
int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic);
void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic);
+int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic);
+void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height);
+enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat * fmt);
int avcodec_thread_init(AVCodecContext *s, int thread_count);
void avcodec_thread_free(AVCodecContext *s);
int avcodec_thread_execute(AVCodecContext *s, int (*func)(AVCodecContext *c2, void *arg2),void **arg, int *ret, int count);
+int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void **arg, int *ret, int count);
//FIXME func typedef
/**
@@ -2091,6 +2097,7 @@ typedef struct AVCodecParserContext {
/* private data */
int64_t last_pts;
int64_t last_dts;
+ int fetch_timestamp;
#define AV_PARSER_PTS_NB 4
int cur_frame_start_index;
@@ -2164,6 +2171,7 @@ extern void av_log_set_level(int);
extern void av_log_set_callback(void (*)(void*, int, const char*, va_list));
/* endian macros */
+#if !defined(BE_16) || !defined(BE_32) || !defined(LE_16) || !defined(LE_32)
#define BE_16(x) ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1])
#define BE_32(x) ((((uint8_t*)(x))[0] << 24) | \
(((uint8_t*)(x))[1] << 16) | \
@@ -2174,6 +2182,14 @@ extern void av_log_set_callback(void (*)(void*, int, const char*, va_list));
(((uint8_t*)(x))[2] << 16) | \
(((uint8_t*)(x))[1] << 8) | \
((uint8_t*)(x))[0])
+#endif
+
+/* unused static macro */
+#if defined(__GNUC__) && !defined(DEBUG)
+/* since we do not compile the encoder part of ffmpeg, some static
+ * functions will be unused; this is ok, the compiler will take care */
+# define static static __attribute__((__unused__))
+#endif
#ifdef __cplusplus
}
diff --git a/src/libffmpeg/libavcodec/cabac.c b/src/libffmpeg/libavcodec/cabac.c
index 0e3e14f56..2ae996a39 100644
--- a/src/libffmpeg/libavcodec/cabac.c
+++ b/src/libffmpeg/libavcodec/cabac.c
@@ -90,7 +90,7 @@ void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size){
*
* @param buf_size size of buf in bits
*/
-void ff_init_cabac_decoder(CABACContext *c, uint8_t *buf, int buf_size){
+void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size){
c->bytestream_start=
c->bytestream= buf;
diff --git a/src/libffmpeg/libavcodec/cabac.h b/src/libffmpeg/libavcodec/cabac.h
index 852d47ebe..05c47363d 100644
--- a/src/libffmpeg/libavcodec/cabac.h
+++ b/src/libffmpeg/libavcodec/cabac.h
@@ -37,8 +37,8 @@ typedef struct CABACContext{
uint8_t lps_range[2*64][4]; ///< rangeTabLPS
uint8_t lps_state[2*64]; ///< transIdxLPS
uint8_t mps_state[2*64]; ///< transIdxMPS
- uint8_t *bytestream_start;
- uint8_t *bytestream;
+ const uint8_t *bytestream_start;
+ const uint8_t *bytestream;
int bits_left; ///<
PutBitContext pb;
}CABACContext;
@@ -48,7 +48,7 @@ extern const uint8_t ff_h264_mps_state[64];
extern const uint8_t ff_h264_lps_state[64];
void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size);
-void ff_init_cabac_decoder(CABACContext *c, uint8_t *buf, int buf_size);
+void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size);
void ff_init_cabac_states(CABACContext *c, uint8_t const (*lps_range)[4],
uint8_t const *mps_state, uint8_t const *lps_state, int state_count);
diff --git a/src/libffmpeg/libavcodec/cljr.c b/src/libffmpeg/libavcodec/cljr.c
new file mode 100644
index 000000000..df1f79851
--- /dev/null
+++ b/src/libffmpeg/libavcodec/cljr.c
@@ -0,0 +1,159 @@
+/*
+ * Cirrus Logic AccuPak (CLJR) codec
+ * Copyright (c) 2003 Alex Beregszaszi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/**
+ * @file cljr.c
+ * Cirrus Logic AccuPak codec.
+ */
+
+#include "avcodec.h"
+#include "mpegvideo.h"
+
+typedef struct CLJRContext{
+ AVCodecContext *avctx;
+ AVFrame picture;
+ int delta[16];
+ int offset[4];
+ GetBitContext gb;
+} CLJRContext;
+
+static int decode_frame(AVCodecContext *avctx,
+ void *data, int *data_size,
+ uint8_t *buf, int buf_size)
+{
+ CLJRContext * const a = avctx->priv_data;
+ AVFrame *picture = data;
+ AVFrame * const p= (AVFrame*)&a->picture;
+ int x, y;
+
+ /* special case for last picture */
+ if (buf_size == 0) {
+ return 0;
+ }
+
+ if(p->data[0])
+ avctx->release_buffer(avctx, p);
+
+ p->reference= 0;
+ if(avctx->get_buffer(avctx, p) < 0){
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return -1;
+ }
+ p->pict_type= I_TYPE;
+ p->key_frame= 1;
+
+ init_get_bits(&a->gb, buf, buf_size);
+
+ for(y=0; y<avctx->height; y++){
+ uint8_t *luma= &a->picture.data[0][ y*a->picture.linesize[0] ];
+ uint8_t *cb= &a->picture.data[1][ y*a->picture.linesize[1] ];
+ uint8_t *cr= &a->picture.data[2][ y*a->picture.linesize[2] ];
+ for(x=0; x<avctx->width; x+=4){
+ luma[3] = get_bits(&a->gb, 5) << 3;
+ luma[2] = get_bits(&a->gb, 5) << 3;
+ luma[1] = get_bits(&a->gb, 5) << 3;
+ luma[0] = get_bits(&a->gb, 5) << 3;
+ luma+= 4;
+ *(cb++) = get_bits(&a->gb, 6) << 2;
+ *(cr++) = get_bits(&a->gb, 6) << 2;
+ }
+ }
+
+ *picture= *(AVFrame*)&a->picture;
+ *data_size = sizeof(AVPicture);
+
+ emms_c();
+
+ return buf_size;
+}
+
+#if 0
+static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
+ CLJRContext * const a = avctx->priv_data;
+ AVFrame *pict = data;
+ AVFrame * const p= (AVFrame*)&a->picture;
+ int size;
+ int mb_x, mb_y;
+
+ *p = *pict;
+ p->pict_type= I_TYPE;
+ p->key_frame= 1;
+
+ emms_c();
+
+ align_put_bits(&a->pb);
+ while(get_bit_count(&a->pb)&31)
+ put_bits(&a->pb, 8, 0);
+
+ size= get_bit_count(&a->pb)/32;
+
+ return size*4;
+}
+#endif
+
+static void common_init(AVCodecContext *avctx){
+ CLJRContext * const a = avctx->priv_data;
+
+ avctx->coded_frame= (AVFrame*)&a->picture;
+ a->avctx= avctx;
+}
+
+static int decode_init(AVCodecContext *avctx){
+
+ common_init(avctx);
+
+ avctx->pix_fmt= PIX_FMT_YUV411P;
+
+ return 0;
+}
+
+static int encode_init(AVCodecContext *avctx){
+
+ common_init(avctx);
+
+ return 0;
+}
+
+AVCodec cljr_decoder = {
+ "cljr",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_CLJR,
+ sizeof(CLJRContext),
+ decode_init,
+ NULL,
+ NULL,
+ decode_frame,
+ CODEC_CAP_DR1,
+};
+#if 0
+#ifdef CONFIG_ENCODERS
+
+AVCodec cljr_encoder = {
+ "cljr",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_cljr,
+ sizeof(CLJRContext),
+ encode_init,
+ encode_frame,
+ //encode_end,
+};
+
+#endif //CONFIG_ENCODERS
+#endif
diff --git a/src/libffmpeg/libavcodec/common.h b/src/libffmpeg/libavcodec/common.h
index b6fdcdd6e..5cf9f2c73 100644
--- a/src/libffmpeg/libavcodec/common.h
+++ b/src/libffmpeg/libavcodec/common.h
@@ -6,7 +6,7 @@
#ifndef COMMON_H
#define COMMON_H
-// xine: disable DEBUG for ffmpeg (too noisy)
+/* xine: disable DEBUG for ffmpeg (too noisy) */
#ifdef DEBUG
#undef DEBUG
#endif
@@ -120,6 +120,10 @@ extern const struct AVOption avoptions_workaround_bug[11];
#define INT64_MAX int64_t_C(9223372036854775807)
#endif
+#ifndef UINT64_MAX
+#define UINT64_MAX uint64_t_C(0xFFFFFFFFFFFFFFFF)
+#endif
+
#ifdef EMULATE_FAST_INT
/* note that we don't emulate 64bit ints */
typedef signed char int_fast8_t;
@@ -213,8 +217,10 @@ static inline float floorf(float f) {
/* debug stuff */
-# if !defined(DEBUG) && !defined(NDEBUG)
+# ifndef DEBUG
+# ifndef NDEBUG
# define NDEBUG
+# endif
# endif
# include <assert.h>
@@ -1282,7 +1288,6 @@ tend= rdtsc();\
#define CLAMP_TO_8BIT(d) ((d > 0xff) ? 0xff : (d < 0) ? 0 : d)
/* avoid usage of various functions */
-#if 0
#define malloc please_use_av_malloc
#define free please_use_av_free
#define realloc please_use_av_realloc
@@ -1293,7 +1298,6 @@ tend= rdtsc();\
#define printf please_use_av_log
#define fprintf please_use_av_log
#endif
-#endif
#define CHECKED_ALLOCZ(p, size)\
{\
diff --git a/src/libffmpeg/libavcodec/cyuv.c b/src/libffmpeg/libavcodec/cyuv.c
index aee2bc5ec..82bc21005 100644
--- a/src/libffmpeg/libavcodec/cyuv.c
+++ b/src/libffmpeg/libavcodec/cyuv.c
@@ -81,8 +81,6 @@ static int cyuv_decode_frame(AVCodecContext *avctx,
unsigned char cur_byte;
int pixel_groups;
- *data_size = 0;
-
/* sanity check the buffer size: A buffer has 3x16-bytes tables
* followed by (height) lines each with 3 bytes to represent groups
* of 4 pixels. Thus, the total size of the buffer ought to be:
diff --git a/src/libffmpeg/libavcodec/dsputil.h b/src/libffmpeg/libavcodec/dsputil.h
index 83c0c4b23..adb4679e0 100644
--- a/src/libffmpeg/libavcodec/dsputil.h
+++ b/src/libffmpeg/libavcodec/dsputil.h
@@ -567,6 +567,11 @@ static inline long int lrintf(float x)
return (int)(rint(x));
#endif
}
+#else
+#ifndef _ISOC9X_SOURCE
+#define _ISOC9X_SOURCE
+#endif
+#include <math.h>
#endif
#endif
diff --git a/src/libffmpeg/libavcodec/dv.c b/src/libffmpeg/libavcodec/dv.c
index c62c964fb..8e359e361 100644
--- a/src/libffmpeg/libavcodec/dv.c
+++ b/src/libffmpeg/libavcodec/dv.c
@@ -171,8 +171,12 @@ static int dvvideo_init(AVCodecContext *avctx)
free_vlc(&dv_vlc);
for (i = 0; i < NB_DV_VLC - 1; i++) {
- if (dv_vlc_run[i] >= DV_VLC_MAP_RUN_SIZE || dv_vlc_level[i] >= DV_VLC_MAP_LEV_SIZE)
+ if (dv_vlc_run[i] >= DV_VLC_MAP_RUN_SIZE)
continue;
+#ifdef DV_CODEC_TINY_TARGET
+ if (dv_vlc_level[i] >= DV_VLC_MAP_LEV_SIZE)
+ continue;
+#endif
if (dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size != 0)
continue;
@@ -885,7 +889,6 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
{
DVVideoContext *s = avctx->priv_data;
- *data_size=0;
/* special case for last picture */
if(buf_size==0)
return 0;
diff --git a/src/libffmpeg/libavcodec/faandct.c b/src/libffmpeg/libavcodec/faandct.c
index 2a9118495..0462cee61 100644
--- a/src/libffmpeg/libavcodec/faandct.c
+++ b/src/libffmpeg/libavcodec/faandct.c
@@ -26,8 +26,6 @@
* @author Michael Niedermayer <michaelni@gmx.at>
*/
-#include <math.h>
-
#include "dsputil.h"
#include "faandct.h"
diff --git a/src/libffmpeg/libavcodec/ffv1.c b/src/libffmpeg/libavcodec/ffv1.c
new file mode 100644
index 000000000..a85baea4b
--- /dev/null
+++ b/src/libffmpeg/libavcodec/ffv1.c
@@ -0,0 +1,1035 @@
+/*
+ * FFV1 codec for libavcodec
+ *
+ * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/**
+ * @file ffv1.c
+ * FF Video Codec 1 (an experimental lossless codec)
+ */
+
+#include "common.h"
+#include "avcodec.h"
+#include "dsputil.h"
+#include "cabac.h"
+#include "golomb.h"
+
+#define MAX_PLANES 4
+#define CONTEXT_SIZE 32
+
+static const int8_t quant3[256]={
+ 0, 0, 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, 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,
+ 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, 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,-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,-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,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0,
+};
+static const int8_t quant5[256]={
+ 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
+-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
+-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
+-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
+-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
+-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
+-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
+-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-1,-1,
+};
+static const int8_t quant7[256]={
+ 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
+-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
+-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
+-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
+-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
+-3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-2,-2,-2,
+-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
+-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-1,
+};
+static const int8_t quant9[256]={
+ 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
+-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
+-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
+-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
+-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
+-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
+-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,
+-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-1,-1,
+};
+static const int8_t quant11[256]={
+ 0, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
+-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
+-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
+-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
+-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
+-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-4,-4,
+-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
+-4,-4,-4,-4,-4,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-1,
+};
+static const int8_t quant13[256]={
+ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 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, 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, 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,-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,-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,-5,
+-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
+-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
+-4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,-2,-2,-1,
+};
+
+static const uint8_t log2_run[32]={
+ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 9,10,11,12,13,14,15,
+};
+
+typedef struct VlcState{
+ int16_t drift;
+ uint16_t error_sum;
+ int8_t bias;
+ uint8_t count;
+} VlcState;
+
+typedef struct PlaneContext{
+ int context_count;
+ uint8_t (*state)[CONTEXT_SIZE];
+ VlcState *vlc_state;
+ uint8_t interlace_bit_state[2];
+} PlaneContext;
+
+typedef struct FFV1Context{
+ AVCodecContext *avctx;
+ CABACContext c;
+ GetBitContext gb;
+ PutBitContext pb;
+ int version;
+ int width, height;
+ int chroma_h_shift, chroma_v_shift;
+ int flags;
+ int picture_number;
+ AVFrame picture;
+ int plane_count;
+ int ac; ///< 1-> CABAC 0-> golomb rice
+ PlaneContext plane[MAX_PLANES];
+ int16_t quant_table[5][256];
+ int run_index;
+ int colorspace;
+
+ DSPContext dsp;
+}FFV1Context;
+
+static always_inline int fold(int diff, int bits){
+ if(bits==8)
+ diff= (int8_t)diff;
+ else{
+ diff+= 1<<(bits-1);
+ diff&=(1<<bits)-1;
+ diff-= 1<<(bits-1);
+ }
+
+ return diff;
+}
+
+static inline int predict(int_fast16_t *src, int_fast16_t *last){
+ const int LT= last[-1];
+ const int T= last[ 0];
+ const int L = src[-1];
+
+ return mid_pred(L, L + T - LT, T);
+}
+
+static inline int get_context(FFV1Context *f, int_fast16_t *src, int_fast16_t *last, int_fast16_t *last2){
+ const int LT= last[-1];
+ const int T= last[ 0];
+ const int RT= last[ 1];
+ const int L = src[-1];
+
+ if(f->quant_table[3][127]){
+ const int TT= last2[0];
+ const int LL= src[-2];
+ return f->quant_table[0][(L-LT) & 0xFF] + f->quant_table[1][(LT-T) & 0xFF] + f->quant_table[2][(T-RT) & 0xFF]
+ +f->quant_table[3][(LL-L) & 0xFF] + f->quant_table[4][(TT-T) & 0xFF];
+ }else
+ return f->quant_table[0][(L-LT) & 0xFF] + f->quant_table[1][(LT-T) & 0xFF] + f->quant_table[2][(T-RT) & 0xFF];
+}
+
+/**
+ * put
+ */
+static inline void put_symbol(CABACContext *c, uint8_t *state, int v, int is_signed, int max_exp){
+ int i;
+
+ if(v){
+ const int a= ABS(v);
+ const int e= av_log2(a);
+
+ put_cabac(c, state+0, 0);
+
+ for(i=0; i<e; i++){
+ put_cabac(c, state+1+i, 1); //1..8
+ }
+
+ if(e<max_exp){
+ put_cabac(c, state+1+i, 0); //1..8
+
+ for(i=e-1; i>=0; i--){
+ put_cabac(c, state+16+e+i, (a>>i)&1); //17..29
+ }
+ if(is_signed)
+ put_cabac(c, state+9 + e, v < 0); //9..16
+ }
+ }else{
+ put_cabac(c, state+0, 1);
+ }
+}
+
+static inline int get_symbol(CABACContext *c, uint8_t *state, int is_signed, int max_exp){
+ if(get_cabac(c, state+0))
+ return 0;
+ else{
+ int i, e;
+
+ for(e=0; e<max_exp; e++){
+ int a= 1<<e;
+
+ if(get_cabac(c, state + 1 + e)==0){ // 1..8
+ for(i=e-1; i>=0; i--){
+ a += get_cabac(c, state+16+e+i)<<i; //17..29
+ }
+
+ if(is_signed && get_cabac(c, state+9 + e)) //9..16
+ return -a;
+ else
+ return a;
+ }
+ }
+ return -(1<<e);
+ }
+}
+
+static inline void update_vlc_state(VlcState * const state, const int v){
+ int drift= state->drift;
+ int count= state->count;
+ state->error_sum += ABS(v);
+ drift += v;
+
+ if(count == 128){ //FIXME variable
+ count >>= 1;
+ drift >>= 1;
+ state->error_sum >>= 1;
+ }
+ count++;
+
+ if(drift <= -count){
+ if(state->bias > -128) state->bias--;
+
+ drift += count;
+ if(drift <= -count)
+ drift= -count + 1;
+ }else if(drift > 0){
+ if(state->bias < 127) state->bias++;
+
+ drift -= count;
+ if(drift > 0)
+ drift= 0;
+ }
+
+ state->drift= drift;
+ state->count= count;
+}
+
+static inline void put_vlc_symbol(PutBitContext *pb, VlcState * const state, int v, int bits){
+ int i, k, code;
+//printf("final: %d ", v);
+ v = fold(v - state->bias, bits);
+
+ i= state->count;
+ k=0;
+ while(i < state->error_sum){ //FIXME optimize
+ k++;
+ i += i;
+ }
+
+ assert(k<=8);
+
+#if 0 // JPEG LS
+ if(k==0 && 2*state->drift <= - state->count) code= v ^ (-1);
+ else code= v;
+#else
+ code= v ^ ((2*state->drift + state->count)>>31);
+#endif
+
+ code = -2*code-1;
+ code^= (code>>31);
+//printf("v:%d/%d bias:%d error:%d drift:%d count:%d k:%d\n", v, code, state->bias, state->error_sum, state->drift, state->count, k);
+ set_ur_golomb(pb, code, k, 12, bits);
+
+ update_vlc_state(state, v);
+}
+
+static inline int get_vlc_symbol(GetBitContext *gb, VlcState * const state, int bits){
+ int k, i, v, ret;
+
+ i= state->count;
+ k=0;
+ while(i < state->error_sum){ //FIXME optimize
+ k++;
+ i += i;
+ }
+
+ assert(k<=8);
+
+ v= get_ur_golomb(gb, k, 12, bits);
+//printf("v:%d bias:%d error:%d drift:%d count:%d k:%d", v, state->bias, state->error_sum, state->drift, state->count, k);
+
+ v++;
+ if(v&1) v= (v>>1);
+ else v= -(v>>1);
+
+#if 0 // JPEG LS
+ if(k==0 && 2*state->drift <= - state->count) v ^= (-1);
+#else
+ v ^= ((2*state->drift + state->count)>>31);
+#endif
+
+ ret= fold(v + state->bias, bits);
+
+ update_vlc_state(state, v);
+//printf("final: %d\n", ret);
+ return ret;
+}
+
+static inline void encode_line(FFV1Context *s, int w, int_fast16_t *sample[2], int plane_index, int bits){
+ PlaneContext * const p= &s->plane[plane_index];
+ CABACContext * const c= &s->c;
+ int x;
+ int run_index= s->run_index;
+ int run_count=0;
+ int run_mode=0;
+
+ for(x=0; x<w; x++){
+ int diff, context;
+
+ context= get_context(s, sample[0]+x, sample[1]+x, sample[2]+x);
+ diff= sample[0][x] - predict(sample[0]+x, sample[1]+x);
+
+ if(context < 0){
+ context = -context;
+ diff= -diff;
+ }
+
+ diff= fold(diff, bits);
+
+ if(s->ac){
+ put_symbol(c, p->state[context], diff, 1, bits-1);
+ }else{
+ if(context == 0) run_mode=1;
+
+ if(run_mode){
+
+ if(diff){
+ while(run_count >= 1<<log2_run[run_index]){
+ run_count -= 1<<log2_run[run_index];
+ run_index++;
+ put_bits(&s->pb, 1, 1);
+ }
+
+ put_bits(&s->pb, 1 + log2_run[run_index], run_count);
+ if(run_index) run_index--;
+ run_count=0;
+ run_mode=0;
+ if(diff>0) diff--;
+ }else{
+ run_count++;
+ }
+ }
+
+// printf("count:%d index:%d, mode:%d, x:%d y:%d pos:%d\n", run_count, run_index, run_mode, x, y, (int)put_bits_count(&s->pb));
+
+ if(run_mode == 0)
+ put_vlc_symbol(&s->pb, &p->vlc_state[context], diff, bits);
+ }
+ }
+ if(run_mode){
+ while(run_count >= 1<<log2_run[run_index]){
+ run_count -= 1<<log2_run[run_index];
+ run_index++;
+ put_bits(&s->pb, 1, 1);
+ }
+
+ if(run_count)
+ put_bits(&s->pb, 1, 1);
+ }
+ s->run_index= run_index;
+}
+
+static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index){
+ int x,y,i;
+ const int ring_size=2;
+ int_fast16_t sample_buffer[ring_size][w+6], *sample[ring_size];
+ s->run_index=0;
+
+ memset(sample_buffer, 0, sizeof(sample_buffer));
+
+ for(y=0; y<h; y++){
+ for(i=0; i<ring_size; i++)
+ sample[i]= sample_buffer[(h+i-y)%ring_size]+3;
+
+ sample[0][-1]= sample[1][0 ];
+ sample[1][ w]= sample[1][w-1];
+//{START_TIMER
+ for(x=0; x<w; x++){
+ sample[0][x]= src[x + stride*y];
+ }
+ encode_line(s, w, sample, plane_index, 8);
+//STOP_TIMER("encode line")}
+ }
+}
+
+static void encode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int stride){
+ int x, y, p, i;
+ const int ring_size=2;
+ int_fast16_t sample_buffer[3][ring_size][w+6], *sample[3][ring_size];
+ s->run_index=0;
+
+ memset(sample_buffer, 0, sizeof(sample_buffer));
+
+ for(y=0; y<h; y++){
+ for(i=0; i<ring_size; i++)
+ for(p=0; p<3; p++)
+ sample[p][i]= sample_buffer[p][(h+i-y)%ring_size]+3;
+
+ for(x=0; x<w; x++){
+ int v= src[x + stride*y];
+ int b= v&0xFF;
+ int g= (v>>8)&0xFF;
+ int r= (v>>16)&0xFF;
+
+ b -= g;
+ r -= g;
+ g += (b + r)>>2;
+ b += 0x100;
+ r += 0x100;
+
+// assert(g>=0 && b>=0 && r>=0);
+// assert(g<256 && b<512 && r<512);
+ sample[0][0][x]= g;
+ sample[1][0][x]= b;
+ sample[2][0][x]= r;
+ }
+ for(p=0; p<3; p++){
+ sample[p][0][-1]= sample[p][1][0 ];
+ sample[p][1][ w]= sample[p][1][w-1];
+ encode_line(s, w, sample[p], FFMIN(p, 1), 9);
+ }
+ }
+}
+
+static void write_quant_table(CABACContext *c, int16_t *quant_table){
+ int last=0;
+ int i;
+ uint8_t state[CONTEXT_SIZE]={0};
+
+ for(i=1; i<128 ; i++){
+ if(quant_table[i] != quant_table[i-1]){
+ put_symbol(c, state, i-last-1, 0, 7);
+ last= i;
+ }
+ }
+ put_symbol(c, state, i-last-1, 0, 7);
+}
+
+static void write_header(FFV1Context *f){
+ uint8_t state[CONTEXT_SIZE]={0};
+ int i;
+ CABACContext * const c= &f->c;
+
+ put_symbol(c, state, f->version, 0, 7);
+ put_symbol(c, state, f->avctx->coder_type, 0, 7);
+ put_symbol(c, state, f->colorspace, 0, 7); //YUV cs type
+ put_cabac(c, state, 1); //chroma planes
+ put_symbol(c, state, f->chroma_h_shift, 0, 7);
+ put_symbol(c, state, f->chroma_v_shift, 0, 7);
+ put_cabac(c, state, 0); //no transparency plane
+
+ for(i=0; i<5; i++)
+ write_quant_table(c, f->quant_table[i]);
+}
+
+static int common_init(AVCodecContext *avctx){
+ FFV1Context *s = avctx->priv_data;
+ int width, height;
+
+ s->avctx= avctx;
+ s->flags= avctx->flags;
+
+ dsputil_init(&s->dsp, avctx);
+
+ width= s->width= avctx->width;
+ height= s->height= avctx->height;
+
+ assert(width && height);
+
+ return 0;
+}
+
+static int encode_init(AVCodecContext *avctx)
+{
+ FFV1Context *s = avctx->priv_data;
+ int i;
+
+ common_init(avctx);
+
+ s->version=0;
+ s->ac= avctx->coder_type;
+
+ s->plane_count=2;
+ for(i=0; i<256; i++){
+ s->quant_table[0][i]= quant11[i];
+ s->quant_table[1][i]= 11*quant11[i];
+ if(avctx->context_model==0){
+ s->quant_table[2][i]= 11*11*quant11[i];
+ s->quant_table[3][i]=
+ s->quant_table[4][i]=0;
+ }else{
+ s->quant_table[2][i]= 11*11*quant5 [i];
+ s->quant_table[3][i]= 5*11*11*quant5 [i];
+ s->quant_table[4][i]= 5*5*11*11*quant5 [i];
+ }
+ }
+
+ for(i=0; i<s->plane_count; i++){
+ PlaneContext * const p= &s->plane[i];
+
+ if(avctx->context_model==0){
+ p->context_count= (11*11*11+1)/2;
+ }else{
+ p->context_count= (11*11*5*5*5+1)/2;
+ }
+
+ if(s->ac){
+ if(!p->state) p->state= av_malloc(CONTEXT_SIZE*p->context_count*sizeof(uint8_t));
+ }else{
+ if(!p->vlc_state) p->vlc_state= av_malloc(p->context_count*sizeof(VlcState));
+ }
+ }
+
+ avctx->coded_frame= &s->picture;
+ switch(avctx->pix_fmt){
+ case PIX_FMT_YUV444P:
+ case PIX_FMT_YUV422P:
+ case PIX_FMT_YUV420P:
+ case PIX_FMT_YUV411P:
+ case PIX_FMT_YUV410P:
+ s->colorspace= 0;
+ break;
+ case PIX_FMT_RGBA32:
+ s->colorspace= 1;
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "format not supported\n");
+ return -1;
+ }
+ avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift);
+
+ s->picture_number=0;
+
+ return 0;
+}
+
+
+static void clear_state(FFV1Context *f){
+ int i, j;
+
+ for(i=0; i<f->plane_count; i++){
+ PlaneContext *p= &f->plane[i];
+
+ p->interlace_bit_state[0]= 0;
+ p->interlace_bit_state[1]= 0;
+
+ for(j=0; j<p->context_count; j++){
+ if(f->ac){
+ memset(p->state[j], 0, sizeof(uint8_t)*CONTEXT_SIZE);
+ p->state[j][7] = 2*62;
+ }else{
+ p->vlc_state[j].drift= 0;
+ p->vlc_state[j].error_sum= 4; //FFMAX((RANGE + 32)/64, 2);
+ p->vlc_state[j].bias= 0;
+ p->vlc_state[j].count= 1;
+ }
+ }
+ }
+}
+
+static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
+ FFV1Context *f = avctx->priv_data;
+ CABACContext * const c= &f->c;
+ AVFrame *pict = data;
+ const int width= f->width;
+ const int height= f->height;
+ AVFrame * const p= &f->picture;
+ int used_count= 0;
+
+ if(avctx->strict_std_compliance >= 0){
+ av_log(avctx, AV_LOG_ERROR, "this codec is under development, files encoded with it wont be decodeable with future versions!!!\n"
+ "use vstrict=-1 to use it anyway\n");
+ return -1;
+ }
+
+ ff_init_cabac_encoder(c, buf, buf_size);
+ ff_init_cabac_states(c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64);
+ c->lps_state[2] = 1;
+ c->lps_state[3] = 0;
+
+ *p = *pict;
+ p->pict_type= FF_I_TYPE;
+
+ if(avctx->gop_size==0 || f->picture_number % avctx->gop_size == 0){
+ put_cabac_bypass(c, 1);
+ p->key_frame= 1;
+ write_header(f);
+ clear_state(f);
+ }else{
+ put_cabac_bypass(c, 0);
+ p->key_frame= 0;
+ }
+
+ if(!f->ac){
+ used_count += put_cabac_terminate(c, 1);
+//printf("pos=%d\n", used_count);
+ init_put_bits(&f->pb, buf + used_count, buf_size - used_count);
+ }
+
+ if(f->colorspace==0){
+ const int chroma_width = -((-width )>>f->chroma_h_shift);
+ const int chroma_height= -((-height)>>f->chroma_v_shift);
+
+ encode_plane(f, p->data[0], width, height, p->linesize[0], 0);
+
+ encode_plane(f, p->data[1], chroma_width, chroma_height, p->linesize[1], 1);
+ encode_plane(f, p->data[2], chroma_width, chroma_height, p->linesize[2], 1);
+ }else{
+ encode_rgb_frame(f, (uint32_t*)(p->data[0]), width, height, p->linesize[0]/4);
+ }
+ emms_c();
+
+ f->picture_number++;
+
+ if(f->ac){
+ return put_cabac_terminate(c, 1);
+ }else{
+ flush_put_bits(&f->pb); //nicer padding FIXME
+ return used_count + (put_bits_count(&f->pb)+7)/8;
+ }
+}
+
+static void common_end(FFV1Context *s){
+ int i;
+
+ for(i=0; i<s->plane_count; i++){
+ PlaneContext *p= &s->plane[i];
+
+ av_freep(&p->state);
+ }
+}
+
+static int encode_end(AVCodecContext *avctx)
+{
+ FFV1Context *s = avctx->priv_data;
+
+ common_end(s);
+
+ return 0;
+}
+
+static inline void decode_line(FFV1Context *s, int w, int_fast16_t *sample[2], int plane_index, int bits){
+ PlaneContext * const p= &s->plane[plane_index];
+ CABACContext * const c= &s->c;
+ int x;
+ int run_count=0;
+ int run_mode=0;
+ int run_index= s->run_index;
+
+ for(x=0; x<w; x++){
+ int diff, context, sign;
+
+ context= get_context(s, sample[1] + x, sample[0] + x, sample[1] + x);
+ if(context < 0){
+ context= -context;
+ sign=1;
+ }else
+ sign=0;
+
+
+ if(s->ac)
+ diff= get_symbol(c, p->state[context], 1, bits-1);
+ else{
+ if(context == 0 && run_mode==0) run_mode=1;
+
+ if(run_mode){
+ if(run_count==0 && run_mode==1){
+ if(get_bits1(&s->gb)){
+ run_count = 1<<log2_run[run_index];
+ if(x + run_count <= w) run_index++;
+ }else{
+ if(log2_run[run_index]) run_count = get_bits(&s->gb, log2_run[run_index]);
+ else run_count=0;
+ if(run_index) run_index--;
+ run_mode=2;
+ }
+ }
+ run_count--;
+ if(run_count < 0){
+ run_mode=0;
+ run_count=0;
+ diff= get_vlc_symbol(&s->gb, &p->vlc_state[context], bits);
+ if(diff>=0) diff++;
+ }else
+ diff=0;
+ }else
+ diff= get_vlc_symbol(&s->gb, &p->vlc_state[context], bits);
+
+// printf("count:%d index:%d, mode:%d, x:%d y:%d pos:%d\n", run_count, run_index, run_mode, x, y, get_bits_count(&s->gb));
+ }
+
+ if(sign) diff= -diff;
+
+ sample[1][x]= (predict(sample[1] + x, sample[0] + x) + diff) & ((1<<bits)-1);
+ }
+ s->run_index= run_index;
+}
+
+static void decode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index){
+ int x, y;
+ int_fast16_t sample_buffer[2][w+6];
+ int_fast16_t *sample[2]= {sample_buffer[0]+3, sample_buffer[1]+3};
+
+ s->run_index=0;
+
+ memset(sample_buffer, 0, sizeof(sample_buffer));
+
+ for(y=0; y<h; y++){
+ int_fast16_t *temp= sample[0]; //FIXME try a normal buffer
+
+ sample[0]= sample[1];
+ sample[1]= temp;
+
+ sample[1][-1]= sample[0][0 ];
+ sample[0][ w]= sample[0][w-1];
+
+//{START_TIMER
+ decode_line(s, w, sample, plane_index, 8);
+ for(x=0; x<w; x++){
+ src[x + stride*y]= sample[1][x];
+ }
+//STOP_TIMER("decode-line")}
+ }
+}
+
+static void decode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int stride){
+ int x, y, p;
+ int_fast16_t sample_buffer[3][2][w+6];
+ int_fast16_t *sample[3][2]= {
+ {sample_buffer[0][0]+3, sample_buffer[0][1]+3},
+ {sample_buffer[1][0]+3, sample_buffer[1][1]+3},
+ {sample_buffer[2][0]+3, sample_buffer[2][1]+3}};
+
+ s->run_index=0;
+
+ memset(sample_buffer, 0, sizeof(sample_buffer));
+
+ for(y=0; y<h; y++){
+ for(p=0; p<3; p++){
+ int_fast16_t *temp= sample[p][0]; //FIXME try a normal buffer
+
+ sample[p][0]= sample[p][1];
+ sample[p][1]= temp;
+
+ sample[p][1][-1]= sample[p][0][0 ];
+ sample[p][0][ w]= sample[p][0][w-1];
+ decode_line(s, w, sample[p], FFMIN(p, 1), 9);
+ }
+ for(x=0; x<w; x++){
+ int g= sample[0][1][x];
+ int b= sample[1][1][x];
+ int r= sample[2][1][x];
+
+// assert(g>=0 && b>=0 && r>=0);
+// assert(g<256 && b<512 && r<512);
+
+ b -= 0x100;
+ r -= 0x100;
+ g -= (b + r)>>2;
+ b += g;
+ r += g;
+
+ src[x + stride*y]= b + (g<<8) + (r<<16);
+ }
+ }
+}
+
+static int read_quant_table(CABACContext *c, int16_t *quant_table, int scale){
+ int v;
+ int i=0;
+ uint8_t state[CONTEXT_SIZE]={0};
+
+ for(v=0; i<128 ; v++){
+ int len= get_symbol(c, state, 0, 7) + 1;
+
+ if(len + i > 128) return -1;
+
+ while(len--){
+ quant_table[i] = scale*v;
+ i++;
+//printf("%2d ",v);
+//if(i%16==0) printf("\n");
+ }
+ }
+
+ for(i=1; i<128; i++){
+ quant_table[256-i]= -quant_table[i];
+ }
+ quant_table[128]= -quant_table[127];
+
+ return 2*v - 1;
+}
+
+static int read_header(FFV1Context *f){
+ uint8_t state[CONTEXT_SIZE]={0};
+ int i, context_count;
+ CABACContext * const c= &f->c;
+
+ f->version= get_symbol(c, state, 0, 7);
+ f->ac= f->avctx->coder_type= get_symbol(c, state, 0, 7);
+ f->colorspace= get_symbol(c, state, 0, 7); //YUV cs type
+ get_cabac(c, state); //no chroma = false
+ f->chroma_h_shift= get_symbol(c, state, 0, 7);
+ f->chroma_v_shift= get_symbol(c, state, 0, 7);
+ get_cabac(c, state); //transparency plane
+ f->plane_count= 2;
+
+ if(f->colorspace==0){
+ switch(16*f->chroma_h_shift + f->chroma_v_shift){
+ case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P; break;
+ case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P; break;
+ case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P; break;
+ case 0x20: f->avctx->pix_fmt= PIX_FMT_YUV411P; break;
+ case 0x33: f->avctx->pix_fmt= PIX_FMT_YUV410P; break;
+ default:
+ av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
+ return -1;
+ }
+ }else if(f->colorspace==1){
+ if(f->chroma_h_shift || f->chroma_v_shift){
+ av_log(f->avctx, AV_LOG_ERROR, "chroma subsampling not supported in this colorspace\n");
+ return -1;
+ }
+ f->avctx->pix_fmt= PIX_FMT_RGBA32;
+ }else{
+ av_log(f->avctx, AV_LOG_ERROR, "colorspace not supported\n");
+ return -1;
+ }
+
+//printf("%d %d %d\n", f->chroma_h_shift, f->chroma_v_shift,f->avctx->pix_fmt);
+
+ context_count=1;
+ for(i=0; i<5; i++){
+ context_count*= read_quant_table(c, f->quant_table[i], context_count);
+ if(context_count < 0){
+ av_log(f->avctx, AV_LOG_ERROR, "read_quant_table error\n");
+ return -1;
+ }
+ }
+ context_count= (context_count+1)/2;
+
+ for(i=0; i<f->plane_count; i++){
+ PlaneContext * const p= &f->plane[i];
+
+ p->context_count= context_count;
+
+ if(f->ac){
+ if(!p->state) p->state= av_malloc(CONTEXT_SIZE*p->context_count*sizeof(uint8_t));
+ }else{
+ if(!p->vlc_state) p->vlc_state= av_malloc(p->context_count*sizeof(VlcState));
+ }
+ }
+
+ return 0;
+}
+
+static int decode_init(AVCodecContext *avctx)
+{
+// FFV1Context *s = avctx->priv_data;
+
+ common_init(avctx);
+
+ return 0;
+}
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){
+ FFV1Context *f = avctx->priv_data;
+ CABACContext * const c= &f->c;
+ const int width= f->width;
+ const int height= f->height;
+ AVFrame * const p= &f->picture;
+ int bytes_read;
+
+ AVFrame *picture = data;
+
+ /* no supplementary picture */
+ if (buf_size == 0)
+ return 0;
+
+ ff_init_cabac_decoder(c, buf, buf_size);
+ ff_init_cabac_states(c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64);
+ c->lps_state[2] = 1;
+ c->lps_state[3] = 0;
+
+
+ p->pict_type= FF_I_TYPE; //FIXME I vs. P
+ if(get_cabac_bypass(c)){
+ p->key_frame= 1;
+ read_header(f);
+ clear_state(f);
+ }else{
+ p->key_frame= 0;
+ }
+
+ p->reference= 0;
+ if(avctx->get_buffer(avctx, p) < 0){
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return -1;
+ }
+
+ if(avctx->debug&FF_DEBUG_PICT_INFO)
+ av_log(avctx, AV_LOG_ERROR, "keyframe:%d coder:%d\n", p->key_frame, f->ac);
+
+ if(!f->ac){
+ bytes_read = get_cabac_terminate(c);
+ if(bytes_read ==0) av_log(avctx, AV_LOG_ERROR, "error at end of AC stream\n");
+//printf("pos=%d\n", bytes_read);
+ init_get_bits(&f->gb, buf + bytes_read, buf_size - bytes_read);
+ } else {
+ bytes_read = 0; /* avoid warning */
+ }
+
+ if(f->colorspace==0){
+ const int chroma_width = -((-width )>>f->chroma_h_shift);
+ const int chroma_height= -((-height)>>f->chroma_v_shift);
+ decode_plane(f, p->data[0], width, height, p->linesize[0], 0);
+
+ decode_plane(f, p->data[1], chroma_width, chroma_height, p->linesize[1], 1);
+ decode_plane(f, p->data[2], chroma_width, chroma_height, p->linesize[2], 1);
+ }else{
+ decode_rgb_frame(f, (uint32_t*)p->data[0], width, height, p->linesize[0]/4);
+ }
+
+ emms_c();
+
+ f->picture_number++;
+
+ *picture= *p;
+
+ avctx->release_buffer(avctx, p); //FIXME
+
+ *data_size = sizeof(AVFrame);
+
+ if(f->ac){
+ bytes_read= get_cabac_terminate(c);
+ if(bytes_read ==0) av_log(f->avctx, AV_LOG_ERROR, "error at end of frame\n");
+ }else{
+ bytes_read+= (get_bits_count(&f->gb)+7)/8;
+ }
+
+ return bytes_read;
+}
+
+AVCodec ffv1_decoder = {
+ "ffv1",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_FFV1,
+ sizeof(FFV1Context),
+ decode_init,
+ NULL,
+ NULL,
+ decode_frame,
+ CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
+ NULL
+};
+
+#ifdef CONFIG_ENCODERS
+AVCodec ffv1_encoder = {
+ "ffv1",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_FFV1,
+ sizeof(FFV1Context),
+ encode_init,
+ encode_frame,
+ encode_end,
+};
+#endif
diff --git a/src/libffmpeg/libavcodec/flac.c b/src/libffmpeg/libavcodec/flac.c
new file mode 100644
index 000000000..7e92fa59e
--- /dev/null
+++ b/src/libffmpeg/libavcodec/flac.c
@@ -0,0 +1,770 @@
+/*
+ * FLAC (Free Lossless Audio Codec) decoder
+ * Copyright (c) 2003 Alex Beregszaszi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/**
+ * @file flac.c
+ * FLAC (Free Lossless Audio Codec) decoder
+ * @author Alex Beregszaszi
+ */
+
+#include <limits.h>
+
+#include "avcodec.h"
+#include "golomb.h"
+
+#undef NDEBUG
+#include <assert.h>
+
+#define MAX_CHANNELS 8
+#define MAX_BLOCKSIZE 65535
+
+enum decorrelation_type {
+ INDEPENDENT,
+ LEFT_SIDE,
+ RIGHT_SIDE,
+ MID_SIDE,
+};
+
+typedef struct FLACContext {
+ AVCodecContext *avctx;
+ GetBitContext gb;
+
+ int min_blocksize, max_blocksize;
+ int min_framesize, max_framesize;
+ int samplerate, channels;
+ int blocksize/*, last_blocksize*/;
+ int bps, curr_bps;
+ enum decorrelation_type decorrelation;
+
+ int32_t *decoded[MAX_CHANNELS];
+ uint8_t *bitstream;
+ int bitstream_size;
+ int bitstream_index;
+ int allocated_bitstream_size;
+} FLACContext;
+
+#define METADATA_TYPE_STREAMINFO 0
+
+static int sample_rate_table[] =
+{ 0, 0, 0, 0,
+ 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000,
+ 0, 0, 0, 0 };
+
+static int sample_size_table[] =
+{ 0, 8, 12, 0, 16, 20, 24, 0 };
+
+static int blocksize_table[] = {
+ 0, 192, 576<<0, 576<<1, 576<<2, 576<<3, 0, 0,
+256<<0, 256<<1, 256<<2, 256<<3, 256<<4, 256<<5, 256<<6, 256<<7
+};
+
+static const uint8_t table_crc8[256] = {
+ 0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15,
+ 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d,
+ 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65,
+ 0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d,
+ 0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5,
+ 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd,
+ 0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85,
+ 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd,
+ 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2,
+ 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea,
+ 0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2,
+ 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a,
+ 0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32,
+ 0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a,
+ 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42,
+ 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a,
+ 0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c,
+ 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,
+ 0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec,
+ 0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4,
+ 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c,
+ 0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44,
+ 0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c,
+ 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34,
+ 0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b,
+ 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63,
+ 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b,
+ 0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13,
+ 0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb,
+ 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83,
+ 0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb,
+ 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3
+};
+
+static int64_t get_utf8(GetBitContext *gb)
+{
+ uint64_t val;
+ int ones=0, bytes;
+
+ while(get_bits1(gb))
+ ones++;
+
+ if (ones==0) bytes=0;
+ else if(ones==1) return -1;
+ else bytes= ones - 1;
+
+ val= get_bits(gb, 7-ones);
+ while(bytes--){
+ const int tmp = get_bits(gb, 8);
+
+ if((tmp>>6) != 2)
+ return -1;
+ val<<=6;
+ val|= tmp&0x3F;
+ }
+ return val;
+}
+
+static int get_crc8(const uint8_t *buf, int count){
+ int crc=0;
+ int i;
+
+ for(i=0; i<count; i++){
+ crc = table_crc8[crc ^ buf[i]];
+ }
+
+ return crc;
+}
+
+static int flac_decode_init(AVCodecContext * avctx)
+{
+ return 0;
+}
+
+static void dump_headers(FLACContext *s)
+{
+ av_log(s->avctx, AV_LOG_DEBUG, " Blocksize: %d .. %d (%d)\n", s->min_blocksize, s->max_blocksize, s->blocksize);
+ av_log(s->avctx, AV_LOG_DEBUG, " Framesize: %d .. %d\n", s->min_framesize, s->max_framesize);
+ av_log(s->avctx, AV_LOG_DEBUG, " Samplerate: %d\n", s->samplerate);
+ av_log(s->avctx, AV_LOG_DEBUG, " Channels: %d\n", s->channels);
+ av_log(s->avctx, AV_LOG_DEBUG, " Bits: %d\n", s->bps);
+}
+
+static void allocate_buffers(FLACContext *s){
+ int i;
+
+ assert(s->max_blocksize);
+
+ if(s->max_framesize == 0 && s->max_blocksize){
+ s->max_framesize= (s->channels * s->bps * s->max_blocksize + 7)/ 8; //FIXME header overhead
+ }
+
+ for (i = 0; i < s->channels; i++)
+ {
+ s->decoded[i] = av_realloc(s->decoded[i], sizeof(int32_t)*s->max_blocksize);
+ }
+
+ s->bitstream= av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->max_framesize);
+}
+
+static void metadata_streaminfo(FLACContext *s)
+{
+ /* mandatory streaminfo */
+ s->min_blocksize = get_bits(&s->gb, 16);
+ s->max_blocksize = get_bits(&s->gb, 16);
+
+ s->min_framesize = get_bits_long(&s->gb, 24);
+ s->max_framesize = get_bits_long(&s->gb, 24);
+
+ s->samplerate = get_bits_long(&s->gb, 20);
+ s->channels = get_bits(&s->gb, 3) + 1;
+ s->bps = get_bits(&s->gb, 5) + 1;
+
+ s->avctx->channels = s->channels;
+ s->avctx->sample_rate = s->samplerate;
+
+ skip_bits(&s->gb, 36); /* total num of samples */
+
+ skip_bits(&s->gb, 64); /* md5 sum */
+ skip_bits(&s->gb, 64); /* md5 sum */
+
+ allocate_buffers(s);
+}
+
+static int decode_residuals(FLACContext *s, int channel, int pred_order)
+{
+ int i, tmp, partition, method_type, rice_order;
+ int sample = 0, samples;
+
+ method_type = get_bits(&s->gb, 2);
+ if (method_type != 0){
+ av_log(s->avctx, AV_LOG_DEBUG, "illegal residual coding method %d\n", method_type);
+ return -1;
+ }
+
+ rice_order = get_bits(&s->gb, 4);
+
+ samples= s->blocksize >> rice_order;
+
+ sample=
+ i= pred_order;
+ for (partition = 0; partition < (1 << rice_order); partition++)
+ {
+ tmp = get_bits(&s->gb, 4);
+ if (tmp == 15)
+ {
+ av_log(s->avctx, AV_LOG_DEBUG, "fixed len partition\n");
+ tmp = get_bits(&s->gb, 5);
+ for (; i < samples; i++, sample++)
+ s->decoded[channel][sample] = get_sbits(&s->gb, tmp);
+ }
+ else
+ {
+// av_log(s->avctx, AV_LOG_DEBUG, "rice coded partition k=%d\n", tmp);
+ for (; i < samples; i++, sample++){
+ s->decoded[channel][sample] = get_sr_golomb_flac(&s->gb, tmp, INT_MAX, 0);
+ }
+ }
+ i= 0;
+ }
+
+// av_log(s->avctx, AV_LOG_DEBUG, "partitions: %d, samples: %d\n", 1 << rice_order, sample);
+
+ return 0;
+}
+
+static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order)
+{
+ int i;
+
+// av_log(s->avctx, AV_LOG_DEBUG, " SUBFRAME FIXED\n");
+
+ /* warm up samples */
+// av_log(s->avctx, AV_LOG_DEBUG, " warm up samples: %d\n", pred_order);
+
+ for (i = 0; i < pred_order; i++)
+ {
+ s->decoded[channel][i] = get_sbits(&s->gb, s->curr_bps);
+// av_log(s->avctx, AV_LOG_DEBUG, " %d: %d\n", i, s->decoded[channel][i]);
+ }
+
+ if (decode_residuals(s, channel, pred_order) < 0)
+ return -1;
+
+ switch(pred_order)
+ {
+ case 0:
+ break;
+ case 1:
+ for (i = pred_order; i < s->blocksize; i++)
+ s->decoded[channel][i] += s->decoded[channel][i-1];
+ break;
+ case 2:
+ for (i = pred_order; i < s->blocksize; i++)
+ s->decoded[channel][i] += 2*s->decoded[channel][i-1]
+ - s->decoded[channel][i-2];
+ break;
+ case 3:
+ for (i = pred_order; i < s->blocksize; i++)
+ s->decoded[channel][i] += 3*s->decoded[channel][i-1]
+ - 3*s->decoded[channel][i-2]
+ + s->decoded[channel][i-3];
+ break;
+ case 4:
+ for (i = pred_order; i < s->blocksize; i++)
+ s->decoded[channel][i] += 4*s->decoded[channel][i-1]
+ - 6*s->decoded[channel][i-2]
+ + 4*s->decoded[channel][i-3]
+ - s->decoded[channel][i-4];
+ break;
+ default:
+ av_log(s->avctx, AV_LOG_ERROR, "illegal pred order %d\n", pred_order);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int decode_subframe_lpc(FLACContext *s, int channel, int pred_order)
+{
+ int sum, i, j;
+ int coeff_prec, qlevel;
+ int coeffs[pred_order];
+
+// av_log(s->avctx, AV_LOG_DEBUG, " SUBFRAME LPC\n");
+
+ /* warm up samples */
+// av_log(s->avctx, AV_LOG_DEBUG, " warm up samples: %d\n", pred_order);
+
+ for (i = 0; i < pred_order; i++)
+ {
+ s->decoded[channel][i] = get_sbits(&s->gb, s->curr_bps);
+// av_log(s->avctx, AV_LOG_DEBUG, " %d: %d\n", i, s->decoded[channel][i]);
+ }
+
+ coeff_prec = get_bits(&s->gb, 4) + 1;
+ if (coeff_prec == 16)
+ {
+ av_log(s->avctx, AV_LOG_DEBUG, "invalid coeff precision\n");
+ return -1;
+ }
+// av_log(s->avctx, AV_LOG_DEBUG, " qlp coeff prec: %d\n", coeff_prec);
+ qlevel = get_sbits(&s->gb, 5);
+// av_log(s->avctx, AV_LOG_DEBUG, " quant level: %d\n", qlevel);
+ if(qlevel < 0){
+ av_log(s->avctx, AV_LOG_DEBUG, "qlevel %d not supported, maybe buggy stream\n", qlevel);
+ return -1;
+ }
+
+ for (i = 0; i < pred_order; i++)
+ {
+ coeffs[i] = get_sbits(&s->gb, coeff_prec);
+// av_log(s->avctx, AV_LOG_DEBUG, " %d: %d\n", i, coeffs[i]);
+ }
+
+ if (decode_residuals(s, channel, pred_order) < 0)
+ return -1;
+
+ for (i = pred_order; i < s->blocksize; i++)
+ {
+ sum = 0;
+ for (j = 0; j < pred_order; j++)
+ sum += coeffs[j] * s->decoded[channel][i-j-1];
+ s->decoded[channel][i] += sum >> qlevel;
+ }
+
+ return 0;
+}
+
+static inline int decode_subframe(FLACContext *s, int channel)
+{
+ int type, wasted = 0;
+ int i, tmp;
+
+ s->curr_bps = s->bps;
+ if(channel == 0){
+ if(s->decorrelation == RIGHT_SIDE)
+ s->curr_bps++;
+ }else{
+ if(s->decorrelation == LEFT_SIDE || s->decorrelation == MID_SIDE)
+ s->curr_bps++;
+ }
+
+ if (get_bits1(&s->gb))
+ {
+ av_log(s->avctx, AV_LOG_DEBUG, "invalid subframe padding\n");
+ return -1;
+ }
+ type = get_bits(&s->gb, 6);
+// wasted = get_bits1(&s->gb);
+
+// if (wasted)
+// {
+// while (!get_bits1(&s->gb))
+// wasted++;
+// if (wasted)
+// wasted++;
+// s->curr_bps -= wasted;
+// }
+#if 0
+ wasted= 16 - av_log2(show_bits(&s->gb, 17));
+ skip_bits(&s->gb, wasted+1);
+ s->curr_bps -= wasted;
+#else
+ if (get_bits1(&s->gb))
+ {
+ wasted = 1;
+ while (!get_bits1(&s->gb))
+ wasted++;
+ s->curr_bps -= wasted;
+ av_log(s->avctx, AV_LOG_DEBUG, "%d wasted bits\n", wasted);
+ }
+#endif
+//FIXME use av_log2 for types
+ if (type == 0)
+ {
+ av_log(s->avctx, AV_LOG_DEBUG, "coding type: constant\n");
+ tmp = get_sbits(&s->gb, s->curr_bps);
+ for (i = 0; i < s->blocksize; i++)
+ s->decoded[channel][i] = tmp;
+ }
+ else if (type == 1)
+ {
+ av_log(s->avctx, AV_LOG_DEBUG, "coding type: verbatim\n");
+ for (i = 0; i < s->blocksize; i++)
+ s->decoded[channel][i] = get_sbits(&s->gb, s->curr_bps);
+ }
+ else if ((type >= 8) && (type <= 12))
+ {
+// av_log(s->avctx, AV_LOG_DEBUG, "coding type: fixed\n");
+ if (decode_subframe_fixed(s, channel, type & ~0x8) < 0)
+ return -1;
+ }
+ else if (type >= 32)
+ {
+// av_log(s->avctx, AV_LOG_DEBUG, "coding type: lpc\n");
+ if (decode_subframe_lpc(s, channel, (type & ~0x20)+1) < 0)
+ return -1;
+ }
+ else
+ {
+ av_log(s->avctx, AV_LOG_DEBUG, "invalid coding type\n");
+ return -1;
+ }
+
+ if (wasted)
+ {
+ int i;
+ for (i = 0; i < s->blocksize; i++)
+ s->decoded[channel][i] <<= wasted;
+ }
+
+ return 0;
+}
+
+static int decode_frame(FLACContext *s)
+{
+ int blocksize_code, sample_rate_code, sample_size_code, assignment, i, crc8;
+ int decorrelation, bps, blocksize, samplerate;
+
+ blocksize_code = get_bits(&s->gb, 4);
+
+ sample_rate_code = get_bits(&s->gb, 4);
+
+ assignment = get_bits(&s->gb, 4); /* channel assignment */
+ if (assignment < 8 && s->channels == assignment+1)
+ decorrelation = INDEPENDENT;
+ else if (assignment >=8 && assignment < 11 && s->channels == 2)
+ decorrelation = LEFT_SIDE + assignment - 8;
+ else
+ {
+ av_log(s->avctx, AV_LOG_DEBUG, "unsupported channel assignment %d (channels=%d)\n", assignment, s->channels);
+ return -1;
+ }
+
+ sample_size_code = get_bits(&s->gb, 3);
+ if(sample_size_code == 0)
+ bps= s->bps;
+ else if((sample_size_code != 3) && (sample_size_code != 7))
+ bps = sample_size_table[sample_size_code];
+ else
+ {
+ av_log(s->avctx, AV_LOG_DEBUG, "invalid sample size code (%d)\n", sample_size_code);
+ return -1;
+ }
+
+ if (get_bits1(&s->gb))
+ {
+ av_log(s->avctx, AV_LOG_DEBUG, "broken stream, invalid padding\n");
+ return -1;
+ }
+
+ if(get_utf8(&s->gb) < 0){
+ av_log(s->avctx, AV_LOG_ERROR, "utf8 fscked\n");
+ return -1;
+ }
+#if 0
+ if (/*((blocksize_code == 6) || (blocksize_code == 7)) &&*/
+ (s->min_blocksize != s->max_blocksize)){
+ }else{
+ }
+#endif
+
+ if (blocksize_code == 0)
+ blocksize = s->min_blocksize;
+ else if (blocksize_code == 6)
+ blocksize = get_bits(&s->gb, 8)+1;
+ else if (blocksize_code == 7)
+ blocksize = get_bits(&s->gb, 16)+1;
+ else
+ blocksize = blocksize_table[blocksize_code];
+
+ if(blocksize > s->max_blocksize){
+ av_log(s->avctx, AV_LOG_ERROR, "blocksize %d > %d\n", blocksize, s->max_blocksize);
+ return -1;
+ }
+
+ if (sample_rate_code == 0){
+ samplerate= s->samplerate;
+ }else if ((sample_rate_code > 3) && (sample_rate_code < 12))
+ samplerate = sample_rate_table[sample_rate_code];
+ else if (sample_rate_code == 12)
+ samplerate = get_bits(&s->gb, 8) * 1000;
+ else if (sample_rate_code == 13)
+ samplerate = get_bits(&s->gb, 16);
+ else if (sample_rate_code == 14)
+ samplerate = get_bits(&s->gb, 16) * 10;
+ else{
+ av_log(s->avctx, AV_LOG_ERROR, "illegal sample rate code %d\n", sample_rate_code);
+ return -1;
+ }
+
+ skip_bits(&s->gb, 8);
+ crc8= get_crc8(s->gb.buffer, get_bits_count(&s->gb)/8);
+ if(crc8){
+ av_log(s->avctx, AV_LOG_ERROR, "header crc missmatch crc=%2X\n", crc8);
+ return -1;
+ }
+
+ s->blocksize = blocksize;
+ s->samplerate = samplerate;
+ s->bps = bps;
+ s->decorrelation= decorrelation;
+
+// dump_headers(s);
+
+ /* subframes */
+ for (i = 0; i < s->channels; i++)
+ {
+// av_log(s->avctx, AV_LOG_DEBUG, "decoded: %x residual: %x\n", s->decoded[i], s->residual[i]);
+ if (decode_subframe(s, i) < 0)
+ return -1;
+ }
+
+ align_get_bits(&s->gb);
+
+ /* frame footer */
+ skip_bits(&s->gb, 16); /* data crc */
+
+ return 0;
+}
+
+static int flac_decode_frame(AVCodecContext *avctx,
+ void *data, int *data_size,
+ uint8_t *buf, int buf_size)
+{
+ FLACContext *s = avctx->priv_data;
+ int metadata_last, metadata_type, metadata_size;
+ int tmp = 0, i, j = 0, input_buf_size;
+ int16_t *samples = data, *left, *right;
+
+ s->avctx = avctx;
+
+ if(s->max_framesize == 0){
+ s->max_framesize= 8192; // should hopefully be enough for the first header
+ s->bitstream= av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->max_framesize);
+ }
+
+ if(1 && s->max_framesize){//FIXME truncated
+ buf_size= FFMIN(buf_size, s->max_framesize - s->bitstream_size);
+ input_buf_size= buf_size;
+
+ if(s->bitstream_index + s->bitstream_size + buf_size > s->allocated_bitstream_size){
+// printf("memmove\n");
+ memmove(s->bitstream, &s->bitstream[s->bitstream_index], s->bitstream_size);
+ s->bitstream_index=0;
+ }
+ memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], buf, buf_size);
+ buf= &s->bitstream[s->bitstream_index];
+ buf_size += s->bitstream_size;
+ s->bitstream_size= buf_size;
+
+ if(buf_size < s->max_framesize){
+// printf("wanna more data ...\n");
+ return input_buf_size;
+ }
+ }
+
+ init_get_bits(&s->gb, buf, buf_size*8);
+
+ /* fLaC signature (be) */
+ if (show_bits_long(&s->gb, 32) == bswap_32(ff_get_fourcc("fLaC")))
+ {
+ skip_bits(&s->gb, 32);
+
+ av_log(s->avctx, AV_LOG_DEBUG, "STREAM HEADER\n");
+ do {
+ metadata_last = get_bits(&s->gb, 1);
+ metadata_type = get_bits(&s->gb, 7);
+ metadata_size = get_bits_long(&s->gb, 24);
+
+ av_log(s->avctx, AV_LOG_DEBUG, " metadata block: flag = %d, type = %d, size = %d\n",
+ metadata_last, metadata_type,
+ metadata_size);
+ if(metadata_size){
+ switch(metadata_type)
+ {
+ case METADATA_TYPE_STREAMINFO:
+ metadata_streaminfo(s);
+ dump_headers(s);
+ break;
+ default:
+ for(i=0; i<metadata_size; i++)
+ skip_bits(&s->gb, 8);
+ }
+ }
+ } while(!metadata_last);
+ }
+ else
+ {
+
+ tmp = show_bits(&s->gb, 16);
+ if(tmp != 0xFFF8){
+ av_log(s->avctx, AV_LOG_ERROR, "FRAME HEADER not here\n");
+ while(get_bits_count(&s->gb)/8+2 < buf_size && show_bits(&s->gb, 16) != 0xFFF8)
+ skip_bits(&s->gb, 8);
+ goto end; // we may not have enough bits left to decode a frame, so try next time
+ }
+ skip_bits(&s->gb, 16);
+ if (decode_frame(s) < 0){
+ av_log(s->avctx, AV_LOG_ERROR, "decode_frame() failed\n");
+ s->bitstream_size=0;
+ s->bitstream_index=0;
+ return -1;
+ }
+ }
+
+
+#if 0
+ /* fix the channel order here */
+ if (s->order == MID_SIDE)
+ {
+ short *left = samples;
+ short *right = samples + s->blocksize;
+ for (i = 0; i < s->blocksize; i += 2)
+ {
+ uint32_t x = s->decoded[0][i];
+ uint32_t y = s->decoded[0][i+1];
+
+ right[i] = x - (y / 2);
+ left[i] = right[i] + y;
+ }
+ *data_size = 2 * s->blocksize;
+ }
+ else
+ {
+ for (i = 0; i < s->channels; i++)
+ {
+ switch(s->order)
+ {
+ case INDEPENDENT:
+ for (j = 0; j < s->blocksize; j++)
+ samples[(s->blocksize*i)+j] = s->decoded[i][j];
+ break;
+ case LEFT_SIDE:
+ case RIGHT_SIDE:
+ if (i == 0)
+ for (j = 0; j < s->blocksize; j++)
+ samples[(s->blocksize*i)+j] = s->decoded[0][j];
+ else
+ for (j = 0; j < s->blocksize; j++)
+ samples[(s->blocksize*i)+j] = s->decoded[0][j] - s->decoded[i][j];
+ break;
+// case MID_SIDE:
+// av_log(s->avctx, AV_LOG_DEBUG, "mid-side unsupported\n");
+ }
+ *data_size += s->blocksize;
+ }
+ }
+#else
+ switch(s->decorrelation)
+ {
+ case INDEPENDENT:
+ for (j = 0; j < s->blocksize; j++)
+ {
+ for (i = 0; i < s->channels; i++)
+ *(samples++) = s->decoded[i][j];
+ }
+ break;
+ case LEFT_SIDE:
+ assert(s->channels == 2);
+ for (i = 0; i < s->blocksize; i++)
+ {
+ *(samples++) = s->decoded[0][i];
+ *(samples++) = s->decoded[0][i] - s->decoded[1][i];
+ }
+ break;
+ case RIGHT_SIDE:
+ assert(s->channels == 2);
+ for (i = 0; i < s->blocksize; i++)
+ {
+ *(samples++) = s->decoded[0][i] + s->decoded[1][i];
+ *(samples++) = s->decoded[1][i];
+ }
+ break;
+ case MID_SIDE:
+ assert(s->channels == 2);
+ for (i = 0; i < s->blocksize; i++)
+ {
+ int mid, side;
+ mid = s->decoded[0][i];
+ side = s->decoded[1][i];
+
+#if 1 //needs to be checked but IMHO it should be binary identical
+ mid -= side>>1;
+ *(samples++) = mid + side;
+ *(samples++) = mid;
+#else
+
+ mid <<= 1;
+ if (side & 1)
+ mid++;
+ *(samples++) = (mid + side) >> 1;
+ *(samples++) = (mid - side) >> 1;
+#endif
+ }
+ break;
+ }
+#endif
+
+ *data_size = (int8_t *)samples - (int8_t *)data;
+// av_log(s->avctx, AV_LOG_DEBUG, "data size: %d\n", *data_size);
+
+// s->last_blocksize = s->blocksize;
+end:
+ i= (get_bits_count(&s->gb)+7)/8;;
+ if(i > buf_size){
+ av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", i - buf_size);
+ s->bitstream_size=0;
+ s->bitstream_index=0;
+ return -1;
+ }
+
+ if(s->bitstream_size){
+ s->bitstream_index += i;
+ s->bitstream_size -= i;
+ return input_buf_size;
+ }else
+ return i;
+}
+
+static int flac_decode_close(AVCodecContext *avctx)
+{
+ FLACContext *s = avctx->priv_data;
+ int i;
+
+ for (i = 0; i < s->channels; i++)
+ {
+ av_freep(&s->decoded[i]);
+ }
+ av_freep(&s->bitstream);
+
+ return 0;
+}
+
+static void flac_flush(AVCodecContext *avctx){
+ FLACContext *s = avctx->priv_data;
+
+ s->bitstream_size=
+ s->bitstream_index= 0;
+}
+
+AVCodec flac_decoder = {
+ "flac",
+ CODEC_TYPE_AUDIO,
+ CODEC_ID_FLAC,
+ sizeof(FLACContext),
+ flac_decode_init,
+ NULL,
+ flac_decode_close,
+ flac_decode_frame,
+ .flush= flac_flush,
+};
diff --git a/src/libffmpeg/libavcodec/g726.c b/src/libffmpeg/libavcodec/g726.c
new file mode 100644
index 000000000..c016f32cf
--- /dev/null
+++ b/src/libffmpeg/libavcodec/g726.c
@@ -0,0 +1,422 @@
+/*
+ * G.726 ADPCM audio codec
+ * Copyright (c) 2004 Roman Shaposhnik.
+ *
+ * This is a very straightforward rendition of the G.726
+ * Section 4 "Computational Details".
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <limits.h>
+#include "avcodec.h"
+#include "common.h"
+
+/*
+ * G.726 Standard uses rather odd 11bit floating point arithmentic for
+ * numerous occasions. It's a mistery to me why they did it this way
+ * instead of simply using 32bit integer arithmetic.
+ */
+typedef struct Float11 {
+ int sign; /* 1bit sign */
+ int exp; /* 4bit exponent */
+ int mant; /* 6bit mantissa */
+} Float11;
+
+static inline Float11* i2f(int16_t i, Float11* f)
+{
+ f->sign = (i < 0);
+ if (f->sign)
+ i = -i;
+ f->exp = av_log2_16bit(i) + !!i;
+ f->mant = i? (i<<6) >> f->exp :
+ 1<<5;
+ return f;
+}
+
+static inline int16_t mult(Float11* f1, Float11* f2)
+{
+ int res, exp;
+
+ exp = f1->exp + f2->exp;
+ res = (((f1->mant * f2->mant) + 0x30) >> 4) << 7;
+ res = exp > 26 ? res << (exp - 26) : res >> (26 - exp);
+ return (f1->sign ^ f2->sign) ? -res : res;
+}
+
+static inline int sgn(int value)
+{
+ return (value < 0) ? -1 : 1;
+}
+
+typedef struct G726Tables {
+ int bits; /* bits per sample */
+ int* quant; /* quantization table */
+ int* iquant; /* inverse quantization table */
+ int* W; /* special table #1 ;-) */
+ int* F; /* special table #2 */
+} G726Tables;
+
+typedef struct G726Context {
+ G726Tables* tbls; /* static tables needed for computation */
+
+ Float11 sr[2]; /* prev. reconstructed samples */
+ Float11 dq[6]; /* prev. difference */
+ int a[2]; /* second order predictor coeffs */
+ int b[6]; /* sixth order predictor coeffs */
+ int pk[2]; /* signs of prev. 2 sez + dq */
+
+ int ap; /* scale factor control */
+ int yu; /* fast scale factor */
+ int yl; /* slow scale factor */
+ int dms; /* short average magnitude of F[i] */
+ int dml; /* long average magnitude of F[i] */
+ int td; /* tone detect */
+
+ int se; /* estimated signal for the next iteration */
+ int sez; /* estimated second order prediction */
+ int y; /* quantizer scaling factor for the next iteration */
+} G726Context;
+
+static int quant_tbl16[] = /* 16kbit/s 2bits per sample */
+ { 260, INT_MAX };
+static int iquant_tbl16[] =
+ { 116, 365, 365, 116 };
+static int W_tbl16[] =
+ { -22, 439, 439, -22 };
+static int F_tbl16[] =
+ { 0, 7, 7, 0 };
+
+static int quant_tbl24[] = /* 24kbit/s 3bits per sample */
+ { 7, 217, 330, INT_MAX };
+static int iquant_tbl24[] =
+ { INT_MIN, 135, 273, 373, 373, 273, 135, INT_MIN };
+static int W_tbl24[] =
+ { -4, 30, 137, 582, 582, 137, 30, -4 };
+static int F_tbl24[] =
+ { 0, 1, 2, 7, 7, 2, 1, 0 };
+
+static int quant_tbl32[] = /* 32kbit/s 4bits per sample */
+ { -125, 79, 177, 245, 299, 348, 399, INT_MAX };
+static int iquant_tbl32[] =
+ { INT_MIN, 4, 135, 213, 273, 323, 373, 425,
+ 425, 373, 323, 273, 213, 135, 4, INT_MIN };
+static int W_tbl32[] =
+ { -12, 18, 41, 64, 112, 198, 355, 1122,
+ 1122, 355, 198, 112, 64, 41, 18, -12};
+static int F_tbl32[] =
+ { 0, 0, 0, 1, 1, 1, 3, 7, 7, 3, 1, 1, 1, 0, 0, 0 };
+
+static int quant_tbl40[] = /* 40kbit/s 5bits per sample */
+ { -122, -16, 67, 138, 197, 249, 297, 338,
+ 377, 412, 444, 474, 501, 527, 552, INT_MAX };
+static int iquant_tbl40[] =
+ { INT_MIN, -66, 28, 104, 169, 224, 274, 318,
+ 358, 395, 429, 459, 488, 514, 539, 566,
+ 566, 539, 514, 488, 459, 429, 395, 358,
+ 318, 274, 224, 169, 104, 28, -66, INT_MIN };
+static int W_tbl40[] =
+ { 14, 14, 24, 39, 40, 41, 58, 100,
+ 141, 179, 219, 280, 358, 440, 529, 696,
+ 696, 529, 440, 358, 280, 219, 179, 141,
+ 100, 58, 41, 40, 39, 24, 14, 14 };
+static int F_tbl40[] =
+ { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 6,
+ 6, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
+
+static G726Tables G726Tables_pool[] =
+ {{ 2, quant_tbl16, iquant_tbl16, W_tbl16, F_tbl16 },
+ { 3, quant_tbl24, iquant_tbl24, W_tbl24, F_tbl24 },
+ { 4, quant_tbl32, iquant_tbl32, W_tbl32, F_tbl32 },
+ { 5, quant_tbl40, iquant_tbl40, W_tbl40, F_tbl40 }};
+
+
+/*
+ * Para 4.2.2 page 18: Adaptive quantizer.
+ */
+static inline uint8_t quant(G726Context* c, int d)
+{
+ int sign, exp, i, dln;
+
+ sign = i = 0;
+ if (d < 0) {
+ sign = 1;
+ d = -d;
+ }
+ exp = av_log2_16bit(d);
+ dln = ((exp<<7) + (((d<<7)>>exp)&0x7f)) - (c->y>>2);
+
+ while (c->tbls->quant[i] < INT_MAX && c->tbls->quant[i] < dln)
+ ++i;
+
+ if (sign)
+ i = ~i;
+ if (c->tbls->bits != 2 && i == 0) /* I'm not sure this is a good idea */
+ i = 0xff;
+
+ return i;
+}
+
+/*
+ * Para 4.2.3 page 22: Inverse adaptive quantizer.
+ */
+static inline int16_t inverse_quant(G726Context* c, int i)
+{
+ int dql, dex, dqt;
+
+ dql = c->tbls->iquant[i] + (c->y >> 2);
+ dex = (dql>>7) & 0xf; /* 4bit exponent */
+ dqt = (1<<7) + (dql & 0x7f); /* log2 -> linear */
+ return (dql < 0) ? 0 : ((dqt<<7) >> (14-dex));
+}
+
+static inline int16_t g726_iterate(G726Context* c, int16_t I)
+{
+ int dq, re_signal, pk0, fa1, i, tr, ylint, ylfrac, thr2, al, dq0;
+ Float11 f;
+
+ dq = inverse_quant(c, I);
+ if (I >> (c->tbls->bits - 1)) /* get the sign */
+ dq = -dq;
+ re_signal = c->se + dq;
+
+ /* Transition detect */
+ ylint = (c->yl >> 15);
+ ylfrac = (c->yl >> 10) & 0x1f;
+ thr2 = (ylint > 9) ? 0x1f << 10 : (0x20 + ylfrac) << ylint;
+ if (c->td == 1 && abs(dq) > ((thr2+(thr2>>1))>>1))
+ tr = 1;
+ else
+ tr = 0;
+
+ /* Update second order predictor coefficient A2 and A1 */
+ pk0 = (c->sez + dq) ? sgn(c->sez + dq) : 0;
+ dq0 = dq ? sgn(dq) : 0;
+ if (tr) {
+ c->a[0] = 0;
+ c->a[1] = 0;
+ for (i=0; i<6; i++)
+ c->b[i] = 0;
+ } else {
+ /* This is a bit crazy, but it really is +255 not +256 */
+ fa1 = clip((-c->a[0]*c->pk[0]*pk0)>>5, -256, 255);
+
+ c->a[1] += 128*pk0*c->pk[1] + fa1 - (c->a[1]>>7);
+ c->a[1] = clip(c->a[1], -12288, 12288);
+ c->a[0] += 64*3*pk0*c->pk[0] - (c->a[0] >> 8);
+ c->a[0] = clip(c->a[0], -(15360 - c->a[1]), 15360 - c->a[1]);
+
+ for (i=0; i<6; i++)
+ c->b[i] += 128*dq0*sgn(-c->dq[i].sign) - (c->b[i]>>8);
+ }
+
+ /* Update Dq and Sr and Pk */
+ c->pk[1] = c->pk[0];
+ c->pk[0] = pk0 ? pk0 : 1;
+ c->sr[1] = c->sr[0];
+ i2f(re_signal, &c->sr[0]);
+ for (i=5; i>0; i--)
+ c->dq[i] = c->dq[i-1];
+ i2f(dq, &c->dq[0]);
+ c->dq[0].sign = I >> (c->tbls->bits - 1); /* Isn't it crazy ?!?! */
+
+ /* Update tone detect [I'm not sure 'tr == 0' is really needed] */
+ c->td = (tr == 0 && c->a[1] < -11776);
+
+ /* Update Ap */
+ c->dms += ((c->tbls->F[I]<<9) - c->dms) >> 5;
+ c->dml += ((c->tbls->F[I]<<11) - c->dml) >> 7;
+ if (tr)
+ c->ap = 256;
+ else if (c->y > 1535 && !c->td && (abs((c->dms << 2) - c->dml) < (c->dml >> 3)))
+ c->ap += (-c->ap) >> 4;
+ else
+ c->ap += (0x200 - c->ap) >> 4;
+
+ /* Update Yu and Yl */
+ c->yu = clip(c->y + (((c->tbls->W[I] << 5) - c->y) >> 5), 544, 5120);
+ c->yl += c->yu + ((-c->yl)>>6);
+
+ /* Next iteration for Y */
+ al = (c->ap >= 256) ? 1<<6 : c->ap >> 2;
+ c->y = (c->yl + (c->yu - (c->yl>>6))*al) >> 6;
+
+ /* Next iteration for SE and SEZ */
+ c->se = 0;
+ for (i=0; i<6; i++)
+ c->se += mult(i2f(c->b[i] >> 2, &f), &c->dq[i]);
+ c->sez = c->se >> 1;
+ for (i=0; i<2; i++)
+ c->se += mult(i2f(c->a[i] >> 2, &f), &c->sr[i]);
+ c->se >>= 1;
+
+ return clip(re_signal << 2, -0xffff, 0xffff);
+}
+
+static int g726_reset(G726Context* c, int bit_rate)
+{
+ int i;
+
+ c->tbls = &G726Tables_pool[bit_rate/8000 - 2];
+ for (i=0; i<2; i++) {
+ i2f(0, &c->sr[i]);
+ c->a[i] = 0;
+ c->pk[i] = 1;
+ }
+ for (i=0; i<6; i++) {
+ i2f(0, &c->dq[i]);
+ c->b[i] = 0;
+ }
+ c->ap = 0;
+ c->dms = 0;
+ c->dml = 0;
+ c->yu = 544;
+ c->yl = 34816;
+ c->td = 0;
+
+ c->se = 0;
+ c->sez = 0;
+ c->y = 544;
+
+ return 0;
+}
+
+static int16_t g726_decode(G726Context* c, int16_t i)
+{
+ return g726_iterate(c, i);
+}
+
+static int16_t g726_encode(G726Context* c, int16_t sig)
+{
+ uint8_t i;
+
+ i = quant(c, sig/4 - c->se) & ((1<<c->tbls->bits) - 1);
+ g726_iterate(c, i);
+ return i;
+}
+
+/* Interfacing to the libavcodec */
+
+typedef struct AVG726Context {
+ G726Context c;
+ int bits_left;
+ int bit_buffer;
+ int code_size;
+} AVG726Context;
+
+static int g726_init(AVCodecContext * avctx)
+{
+ AVG726Context* c = (AVG726Context*)avctx->priv_data;
+
+ if (avctx->channels != 1 ||
+ (avctx->bit_rate != 16000 && avctx->bit_rate != 24000 &&
+ avctx->bit_rate != 32000 && avctx->bit_rate != 40000)) {
+ av_log(avctx, AV_LOG_ERROR, "G726: unsupported audio format\n");
+ return -1;
+ }
+ if (avctx->sample_rate != 8000 && avctx->strict_std_compliance>=0) {
+ av_log(avctx, AV_LOG_ERROR, "G726: unsupported audio format\n");
+ return -1;
+ }
+ g726_reset(&c->c, avctx->bit_rate);
+ c->code_size = c->c.tbls->bits;
+ c->bit_buffer = 0;
+ c->bits_left = 0;
+
+ avctx->coded_frame = avcodec_alloc_frame();
+ if (!avctx->coded_frame)
+ return -ENOMEM;
+ avctx->coded_frame->key_frame = 1;
+
+ return 0;
+}
+
+static int g726_close(AVCodecContext *avctx)
+{
+ av_freep(&avctx->coded_frame);
+ return 0;
+}
+
+static int g726_encode_frame(AVCodecContext *avctx,
+ uint8_t *dst, int buf_size, void *data)
+{
+ AVG726Context *c = avctx->priv_data;
+ short *samples = data;
+ PutBitContext pb;
+
+ init_put_bits(&pb, dst, 1024*1024);
+
+ for (; buf_size; buf_size--)
+ put_bits(&pb, c->code_size, g726_encode(&c->c, *samples++));
+
+ flush_put_bits(&pb);
+
+ return put_bits_count(&pb)>>3;
+}
+
+static int g726_decode_frame(AVCodecContext *avctx,
+ void *data, int *data_size,
+ uint8_t *buf, int buf_size)
+{
+ AVG726Context *c = avctx->priv_data;
+ short *samples = data;
+ uint8_t code;
+ uint8_t mask;
+ GetBitContext gb;
+
+ if (!buf_size)
+ goto out;
+
+ mask = (1<<c->code_size) - 1;
+ init_get_bits(&gb, buf, buf_size * 8);
+ if (c->bits_left) {
+ int s = c->code_size - c->bits_left;;
+ code = (c->bit_buffer << s) | get_bits(&gb, s);
+ *samples++ = g726_decode(&c->c, code & mask);
+ }
+
+ while (get_bits_count(&gb) + c->code_size <= buf_size*8)
+ *samples++ = g726_decode(&c->c, get_bits(&gb, c->code_size) & mask);
+
+ c->bits_left = buf_size*8 - get_bits_count(&gb);
+ c->bit_buffer = get_bits(&gb, c->bits_left);
+
+out:
+ *data_size = (uint8_t*)samples - (uint8_t*)data;
+ return buf_size;
+}
+
+#ifdef CONFIG_ENCODERS
+AVCodec adpcm_g726_encoder = {
+ "g726",
+ CODEC_TYPE_AUDIO,
+ CODEC_ID_ADPCM_G726,
+ sizeof(AVG726Context),
+ g726_init,
+ g726_encode_frame,
+ g726_close,
+ NULL,
+};
+#endif //CONFIG_ENCODERS
+
+AVCodec adpcm_g726_decoder = {
+ "g726",
+ CODEC_TYPE_AUDIO,
+ CODEC_ID_ADPCM_G726,
+ sizeof(AVG726Context),
+ g726_init,
+ NULL,
+ g726_close,
+ g726_decode_frame,
+};
diff --git a/src/libffmpeg/libavcodec/h263.c b/src/libffmpeg/libavcodec/h263.c
index 59d746272..9175eff0e 100644
--- a/src/libffmpeg/libavcodec/h263.c
+++ b/src/libffmpeg/libavcodec/h263.c
@@ -56,7 +56,6 @@
#ifdef CONFIG_ENCODERS
static void h263_encode_block(MpegEncContext * s, DCTELEM * block,
int n);
-static void h263_encode_motion(MpegEncContext * s, int val, int fcode);
static void h263p_encode_umotion(MpegEncContext * s, int val);
static inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block,
int n, int dc, uint8_t *scan_table,
@@ -851,23 +850,23 @@ void mpeg4_encode_mb(MpegEncContext * s,
if(mb_type == 0){
assert(s->mv_dir & MV_DIRECT);
- h263_encode_motion(s, motion_x, 1);
- h263_encode_motion(s, motion_y, 1);
+ ff_h263_encode_motion(s, motion_x, 1);
+ ff_h263_encode_motion(s, motion_y, 1);
s->b_count++;
s->f_count++;
}else{
assert(mb_type > 0 && mb_type < 4);
if(s->mv_type != MV_TYPE_FIELD){
if(s->mv_dir & MV_DIR_FORWARD){
- h263_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code);
- h263_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code);
+ ff_h263_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code);
+ ff_h263_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code);
s->last_mv[0][0][0]= s->last_mv[0][1][0]= s->mv[0][0][0];
s->last_mv[0][0][1]= s->last_mv[0][1][1]= s->mv[0][0][1];
s->f_count++;
}
if(s->mv_dir & MV_DIR_BACKWARD){
- h263_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code);
- h263_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code);
+ ff_h263_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code);
+ ff_h263_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code);
s->last_mv[1][0][0]= s->last_mv[1][1][0]= s->mv[1][0][0];
s->last_mv[1][0][1]= s->last_mv[1][1][1]= s->mv[1][0][1];
s->b_count++;
@@ -883,8 +882,8 @@ void mpeg4_encode_mb(MpegEncContext * s,
}
if(s->mv_dir & MV_DIR_FORWARD){
for(i=0; i<2; i++){
- h263_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code);
- h263_encode_motion(s, s->mv[0][i][1] - s->last_mv[0][i][1]/2, s->f_code);
+ ff_h263_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code);
+ ff_h263_encode_motion(s, s->mv[0][i][1] - s->last_mv[0][i][1]/2, s->f_code);
s->last_mv[0][i][0]= s->mv[0][i][0];
s->last_mv[0][i][1]= s->mv[0][i][1]*2;
}
@@ -892,8 +891,8 @@ void mpeg4_encode_mb(MpegEncContext * s,
}
if(s->mv_dir & MV_DIR_BACKWARD){
for(i=0; i<2; i++){
- h263_encode_motion(s, s->mv[1][i][0] - s->last_mv[1][i][0] , s->b_code);
- h263_encode_motion(s, s->mv[1][i][1] - s->last_mv[1][i][1]/2, s->b_code);
+ ff_h263_encode_motion(s, s->mv[1][i][0] - s->last_mv[1][i][0] , s->b_code);
+ ff_h263_encode_motion(s, s->mv[1][i][1] - s->last_mv[1][i][1]/2, s->b_code);
s->last_mv[1][i][0]= s->mv[1][i][0];
s->last_mv[1][i][1]= s->mv[1][i][1]*2;
}
@@ -993,8 +992,8 @@ void mpeg4_encode_mb(MpegEncContext * s,
/* motion vectors: 16x16 mode */
h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
- h263_encode_motion(s, motion_x - pred_x, s->f_code);
- h263_encode_motion(s, motion_y - pred_y, s->f_code);
+ ff_h263_encode_motion(s, motion_x - pred_x, s->f_code);
+ ff_h263_encode_motion(s, motion_y - pred_y, s->f_code);
}else if(s->mv_type==MV_TYPE_FIELD){
if(s->dquant) cbpc+= 8;
put_bits(&s->pb,
@@ -1021,10 +1020,10 @@ void mpeg4_encode_mb(MpegEncContext * s,
put_bits(&s->pb, 1, s->field_select[0][0]);
put_bits(&s->pb, 1, s->field_select[0][1]);
- h263_encode_motion(s, s->mv[0][0][0] - pred_x, s->f_code);
- h263_encode_motion(s, s->mv[0][0][1] - pred_y, s->f_code);
- h263_encode_motion(s, s->mv[0][1][0] - pred_x, s->f_code);
- h263_encode_motion(s, s->mv[0][1][1] - pred_y, s->f_code);
+ ff_h263_encode_motion(s, s->mv[0][0][0] - pred_x, s->f_code);
+ ff_h263_encode_motion(s, s->mv[0][0][1] - pred_y, s->f_code);
+ ff_h263_encode_motion(s, s->mv[0][1][0] - pred_x, s->f_code);
+ ff_h263_encode_motion(s, s->mv[0][1][1] - pred_y, s->f_code);
}else{
assert(s->mv_type==MV_TYPE_8X8);
put_bits(&s->pb,
@@ -1045,8 +1044,8 @@ void mpeg4_encode_mb(MpegEncContext * s,
/* motion vectors: 8x8 mode*/
h263_pred_motion(s, i, 0, &pred_x, &pred_y);
- h263_encode_motion(s, s->current_picture.motion_val[0][ s->block_index[i] ][0] - pred_x, s->f_code);
- h263_encode_motion(s, s->current_picture.motion_val[0][ s->block_index[i] ][1] - pred_y, s->f_code);
+ ff_h263_encode_motion(s, s->current_picture.motion_val[0][ s->block_index[i] ][0] - pred_x, s->f_code);
+ ff_h263_encode_motion(s, s->current_picture.motion_val[0][ s->block_index[i] ][1] - pred_y, s->f_code);
}
}
@@ -1186,8 +1185,8 @@ void h263_encode_mb(MpegEncContext * s,
h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
if (!s->umvplus) {
- h263_encode_motion(s, motion_x - pred_x, 1);
- h263_encode_motion(s, motion_y - pred_y, 1);
+ ff_h263_encode_motion(s, motion_x - pred_x, 1);
+ ff_h263_encode_motion(s, motion_y - pred_y, 1);
}
else {
h263p_encode_umotion(s, motion_x - pred_x);
@@ -1215,8 +1214,8 @@ void h263_encode_mb(MpegEncContext * s,
motion_x= s->current_picture.motion_val[0][ s->block_index[i] ][0];
motion_y= s->current_picture.motion_val[0][ s->block_index[i] ][1];
if (!s->umvplus) {
- h263_encode_motion(s, motion_x - pred_x, 1);
- h263_encode_motion(s, motion_y - pred_y, 1);
+ ff_h263_encode_motion(s, motion_x - pred_x, 1);
+ ff_h263_encode_motion(s, motion_y - pred_y, 1);
}
else {
h263p_encode_umotion(s, motion_x - pred_x);
@@ -1619,7 +1618,7 @@ int16_t *h263_pred_motion(MpegEncContext * s, int block, int dir,
}
#ifdef CONFIG_ENCODERS
-static void h263_encode_motion(MpegEncContext * s, int val, int f_code)
+void ff_h263_encode_motion(MpegEncContext * s, int val, int f_code)
{
int range, l, bit_size, sign, code, bits;
@@ -5419,6 +5418,8 @@ static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){
if (get_bits1(gb) != 0) { /* fixed_vop_rate */
skip_bits(gb, s->time_increment_bits);
}
+
+ s->t_frame=0;
if (s->shape != BIN_ONLY_SHAPE) {
if (s->shape == RECT_SHAPE) {
@@ -5692,7 +5693,7 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){
else time_increment= get_bits(gb, s->time_increment_bits);
// printf("%d %X\n", s->time_increment_bits, time_increment);
-//printf(" type:%d modulo_time_base:%d increment:%d\n", s->pict_type, time_incr, time_increment);
+//av_log(s->avctx, AV_LOG_DEBUG, " type:%d modulo_time_base:%d increment:%d t_frame %d\n", s->pict_type, time_incr, time_increment, s->t_frame);
if(s->pict_type!=B_TYPE){
s->last_time_base= s->time_base;
s->time_base+= time_incr;
@@ -5714,19 +5715,19 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){
return FRAME_SKIPED;
}
- if(s->t_frame==0) s->t_frame= s->time - s->last_time_base;
+ if(s->t_frame==0) s->t_frame= s->pb_time;
if(s->t_frame==0) s->t_frame=1; // 1/0 protection
-//printf("%Ld %Ld %d %d\n", s->last_non_b_time, s->time, s->pp_time, s->t_frame); fflush(stdout);
s->pp_field_time= ( ROUNDED_DIV(s->last_non_b_time, s->t_frame)
- ROUNDED_DIV(s->last_non_b_time - s->pp_time, s->t_frame))*2;
s->pb_field_time= ( ROUNDED_DIV(s->time, s->t_frame)
- ROUNDED_DIV(s->last_non_b_time - s->pp_time, s->t_frame))*2;
}
+//av_log(s->avctx, AV_LOG_DEBUG, "last nonb %Ld last_base %d time %Ld pp %d pb %d t %d ppf %d pbf %d\n", s->last_non_b_time, s->last_time_base, s->time, s->pp_time, s->pb_time, s->t_frame, s->pp_field_time, s->pb_field_time);
s->current_picture_ptr->pts= s->time*(int64_t)AV_TIME_BASE / s->time_increment_resolution;
if(s->avctx->debug&FF_DEBUG_PTS)
av_log(s->avctx, AV_LOG_DEBUG, "MPEG4 PTS: %f\n", s->current_picture_ptr->pts/(float)AV_TIME_BASE);
-
+
check_marker(gb, "before vop_coded");
/* vop coded */
diff --git a/src/libffmpeg/libavcodec/h263dec.c b/src/libffmpeg/libavcodec/h263dec.c
index ea8badb9d..1ffefa1b2 100644
--- a/src/libffmpeg/libavcodec/h263dec.c
+++ b/src/libffmpeg/libavcodec/h263dec.c
@@ -417,8 +417,6 @@ uint64_t time= rdtsc();
s->flags= avctx->flags;
s->flags2= avctx->flags2;
- *data_size = 0;
-
/* no supplementary picture */
if (buf_size == 0) {
/* special case for last picture */
diff --git a/src/libffmpeg/libavcodec/h264.c b/src/libffmpeg/libavcodec/h264.c
index 77c3393ef..594a4b264 100644
--- a/src/libffmpeg/libavcodec/h264.c
+++ b/src/libffmpeg/libavcodec/h264.c
@@ -5713,8 +5713,6 @@ static int decode_frame(AVCodecContext *avctx,
s->flags= avctx->flags;
s->flags2= avctx->flags2;
- *data_size = 0;
-
/* no supplementary picture */
if (buf_size == 0) {
return 0;
diff --git a/src/libffmpeg/libavcodec/huffyuv.c b/src/libffmpeg/libavcodec/huffyuv.c
index 210d45419..ecc6a5fa2 100644
--- a/src/libffmpeg/libavcodec/huffyuv.c
+++ b/src/libffmpeg/libavcodec/huffyuv.c
@@ -684,8 +684,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
AVFrame *picture = data;
- *data_size = 0;
-
/* no supplementary picture */
if (buf_size == 0)
return 0;
diff --git a/src/libffmpeg/libavcodec/i386/dsputil_mmx.c b/src/libffmpeg/libavcodec/i386/dsputil_mmx.c
index c8db22e64..11504e225 100644
--- a/src/libffmpeg/libavcodec/i386/dsputil_mmx.c
+++ b/src/libffmpeg/libavcodec/i386/dsputil_mmx.c
@@ -2132,10 +2132,10 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx)
#endif
if (mm_flags & MM_MMX) {
- const int dct_algo = avctx->dct_algo;
const int idct_algo= avctx->idct_algo;
#ifdef CONFIG_ENCODERS
+ const int dct_algo = avctx->dct_algo;
if(dct_algo==FF_DCT_AUTO || dct_algo==FF_DCT_MMX){
if(mm_flags & MM_SSE2){
c->fdct = ff_fdct_sse2;
diff --git a/src/libffmpeg/libavcodec/i386/dsputil_mmx_avg.h b/src/libffmpeg/libavcodec/i386/dsputil_mmx_avg.h
index c8494f51a..052aad75c 100644
--- a/src/libffmpeg/libavcodec/i386/dsputil_mmx_avg.h
+++ b/src/libffmpeg/libavcodec/i386/dsputil_mmx_avg.h
@@ -53,7 +53,7 @@ static void DEF(put_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_
:"%eax", "memory");
}
-static void DEF(put_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
+static __attribute__((unused)) void DEF(put_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
{
__asm __volatile(
"1: \n\t"
@@ -125,7 +125,7 @@ static void DEF(put_pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line
:"%eax", "memory");
}
-static void DEF(put_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
+static __attribute__((unused)) void DEF(put_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
{
__asm __volatile(
"1: \n\t"
diff --git a/src/libffmpeg/libavcodec/i386/dsputil_mmx_rnd.h b/src/libffmpeg/libavcodec/i386/dsputil_mmx_rnd.h
index 21f0bfd84..1b79aa56a 100644
--- a/src/libffmpeg/libavcodec/i386/dsputil_mmx_rnd.h
+++ b/src/libffmpeg/libavcodec/i386/dsputil_mmx_rnd.h
@@ -359,7 +359,7 @@ static void DEF(avg, pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line
} while (--h);
}
-static void DEF(avg, pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
+static __attribute__((unused)) void DEF(avg, pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
{
MOVQ_BFE(mm6);
JUMPALIGN();
@@ -406,7 +406,7 @@ static void DEF(avg, pixels16_x2)(uint8_t *block, const uint8_t *pixels, int lin
} while (--h);
}
-static void DEF(avg, pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
+static __attribute__((unused)) void DEF(avg, pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
{
MOVQ_BFE(mm6);
JUMPALIGN();
diff --git a/src/libffmpeg/libavcodec/i386/fdct_mmx.c b/src/libffmpeg/libavcodec/i386/fdct_mmx.c
index 68f788a23..7f348329a 100644
--- a/src/libffmpeg/libavcodec/i386/fdct_mmx.c
+++ b/src/libffmpeg/libavcodec/i386/fdct_mmx.c
@@ -14,6 +14,7 @@
* Skal's fdct at http://skal.planet-d.net/coding/dct.html
*/
#include "../common.h"
+#include "../dsputil.h"
#include "mmx.h"
#define ATTR_ALIGN(align) __attribute__ ((__aligned__ (align)))
diff --git a/src/libffmpeg/libavcodec/i386/idct_mmx.c b/src/libffmpeg/libavcodec/i386/idct_mmx.c
index 298c8a8b0..c356afe12 100644
--- a/src/libffmpeg/libavcodec/i386/idct_mmx.c
+++ b/src/libffmpeg/libavcodec/i386/idct_mmx.c
@@ -23,6 +23,7 @@
*/
#include "../common.h"
+#include "../dsputil.h"
#include "mmx.h"
@@ -588,6 +589,8 @@ void idct (int16_t * block) \
idct_col (block, 4); \
}
+void ff_mmx_idct(DCTELEM *block);
+void ff_mmxext_idct(DCTELEM *block);
declare_idct (ff_mmxext_idct, mmxext_table,
mmxext_row_head, mmxext_row, mmxext_row_tail, mmxext_row_mid)
diff --git a/src/libffmpeg/libavcodec/i386/mpegvideo_mmx.c b/src/libffmpeg/libavcodec/i386/mpegvideo_mmx.c
index 1c0e9f5ae..f19de73d6 100644
--- a/src/libffmpeg/libavcodec/i386/mpegvideo_mmx.c
+++ b/src/libffmpeg/libavcodec/i386/mpegvideo_mmx.c
@@ -109,7 +109,7 @@ asm volatile(
static void dct_unquantize_h263_inter_mmx(MpegEncContext *s,
DCTELEM *block, int n, int qscale)
{
- int level, qmul, qadd, nCoeffs;
+ int qmul, qadd, nCoeffs;
qmul = qscale << 1;
qadd = (qscale - 1) | 1;
diff --git a/src/libffmpeg/libavcodec/i386/simple_idct_mmx.c b/src/libffmpeg/libavcodec/i386/simple_idct_mmx.c
index b005f9d82..92a366f21 100644
--- a/src/libffmpeg/libavcodec/i386/simple_idct_mmx.c
+++ b/src/libffmpeg/libavcodec/i386/simple_idct_mmx.c
@@ -18,6 +18,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../dsputil.h"
+#include "../simple_idct.h"
/*
23170.475006
diff --git a/src/libffmpeg/libavcodec/indeo3.c b/src/libffmpeg/libavcodec/indeo3.c
index 12f4ced6d..14ff02858 100644
--- a/src/libffmpeg/libavcodec/indeo3.c
+++ b/src/libffmpeg/libavcodec/indeo3.c
@@ -1058,7 +1058,6 @@ static int indeo3_decode_frame(AVCodecContext *avctx,
/* no supplementary picture */
if (buf_size == 0) {
- *data_size = 0;
return 0;
}
diff --git a/src/libffmpeg/libavcodec/libpostproc/Makefile.am b/src/libffmpeg/libavcodec/libpostproc/Makefile.am
index 19a6ebdde..8867608fe 100644
--- a/src/libffmpeg/libavcodec/libpostproc/Makefile.am
+++ b/src/libffmpeg/libavcodec/libpostproc/Makefile.am
@@ -5,7 +5,7 @@ ASFLAGS =
noinst_LTLIBRARIES = libpostprocess.la
-EXTRA_DIST = postprocess_template.c
+EXTRA_DIST = postprocess_template.c postprocess_altivec_template.c
libpostprocess_la_SOURCES = postprocess.c
diff --git a/src/libffmpeg/libavcodec/libpostproc/postprocess.c b/src/libffmpeg/libavcodec/libpostproc/postprocess.c
index 9ac18eaf2..a03ff133d 100644
--- a/src/libffmpeg/libavcodec/libpostproc/postprocess.c
+++ b/src/libffmpeg/libavcodec/libpostproc/postprocess.c
@@ -1,6 +1,8 @@
/*
Copyright (C) 2001-2003 Michael Niedermayer (michaelni@gmx.at)
+ AltiVec optimizations (C) 2004 Romain Dolbeau <romain@dolbeau.org>
+
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
@@ -22,16 +24,16 @@
*/
/*
- C MMX MMX2 3DNow
-isVertDC Ec Ec
-isVertMinMaxOk Ec Ec
-doVertLowPass E e e
-doVertDefFilter Ec Ec e e
+ C MMX MMX2 3DNow AltiVec
+isVertDC Ec Ec Ec
+isVertMinMaxOk Ec Ec Ec
+doVertLowPass E e e Ec
+doVertDefFilter Ec Ec e e Ec
isHorizDC Ec Ec
isHorizMinMaxOk a E
doHorizLowPass E e e
doHorizDefFilter Ec Ec e e
-deRing E e e*
+deRing E e e* Ecp
Vertical RKAlgo1 E a a
Horizontal RKAlgo1 a a
Vertical X1# a E E
@@ -48,6 +50,7 @@ E = Exact implementation
e = allmost exact implementation (slightly different rounding,...)
a = alternative / approximate impl
c = checked against the other implementations (-vo md5)
+p = partially optimized, still some work to do
*/
/*
@@ -123,7 +126,7 @@ static uint64_t __attribute__((aligned(8))) attribute_used b80= 0x808080808080
static uint8_t clip_table[3*256];
static uint8_t * const clip_tab= clip_table + 256;
-static int verbose= 0;
+static const int verbose= 0;
static const int attribute_used deringThreshold= 20;
@@ -158,13 +161,6 @@ static char *replaceTable[]=
NULL //End Marker
};
-#ifdef ARCH_X86
-static inline void unusedVariableWarningFixer()
-{
- if(w05 + w20 + b00 + b01 + b02 + b08 + b80 == 0) b00=0;
-}
-#endif
-
#ifdef ARCH_X86
static inline void prefetchnta(void *p)
@@ -201,7 +197,7 @@ static inline void prefetcht2(void *p)
/**
* Check if the given 8x8 Block is mostly "flat"
*/
-static inline int isHorizDC(uint8_t src[], int stride, PPContext *c)
+static inline int isHorizDC_C(uint8_t src[], int stride, PPContext *c)
{
int numEq= 0;
int y;
@@ -247,7 +243,7 @@ static inline int isVertDC_C(uint8_t src[], int stride, PPContext *c){
return numEq > c->ppMode.flatnessThreshold;
}
-static inline int isHorizMinMaxOk(uint8_t src[], int stride, int QP)
+static inline int isHorizMinMaxOk_C(uint8_t src[], int stride, int QP)
{
int i;
#if 1
@@ -311,6 +307,17 @@ static inline int isVertMinMaxOk_C(uint8_t src[], int stride, int QP)
#endif
}
+static inline int horizClassify_C(uint8_t src[], int stride, PPContext *c){
+ if( isHorizDC_C(src, stride, c) ){
+ if( isHorizMinMaxOk_C(src, stride, c->QP) )
+ return 1;
+ else
+ return 0;
+ }else{
+ return 2;
+ }
+}
+
static inline int vertClassify_C(uint8_t src[], int stride, PPContext *c){
if( isVertDC_C(src, stride, c) ){
if( isVertMinMaxOk_C(src, stride, c->QP) )
@@ -322,14 +329,14 @@ static inline int vertClassify_C(uint8_t src[], int stride, PPContext *c){
}
}
-static inline void doHorizDefFilter(uint8_t dst[], int stride, int QP)
+static inline void doHorizDefFilter_C(uint8_t dst[], int stride, PPContext *c)
{
int y;
for(y=0; y<BLOCK_SIZE; y++)
{
- const int middleEnergy= 5*(dst[4] - dst[5]) + 2*(dst[2] - dst[5]);
+ const int middleEnergy= 5*(dst[4] - dst[3]) + 2*(dst[2] - dst[5]);
- if(ABS(middleEnergy) < 8*QP)
+ if(ABS(middleEnergy) < 8*c->QP)
{
const int q=(dst[3] - dst[4])/2;
const int leftEnergy= 5*(dst[2] - dst[1]) + 2*(dst[0] - dst[3]);
@@ -363,14 +370,14 @@ static inline void doHorizDefFilter(uint8_t dst[], int stride, int QP)
* Do a horizontal low pass filter on the 10x8 block (dst points to middle 8x8 Block)
* using the 9-Tap Filter (1,1,2,2,4,2,2,1,1)/16 (C version)
*/
-static inline void doHorizLowPass(uint8_t dst[], int stride, int QP)
+static inline void doHorizLowPass_C(uint8_t dst[], int stride, PPContext *c)
{
int y;
for(y=0; y<BLOCK_SIZE; y++)
{
- const int first= ABS(dst[-1] - dst[0]) < QP ? dst[-1] : dst[0];
- const int last= ABS(dst[8] - dst[7]) < QP ? dst[8] : dst[7];
+ const int first= ABS(dst[-1] - dst[0]) < c->QP ? dst[-1] : dst[0];
+ const int last= ABS(dst[8] - dst[7]) < c->QP ? dst[8] : dst[7];
int sums[9];
sums[0] = first + dst[0];
@@ -469,6 +476,17 @@ static inline void horizX1Filter(uint8_t *src, int stride, int QP)
#define COMPILE_C
#endif
+#ifdef ARCH_POWERPC
+#ifdef HAVE_ALTIVEC
+#define COMPILE_ALTIVEC
+#ifndef CONFIG_DARWIN
+#warning "################################################################################"
+#warning "WARNING: No gcc available as of today (2004-05-25) seems to be able to compile properly some of the code under non-Darwin PPC OSes. Some functions result in wrong results, while others simply won't compile (gcc explodes after allocating 1GiB+)."
+#warning "################################################################################"
+#endif //CONFIG_DARWIN
+#endif //HAVE_ALTIVEC
+#endif //ARCH_POWERPC
+
#ifdef ARCH_X86
#if (defined (HAVE_MMX) && !defined (HAVE_3DNOW) && !defined (HAVE_MMX2)) || defined (RUNTIME_CPUDETECT)
@@ -487,6 +505,7 @@ static inline void horizX1Filter(uint8_t *src, int stride, int QP)
#undef HAVE_MMX
#undef HAVE_MMX2
#undef HAVE_3DNOW
+#undef HAVE_ALTIVEC
#undef ARCH_X86
#ifdef COMPILE_C
@@ -498,6 +517,16 @@ static inline void horizX1Filter(uint8_t *src, int stride, int QP)
#include "postprocess_template.c"
#endif
+#ifdef ARCH_POWERPC
+#ifdef COMPILE_ALTIVEC
+#undef RENAME
+#define HAVE_ALTIVEC
+#define RENAME(a) a ## _altivec
+#include "postprocess_altivec_template.c"
+#include "postprocess_template.c"
+#endif
+#endif //ARCH_POWERPC
+
//MMX versions
#ifdef COMPILE_MMX
#undef RENAME
@@ -555,6 +584,13 @@ static inline void postProcess(uint8_t src[], int srcStride, uint8_t dst[], int
else
postProcess_C(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
#else
+#ifdef ARCH_POWERPC
+#ifdef HAVE_ALTIVEC
+ else if(c->cpuCaps & PP_CPU_CAPS_ALTIVEC)
+ postProcess_altivec(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
+ else
+#endif
+#endif
postProcess_C(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
#endif
#else //RUNTIME_CPUDETECT
@@ -564,6 +600,8 @@ static inline void postProcess(uint8_t src[], int srcStride, uint8_t dst[], int
postProcess_3DNow(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
#elif defined (HAVE_MMX)
postProcess_MMX(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
+#elif defined (HAVE_ALTIVEC)
+ postProcess_altivec(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
#else
postProcess_C(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
#endif
diff --git a/src/libffmpeg/libavcodec/libpostproc/postprocess.h b/src/libffmpeg/libavcodec/libpostproc/postprocess.h
index dae863044..b5d4fa319 100644
--- a/src/libffmpeg/libavcodec/libpostproc/postprocess.h
+++ b/src/libffmpeg/libavcodec/libpostproc/postprocess.h
@@ -59,6 +59,7 @@ void pp_free_context(pp_context_t *ppContext);
#define PP_CPU_CAPS_MMX 0x80000000
#define PP_CPU_CAPS_MMX2 0x20000000
#define PP_CPU_CAPS_3DNOW 0x40000000
+#define PP_CPU_CAPS_ALTIVEC 0x10000000
#define PP_FORMAT 0x00000008
#define PP_FORMAT_420 (0x00000011|PP_FORMAT)
diff --git a/src/libffmpeg/libavcodec/libpostproc/postprocess_altivec_template.c b/src/libffmpeg/libavcodec/libpostproc/postprocess_altivec_template.c
new file mode 100644
index 000000000..0c84873cc
--- /dev/null
+++ b/src/libffmpeg/libavcodec/libpostproc/postprocess_altivec_template.c
@@ -0,0 +1,713 @@
+/*
+ AltiVec optimizations (C) 2004 Romain Dolbeau <romain@dolbeau.org>
+
+ based on code by Copyright (C) 2001-2003 Michael Niedermayer (michaelni@gmx.at)
+
+ 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
+*/
+
+
+#ifdef CONFIG_DARWIN
+#define AVV(x...) (x)
+#else
+#define AVV(x...) {x}
+#endif
+
+static inline int vertClassify_altivec(uint8_t src[], int stride, PPContext *c) {
+ /*
+ this code makes no assumption on src or stride.
+ One could remove the recomputation of the perm
+ vector by assuming (stride % 16) == 0, unfortunately
+ this is not always true.
+ */
+ register int y;
+ short __attribute__ ((aligned(16))) data[8];
+ int numEq;
+ uint8_t *src2 = src;
+ vector signed short v_dcOffset;
+ vector signed short v2QP;
+ vector unsigned short v4QP;
+ vector unsigned short v_dcThreshold;
+ int two_vectors = ((((unsigned long)src2 % 16) > 8) || (stride % 16)) ? 1 : 0;
+ const vector signed int zero = vec_splat_s32(0);
+ const vector signed short mask = vec_splat_s16(1);
+ vector signed int v_numEq = vec_splat_s32(0);
+
+ data[0] = ((c->nonBQP*c->ppMode.baseDcDiff)>>8) + 1;
+ data[1] = data[0] * 2 + 1;
+ data[2] = c->QP * 2;
+ data[3] = c->QP * 4;
+ vector signed short v_data = vec_ld(0, data);
+ v_dcOffset = vec_splat(v_data, 0);
+ v_dcThreshold = (vector unsigned short)vec_splat(v_data, 1);
+ v2QP = vec_splat(v_data, 2);
+ v4QP = (vector unsigned short)vec_splat(v_data, 3);
+
+ src2 += stride * 4;
+
+#define LOAD_LINE(i) \
+ register int j##i = i * stride; \
+ vector unsigned char perm##i = vec_lvsl(j##i, src2); \
+ const vector unsigned char v_srcA1##i = vec_ld(j##i, src2); \
+ vector unsigned char v_srcA2##i; \
+ if (two_vectors) \
+ v_srcA2##i = vec_ld(j##i + 16, src2); \
+ const vector unsigned char v_srcA##i = \
+ vec_perm(v_srcA1##i, v_srcA2##i, perm##i); \
+ vector signed short v_srcAss##i = \
+ (vector signed short)vec_mergeh((vector signed char)zero, \
+ (vector signed char)v_srcA##i)
+
+ LOAD_LINE(0);
+ LOAD_LINE(1);
+ LOAD_LINE(2);
+ LOAD_LINE(3);
+ LOAD_LINE(4);
+ LOAD_LINE(5);
+ LOAD_LINE(6);
+ LOAD_LINE(7);
+#undef LOAD_LINE
+
+#define ITER(i, j) \
+ const vector signed short v_diff##i = \
+ vec_sub(v_srcAss##i, v_srcAss##j); \
+ const vector signed short v_sum##i = \
+ vec_add(v_diff##i, v_dcOffset); \
+ const vector signed short v_comp##i = \
+ (vector signed short)vec_cmplt((vector unsigned short)v_sum##i, \
+ v_dcThreshold); \
+ const vector signed short v_part##i = vec_and(mask, v_comp##i); \
+ v_numEq = vec_sum4s(v_part##i, v_numEq);
+
+ ITER(0, 1);
+ ITER(1, 2);
+ ITER(2, 3);
+ ITER(3, 4);
+ ITER(4, 5);
+ ITER(5, 6);
+ ITER(6, 7);
+#undef ITER
+
+ v_numEq = vec_sums(v_numEq, zero);
+
+ v_numEq = vec_splat(v_numEq, 3);
+ vec_ste(v_numEq, 0, &numEq);
+
+ if (numEq > c->ppMode.flatnessThreshold)
+ {
+ const vector unsigned char mmoP1 = (const vector unsigned char)
+ AVV(0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
+ 0x00, 0x01, 0x12, 0x13, 0x08, 0x09, 0x1A, 0x1B);
+ const vector unsigned char mmoP2 = (const vector unsigned char)
+ AVV(0x04, 0x05, 0x16, 0x17, 0x0C, 0x0D, 0x1E, 0x1F,
+ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f);
+ const vector unsigned char mmoP = (const vector unsigned char)
+ vec_lvsl(8, (unsigned char*)0);
+
+ vector signed short mmoL1 = vec_perm(v_srcAss0, v_srcAss2, mmoP1);
+ vector signed short mmoL2 = vec_perm(v_srcAss4, v_srcAss6, mmoP2);
+ vector signed short mmoL = vec_perm(mmoL1, mmoL2, mmoP);
+ vector signed short mmoR1 = vec_perm(v_srcAss5, v_srcAss7, mmoP1);
+ vector signed short mmoR2 = vec_perm(v_srcAss1, v_srcAss3, mmoP2);
+ vector signed short mmoR = vec_perm(mmoR1, mmoR2, mmoP);
+ vector signed short mmoDiff = vec_sub(mmoL, mmoR);
+ vector unsigned short mmoSum = (vector unsigned short)vec_add(mmoDiff, v2QP);
+
+ if (vec_any_gt(mmoSum, v4QP))
+ return 0;
+ else
+ return 1;
+ }
+ else return 2;
+}
+
+
+static inline void doVertLowPass_altivec(uint8_t *src, int stride, PPContext *c) {
+ /*
+ this code makes no assumption on src or stride.
+ One could remove the recomputation of the perm
+ vector by assuming (stride % 16) == 0, unfortunately
+ this is not always true. Quite a lot of load/stores
+ can be removed by assuming proper alignement of
+ src & stride :-(
+ */
+ uint8_t *src2 = src;
+ const vector signed int zero = vec_splat_s32(0);
+ short __attribute__ ((aligned(16))) qp[8];
+ qp[0] = c->QP;
+ vector signed short vqp = vec_ld(0, qp);
+ vqp = vec_splat(vqp, 0);
+
+#define LOAD_LINE(i) \
+ const vector unsigned char perml##i = \
+ vec_lvsl(i * stride, src2); \
+ const vector unsigned char vbA##i = \
+ vec_ld(i * stride, src2); \
+ const vector unsigned char vbB##i = \
+ vec_ld(i * stride + 16, src2); \
+ const vector unsigned char vbT##i = \
+ vec_perm(vbA##i, vbB##i, perml##i); \
+ const vector signed short vb##i = \
+ (vector signed short)vec_mergeh((vector unsigned char)zero, \
+ (vector unsigned char)vbT##i)
+
+ src2 += stride*3;
+
+ LOAD_LINE(0);
+ LOAD_LINE(1);
+ LOAD_LINE(2);
+ LOAD_LINE(3);
+ LOAD_LINE(4);
+ LOAD_LINE(5);
+ LOAD_LINE(6);
+ LOAD_LINE(7);
+ LOAD_LINE(8);
+ LOAD_LINE(9);
+#undef LOAD_LINE
+
+ const vector unsigned short v_1 = vec_splat_u16(1);
+ const vector unsigned short v_2 = vec_splat_u16(2);
+ const vector unsigned short v_4 = vec_splat_u16(4);
+ const vector signed short v_8 = vec_splat_s16(8);
+
+ const vector signed short v_first = vec_sel(vb1, vb0,
+ vec_cmplt(vec_abs(vec_sub(vb0, vb1)),
+ vqp));
+ const vector signed short v_last = vec_sel(vb8, vb9,
+ vec_cmplt(vec_abs(vec_sub(vb8, vb9)),
+ vqp));
+
+ const vector signed short v_sums0 = vec_add(v_first, vb1);
+ const vector signed short v_sums1 = vec_add(vb1, vb2);
+ const vector signed short v_sums2 = vec_add(vb2, vb3);
+ const vector signed short v_sums3 = vec_add(vb3, vb4);
+ const vector signed short v_sums4 = vec_add(vb4, vb5);
+ const vector signed short v_sums5 = vec_add(vb5, vb6);
+ const vector signed short v_sums6 = vec_add(vb6, vb7);
+ const vector signed short v_sums7 = vec_add(vb7, vb8);
+ const vector signed short v_sums8 = vec_add(vb8, v_last);
+
+ const vector signed short vr1 = vec_sra(vec_add(vec_add(vec_sl(v_sums0, v_2),
+ vec_sl(vec_add(v_first, v_sums2), v_1)),
+ vec_add(v_sums4, v_8)),
+ v_4);
+ const vector signed short vr2 = vec_sra(vec_add(vec_add(vec_sl(vb2, v_2),
+ v_sums5),
+ vec_add(v_8,
+ vec_sl(vec_add(v_first,
+ vec_add(v_sums0, v_sums3)),
+ v_1))),
+ v_4);
+ const vector signed short vr3 = vec_sra(vec_add(vec_add(vec_sl(vb3, v_2),
+ v_sums6),
+ vec_add(v_8,
+ vec_sl(vec_add(v_first,
+ vec_add(v_sums1, v_sums4)),
+ v_1))),
+ v_4);
+ const vector signed short vr4 = vec_sra(vec_add(vec_add(vec_sl(vb4, v_2),
+ v_sums7),
+ vec_add(v_8,
+ vec_add(v_sums0,
+ vec_sl(vec_add(v_sums2, v_sums5),
+ v_1)))),
+ v_4);
+ const vector signed short vr5 = vec_sra(vec_add(vec_add(vec_sl(vb5, v_2),
+ v_sums8),
+ vec_add(v_8,
+ vec_add(v_sums1,
+ vec_sl(vec_add(v_sums3, v_sums6),
+ v_1)))),
+ v_4);
+ const vector signed short vr6 = vec_sra(vec_add(vec_add(vec_sl(vb6, v_2),
+ v_sums2),
+ vec_add(v_8,
+ vec_sl(vec_add(v_last,
+ vec_add(v_sums7, v_sums4)),
+ v_1))),
+ v_4);
+ const vector signed short vr7 = vec_sra(vec_add(vec_add(vec_sl(vec_add(v_last, vb7), v_2),
+ vec_sl(vec_add(vb8, v_sums5), v_1)),
+ vec_add(v_8, v_sums3)),
+ v_4);
+ const vector signed short vr8 = vec_sra(vec_add(vec_add(vec_sl(v_sums8, v_2),
+ vec_sl(vec_add(v_last, v_sums6), v_1)),
+ vec_add(v_sums4, v_8)),
+ v_4);
+
+ const vector unsigned char neg1 = (vector unsigned char)AVV(-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1);
+ const vector unsigned char permHH = (vector unsigned char)AVV(0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F);
+
+#define PACK_AND_STORE(i) \
+ const vector unsigned char perms##i = \
+ vec_lvsr(i * stride, src2); \
+ const vector unsigned char vf##i = \
+ vec_packsu(vr##i, (vector signed short)zero); \
+ const vector unsigned char vg##i = \
+ vec_perm(vf##i, vbT##i, permHH); \
+ const vector unsigned char mask##i = \
+ vec_perm((vector unsigned char)zero, neg1, perms##i); \
+ const vector unsigned char vg2##i = \
+ vec_perm(vg##i, vg##i, perms##i); \
+ const vector unsigned char svA##i = \
+ vec_sel(vbA##i, vg2##i, mask##i); \
+ const vector unsigned char svB##i = \
+ vec_sel(vg2##i, vbB##i, mask##i); \
+ vec_st(svA##i, i * stride, src2); \
+ vec_st(svB##i, i * stride + 16, src2)
+
+ PACK_AND_STORE(1);
+ PACK_AND_STORE(2);
+ PACK_AND_STORE(3);
+ PACK_AND_STORE(4);
+ PACK_AND_STORE(5);
+ PACK_AND_STORE(6);
+ PACK_AND_STORE(7);
+ PACK_AND_STORE(8);
+
+#undef PACK_AND_STORE
+}
+
+
+
+static inline void doVertDefFilter_altivec(uint8_t src[], int stride, PPContext *c) {
+ /*
+ this code makes no assumption on src or stride.
+ One could remove the recomputation of the perm
+ vector by assuming (stride % 16) == 0, unfortunately
+ this is not always true. Quite a lot of load/stores
+ can be removed by assuming proper alignement of
+ src & stride :-(
+ */
+ uint8_t *src2 = src;
+ const vector signed int zero = vec_splat_s32(0);
+ short __attribute__ ((aligned(16))) qp[8];
+ qp[0] = 8*c->QP;
+ vector signed short vqp = vec_ld(0, qp);
+ vqp = vec_splat(vqp, 0);
+
+#define LOAD_LINE(i) \
+ const vector unsigned char perm##i = \
+ vec_lvsl(i * stride, src2); \
+ const vector unsigned char vbA##i = \
+ vec_ld(i * stride, src2); \
+ const vector unsigned char vbB##i = \
+ vec_ld(i * stride + 16, src2); \
+ const vector unsigned char vbT##i = \
+ vec_perm(vbA##i, vbB##i, perm##i); \
+ const vector signed short vb##i = \
+ (vector signed short)vec_mergeh((vector unsigned char)zero, \
+ (vector unsigned char)vbT##i)
+
+ src2 += stride*3;
+
+ LOAD_LINE(1);
+ LOAD_LINE(2);
+ LOAD_LINE(3);
+ LOAD_LINE(4);
+ LOAD_LINE(5);
+ LOAD_LINE(6);
+ LOAD_LINE(7);
+ LOAD_LINE(8);
+#undef LOAD_LINE
+
+ const vector signed short v_1 = vec_splat_s16(1);
+ const vector signed short v_2 = vec_splat_s16(2);
+ const vector signed short v_5 = vec_splat_s16(5);
+ const vector signed short v_32 = vec_sl(v_1,
+ (vector unsigned short)v_5);
+ /* middle energy */
+ const vector signed short l3minusl6 = vec_sub(vb3, vb6);
+ const vector signed short l5minusl4 = vec_sub(vb5, vb4);
+ const vector signed short twotimes_l3minusl6 = vec_mladd(v_2, l3minusl6, (vector signed short)zero);
+ const vector signed short mE = vec_mladd(v_5, l5minusl4, twotimes_l3minusl6);
+ const vector signed short absmE = vec_abs(mE);
+ /* left & right energy */
+ const vector signed short l1minusl4 = vec_sub(vb1, vb4);
+ const vector signed short l3minusl2 = vec_sub(vb3, vb2);
+ const vector signed short l5minusl8 = vec_sub(vb5, vb8);
+ const vector signed short l7minusl6 = vec_sub(vb7, vb6);
+ const vector signed short twotimes_l1minusl4 = vec_mladd(v_2, l1minusl4, (vector signed short)zero);
+ const vector signed short twotimes_l5minusl8 = vec_mladd(v_2, l5minusl8, (vector signed short)zero);
+ const vector signed short lE = vec_mladd(v_5, l3minusl2, twotimes_l1minusl4);
+ const vector signed short rE = vec_mladd(v_5, l7minusl6, twotimes_l5minusl8);
+ /* d */
+ const vector signed short ddiff = vec_sub(absmE,
+ vec_min(vec_abs(lE),
+ vec_abs(rE)));
+ const vector signed short ddiffclamp = vec_max(ddiff, (vector signed short)zero);
+ const vector signed short dtimes64 = vec_mladd(v_5, ddiffclamp, v_32);
+ const vector signed short d = vec_sra(dtimes64, vec_splat_u16(6));
+ const vector signed short minusd = vec_sub((vector signed short)zero, d);
+ const vector signed short finald = vec_sel(minusd,
+ d,
+ vec_cmpgt(vec_sub((vector signed short)zero, mE),
+ (vector signed short)zero));
+ /* q */
+ const vector signed short qtimes2 = vec_sub(vb4, vb5);
+ /* for a shift right to behave like /2, we need to add one
+ to all negative integer */
+ const vector signed short rounddown = vec_sel((vector signed short)zero,
+ v_1,
+ vec_cmplt(qtimes2, (vector signed short)zero));
+ const vector signed short q = vec_sra(vec_add(qtimes2, rounddown), vec_splat_u16(1));
+ /* clamp */
+ const vector signed short dclamp_P1 = vec_max((vector signed short)zero, finald);
+ const vector signed short dclamp_P = vec_min(dclamp_P1, q);
+ const vector signed short dclamp_N1 = vec_min((vector signed short)zero, finald);
+ const vector signed short dclamp_N = vec_max(dclamp_N1, q);
+
+ const vector signed short dclampedfinal = vec_sel(dclamp_N,
+ dclamp_P,
+ vec_cmpgt(q, (vector signed short)zero));
+ const vector signed short dornotd = vec_sel((vector signed short)zero,
+ dclampedfinal,
+ vec_cmplt(absmE, vqp));
+ /* add/substract to l4 and l5 */
+ const vector signed short vb4minusd = vec_sub(vb4, dornotd);
+ const vector signed short vb5plusd = vec_add(vb5, dornotd);
+ /* finally, stores */
+ const vector unsigned char st4 = vec_packsu(vb4minusd, (vector signed short)zero);
+ const vector unsigned char st5 = vec_packsu(vb5plusd, (vector signed short)zero);
+
+ const vector unsigned char neg1 = (vector unsigned char)AVV(-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1);
+
+ const vector unsigned char permHH = (vector unsigned char)AVV(0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F);
+
+#define STORE(i) \
+ const vector unsigned char perms##i = \
+ vec_lvsr(i * stride, src2); \
+ const vector unsigned char vg##i = \
+ vec_perm(st##i, vbT##i, permHH); \
+ const vector unsigned char mask##i = \
+ vec_perm((vector unsigned char)zero, neg1, perms##i); \
+ const vector unsigned char vg2##i = \
+ vec_perm(vg##i, vg##i, perms##i); \
+ const vector unsigned char svA##i = \
+ vec_sel(vbA##i, vg2##i, mask##i); \
+ const vector unsigned char svB##i = \
+ vec_sel(vg2##i, vbB##i, mask##i); \
+ vec_st(svA##i, i * stride, src2); \
+ vec_st(svB##i, i * stride + 16, src2)
+
+ STORE(4);
+ STORE(5);
+}
+
+static inline void dering_altivec(uint8_t src[], int stride, PPContext *c) {
+ /*
+ this code makes no assumption on src or stride.
+ One could remove the recomputation of the perm
+ vector by assuming (stride % 16) == 0, unfortunately
+ this is not always true. Quite a lot of load/stores
+ can be removed by assuming proper alignement of
+ src & stride :-(
+ */
+ uint8_t *srcCopy = src;
+ uint8_t __attribute__((aligned(16))) dt[16];
+ const vector unsigned char vuint8_1 = vec_splat_u8(1);
+ const vector signed int zero = vec_splat_s32(0);
+ vector unsigned char v_dt;
+ dt[0] = deringThreshold;
+ v_dt = vec_splat(vec_ld(0, dt), 0);
+
+#define LOAD_LINE(i) \
+ const vector unsigned char perm##i = \
+ vec_lvsl(i * stride, srcCopy); \
+ vector unsigned char sA##i = vec_ld(i * stride, srcCopy); \
+ vector unsigned char sB##i = vec_ld(i * stride + 16, srcCopy); \
+ vector unsigned char src##i = vec_perm(sA##i, sB##i, perm##i)
+
+ LOAD_LINE(0);
+ LOAD_LINE(1);
+ LOAD_LINE(2);
+ LOAD_LINE(3);
+ LOAD_LINE(4);
+ LOAD_LINE(5);
+ LOAD_LINE(6);
+ LOAD_LINE(7);
+ LOAD_LINE(8);
+ LOAD_LINE(9);
+#undef LOAD_LINE
+
+ vector unsigned char v_avg;
+ {
+ const vector unsigned char trunc_perm = (vector unsigned char)
+ AVV(0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18);
+ const vector unsigned char trunc_src12 = vec_perm(src1, src2, trunc_perm);
+ const vector unsigned char trunc_src34 = vec_perm(src3, src4, trunc_perm);
+ const vector unsigned char trunc_src56 = vec_perm(src5, src6, trunc_perm);
+ const vector unsigned char trunc_src78 = vec_perm(src7, src8, trunc_perm);
+
+#define EXTRACT(op) do { \
+ const vector unsigned char s##op##_1 = vec_##op(trunc_src12, trunc_src34); \
+ const vector unsigned char s##op##_2 = vec_##op(trunc_src56, trunc_src78); \
+ const vector unsigned char s##op##_6 = vec_##op(s##op##_1, s##op##_2); \
+ const vector unsigned char s##op##_8h = vec_mergeh(s##op##_6, s##op##_6); \
+ const vector unsigned char s##op##_8l = vec_mergel(s##op##_6, s##op##_6); \
+ const vector unsigned char s##op##_9 = vec_##op(s##op##_8h, s##op##_8l); \
+ const vector unsigned char s##op##_9h = vec_mergeh(s##op##_9, s##op##_9); \
+ const vector unsigned char s##op##_9l = vec_mergel(s##op##_9, s##op##_9); \
+ const vector unsigned char s##op##_10 = vec_##op(s##op##_9h, s##op##_9l); \
+ const vector unsigned char s##op##_10h = vec_mergeh(s##op##_10, s##op##_10); \
+ const vector unsigned char s##op##_10l = vec_mergel(s##op##_10, s##op##_10); \
+ const vector unsigned char s##op##_11 = vec_##op(s##op##_10h, s##op##_10l); \
+ const vector unsigned char s##op##_11h = vec_mergeh(s##op##_11, s##op##_11); \
+ const vector unsigned char s##op##_11l = vec_mergel(s##op##_11, s##op##_11); \
+ v_##op = vec_##op(s##op##_11h, s##op##_11l); } while (0)
+
+ vector unsigned char v_min;
+ vector unsigned char v_max;
+ EXTRACT(min);
+ EXTRACT(max);
+#undef EXTRACT
+
+ if (vec_all_lt(vec_sub(v_max, v_min), v_dt))
+ return;
+
+ v_avg = vec_avg(v_min, v_max);
+ }
+
+ signed int __attribute__((aligned(16))) S[8];
+ {
+ const vector unsigned short mask1 = (vector unsigned short)
+ AVV(0x0001, 0x0002, 0x0004, 0x0008,
+ 0x0010, 0x0020, 0x0040, 0x0080);
+ const vector unsigned short mask2 = (vector unsigned short)
+ AVV(0x0100, 0x0200, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000);
+
+ const vector unsigned int vuint32_16 = vec_sl(vec_splat_u32(1), vec_splat_u32(4));
+ const vector unsigned int vuint32_1 = vec_splat_u32(1);
+
+#define COMPARE(i) \
+ vector signed int sum##i; \
+ do { \
+ const vector unsigned char cmp##i = \
+ (vector unsigned char)vec_cmpgt(src##i, v_avg); \
+ const vector unsigned short cmpHi##i = \
+ (vector unsigned short)vec_mergeh(cmp##i, cmp##i); \
+ const vector unsigned short cmpLi##i = \
+ (vector unsigned short)vec_mergel(cmp##i, cmp##i); \
+ const vector signed short cmpHf##i = \
+ (vector signed short)vec_and(cmpHi##i, mask1); \
+ const vector signed short cmpLf##i = \
+ (vector signed short)vec_and(cmpLi##i, mask2); \
+ const vector signed int sump##i = vec_sum4s(cmpHf##i, zero); \
+ const vector signed int sumq##i = vec_sum4s(cmpLf##i, sump##i); \
+ sum##i = vec_sums(sumq##i, zero); } while (0)
+
+ COMPARE(0);
+ COMPARE(1);
+ COMPARE(2);
+ COMPARE(3);
+ COMPARE(4);
+ COMPARE(5);
+ COMPARE(6);
+ COMPARE(7);
+ COMPARE(8);
+ COMPARE(9);
+#undef COMPARE
+
+ vector signed int sumA2;
+ vector signed int sumB2;
+ {
+ const vector signed int sump02 = vec_mergel(sum0, sum2);
+ const vector signed int sump13 = vec_mergel(sum1, sum3);
+ const vector signed int sumA = vec_mergel(sump02, sump13);
+
+ const vector signed int sump46 = vec_mergel(sum4, sum6);
+ const vector signed int sump57 = vec_mergel(sum5, sum7);
+ const vector signed int sumB = vec_mergel(sump46, sump57);
+
+ const vector signed int sump8A = vec_mergel(sum8, zero);
+ const vector signed int sump9B = vec_mergel(sum9, zero);
+ const vector signed int sumC = vec_mergel(sump8A, sump9B);
+
+ const vector signed int tA = vec_sl(vec_nor(zero, sumA), vuint32_16);
+ const vector signed int tB = vec_sl(vec_nor(zero, sumB), vuint32_16);
+ const vector signed int tC = vec_sl(vec_nor(zero, sumC), vuint32_16);
+ const vector signed int t2A = vec_or(sumA, tA);
+ const vector signed int t2B = vec_or(sumB, tB);
+ const vector signed int t2C = vec_or(sumC, tC);
+ const vector signed int t3A = vec_and(vec_sra(t2A, vuint32_1),
+ vec_sl(t2A, vuint32_1));
+ const vector signed int t3B = vec_and(vec_sra(t2B, vuint32_1),
+ vec_sl(t2B, vuint32_1));
+ const vector signed int t3C = vec_and(vec_sra(t2C, vuint32_1),
+ vec_sl(t2C, vuint32_1));
+ const vector signed int yA = vec_and(t2A, t3A);
+ const vector signed int yB = vec_and(t2B, t3B);
+ const vector signed int yC = vec_and(t2C, t3C);
+
+ const vector unsigned char strangeperm1 = vec_lvsl(4, (unsigned char*)0);
+ const vector unsigned char strangeperm2 = vec_lvsl(8, (unsigned char*)0);
+ const vector signed int sumAd4 = vec_perm(yA, yB, strangeperm1);
+ const vector signed int sumAd8 = vec_perm(yA, yB, strangeperm2);
+ const vector signed int sumBd4 = vec_perm(yB, yC, strangeperm1);
+ const vector signed int sumBd8 = vec_perm(yB, yC, strangeperm2);
+ const vector signed int sumAp = vec_and(yA,
+ vec_and(sumAd4,sumAd8));
+ const vector signed int sumBp = vec_and(yB,
+ vec_and(sumBd4,sumBd8));
+ sumA2 = vec_or(sumAp,
+ vec_sra(sumAp,
+ vuint32_16));
+ sumB2 = vec_or(sumBp,
+ vec_sra(sumBp,
+ vuint32_16));
+ }
+ vec_st(sumA2, 0, S);
+ vec_st(sumB2, 16, S);
+ }
+
+ /* I'm not sure the following is actually faster
+ than straight, unvectorized C code :-( */
+
+ int __attribute__((aligned(16))) tQP2[4];
+ tQP2[0]= c->QP/2 + 1;
+ vector signed int vQP2 = vec_ld(0, tQP2);
+ vQP2 = vec_splat(vQP2, 0);
+ const vector unsigned char vuint8_2 = vec_splat_u8(2);
+ const vector signed int vsint32_8 = vec_splat_s32(8);
+ const vector unsigned int vuint32_4 = vec_splat_u32(4);
+
+ const vector unsigned char permA1 = (vector unsigned char)
+ AVV(0x00, 0x01, 0x02, 0x10, 0x11, 0x12, 0x1F, 0x1F,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F);
+ const vector unsigned char permA2 = (vector unsigned char)
+ AVV(0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x10, 0x11,
+ 0x12, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F);
+ const vector unsigned char permA1inc = (vector unsigned char)
+ AVV(0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ const vector unsigned char permA2inc = (vector unsigned char)
+ AVV(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ const vector unsigned char magic = (vector unsigned char)
+ AVV(0x01, 0x02, 0x01, 0x02, 0x04, 0x02, 0x01, 0x02,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ const vector unsigned char extractPerm = (vector unsigned char)
+ AVV(0x10, 0x10, 0x10, 0x01, 0x10, 0x10, 0x10, 0x01,
+ 0x10, 0x10, 0x10, 0x01, 0x10, 0x10, 0x10, 0x01);
+ const vector unsigned char extractPermInc = (vector unsigned char)
+ AVV(0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01);
+ const vector unsigned char identity = vec_lvsl(0,(unsigned char *)0);
+ const vector unsigned char tenRight = (vector unsigned char)
+ AVV(0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ const vector unsigned char eightLeft = (vector unsigned char)
+ AVV(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08);
+
+
+#define F_INIT(i) \
+ vector unsigned char tenRightM##i = tenRight; \
+ vector unsigned char permA1M##i = permA1; \
+ vector unsigned char permA2M##i = permA2; \
+ vector unsigned char extractPermM##i = extractPerm
+
+#define F2(i, j, k, l) \
+ if (S[i] & (1 << (l+1))) { \
+ const vector unsigned char a_##j##_A##l = \
+ vec_perm(src##i, src##j, permA1M##i); \
+ const vector unsigned char a_##j##_B##l = \
+ vec_perm(a_##j##_A##l, src##k, permA2M##i); \
+ const vector signed int a_##j##_sump##l = \
+ (vector signed int)vec_msum(a_##j##_B##l, magic, \
+ (vector unsigned int)zero); \
+ vector signed int F_##j##_##l = \
+ vec_sr(vec_sums(a_##j##_sump##l, vsint32_8), vuint32_4); \
+ F_##j##_##l = vec_splat(F_##j##_##l, 3); \
+ const vector signed int p_##j##_##l = \
+ (vector signed int)vec_perm(src##j, \
+ (vector unsigned char)zero, \
+ extractPermM##i); \
+ const vector signed int sum_##j##_##l = vec_add( p_##j##_##l, vQP2); \
+ const vector signed int diff_##j##_##l = vec_sub( p_##j##_##l, vQP2); \
+ vector signed int newpm_##j##_##l; \
+ if (vec_all_lt(sum_##j##_##l, F_##j##_##l)) \
+ newpm_##j##_##l = sum_##j##_##l; \
+ else if (vec_all_gt(diff_##j##_##l, F_##j##_##l)) \
+ newpm_##j##_##l = diff_##j##_##l; \
+ else newpm_##j##_##l = F_##j##_##l; \
+ const vector unsigned char newpm2_##j##_##l = \
+ vec_splat((vector unsigned char)newpm_##j##_##l, 15); \
+ const vector unsigned char mask##j##l = vec_add(identity, \
+ tenRightM##i); \
+ src##j = vec_perm(src##j, newpm2_##j##_##l, mask##j##l); \
+ } \
+ permA1M##i = vec_add(permA1M##i, permA1inc); \
+ permA2M##i = vec_add(permA2M##i, permA2inc); \
+ tenRightM##i = vec_sro(tenRightM##i, eightLeft); \
+ extractPermM##i = vec_add(extractPermM##i, extractPermInc)
+
+#define ITER(i, j, k) \
+ F_INIT(i); \
+ F2(i, j, k, 0); \
+ F2(i, j, k, 1); \
+ F2(i, j, k, 2); \
+ F2(i, j, k, 3); \
+ F2(i, j, k, 4); \
+ F2(i, j, k, 5); \
+ F2(i, j, k, 6); \
+ F2(i, j, k, 7)
+
+ ITER(0, 1, 2);
+ ITER(1, 2, 3);
+ ITER(2, 3, 4);
+ ITER(3, 4, 5);
+ ITER(4, 5, 6);
+ ITER(5, 6, 7);
+ ITER(6, 7, 8);
+ ITER(7, 8, 9);
+
+ const vector signed char neg1 = vec_splat_s8( -1 );
+
+#define STORE_LINE(i) \
+ const vector unsigned char permST##i = \
+ vec_lvsr(i * stride, srcCopy); \
+ const vector unsigned char maskST##i = \
+ vec_perm((vector unsigned char)zero, \
+ (vector unsigned char)neg1, permST##i); \
+ src##i = vec_perm(src##i ,src##i, permST##i); \
+ sA##i= vec_sel(sA##i, src##i, maskST##i); \
+ sB##i= vec_sel(src##i, sB##i, maskST##i); \
+ vec_st(sA##i, i * stride, srcCopy); \
+ vec_st(sB##i, i * stride + 16, srcCopy)
+
+ STORE_LINE(1);
+ STORE_LINE(2);
+ STORE_LINE(3);
+ STORE_LINE(4);
+ STORE_LINE(5);
+ STORE_LINE(6);
+ STORE_LINE(7);
+ STORE_LINE(8);
+
+#undef STORE_LINE
+#undef ITER
+#undef F2
+}
+
+#define horizClassify_altivec(a...) horizClassify_C(a)
+#define doHorizLowPass_altivec(a...) doHorizLowPass_C(a)
+#define doHorizDefFilter_altivec(a...) doHorizDefFilter_C(a)
diff --git a/src/libffmpeg/libavcodec/libpostproc/postprocess_template.c b/src/libffmpeg/libavcodec/libpostproc/postprocess_template.c
index 7ebc08bd4..4e81bd556 100644
--- a/src/libffmpeg/libavcodec/libpostproc/postprocess_template.c
+++ b/src/libffmpeg/libavcodec/libpostproc/postprocess_template.c
@@ -170,6 +170,7 @@ asm volatile(
* Do a vertical low pass filter on the 8x16 block (only write to the 8x8 block in the middle)
* using the 9-Tap Filter (1,1,2,2,4,2,2,1,1)/16
*/
+#ifndef HAVE_ALTIVEC
static inline void RENAME(doVertLowPass)(uint8_t *src, int stride, PPContext *c)
{
#if defined (HAVE_MMX2) || defined (HAVE_3DNOW)
@@ -340,6 +341,7 @@ static inline void RENAME(doVertLowPass)(uint8_t *src, int stride, PPContext *c)
}
#endif
}
+#endif //HAVE_ALTIVEC
#if 0
/**
@@ -582,6 +584,7 @@ static inline void RENAME(vertX1Filter)(uint8_t *src, int stride, PPContext *co)
#endif
}
+#ifndef HAVE_ALTIVEC
static inline void RENAME(doVertDefFilter)(uint8_t src[], int stride, PPContext *c)
{
#if defined (HAVE_MMX2) || defined (HAVE_3DNOW)
@@ -1149,7 +1152,9 @@ src-=8;
}
#endif
}
+#endif //HAVE_ALTIVEC
+#ifndef HAVE_ALTIVEC
static inline void RENAME(dering)(uint8_t src[], int stride, PPContext *c)
{
#if defined (HAVE_MMX2) || defined (HAVE_3DNOW)
@@ -1505,6 +1510,7 @@ DERING_CORE((%0, %1, 8),(%%edx, %1, 4) ,%%mm2,%%mm4,%%mm0,%%mm3,%%mm5,%%mm1,%%mm
#endif
#endif
}
+#endif //HAVE_ALTIVEC
/**
* Deinterlaces the given block by linearly interpolating every second line.
@@ -2789,7 +2795,7 @@ static void RENAME(postProcess)(uint8_t src[], int srcStride, uint8_t dst[], int
uint64_t * const yHistogram= c.yHistogram;
uint8_t * const tempSrc= c.tempSrc;
uint8_t * const tempDst= c.tempDst;
- const int mbWidth= isColor ? (width+7)>>3 : (width+15)>>4;
+ //const int mbWidth= isColor ? (width+7)>>3 : (width+15)>>4;
#ifdef HAVE_MMX
for(i=0; i<57; i++){
@@ -3134,13 +3140,12 @@ static void RENAME(postProcess)(uint8_t src[], int srcStride, uint8_t dst[], int
horizX1Filter(dstBlock-4, stride, QP);
else if(mode & H_DEBLOCK)
{
- if( isHorizDC(dstBlock-4, stride, &c))
- {
- if(isHorizMinMaxOk(dstBlock-4, stride, QP))
- doHorizLowPass(dstBlock-4, stride, QP);
- }
- else
- doHorizDefFilter(dstBlock-4, stride, QP);
+ const int t= RENAME(horizClassify)(dstBlock-4, stride, &c);
+
+ if(t==1)
+ RENAME(doHorizLowPass)(dstBlock-4, stride, &c);
+ else if(t==2)
+ RENAME(doHorizDefFilter)(dstBlock-4, stride, &c);
}
#endif
if(mode & DERING)
diff --git a/src/libffmpeg/libavcodec/mace.c b/src/libffmpeg/libavcodec/mace.c
index 1beac6c40..8a4a20568 100644
--- a/src/libffmpeg/libavcodec/mace.c
+++ b/src/libffmpeg/libavcodec/mace.c
@@ -421,7 +421,6 @@ puts("mace_decode_frame[6]()");
*data_size = 2 * 6 * buf_size;
break;
default:
- *data_size = 0;
return -1;
}
return buf_size;
diff --git a/src/libffmpeg/libavcodec/mangle.h b/src/libffmpeg/libavcodec/mangle.h
deleted file mode 100644
index df7477774..000000000
--- a/src/libffmpeg/libavcodec/mangle.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* mangle.h - This file has some CPP macros to deal with different symbol
- * mangling across binary formats.
- * (c)2002 by Felix Buenemann <atmosfear at users.sourceforge.net>
- * File licensed under the GPL, see http://www.fsf.org/ for more info.
- */
-
-#ifndef __MANGLE_H
-#define __MANGLE_H
-
-/* Feel free to add more to the list, eg. a.out IMO */
-#if defined(__CYGWIN__)
-#define MANGLE(a) "_" #a
-#else
-#define MANGLE(a) #a
-#endif
-
-#endif /* !__MANGLE_H */
-
diff --git a/src/libffmpeg/libavcodec/mdec.c b/src/libffmpeg/libavcodec/mdec.c
index 219a39b25..ef4e6ec0a 100644
--- a/src/libffmpeg/libavcodec/mdec.c
+++ b/src/libffmpeg/libavcodec/mdec.c
@@ -163,8 +163,6 @@ static int decode_frame(AVCodecContext *avctx,
AVFrame * const p= (AVFrame*)&a->picture;
int i;
- *data_size = 0;
-
/* special case for last picture */
if (buf_size == 0) {
return 0;
diff --git a/src/libffmpeg/libavcodec/mjpeg.c b/src/libffmpeg/libavcodec/mjpeg.c
index 78a620fd3..4e2305aef 100644
--- a/src/libffmpeg/libavcodec/mjpeg.c
+++ b/src/libffmpeg/libavcodec/mjpeg.c
@@ -1724,8 +1724,6 @@ static int mjpeg_decode_frame(AVCodecContext *avctx,
int start_code;
AVFrame *picture = data;
- *data_size = 0;
-
/* no supplementary picture */
if (buf_size == 0)
return 0;
@@ -1902,8 +1900,6 @@ static int mjpegb_decode_frame(AVCodecContext *avctx,
uint32_t dqt_offs, dht_offs, sof_offs, sos_offs, second_field_offs;
uint32_t field_size;
- *data_size = 0;
-
/* no supplementary picture */
if (buf_size == 0)
return 0;
@@ -2015,8 +2011,6 @@ static int sp5x_decode_frame(AVCodecContext *avctx,
uint8_t *buf_ptr, *buf_end, *recoded;
int i = 0, j = 0;
- *data_size = 0;
-
/* no supplementary picture */
if (buf_size == 0)
return 0;
diff --git a/src/libffmpeg/libavcodec/motion_est.c b/src/libffmpeg/libavcodec/motion_est.c
index 6aeedd5b9..a434870a6 100644
--- a/src/libffmpeg/libavcodec/motion_est.c
+++ b/src/libffmpeg/libavcodec/motion_est.c
@@ -20,6 +20,9 @@
*
* new Motion Estimation (X1/EPZS) by Michael Niedermayer <michaelni@gmx.at>
*/
+
+/* motion estimation only needed for encoders */
+#ifdef CONFIG_ENCODERS
/**
* @file motion_est.c
@@ -49,14 +52,14 @@ static inline int sad_hpel_motion_search(MpegEncContext * s,
int src_index, int ref_index,
int size, int h);
-static inline int update_map_generation(MpegEncContext * s)
+static inline int update_map_generation(MotionEstContext *c)
{
- s->me.map_generation+= 1<<(ME_MAP_MV_BITS*2);
- if(s->me.map_generation==0){
- s->me.map_generation= 1<<(ME_MAP_MV_BITS*2);
- memset(s->me.map, 0, sizeof(uint32_t)*ME_MAP_SIZE);
+ c->map_generation+= 1<<(ME_MAP_MV_BITS*2);
+ if(c->map_generation==0){
+ c->map_generation= 1<<(ME_MAP_MV_BITS*2);
+ memset(c->map, 0, sizeof(uint32_t)*ME_MAP_SIZE);
}
- return s->me.map_generation;
+ return c->map_generation;
}
/* shape adaptive search stuff */
@@ -77,8 +80,7 @@ static int minima_cmp(const void *a, const void *b){
#define FLAG_CHROMA 2
#define FLAG_DIRECT 4
-static inline void init_ref(MpegEncContext *s, uint8_t *src[3], uint8_t *ref[3], uint8_t *ref2[3], int x, int y, int ref_index){
- MotionEstContext * const c= &s->me;
+static inline void init_ref(MotionEstContext *c, uint8_t *src[3], uint8_t *ref[3], uint8_t *ref2[3], int x, int y, int ref_index){
const int offset[3]= {
y*c-> stride + x,
((y*c->uvstride + x)>>1),
@@ -96,8 +98,8 @@ static inline void init_ref(MpegEncContext *s, uint8_t *src[3], uint8_t *ref[3],
}
}
-static int get_flags(MpegEncContext *s, int direct, int chroma){
- return ((s->flags&CODEC_FLAG_QPEL) ? FLAG_QPEL : 0)
+static int get_flags(MotionEstContext *c, int direct, int chroma){
+ return ((c->avctx->flags&CODEC_FLAG_QPEL) ? FLAG_QPEL : 0)
+ (direct ? FLAG_DIRECT : 0)
+ (chroma ? FLAG_CHROMA : 0);
}
@@ -241,41 +243,42 @@ static inline int get_penalty_factor(MpegEncContext *s, int type){
void ff_init_me(MpegEncContext *s){
MotionEstContext * const c= &s->me;
+ c->avctx= s->avctx;
- ff_set_cmp(&s->dsp, s->dsp.me_pre_cmp, s->avctx->me_pre_cmp);
- ff_set_cmp(&s->dsp, s->dsp.me_cmp, s->avctx->me_cmp);
- ff_set_cmp(&s->dsp, s->dsp.me_sub_cmp, s->avctx->me_sub_cmp);
- ff_set_cmp(&s->dsp, s->dsp.mb_cmp, s->avctx->mb_cmp);
+ ff_set_cmp(&s->dsp, s->dsp.me_pre_cmp, c->avctx->me_pre_cmp);
+ ff_set_cmp(&s->dsp, s->dsp.me_cmp, c->avctx->me_cmp);
+ ff_set_cmp(&s->dsp, s->dsp.me_sub_cmp, c->avctx->me_sub_cmp);
+ ff_set_cmp(&s->dsp, s->dsp.mb_cmp, c->avctx->mb_cmp);
- s->me.flags = get_flags(s, 0, s->avctx->me_cmp &FF_CMP_CHROMA);
- s->me.sub_flags= get_flags(s, 0, s->avctx->me_sub_cmp&FF_CMP_CHROMA);
- s->me.mb_flags = get_flags(s, 0, s->avctx->mb_cmp &FF_CMP_CHROMA);
+ c->flags = get_flags(c, 0, c->avctx->me_cmp &FF_CMP_CHROMA);
+ c->sub_flags= get_flags(c, 0, c->avctx->me_sub_cmp&FF_CMP_CHROMA);
+ c->mb_flags = get_flags(c, 0, c->avctx->mb_cmp &FF_CMP_CHROMA);
/*FIXME s->no_rounding b_type*/
if(s->flags&CODEC_FLAG_QPEL){
- s->me.sub_motion_search= qpel_motion_search;
+ c->sub_motion_search= qpel_motion_search;
c->qpel_avg= s->dsp.avg_qpel_pixels_tab;
if(s->no_rounding) c->qpel_put= s->dsp.put_no_rnd_qpel_pixels_tab;
else c->qpel_put= s->dsp.put_qpel_pixels_tab;
}else{
- if(s->avctx->me_sub_cmp&FF_CMP_CHROMA)
- s->me.sub_motion_search= hpel_motion_search;
- else if( s->avctx->me_sub_cmp == FF_CMP_SAD
- && s->avctx-> me_cmp == FF_CMP_SAD
- && s->avctx-> mb_cmp == FF_CMP_SAD)
- s->me.sub_motion_search= sad_hpel_motion_search; // 2050 vs. 2450 cycles
+ if(c->avctx->me_sub_cmp&FF_CMP_CHROMA)
+ c->sub_motion_search= hpel_motion_search;
+ else if( c->avctx->me_sub_cmp == FF_CMP_SAD
+ && c->avctx-> me_cmp == FF_CMP_SAD
+ && c->avctx-> mb_cmp == FF_CMP_SAD)
+ c->sub_motion_search= sad_hpel_motion_search; // 2050 vs. 2450 cycles
else
- s->me.sub_motion_search= hpel_motion_search;
+ c->sub_motion_search= hpel_motion_search;
c->hpel_avg= s->dsp.avg_pixels_tab;
if(s->no_rounding) c->hpel_put= s->dsp.put_no_rnd_pixels_tab;
else c->hpel_put= s->dsp.put_pixels_tab;
}
if(s->linesize){
- s->me.stride = s->linesize;
- s->me.uvstride= s->uvlinesize;
+ c->stride = s->linesize;
+ c->uvstride= s->uvlinesize;
}else{
- s->me.stride = 16*s->mb_width + 32;
- s->me.uvstride= 8*s->mb_width + 16;
+ c->stride = 16*s->mb_width + 32;
+ c->uvstride= 8*s->mb_width + 16;
}
c->temp= c->scratchpad;
@@ -548,16 +551,17 @@ static inline int sad_hpel_motion_search(MpegEncContext * s,
int src_index, int ref_index,
int size, int h)
{
- const int penalty_factor= s->me.sub_penalty_factor;
+ MotionEstContext * const c= &s->me;
+ const int penalty_factor= c->sub_penalty_factor;
int mx, my, dminh;
uint8_t *pix, *ptr;
- int stride= s->me.stride;
- const int flags= s->me.sub_flags;
+ int stride= c->stride;
+ const int flags= c->sub_flags;
LOAD_COMMON
assert(flags == 0);
- if(s->me.skip){
+ if(c->skip){
// printf("S");
*mx_ptr = 0;
*my_ptr = 0;
@@ -565,11 +569,11 @@ static inline int sad_hpel_motion_search(MpegEncContext * s,
}
// printf("N");
- pix = s->me.src[src_index][0];
+ pix = c->src[src_index][0];
mx = *mx_ptr;
my = *my_ptr;
- ptr = s->me.ref[ref_index][0] + (my * stride) + mx;
+ ptr = c->ref[ref_index][0] + (my * stride) + mx;
dminh = dmin;
@@ -679,26 +683,26 @@ static inline void set_p_mv_tables(MpegEncContext * s, int mx, int my, int mv4)
*/
static inline void get_limits(MpegEncContext *s, int x, int y)
{
+ MotionEstContext * const c= &s->me;
/*
- if(s->avctx->me_range) s->me.range= s->avctx->me_range >> 1;
- else s->me.range= 16;
+ if(c->avctx->me_range) c->range= c->avctx->me_range >> 1;
+ else c->range= 16;
*/
if (s->unrestricted_mv) {
- s->me.xmin = - x - 16;
- s->me.ymin = - y - 16;
- s->me.xmax = - x + s->mb_width *16;
- s->me.ymax = - y + s->mb_height*16;
+ c->xmin = - x - 16;
+ c->ymin = - y - 16;
+ c->xmax = - x + s->mb_width *16;
+ c->ymax = - y + s->mb_height*16;
} else {
- s->me.xmin = - x;
- s->me.ymin = - y;
- s->me.xmax = - x + s->mb_width *16 - 16;
- s->me.ymax = - y + s->mb_height*16 - 16;
+ c->xmin = - x;
+ c->ymin = - y;
+ c->xmax = - x + s->mb_width *16 - 16;
+ c->ymax = - y + s->mb_height*16 - 16;
}
}
-static inline void init_mv4_ref(MpegEncContext *s){
- MotionEstContext * const c= &s->me;
- const int stride= s->linesize;
+static inline void init_mv4_ref(MotionEstContext *c){
+ const int stride= c->stride;
c->ref[1][0] = c->ref[0][0] + 8;
c->ref[2][0] = c->ref[0][0] + 8*stride;
@@ -717,11 +721,11 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
int P[10][2];
int dmin_sum=0, mx4_sum=0, my4_sum=0;
int same=1;
- const int stride= s->linesize;
- const int uvstride= s->uvlinesize;
- uint8_t *mv_penalty= s->me.current_mv_penalty;
+ const int stride= c->stride;
+ const int uvstride= c->uvstride;
+ uint8_t *mv_penalty= c->current_mv_penalty;
- init_mv4_ref(s);
+ init_mv4_ref(c);
for(block=0; block<4; block++){
int mx4, my4;
@@ -734,39 +738,39 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0];
P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1];
- if(P_LEFT[0] > (s->me.xmax<<shift)) P_LEFT[0] = (s->me.xmax<<shift);
+ if(P_LEFT[0] > (c->xmax<<shift)) P_LEFT[0] = (c->xmax<<shift);
/* special case for first line */
if (s->first_slice_line && block<2) {
- s->me.pred_x= pred_x4= P_LEFT[0];
- s->me.pred_y= pred_y4= P_LEFT[1];
+ c->pred_x= pred_x4= P_LEFT[0];
+ c->pred_y= pred_y4= P_LEFT[1];
} else {
P_TOP[0] = s->current_picture.motion_val[0][mot_xy - mot_stride ][0];
P_TOP[1] = s->current_picture.motion_val[0][mot_xy - mot_stride ][1];
P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][0];
P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][1];
- if(P_TOP[1] > (s->me.ymax<<shift)) P_TOP[1] = (s->me.ymax<<shift);
- if(P_TOPRIGHT[0] < (s->me.xmin<<shift)) P_TOPRIGHT[0]= (s->me.xmin<<shift);
- if(P_TOPRIGHT[0] > (s->me.xmax<<shift)) P_TOPRIGHT[0]= (s->me.xmax<<shift);
- if(P_TOPRIGHT[1] > (s->me.ymax<<shift)) P_TOPRIGHT[1]= (s->me.ymax<<shift);
+ if(P_TOP[1] > (c->ymax<<shift)) P_TOP[1] = (c->ymax<<shift);
+ if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift);
+ if(P_TOPRIGHT[0] > (c->xmax<<shift)) P_TOPRIGHT[0]= (c->xmax<<shift);
+ if(P_TOPRIGHT[1] > (c->ymax<<shift)) P_TOPRIGHT[1]= (c->ymax<<shift);
P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
- s->me.pred_x= pred_x4 = P_MEDIAN[0];
- s->me.pred_y= pred_y4 = P_MEDIAN[1];
+ c->pred_x= pred_x4 = P_MEDIAN[0];
+ c->pred_y= pred_y4 = P_MEDIAN[1];
}
P_MV1[0]= mx;
P_MV1[1]= my;
dmin4 = epzs_motion_search4(s, &mx4, &my4, P, block, block, s->p_mv_table, (1<<16)>>shift);
- dmin4= s->me.sub_motion_search(s, &mx4, &my4, dmin4, block, block, size, h);
+ dmin4= c->sub_motion_search(s, &mx4, &my4, dmin4, block, block, size, h);
if(s->dsp.me_sub_cmp[0] != s->dsp.mb_cmp[0]){
int dxy;
const int offset= ((block&1) + (block>>1)*stride)*8;
- uint8_t *dest_y = s->me.scratchpad + offset;
+ uint8_t *dest_y = c->scratchpad + offset;
if(s->quarter_sample){
uint8_t *ref= c->ref[block][0] + (mx4>>2) + (my4>>2)*stride;
dxy = ((my4 & 3) << 2) | (mx4 & 3);
@@ -784,7 +788,7 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
else
s->dsp.put_pixels_tab [1][dxy](dest_y , ref , stride, h);
}
- dmin_sum+= (mv_penalty[mx4-pred_x4] + mv_penalty[my4-pred_y4])*s->me.mb_penalty_factor;
+ dmin_sum+= (mv_penalty[mx4-pred_x4] + mv_penalty[my4-pred_y4])*c->mb_penalty_factor;
}else
dmin_sum+= dmin4;
@@ -806,10 +810,10 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
return INT_MAX;
if(s->dsp.me_sub_cmp[0] != s->dsp.mb_cmp[0]){
- dmin_sum += s->dsp.mb_cmp[0](s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*16*stride, s->me.scratchpad, stride, 16);
+ dmin_sum += s->dsp.mb_cmp[0](s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*16*stride, c->scratchpad, stride, 16);
}
- if(s->avctx->mb_cmp&FF_CMP_CHROMA){
+ if(c->avctx->mb_cmp&FF_CMP_CHROMA){
int dxy;
int mx, my;
int offset;
@@ -821,27 +825,27 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
offset= (s->mb_x*8 + (mx>>1)) + (s->mb_y*8 + (my>>1))*s->uvlinesize;
if(s->no_rounding){
- s->dsp.put_no_rnd_pixels_tab[1][dxy](s->me.scratchpad , s->last_picture.data[1] + offset, s->uvlinesize, 8);
- s->dsp.put_no_rnd_pixels_tab[1][dxy](s->me.scratchpad+8 , s->last_picture.data[2] + offset, s->uvlinesize, 8);
+ s->dsp.put_no_rnd_pixels_tab[1][dxy](c->scratchpad , s->last_picture.data[1] + offset, s->uvlinesize, 8);
+ s->dsp.put_no_rnd_pixels_tab[1][dxy](c->scratchpad+8 , s->last_picture.data[2] + offset, s->uvlinesize, 8);
}else{
- s->dsp.put_pixels_tab [1][dxy](s->me.scratchpad , s->last_picture.data[1] + offset, s->uvlinesize, 8);
- s->dsp.put_pixels_tab [1][dxy](s->me.scratchpad+8 , s->last_picture.data[2] + offset, s->uvlinesize, 8);
+ s->dsp.put_pixels_tab [1][dxy](c->scratchpad , s->last_picture.data[1] + offset, s->uvlinesize, 8);
+ s->dsp.put_pixels_tab [1][dxy](c->scratchpad+8 , s->last_picture.data[2] + offset, s->uvlinesize, 8);
}
- dmin_sum += s->dsp.mb_cmp[1](s, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*8*s->uvlinesize, s->me.scratchpad , s->uvlinesize, 8);
- dmin_sum += s->dsp.mb_cmp[1](s, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*8*s->uvlinesize, s->me.scratchpad+8, s->uvlinesize, 8);
+ dmin_sum += s->dsp.mb_cmp[1](s, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*8*s->uvlinesize, c->scratchpad , s->uvlinesize, 8);
+ dmin_sum += s->dsp.mb_cmp[1](s, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*8*s->uvlinesize, c->scratchpad+8, s->uvlinesize, 8);
}
- s->me.pred_x= mx;
- s->me.pred_y= my;
+ c->pred_x= mx;
+ c->pred_y= my;
- switch(s->avctx->mb_cmp&0xFF){
+ switch(c->avctx->mb_cmp&0xFF){
/*case FF_CMP_SSE:
return dmin_sum+ 32*s->qscale*s->qscale;*/
case FF_CMP_RD:
return dmin_sum;
default:
- return dmin_sum+ 11*s->me.mb_penalty_factor;
+ return dmin_sum+ 11*c->mb_penalty_factor;
}
}
@@ -898,8 +902,8 @@ static int interlaced_search(MpegEncContext *s, int ref_index,
P_LEFT[1] = mv_table[xy - 1][1];
if(P_LEFT[0] > (c->xmax<<1)) P_LEFT[0] = (c->xmax<<1);
- s->me.pred_x= P_LEFT[0];
- s->me.pred_y= P_LEFT[1];
+ c->pred_x= P_LEFT[0];
+ c->pred_y= P_LEFT[1];
if(!s->first_slice_line){
P_TOP[0] = mv_table[xy - mot_stride][0];
@@ -937,7 +941,7 @@ static int interlaced_search(MpegEncContext *s, int ref_index,
s->dsp.put_pixels_tab [size][dxy](c->scratchpad, ref , stride, h);
}
dmin= s->dsp.mb_cmp[size](s, c->src[block][0], c->scratchpad, stride, h);
- dmin+= (mv_penalty[mx_i-s->me.pred_x] + mv_penalty[my_i-s->me.pred_y] + 1)*c->mb_penalty_factor;
+ dmin+= (mv_penalty[mx_i-c->pred_x] + mv_penalty[my_i-c->pred_y] + 1)*c->mb_penalty_factor;
}else
dmin+= c->mb_penalty_factor; //field_select bits
@@ -969,7 +973,7 @@ static int interlaced_search(MpegEncContext *s, int ref_index,
if(same)
return INT_MAX;
- switch(s->avctx->mb_cmp&0xFF){
+ switch(c->avctx->mb_cmp&0xFF){
/*case FF_CMP_SSE:
return dmin_sum+ 32*s->qscale*s->qscale;*/
case FF_CMP_RD:
@@ -1003,7 +1007,7 @@ static inline int check_input_motion(MpegEncContext * s, int mb_x, int mb_y, int
c->uvstride<<=1;
if(!(s->flags & CODEC_FLAG_INTERLACED_ME)){
- av_log(s->avctx, AV_LOG_ERROR, "Interlaced macroblock selected but interlaced motion estimation disabled\n");
+ av_log(c->avctx, AV_LOG_ERROR, "Interlaced macroblock selected but interlaced motion estimation disabled\n");
return -1;
}
@@ -1064,12 +1068,12 @@ static inline int check_input_motion(MpegEncContext * s, int mb_x, int mb_y, int
c->uvstride>>=1;
}else if(IS_8X8(mb_type)){
if(!(s->flags & CODEC_FLAG_4MV)){
- av_log(s->avctx, AV_LOG_ERROR, "4MV macroblock selected but 4MV encoding disabled\n");
+ av_log(c->avctx, AV_LOG_ERROR, "4MV macroblock selected but 4MV encoding disabled\n");
return -1;
}
cmpf= s->dsp.sse[1];
chroma_cmpf= s->dsp.sse[1];
- init_mv4_ref(s);
+ init_mv4_ref(c);
for(i=0; i<4; i++){
xy= s->block_index[i];
x= p->motion_val[0][xy][0];
@@ -1117,19 +1121,19 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
int mb_type=0;
Picture * const pic= &s->current_picture;
- init_ref(s, s->new_picture.data, s->last_picture.data, NULL, 16*mb_x, 16*mb_y, 0);
+ init_ref(c, s->new_picture.data, s->last_picture.data, NULL, 16*mb_x, 16*mb_y, 0);
assert(s->quarter_sample==0 || s->quarter_sample==1);
- assert(s->linesize == s->me.stride);
- assert(s->uvlinesize == s->me.uvstride);
+ assert(s->linesize == c->stride);
+ assert(s->uvlinesize == c->uvstride);
- s->me.penalty_factor = get_penalty_factor(s, s->avctx->me_cmp);
- s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp);
- s->me.mb_penalty_factor = get_penalty_factor(s, s->avctx->mb_cmp);
- s->me.current_mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV;
+ c->penalty_factor = get_penalty_factor(s, c->avctx->me_cmp);
+ c->sub_penalty_factor= get_penalty_factor(s, c->avctx->me_sub_cmp);
+ c->mb_penalty_factor = get_penalty_factor(s, c->avctx->mb_cmp);
+ c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_MV;
get_limits(s, 16*mb_x, 16*mb_y);
- s->me.skip=0;
+ c->skip=0;
/* intra / predictive decision */
pix = c->src[0][0];
@@ -1138,22 +1142,22 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
pic->mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8;
pic->mb_var [s->mb_stride * mb_y + mb_x] = varc;
- s->mb_var_sum_temp += varc;
+ c->mb_var_sum_temp += varc;
- if(s->avctx->me_threshold){
+ if(c->avctx->me_threshold){
vard= (check_input_motion(s, mb_x, mb_y, 1)+128)>>8;
- if(vard<s->avctx->me_threshold){
+ if(vard<c->avctx->me_threshold){
pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = vard;
- s->mc_mb_var_sum_temp += vard;
+ c->mc_mb_var_sum_temp += vard;
if (vard <= 64 || vard < varc) { //FIXME
- s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
+ c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
}else{
- s->scene_change_score+= s->qscale;
+ c->scene_change_score+= s->qscale;
}
return;
}
- if(vard<s->avctx->mb_threshold)
+ if(vard<c->avctx->mb_threshold)
mb_type= s->mb_type[mb_x + mb_y*s->mb_stride];
}
@@ -1191,16 +1195,16 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0];
P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1];
- if(P_LEFT[0] > (s->me.xmax<<shift)) P_LEFT[0] = (s->me.xmax<<shift);
+ if(P_LEFT[0] > (c->xmax<<shift)) P_LEFT[0] = (c->xmax<<shift);
if(!s->first_slice_line) {
P_TOP[0] = s->current_picture.motion_val[0][mot_xy - mot_stride ][0];
P_TOP[1] = s->current_picture.motion_val[0][mot_xy - mot_stride ][1];
P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + 2][0];
P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + 2][1];
- if(P_TOP[1] > (s->me.ymax<<shift)) P_TOP[1] = (s->me.ymax<<shift);
- if(P_TOPRIGHT[0] < (s->me.xmin<<shift)) P_TOPRIGHT[0]= (s->me.xmin<<shift);
- if(P_TOPRIGHT[1] > (s->me.ymax<<shift)) P_TOPRIGHT[1]= (s->me.ymax<<shift);
+ if(P_TOP[1] > (c->ymax<<shift)) P_TOP[1] = (c->ymax<<shift);
+ if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift);
+ if(P_TOPRIGHT[1] > (c->ymax<<shift)) P_TOPRIGHT[1]= (c->ymax<<shift);
P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
@@ -1230,7 +1234,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = vard;
// pic->mb_cmp_score[s->mb_stride * mb_y + mb_x] = dmin;
- s->mc_mb_var_sum_temp += vard;
+ c->mc_mb_var_sum_temp += vard;
#if 0
printf("varc=%4d avg_var=%4d (sum=%4d) vard=%4d mx=%2d my=%2d\n",
@@ -1238,12 +1242,12 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
#endif
if(mb_type){
if (vard <= 64 || vard < varc)
- s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
+ c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
else
- s->scene_change_score+= s->qscale;
+ c->scene_change_score+= s->qscale;
if(mb_type == CANDIDATE_MB_TYPE_INTER){
- s->me.sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
+ c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
set_p_mv_tables(s, mx, my, 1);
}else{
mx <<=shift;
@@ -1257,17 +1261,17 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
if(mb_type == CANDIDATE_MB_TYPE_INTER_I){
interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 1);
}
- }else if(s->avctx->mb_decision > FF_MB_DECISION_SIMPLE){
+ }else if(c->avctx->mb_decision > FF_MB_DECISION_SIMPLE){
if (vard <= 64 || vard < varc)
- s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
+ c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
else
- s->scene_change_score+= s->qscale;
+ c->scene_change_score+= s->qscale;
if (vard*2 + 200 > varc)
mb_type|= CANDIDATE_MB_TYPE_INTRA;
if (varc*2 + 200 > vard){
mb_type|= CANDIDATE_MB_TYPE_INTER;
- s->me.sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
+ c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
if(s->flags&CODEC_FLAG_MV0)
if(mx || my)
mb_type |= CANDIDATE_MB_TYPE_SKIPED; //FIXME check difference
@@ -1276,7 +1280,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
my <<=shift;
}
if((s->flags&CODEC_FLAG_4MV)
- && !s->me.skip && varc>50 && vard>10){
+ && !c->skip && varc>50 && vard>10){
if(h263_mv4_search(s, mx, my, shift) < INT_MAX)
mb_type|=CANDIDATE_MB_TYPE_INTER4V;
@@ -1284,7 +1288,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
}else
set_p_mv_tables(s, mx, my, 1);
if((s->flags&CODEC_FLAG_INTERLACED_ME)
- && !s->me.skip){ //FIXME varc/d checks
+ && !c->skip){ //FIXME varc/d checks
if(interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 0) < INT_MAX)
mb_type |= CANDIDATE_MB_TYPE_INTER_I;
}
@@ -1292,12 +1296,12 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
int intra_score, i;
mb_type= CANDIDATE_MB_TYPE_INTER;
- dmin= s->me.sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
- if(s->avctx->me_sub_cmp != s->avctx->mb_cmp && !s->me.skip)
+ dmin= c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
+ if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip)
dmin= get_mb_score(s, mx, my, 0, 0);
if((s->flags&CODEC_FLAG_4MV)
- && !s->me.skip && varc>50 && vard>10){
+ && !c->skip && varc>50 && vard>10){
int dmin4= h263_mv4_search(s, mx, my, shift);
if(dmin4 < dmin){
mb_type= CANDIDATE_MB_TYPE_INTER4V;
@@ -1305,7 +1309,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
}
}
if((s->flags&CODEC_FLAG_INTERLACED_ME)
- && !s->me.skip){ //FIXME varc/d checks
+ && !c->skip){ //FIXME varc/d checks
int dmin_i= interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 0);
if(dmin_i < dmin){
mb_type = CANDIDATE_MB_TYPE_INTER_I;
@@ -1317,24 +1321,24 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
set_p_mv_tables(s, mx, my, mb_type!=CANDIDATE_MB_TYPE_INTER4V);
/* get intra luma score */
- if((s->avctx->mb_cmp&0xFF)==FF_CMP_SSE){
+ if((c->avctx->mb_cmp&0xFF)==FF_CMP_SSE){
intra_score= (varc<<8) - 500; //FIXME dont scale it down so we dont have to fix it
}else{
int mean= (sum+128)>>8;
mean*= 0x01010101;
for(i=0; i<16; i++){
- *(uint32_t*)(&s->me.scratchpad[i*s->linesize+ 0]) = mean;
- *(uint32_t*)(&s->me.scratchpad[i*s->linesize+ 4]) = mean;
- *(uint32_t*)(&s->me.scratchpad[i*s->linesize+ 8]) = mean;
- *(uint32_t*)(&s->me.scratchpad[i*s->linesize+12]) = mean;
+ *(uint32_t*)(&c->scratchpad[i*s->linesize+ 0]) = mean;
+ *(uint32_t*)(&c->scratchpad[i*s->linesize+ 4]) = mean;
+ *(uint32_t*)(&c->scratchpad[i*s->linesize+ 8]) = mean;
+ *(uint32_t*)(&c->scratchpad[i*s->linesize+12]) = mean;
}
- intra_score= s->dsp.mb_cmp[0](s, s->me.scratchpad, pix, s->linesize, 16);
+ intra_score= s->dsp.mb_cmp[0](s, c->scratchpad, pix, s->linesize, 16);
}
#if 0 //FIXME
/* get chroma score */
- if(s->avctx->mb_cmp&FF_CMP_CHROMA){
+ if(c->avctx->mb_cmp&FF_CMP_CHROMA){
for(i=1; i<3; i++){
uint8_t *dest_c;
int mean;
@@ -1348,15 +1352,15 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
mean*= 0x01010101;
for(i=0; i<8; i++){
- *(uint32_t*)(&s->me.scratchpad[i*s->uvlinesize+ 0]) = mean;
- *(uint32_t*)(&s->me.scratchpad[i*s->uvlinesize+ 4]) = mean;
+ *(uint32_t*)(&c->scratchpad[i*s->uvlinesize+ 0]) = mean;
+ *(uint32_t*)(&c->scratchpad[i*s->uvlinesize+ 4]) = mean;
}
- intra_score+= s->dsp.mb_cmp[1](s, s->me.scratchpad, dest_c, s->uvlinesize);
+ intra_score+= s->dsp.mb_cmp[1](s, c->scratchpad, dest_c, s->uvlinesize);
}
}
#endif
- intra_score += s->me.mb_penalty_factor*16;
+ intra_score += c->mb_penalty_factor*16;
if(intra_score < dmin){
mb_type= CANDIDATE_MB_TYPE_INTRA;
@@ -1365,9 +1369,9 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
s->current_picture.mb_type[mb_y*s->mb_stride + mb_x]= 0;
if (vard <= 64 || vard < varc) { //FIXME
- s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
+ c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
}else{
- s->scene_change_score+= s->qscale;
+ c->scene_change_score+= s->qscale;
}
}
@@ -1382,20 +1386,20 @@ int ff_pre_estimate_p_frame_motion(MpegEncContext * s,
int P[10][2];
const int shift= 1+s->quarter_sample;
const int xy= mb_x + mb_y*s->mb_stride;
- init_ref(s, s->new_picture.data, s->last_picture.data, NULL, 16*mb_x, 16*mb_y, 0);
+ init_ref(c, s->new_picture.data, s->last_picture.data, NULL, 16*mb_x, 16*mb_y, 0);
assert(s->quarter_sample==0 || s->quarter_sample==1);
- s->me.pre_penalty_factor = get_penalty_factor(s, s->avctx->me_pre_cmp);
- s->me.current_mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV;
+ c->pre_penalty_factor = get_penalty_factor(s, c->avctx->me_pre_cmp);
+ c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_MV;
get_limits(s, 16*mb_x, 16*mb_y);
- s->me.skip=0;
+ c->skip=0;
P_LEFT[0] = s->p_mv_table[xy + 1][0];
P_LEFT[1] = s->p_mv_table[xy + 1][1];
- if(P_LEFT[0] < (s->me.xmin<<shift)) P_LEFT[0] = (s->me.xmin<<shift);
+ if(P_LEFT[0] < (c->xmin<<shift)) P_LEFT[0] = (c->xmin<<shift);
/* special case for first line */
if (s->first_slice_line) {
@@ -1408,9 +1412,9 @@ int ff_pre_estimate_p_frame_motion(MpegEncContext * s,
P_TOP[1] = s->p_mv_table[xy + s->mb_stride ][1];
P_TOPRIGHT[0] = s->p_mv_table[xy + s->mb_stride - 1][0];
P_TOPRIGHT[1] = s->p_mv_table[xy + s->mb_stride - 1][1];
- if(P_TOP[1] < (s->me.ymin<<shift)) P_TOP[1] = (s->me.ymin<<shift);
- if(P_TOPRIGHT[0] > (s->me.xmax<<shift)) P_TOPRIGHT[0]= (s->me.xmax<<shift);
- if(P_TOPRIGHT[1] < (s->me.ymin<<shift)) P_TOPRIGHT[1]= (s->me.ymin<<shift);
+ if(P_TOP[1] < (c->ymin<<shift)) P_TOP[1] = (c->ymin<<shift);
+ if(P_TOPRIGHT[0] > (c->xmax<<shift)) P_TOPRIGHT[0]= (c->xmax<<shift);
+ if(P_TOPRIGHT[1] < (c->ymin<<shift)) P_TOPRIGHT[1]= (c->ymin<<shift);
P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
@@ -1430,18 +1434,19 @@ int ff_pre_estimate_p_frame_motion(MpegEncContext * s,
static int ff_estimate_motion_b(MpegEncContext * s,
int mb_x, int mb_y, int16_t (*mv_table)[2], int ref_index, int f_code)
{
+ MotionEstContext * const c= &s->me;
int mx, my, dmin;
int P[10][2];
const int shift= 1+s->quarter_sample;
const int mot_stride = s->mb_stride;
const int mot_xy = mb_y*mot_stride + mb_x;
- uint8_t * const mv_penalty= s->me.mv_penalty[f_code] + MAX_MV;
+ uint8_t * const mv_penalty= c->mv_penalty[f_code] + MAX_MV;
int mv_scale;
- s->me.penalty_factor = get_penalty_factor(s, s->avctx->me_cmp);
- s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp);
- s->me.mb_penalty_factor = get_penalty_factor(s, s->avctx->mb_cmp);
- s->me.current_mv_penalty= mv_penalty;
+ c->penalty_factor = get_penalty_factor(s, c->avctx->me_cmp);
+ c->sub_penalty_factor= get_penalty_factor(s, c->avctx->me_sub_cmp);
+ c->mb_penalty_factor = get_penalty_factor(s, c->avctx->mb_cmp);
+ c->current_mv_penalty= mv_penalty;
get_limits(s, 16*mb_x, 16*mb_y);
@@ -1476,7 +1481,7 @@ static int ff_estimate_motion_b(MpegEncContext * s,
P_LEFT[0] = mv_table[mot_xy - 1][0];
P_LEFT[1] = mv_table[mot_xy - 1][1];
- if(P_LEFT[0] > (s->me.xmax<<shift)) P_LEFT[0] = (s->me.xmax<<shift);
+ if(P_LEFT[0] > (c->xmax<<shift)) P_LEFT[0] = (c->xmax<<shift);
/* special case for first line */
if (!s->first_slice_line) {
@@ -1484,15 +1489,15 @@ static int ff_estimate_motion_b(MpegEncContext * s,
P_TOP[1] = mv_table[mot_xy - mot_stride ][1];
P_TOPRIGHT[0] = mv_table[mot_xy - mot_stride + 1 ][0];
P_TOPRIGHT[1] = mv_table[mot_xy - mot_stride + 1 ][1];
- if(P_TOP[1] > (s->me.ymax<<shift)) P_TOP[1]= (s->me.ymax<<shift);
- if(P_TOPRIGHT[0] < (s->me.xmin<<shift)) P_TOPRIGHT[0]= (s->me.xmin<<shift);
- if(P_TOPRIGHT[1] > (s->me.ymax<<shift)) P_TOPRIGHT[1]= (s->me.ymax<<shift);
+ if(P_TOP[1] > (c->ymax<<shift)) P_TOP[1]= (c->ymax<<shift);
+ if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift);
+ if(P_TOPRIGHT[1] > (c->ymax<<shift)) P_TOPRIGHT[1]= (c->ymax<<shift);
P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
}
- s->me.pred_x= P_LEFT[0];
- s->me.pred_y= P_LEFT[1];
+ c->pred_x= P_LEFT[0];
+ c->pred_y= P_LEFT[1];
}
if(mv_table == s->b_forw_mv_table){
@@ -1506,9 +1511,9 @@ static int ff_estimate_motion_b(MpegEncContext * s,
break;
}
- dmin= s->me.sub_motion_search(s, &mx, &my, dmin, 0, ref_index, 0, 16);
+ dmin= c->sub_motion_search(s, &mx, &my, dmin, 0, ref_index, 0, 16);
- if(s->avctx->me_sub_cmp != s->avctx->mb_cmp && !s->me.skip)
+ if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip)
dmin= get_mb_score(s, mx, my, 0, ref_index);
//printf("%d %d %d %d//", s->mb_x, s->mb_y, mx, my);
@@ -1530,10 +1535,10 @@ static inline int check_bidir_mv(MpegEncContext * s,
//FIXME better f_code prediction (max mv & distance)
//FIXME pointers
MotionEstContext * const c= &s->me;
- uint8_t * const mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame
- int stride= s->me.stride;
- int uvstride= s->me.uvstride;
- uint8_t *dest_y = s->me.scratchpad;
+ uint8_t * const mv_penalty= c->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame
+ int stride= c->stride;
+ int uvstride= c->uvstride;
+ uint8_t *dest_y = c->scratchpad;
uint8_t *ptr;
int dxy;
int src_x, src_y;
@@ -1572,11 +1577,11 @@ static inline int check_bidir_mv(MpegEncContext * s,
s->dsp.avg_pixels_tab[size][dxy](dest_y , ptr , stride, h);
}
- fbmin = (mv_penalty[motion_fx-pred_fx] + mv_penalty[motion_fy-pred_fy])*s->me.mb_penalty_factor
- +(mv_penalty[motion_bx-pred_bx] + mv_penalty[motion_by-pred_by])*s->me.mb_penalty_factor
+ fbmin = (mv_penalty[motion_fx-pred_fx] + mv_penalty[motion_fy-pred_fy])*c->mb_penalty_factor
+ +(mv_penalty[motion_bx-pred_bx] + mv_penalty[motion_by-pred_by])*c->mb_penalty_factor
+ s->dsp.mb_cmp[size](s, src_data[0], dest_y, stride, h); //FIXME new_pic
- if(s->avctx->mb_cmp&FF_CMP_CHROMA){
+ if(c->avctx->mb_cmp&FF_CMP_CHROMA){
}
//FIXME CHROMA !!!
@@ -1611,6 +1616,7 @@ static inline int bidir_refine(MpegEncContext * s, int mb_x, int mb_y)
static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
{
+ MotionEstContext * const c= &s->me;
int P[10][2];
const int mot_stride = s->mb_stride;
const int mot_xy = mb_y*mot_stride + mb_x;
@@ -1621,7 +1627,7 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
int mx, my, xmin, xmax, ymin, ymax;
int16_t (*mv_table)[2]= s->b_direct_mv_table;
- s->me.current_mv_penalty= s->me.mv_penalty[1] + MAX_MV;
+ c->current_mv_penalty= c->mv_penalty[1] + MAX_MV;
ymin= xmin=(-32)>>shift;
ymax= xmax= 31>>shift;
@@ -1635,22 +1641,22 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
int index= s->block_index[i];
int min, max;
- s->me.co_located_mv[i][0]= s->next_picture.motion_val[0][index][0];
- s->me.co_located_mv[i][1]= s->next_picture.motion_val[0][index][1];
- s->me.direct_basis_mv[i][0]= s->me.co_located_mv[i][0]*time_pb/time_pp + ((i& 1)<<(shift+3));
- s->me.direct_basis_mv[i][1]= s->me.co_located_mv[i][1]*time_pb/time_pp + ((i>>1)<<(shift+3));
-// s->me.direct_basis_mv[1][i][0]= s->me.co_located_mv[i][0]*(time_pb - time_pp)/time_pp + ((i &1)<<(shift+3);
-// s->me.direct_basis_mv[1][i][1]= s->me.co_located_mv[i][1]*(time_pb - time_pp)/time_pp + ((i>>1)<<(shift+3);
-
- max= FFMAX(s->me.direct_basis_mv[i][0], s->me.direct_basis_mv[i][0] - s->me.co_located_mv[i][0])>>shift;
- min= FFMIN(s->me.direct_basis_mv[i][0], s->me.direct_basis_mv[i][0] - s->me.co_located_mv[i][0])>>shift;
+ c->co_located_mv[i][0]= s->next_picture.motion_val[0][index][0];
+ c->co_located_mv[i][1]= s->next_picture.motion_val[0][index][1];
+ c->direct_basis_mv[i][0]= c->co_located_mv[i][0]*time_pb/time_pp + ((i& 1)<<(shift+3));
+ c->direct_basis_mv[i][1]= c->co_located_mv[i][1]*time_pb/time_pp + ((i>>1)<<(shift+3));
+// c->direct_basis_mv[1][i][0]= c->co_located_mv[i][0]*(time_pb - time_pp)/time_pp + ((i &1)<<(shift+3);
+// c->direct_basis_mv[1][i][1]= c->co_located_mv[i][1]*(time_pb - time_pp)/time_pp + ((i>>1)<<(shift+3);
+
+ max= FFMAX(c->direct_basis_mv[i][0], c->direct_basis_mv[i][0] - c->co_located_mv[i][0])>>shift;
+ min= FFMIN(c->direct_basis_mv[i][0], c->direct_basis_mv[i][0] - c->co_located_mv[i][0])>>shift;
max+= 16*mb_x + 1; // +-1 is for the simpler rounding
min+= 16*mb_x - 1;
xmax= FFMIN(xmax, s->width - max);
xmin= FFMAX(xmin, - 16 - min);
- max= FFMAX(s->me.direct_basis_mv[i][1], s->me.direct_basis_mv[i][1] - s->me.co_located_mv[i][1])>>shift;
- min= FFMIN(s->me.direct_basis_mv[i][1], s->me.direct_basis_mv[i][1] - s->me.co_located_mv[i][1])>>shift;
+ max= FFMAX(c->direct_basis_mv[i][1], c->direct_basis_mv[i][1] - c->co_located_mv[i][1])>>shift;
+ min= FFMIN(c->direct_basis_mv[i][1], c->direct_basis_mv[i][1] - c->co_located_mv[i][1])>>shift;
max+= 16*mb_y + 1; // +-1 is for the simpler rounding
min+= 16*mb_y - 1;
ymax= FFMIN(ymax, s->height - max);
@@ -1668,14 +1674,14 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
return 256*256*256*64;
}
- s->me.xmin= xmin;
- s->me.ymin= ymin;
- s->me.xmax= xmax;
- s->me.ymax= ymax;
- s->me.flags |= FLAG_DIRECT;
- s->me.sub_flags |= FLAG_DIRECT;
- s->me.pred_x=0;
- s->me.pred_y=0;
+ c->xmin= xmin;
+ c->ymin= ymin;
+ c->xmax= xmax;
+ c->ymax= ymax;
+ c->flags |= FLAG_DIRECT;
+ c->sub_flags |= FLAG_DIRECT;
+ c->pred_x=0;
+ c->pred_y=0;
P_LEFT[0] = clip(mv_table[mot_xy - 1][0], xmin<<shift, xmax<<shift);
P_LEFT[1] = clip(mv_table[mot_xy - 1][1], ymin<<shift, ymax<<shift);
@@ -1692,20 +1698,20 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
}
dmin = epzs_motion_search(s, &mx, &my, P, 0, 0, mv_table, 1<<(16-shift));
- if(s->me.sub_flags&FLAG_QPEL)
+ if(c->sub_flags&FLAG_QPEL)
dmin = qpel_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
else
dmin = hpel_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
- if(s->avctx->me_sub_cmp != s->avctx->mb_cmp && !s->me.skip)
+ if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip)
dmin= get_mb_score(s, mx, my, 0, 0);
- get_limits(s, 16*mb_x, 16*mb_y); //restore s->me.?min/max, maybe not needed
+ get_limits(s, 16*mb_x, 16*mb_y); //restore c->?min/max, maybe not needed
s->b_direct_mv_table[mot_xy][0]= mx;
s->b_direct_mv_table[mot_xy][1]= my;
- s->me.flags &= ~FLAG_DIRECT;
- s->me.sub_flags &= ~FLAG_DIRECT;
+ c->flags &= ~FLAG_DIRECT;
+ c->sub_flags &= ~FLAG_DIRECT;
return dmin;
}
@@ -1713,18 +1719,19 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
void ff_estimate_b_frame_motion(MpegEncContext * s,
int mb_x, int mb_y)
{
- const int penalty_factor= s->me.mb_penalty_factor;
+ MotionEstContext * const c= &s->me;
+ const int penalty_factor= c->mb_penalty_factor;
int fmin, bmin, dmin, fbmin, bimin, fimin;
int type=0;
const int xy = mb_y*s->mb_stride + mb_x;
- init_ref(s, s->new_picture.data, s->last_picture.data, s->next_picture.data, 16*mb_x, 16*mb_y, 2);
+ init_ref(c, s->new_picture.data, s->last_picture.data, s->next_picture.data, 16*mb_x, 16*mb_y, 2);
- s->me.skip=0;
- if(s->avctx->me_threshold){
+ c->skip=0;
+ if(c->avctx->me_threshold){
int vard= (check_input_motion(s, mb_x, mb_y, 0)+128)>>8;
- if(vard<s->avctx->me_threshold){
+ if(vard<c->avctx->me_threshold){
// pix = c->src[0][0];
// sum = s->dsp.pix_sum(pix, s->linesize);
// varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8;
@@ -1732,38 +1739,38 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
// pic->mb_var [s->mb_stride * mb_y + mb_x] = varc;
s->current_picture.mc_mb_var[s->mb_stride * mb_y + mb_x] = vard;
/* pic->mb_mean [s->mb_stride * mb_y + mb_x] = (sum+128)>>8;
- s->mb_var_sum_temp += varc;*/
- s->mc_mb_var_sum_temp += vard;
+ c->mb_var_sum_temp += varc;*/
+ c->mc_mb_var_sum_temp += vard;
/* if (vard <= 64 || vard < varc) {
- s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
+ c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
}else{
- s->scene_change_score+= s->qscale;
+ c->scene_change_score+= s->qscale;
}*/
return;
}
- if(vard<s->avctx->mb_threshold){
+ if(vard<c->avctx->mb_threshold){
type= s->mb_type[mb_y*s->mb_stride + mb_x];
if(type == CANDIDATE_MB_TYPE_DIRECT){
direct_search(s, mb_x, mb_y);
}
if(type == CANDIDATE_MB_TYPE_FORWARD || type == CANDIDATE_MB_TYPE_BIDIR){
- s->me.skip=0;
+ c->skip=0;
ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, 0, s->f_code);
}
if(type == CANDIDATE_MB_TYPE_BACKWARD || type == CANDIDATE_MB_TYPE_BIDIR){
- s->me.skip=0;
+ c->skip=0;
ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code);
}
if(type == CANDIDATE_MB_TYPE_FORWARD_I || type == CANDIDATE_MB_TYPE_BIDIR_I){
- s->me.skip=0;
- s->me.current_mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV;
+ c->skip=0;
+ c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_MV;
interlaced_search(s, 0,
s->b_field_mv_table[0], s->b_field_select_table[0],
s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1], 1);
}
if(type == CANDIDATE_MB_TYPE_BACKWARD_I || type == CANDIDATE_MB_TYPE_BIDIR_I){
- s->me.skip=0;
- s->me.current_mv_penalty= s->me.mv_penalty[s->b_code] + MAX_MV;
+ c->skip=0;
+ c->current_mv_penalty= c->mv_penalty[s->b_code] + MAX_MV;
interlaced_search(s, 2,
s->b_field_mv_table[1], s->b_field_select_table[1],
s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1], 1);
@@ -1777,25 +1784,25 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
else
dmin= INT_MAX;
//FIXME penalty stuff for non mpeg4
- s->me.skip=0;
+ c->skip=0;
fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, 0, s->f_code) + 3*penalty_factor;
- s->me.skip=0;
+ c->skip=0;
bmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code) + 2*penalty_factor;
//printf(" %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]);
- s->me.skip=0;
+ c->skip=0;
fbmin= bidir_refine(s, mb_x, mb_y) + penalty_factor;
//printf("%d %d %d %d\n", dmin, fmin, bmin, fbmin);
if(s->flags & CODEC_FLAG_INTERLACED_ME){
//FIXME mb type penalty
- s->me.skip=0;
- s->me.current_mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV;
+ c->skip=0;
+ c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_MV;
fimin= interlaced_search(s, 0,
s->b_field_mv_table[0], s->b_field_select_table[0],
s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1], 0);
- s->me.current_mv_penalty= s->me.mv_penalty[s->b_code] + MAX_MV;
+ c->current_mv_penalty= c->mv_penalty[s->b_code] + MAX_MV;
bimin= interlaced_search(s, 2,
s->b_field_mv_table[1], s->b_field_select_table[1],
s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1], 0);
@@ -1828,11 +1835,11 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
}
score= ((unsigned)(score*score + 128*256))>>16;
- s->mc_mb_var_sum_temp += score;
+ c->mc_mb_var_sum_temp += score;
s->current_picture.mc_mb_var[mb_y*s->mb_stride + mb_x] = score; //FIXME use SSE
}
- if(s->avctx->mb_decision > FF_MB_DECISION_SIMPLE){
+ if(c->avctx->mb_decision > FF_MB_DECISION_SIMPLE){
type= CANDIDATE_MB_TYPE_FORWARD | CANDIDATE_MB_TYPE_BACKWARD | CANDIDATE_MB_TYPE_BIDIR | CANDIDATE_MB_TYPE_DIRECT;
if(fimin < INT_MAX)
type |= CANDIDATE_MB_TYPE_FORWARD_I;
@@ -1903,6 +1910,7 @@ int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type)
void ff_fix_long_p_mvs(MpegEncContext * s)
{
+ MotionEstContext * const c= &s->me;
const int f_code= s->f_code;
int y, range;
assert(s->pict_type==P_TYPE);
@@ -1911,7 +1919,7 @@ void ff_fix_long_p_mvs(MpegEncContext * s)
if(s->msmpeg4_version) range= 16;
- if(s->avctx->me_range && range > s->avctx->me_range) range= s->avctx->me_range;
+ if(c->avctx->me_range && range > c->avctx->me_range) range= c->avctx->me_range;
//printf("%d no:%d %d//\n", clip, noclip, f_code);
if(s->flags&CODEC_FLAG_4MV){
@@ -1953,13 +1961,14 @@ void ff_fix_long_p_mvs(MpegEncContext * s)
void ff_fix_long_mvs(MpegEncContext * s, uint8_t *field_select_table, int field_select,
int16_t (*mv_table)[2], int f_code, int type, int truncate)
{
+ MotionEstContext * const c= &s->me;
int y, h_range, v_range;
// RAL: 8 in MPEG-1, 16 in MPEG-4
int range = (((s->out_format == FMT_MPEG1) ? 8 : 16) << f_code);
if(s->msmpeg4_version) range= 16;
- if(s->avctx->me_range && range > s->avctx->me_range) range= s->avctx->me_range;
+ if(c->avctx->me_range && range > c->avctx->me_range) range= c->avctx->me_range;
h_range= range;
v_range= field_select_table ? range>>1 : range;
@@ -1992,3 +2001,5 @@ void ff_fix_long_mvs(MpegEncContext * s, uint8_t *field_select_table, int field_
}
}
}
+
+#endif /* CONFIG_ENCODERS */
diff --git a/src/libffmpeg/libavcodec/motion_est_template.c b/src/libffmpeg/libavcodec/motion_est_template.c
index 8ab6c7be4..8cfb24955 100644
--- a/src/libffmpeg/libavcodec/motion_est_template.c
+++ b/src/libffmpeg/libavcodec/motion_est_template.c
@@ -25,14 +25,14 @@
//lets hope gcc will remove the unused vars ...(gcc 3.2.2 seems to do it ...)
#define LOAD_COMMON\
- uint32_t * const score_map= s->me.score_map;\
- const int xmin= s->me.xmin;\
- const int ymin= s->me.ymin;\
- const int xmax= s->me.xmax;\
- const int ymax= s->me.ymax;\
- uint8_t *mv_penalty= s->me.current_mv_penalty;\
- const int pred_x= s->me.pred_x;\
- const int pred_y= s->me.pred_y;\
+ uint32_t * const score_map= c->score_map;\
+ const int xmin= c->xmin;\
+ const int ymin= c->ymin;\
+ const int xmax= c->xmax;\
+ const int ymax= c->ymax;\
+ uint8_t *mv_penalty= c->current_mv_penalty;\
+ const int pred_x= c->pred_x;\
+ const int pred_y= c->pred_y;\
#define CHECK_HALF_MV(dx, dy, x, y)\
{\
@@ -53,7 +53,7 @@ static int hpel_motion_search)(MpegEncContext * s,
const int yy = 16 * s->mb_y + 8*(n>>1);
const int mx = *mx_ptr;
const int my = *my_ptr;
- const int penalty_factor= s->me.sub_penalty_factor;
+ const int penalty_factor= c->sub_penalty_factor;
LOAD_COMMON
@@ -73,13 +73,13 @@ static int hpel_motion_search)(MpegEncContext * s,
cmp_sub= s->dsp.me_sub_cmp[size];
chroma_cmp_sub= s->dsp.me_sub_cmp[size+1];
- if(s->me.skip){ //FIXME somehow move up (benchmark)
+ if(c->skip){ //FIXME somehow move up (benchmark)
*mx_ptr = 0;
*my_ptr = 0;
return dmin;
}
- if(s->avctx->me_cmp != s->avctx->me_sub_cmp){
+ if(c->avctx->me_cmp != c->avctx->me_sub_cmp){
CMP_HPEL(dmin, 0, 0, mx, my, size);
if(mx || my)
dmin += (mv_penalty[2*mx - pred_x] + mv_penalty[2*my - pred_y])*penalty_factor;
@@ -117,27 +117,28 @@ static int hpel_motion_search(MpegEncContext * s,
int src_index, int ref_index,
int size, int h)
{
+ MotionEstContext * const c= &s->me;
const int mx = *mx_ptr;
const int my = *my_ptr;
- const int penalty_factor= s->me.sub_penalty_factor;
+ const int penalty_factor= c->sub_penalty_factor;
me_cmp_func cmp_sub, chroma_cmp_sub;
int bx=2*mx, by=2*my;
LOAD_COMMON
- int flags= s->me.sub_flags;
+ int flags= c->sub_flags;
//FIXME factorize
cmp_sub= s->dsp.me_sub_cmp[size];
chroma_cmp_sub= s->dsp.me_sub_cmp[size+1];
- if(s->me.skip){ //FIXME move out of hpel?
+ if(c->skip){ //FIXME move out of hpel?
*mx_ptr = 0;
*my_ptr = 0;
return dmin;
}
- if(s->avctx->me_cmp != s->avctx->me_sub_cmp){
+ if(c->avctx->me_cmp != c->avctx->me_sub_cmp){
dmin= cmp(s, mx, my, 0, 0, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);
if(mx || my || size>0)
dmin += (mv_penalty[2*mx - pred_x] + mv_penalty[2*my - pred_y])*penalty_factor;
@@ -148,19 +149,19 @@ static int hpel_motion_search(MpegEncContext * s,
int d= dmin;
const int index= (my<<ME_MAP_SHIFT) + mx;
const int t= score_map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)]
- + (mv_penalty[bx - pred_x] + mv_penalty[by-2 - pred_y])*s->me.penalty_factor;
+ + (mv_penalty[bx - pred_x] + mv_penalty[by-2 - pred_y])*c->penalty_factor;
const int l= score_map[(index- 1 )&(ME_MAP_SIZE-1)]
- + (mv_penalty[bx-2 - pred_x] + mv_penalty[by - pred_y])*s->me.penalty_factor;
+ + (mv_penalty[bx-2 - pred_x] + mv_penalty[by - pred_y])*c->penalty_factor;
const int r= score_map[(index+ 1 )&(ME_MAP_SIZE-1)]
- + (mv_penalty[bx+2 - pred_x] + mv_penalty[by - pred_y])*s->me.penalty_factor;
+ + (mv_penalty[bx+2 - pred_x] + mv_penalty[by - pred_y])*c->penalty_factor;
const int b= score_map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)]
- + (mv_penalty[bx - pred_x] + mv_penalty[by+2 - pred_y])*s->me.penalty_factor;
+ + (mv_penalty[bx - pred_x] + mv_penalty[by+2 - pred_y])*c->penalty_factor;
#if 1
int key;
- int map_generation= s->me.map_generation;
+ int map_generation= c->map_generation;
#ifndef NDEBUG
- uint32_t *map= s->me.map;
+ uint32_t *map= c->map;
#endif
key= ((my-1)<<ME_MAP_MV_BITS) + (mx) + map_generation;
assert(map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] == key);
@@ -224,10 +225,11 @@ static int inline get_mb_score(MpegEncContext * s, int mx, int my, int src_index
int ref_index)
{
// const int check_luma= s->dsp.me_sub_cmp != s->dsp.mb_cmp;
+ MotionEstContext * const c= &s->me;
const int size= 0;
const int h= 16;
- const int penalty_factor= s->me.mb_penalty_factor;
- const int flags= s->me.mb_flags;
+ const int penalty_factor= c->mb_penalty_factor;
+ const int flags= c->mb_flags;
const int qpel= flags & FLAG_QPEL;
const int mask= 1+2*qpel;
me_cmp_func cmp_sub, chroma_cmp_sub;
@@ -240,8 +242,8 @@ static int inline get_mb_score(MpegEncContext * s, int mx, int my, int src_index
cmp_sub= s->dsp.mb_cmp[size];
chroma_cmp_sub= s->dsp.mb_cmp[size+1];
- assert(!s->me.skip);
- assert(s->avctx->me_sub_cmp != s->avctx->mb_cmp);
+ assert(!c->skip);
+ assert(c->avctx->me_sub_cmp != c->avctx->mb_cmp);
d= cmp(s, mx>>(qpel+1), my>>(qpel+1), mx&mask, my&mask, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);
//FIXME check cbp before adding penalty for (0,0) vector
@@ -265,17 +267,18 @@ static int qpel_motion_search(MpegEncContext * s,
int src_index, int ref_index,
int size, int h)
{
+ MotionEstContext * const c= &s->me;
const int mx = *mx_ptr;
const int my = *my_ptr;
- const int penalty_factor= s->me.sub_penalty_factor;
- const int map_generation= s->me.map_generation;
- const int subpel_quality= s->avctx->me_subpel_quality;
- uint32_t *map= s->me.map;
+ const int penalty_factor= c->sub_penalty_factor;
+ const int map_generation= c->map_generation;
+ const int subpel_quality= c->avctx->me_subpel_quality;
+ uint32_t *map= c->map;
me_cmp_func cmpf, chroma_cmpf;
me_cmp_func cmp_sub, chroma_cmp_sub;
LOAD_COMMON
- int flags= s->me.sub_flags;
+ int flags= c->sub_flags;
cmpf= s->dsp.me_cmp[size];
chroma_cmpf= s->dsp.me_cmp[size+1]; //factorize FIXME
@@ -284,13 +287,13 @@ static int qpel_motion_search(MpegEncContext * s,
cmp_sub= s->dsp.me_sub_cmp[size];
chroma_cmp_sub= s->dsp.me_sub_cmp[size+1];
- if(s->me.skip){ //FIXME somehow move up (benchmark)
+ if(c->skip){ //FIXME somehow move up (benchmark)
*mx_ptr = 0;
*my_ptr = 0;
return dmin;
}
- if(s->avctx->me_cmp != s->avctx->me_sub_cmp){
+ if(c->avctx->me_cmp != c->avctx->me_sub_cmp){
dmin= cmp(s, mx, my, 0, 0, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);
if(mx || my || size>0)
dmin += (mv_penalty[4*mx - pred_x] + mv_penalty[4*my - pred_y])*penalty_factor;
@@ -330,8 +333,8 @@ static int qpel_motion_search(MpegEncContext * s,
score += 1024*(mv_penalty[4*mx + nx - pred_x] + mv_penalty[4*my + ny - pred_y])*penalty_factor;
-// if(nx&1) score-=1024*s->me.penalty_factor;
-// if(ny&1) score-=1024*s->me.penalty_factor;
+// if(nx&1) score-=1024*c->penalty_factor;
+// if(ny&1) score-=1024*c->penalty_factor;
for(i=0; i<8; i++){
if(score < best[i]){
@@ -375,8 +378,8 @@ static int qpel_motion_search(MpegEncContext * s,
if((nx&3)==0 && (ny&3)==0) continue;
score += 32*(mv_penalty[4*mx + nx - pred_x] + mv_penalty[4*my + ny - pred_y])*penalty_factor;
-// if(nx&1) score-=32*s->me.penalty_factor;
- // if(ny&1) score-=32*s->me.penalty_factor;
+// if(nx&1) score-=32*c->penalty_factor;
+ // if(ny&1) score-=32*c->penalty_factor;
for(i=0; i<8; i++){
if(score < best[i]){
@@ -531,7 +534,7 @@ if( (y)<(ymin<<(S)) ) printf("%d %d %d %d %d ymin" #v, ymin, (x), (y), s->mb_x,
if( (y)>(ymax<<(S)) ) printf("%d %d %d %d %d ymax" #v, ymax, (x), (y), s->mb_x, s->mb_y);\
#define LOAD_COMMON2\
- uint32_t *map= s->me.map;\
+ uint32_t *map= c->map;\
const int qpel= flags&FLAG_QPEL;\
const int shift= 1+qpel;\
@@ -539,11 +542,12 @@ static always_inline int small_diamond_search(MpegEncContext * s, int *best, int
int src_index, int ref_index, int const penalty_factor,
int size, int h, int flags)
{
+ MotionEstContext * const c= &s->me;
me_cmp_func cmpf, chroma_cmpf;
int next_dir=-1;
LOAD_COMMON
LOAD_COMMON2
- int map_generation= s->me.map_generation;
+ int map_generation= c->map_generation;
cmpf= s->dsp.me_cmp[size];
chroma_cmpf= s->dsp.me_cmp[size+1];
@@ -580,11 +584,12 @@ static int funny_diamond_search(MpegEncContext * s, int *best, int dmin,
int src_index, int ref_index, int const penalty_factor,
int size, int h, int flags)
{
+ MotionEstContext * const c= &s->me;
me_cmp_func cmpf, chroma_cmpf;
int dia_size;
LOAD_COMMON
LOAD_COMMON2
- int map_generation= s->me.map_generation;
+ int map_generation= c->map_generation;
cmpf= s->dsp.me_cmp[size];
chroma_cmpf= s->dsp.me_cmp[size+1];
@@ -670,13 +675,14 @@ static int sab_diamond_search(MpegEncContext * s, int *best, int dmin,
int src_index, int ref_index, int const penalty_factor,
int size, int h, int flags)
{
+ MotionEstContext * const c= &s->me;
me_cmp_func cmpf, chroma_cmpf;
Minima minima[MAX_SAB_SIZE];
- const int minima_count= ABS(s->me.dia_size);
+ const int minima_count= ABS(c->dia_size);
int i, j;
LOAD_COMMON
LOAD_COMMON2
- int map_generation= s->me.map_generation;
+ int map_generation= c->map_generation;
cmpf= s->dsp.me_cmp[size];
chroma_cmpf= s->dsp.me_cmp[size+1];
@@ -749,16 +755,17 @@ static int var_diamond_search(MpegEncContext * s, int *best, int dmin,
int src_index, int ref_index, int const penalty_factor,
int size, int h, int flags)
{
+ MotionEstContext * const c= &s->me;
me_cmp_func cmpf, chroma_cmpf;
int dia_size;
LOAD_COMMON
LOAD_COMMON2
- int map_generation= s->me.map_generation;
+ int map_generation= c->map_generation;
cmpf= s->dsp.me_cmp[size];
chroma_cmpf= s->dsp.me_cmp[size+1];
- for(dia_size=1; dia_size<=s->me.dia_size; dia_size++){
+ for(dia_size=1; dia_size<=c->dia_size; dia_size++){
int dir, start, end;
const int x= best[0];
const int y= best[1];
@@ -824,11 +831,12 @@ if(256*256*256*64 % (stats[0]+1)==0){
static always_inline int diamond_search(MpegEncContext * s, int *best, int dmin,
int src_index, int ref_index, int const penalty_factor,
int size, int h, int flags){
- if(s->me.dia_size==-1)
+ MotionEstContext * const c= &s->me;
+ if(c->dia_size==-1)
return funny_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
- else if(s->me.dia_size<-1)
+ else if(c->dia_size<-1)
return sab_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
- else if(s->me.dia_size<2)
+ else if(c->dia_size<2)
return small_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
else
return var_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
@@ -838,10 +846,11 @@ static always_inline int epzs_motion_search_internal(MpegEncContext * s, int *mx
int P[10][2], int src_index, int ref_index, int16_t (*last_mv)[2],
int ref_mv_scale, int flags)
{
+ MotionEstContext * const c= &s->me;
int best[2]={0, 0};
int d, dmin;
int map_generation;
- const int penalty_factor= s->me.penalty_factor;
+ const int penalty_factor= c->penalty_factor;
const int size=0;
const int h=16;
const int ref_mv_stride= s->mb_stride; //pass as arg FIXME
@@ -854,7 +863,7 @@ static always_inline int epzs_motion_search_internal(MpegEncContext * s, int *mx
cmpf= s->dsp.me_cmp[size];
chroma_cmpf= s->dsp.me_cmp[size+1];
- map_generation= update_map_generation(s);
+ map_generation= update_map_generation(c);
dmin= cmp(s, 0, 0, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);
map[0]= map_generation;
@@ -871,7 +880,7 @@ static always_inline int epzs_motion_search_internal(MpegEncContext * s, int *mx
|P_TOPRIGHT[0]|P_TOPRIGHT[1])==0){
*mx_ptr= 0;
*my_ptr= 0;
- s->me.skip=1;
+ c->skip=1;
return dmin;
}
CHECK_MV(P_MEDIAN[0]>>shift, P_MEDIAN[1]>>shift)
@@ -884,7 +893,7 @@ static always_inline int epzs_motion_search_internal(MpegEncContext * s, int *mx
}
}
if(dmin>256*4){
- if(s->me.pre_pass){
+ if(c->pre_pass){
CHECK_CLIPED_MV((last_mv[ref_mv_xy-1][0]*ref_mv_scale + (1<<15))>>16,
(last_mv[ref_mv_xy-1][1]*ref_mv_scale + (1<<15))>>16)
if(!s->first_slice_line)
@@ -899,8 +908,8 @@ static always_inline int epzs_motion_search_internal(MpegEncContext * s, int *mx
}
}
- if(s->avctx->last_predictor_count){
- const int count= s->avctx->last_predictor_count;
+ if(c->avctx->last_predictor_count){
+ const int count= c->avctx->last_predictor_count;
const int xstart= FFMAX(0, s->mb_x - count);
const int ystart= FFMAX(0, s->mb_y - count);
const int xend= FFMIN(s->mb_width , s->mb_x + count + 1);
@@ -936,14 +945,15 @@ static inline int epzs_motion_search(MpegEncContext * s, int *mx_ptr, int *my_pt
int P[10][2], int src_index, int ref_index, int16_t (*last_mv)[2],
int ref_mv_scale)
{
+ MotionEstContext * const c= &s->me;
//FIXME convert other functions in the same way if faster
- switch(s->me.flags){
+ switch(c->flags){
case 0:
return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, 0);
// case FLAG_QPEL:
// return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, FLAG_QPEL);
default:
- return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, s->me.flags);
+ return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, c->flags);
}
}
@@ -952,23 +962,24 @@ static int epzs_motion_search4(MpegEncContext * s,
int src_index, int ref_index, int16_t (*last_mv)[2],
int ref_mv_scale)
{
+ MotionEstContext * const c= &s->me;
int best[2]={0, 0};
int d, dmin;
int map_generation;
- const int penalty_factor= s->me.penalty_factor;
+ const int penalty_factor= c->penalty_factor;
const int size=1;
const int h=8;
const int ref_mv_stride= s->mb_stride;
const int ref_mv_xy= s->mb_x + s->mb_y *ref_mv_stride;
me_cmp_func cmpf, chroma_cmpf;
LOAD_COMMON
- int flags= s->me.flags;
+ int flags= c->flags;
LOAD_COMMON2
cmpf= s->dsp.me_cmp[size];
chroma_cmpf= s->dsp.me_cmp[size+1];
- map_generation= update_map_generation(s);
+ map_generation= update_map_generation(c);
dmin = 1000000;
//printf("%d %d %d %d //",xmin, ymin, xmax, ymax);
@@ -1013,23 +1024,24 @@ static int epzs_motion_search2(MpegEncContext * s,
int src_index, int ref_index, int16_t (*last_mv)[2],
int ref_mv_scale)
{
+ MotionEstContext * const c= &s->me;
int best[2]={0, 0};
int d, dmin;
int map_generation;
- const int penalty_factor= s->me.penalty_factor;
+ const int penalty_factor= c->penalty_factor;
const int size=0; //FIXME pass as arg
const int h=8;
const int ref_mv_stride= s->mb_stride;
const int ref_mv_xy= s->mb_x + s->mb_y *ref_mv_stride;
me_cmp_func cmpf, chroma_cmpf;
LOAD_COMMON
- int flags= s->me.flags;
+ int flags= c->flags;
LOAD_COMMON2
cmpf= s->dsp.me_cmp[size];
chroma_cmpf= s->dsp.me_cmp[size+1];
- map_generation= update_map_generation(s);
+ map_generation= update_map_generation(c);
dmin = 1000000;
//printf("%d %d %d %d //",xmin, ymin, xmax, ymax);
diff --git a/src/libffmpeg/libavcodec/mpeg12.c b/src/libffmpeg/libavcodec/mpeg12.c
index 20ca493f2..9e57398ef 100644
--- a/src/libffmpeg/libavcodec/mpeg12.c
+++ b/src/libffmpeg/libavcodec/mpeg12.c
@@ -36,7 +36,7 @@
/* if xine's MPEG encoder is enabled, enable the encoding features in
* this particular module */
-#ifdef XINE_MPEG_ENCODER
+#if defined(XINE_MPEG_ENCODER) && !defined(CONFIG_ENCODERS)
#define CONFIG_ENCODERS
#endif
@@ -2567,12 +2567,10 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx,
s->chroma_intra_matrix[j] = v;
}
#ifdef DEBUG
-/*
dprintf("intra matrix present\n");
for(i=0;i<64;i++)
dprintf(" %d", s->intra_matrix[s->dsp.idct_permutation[i]);
printf("\n");
-*/
#endif
} else {
for(i=0;i<64;i++) {
@@ -2594,12 +2592,10 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx,
s->chroma_inter_matrix[j] = v;
}
#ifdef DEBUG
-/*
dprintf("non intra matrix present\n");
for(i=0;i<64;i++)
dprintf(" %d", s->inter_matrix[s->dsp.idct_permutation[i]);
printf("\n");
-*/
#endif
} else {
for(i=0;i<64;i++) {
@@ -2802,8 +2798,6 @@ static int mpeg_decode_frame(AVCodecContext *avctx,
MpegEncContext *s2 = &s->mpeg_enc_ctx;
dprintf("fill_buffer\n");
- *data_size = 0;
-
/* special case for last picture */
if (buf_size == 0 && s2->low_delay==0 && s2->next_picture_ptr) {
*picture= *(AVFrame*)s2->next_picture_ptr;
diff --git a/src/libffmpeg/libavcodec/mpegaudiodec.c b/src/libffmpeg/libavcodec/mpegaudiodec.c
index a9eed4e36..f9cb389aa 100644
--- a/src/libffmpeg/libavcodec/mpegaudiodec.c
+++ b/src/libffmpeg/libavcodec/mpegaudiodec.c
@@ -2520,7 +2520,6 @@ static int decode_frame(AVCodecContext * avctx,
int len, out_size;
short *out_samples = data;
- *data_size = 0;
buf_ptr = buf;
while (buf_size > 0) {
len = s->inbuf_ptr - s->inbuf;
diff --git a/src/libffmpeg/libavcodec/mpegvideo.c b/src/libffmpeg/libavcodec/mpegvideo.c
index 41ee62435..f86238570 100644
--- a/src/libffmpeg/libavcodec/mpegvideo.c
+++ b/src/libffmpeg/libavcodec/mpegvideo.c
@@ -25,12 +25,11 @@
* The simplest mpeg encoder (well, it was the simplest!).
*/
-#include <limits.h>
-#include <math.h> //for PI
#include "avcodec.h"
#include "dsputil.h"
#include "mpegvideo.h"
#include "faandct.h"
+#include <limits.h>
#ifdef USE_FASTMEMCPY
#include "fastmemcpy.h"
@@ -42,7 +41,7 @@
/* if xine's MPEG encoder is enabled, enable the encoding features in
* this particular module */
-#ifdef XINE_MPEG_ENCODER
+#if defined(XINE_MPEG_ENCODER) && !defined(CONFIG_ENCODERS)
#define CONFIG_ENCODERS
#endif
@@ -575,7 +574,7 @@ void MPV_decode_defaults(MpegEncContext *s){
*/
#ifdef CONFIG_ENCODERS
-void MPV_encode_defaults(MpegEncContext *s){
+static void MPV_encode_defaults(MpegEncContext *s){
static int done=0;
MPV_common_defaults(s);
@@ -1731,7 +1730,7 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict){
if((s->avctx->debug_mv) && pict->motion_val){
int type;
for(type=0; type<3; type++){
- int direction;
+ int direction = 0;
switch (type) {
case 0: if ((!(s->avctx->debug_mv&FF_DEBUG_VIS_MV_P_FOR)) || (pict->pict_type!=FF_P_TYPE))
continue;
@@ -3987,7 +3986,7 @@ static int mb_var_thread(AVCodecContext *c, void *arg){
s->current_picture.mb_var [s->mb_stride * mb_y + mb_x] = varc;
s->current_picture.mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8;
- s->mb_var_sum_temp += varc;
+ s->me.mb_var_sum_temp += varc;
}
}
return 0;
@@ -4141,7 +4140,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
}
if (s->avctx->rtp_callback)
- s->avctx->rtp_callback(s->ptr_lastgob, current_packet_size, 0);
+ s->avctx->rtp_callback(s->avctx, s->ptr_lastgob, current_packet_size, 0);
switch(s->codec_id){
/* xine: do not need this for decode or MPEG-1 encoding modes */
@@ -4597,7 +4596,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
pdif = pbBufPtr(&s->pb) - s->ptr_lastgob;
/* Call the RTP callback to send the last GOB */
emms_c();
- s->avctx->rtp_callback(s->ptr_lastgob, pdif, 0);
+ s->avctx->rtp_callback(s->avctx, s->ptr_lastgob, pdif, 0);
}
return 0;
@@ -4605,9 +4604,9 @@ static int encode_thread(AVCodecContext *c, void *arg){
#define MERGE(field) dst->field += src->field; src->field=0
static void merge_context_after_me(MpegEncContext *dst, MpegEncContext *src){
- MERGE(scene_change_score);
- MERGE(mc_mb_var_sum_temp);
- MERGE(mb_var_sum_temp);
+ MERGE(me.scene_change_score);
+ MERGE(me.mc_mb_var_sum_temp);
+ MERGE(me.mb_var_sum_temp);
}
static void merge_context_after_encode(MpegEncContext *dst, MpegEncContext *src){
@@ -4642,14 +4641,14 @@ static void merge_context_after_encode(MpegEncContext *dst, MpegEncContext *src)
static void encode_picture(MpegEncContext *s, int picture_number)
{
- int i, j;
+ int i;
int bits;
s->picture_number = picture_number;
/* Reset the average MB variance */
- s->mb_var_sum_temp =
- s->mc_mb_var_sum_temp = 0;
+ s->me.mb_var_sum_temp =
+ s->me.mc_mb_var_sum_temp = 0;
/* xine: do not need this for decode or MPEG-1 encoding modes */
#if 0
@@ -4661,7 +4660,7 @@ static void encode_picture(MpegEncContext *s, int picture_number)
#endif
#endif /* #if 0 */
- s->scene_change_score=0;
+ s->me.scene_change_score=0;
s->lambda= s->current_picture_ptr->quality; //FIXME qscale / ... stuff for ME ratedistoration
@@ -4678,6 +4677,8 @@ static void encode_picture(MpegEncContext *s, int picture_number)
ff_update_duplicate_context(s->thread_context[i], s);
}
+/* xine: do not need this for decode or MPEG-1 encoding modes */
+#if 0
ff_init_me(s);
/* Estimate motion for every MB */
@@ -4690,6 +4691,8 @@ static void encode_picture(MpegEncContext *s, int picture_number)
s->avctx->execute(s->avctx, estimate_motion_thread, (void**)&(s->thread_context[0]), NULL, s->avctx->thread_count);
}else /* if(s->pict_type == I_TYPE) */{
+#endif /* #if 0 */
+ {
/* I-Frame */
for(i=0; i<s->mb_stride*s->mb_height; i++)
s->mb_type[i]= CANDIDATE_MB_TYPE_INTRA;
@@ -4702,11 +4705,11 @@ static void encode_picture(MpegEncContext *s, int picture_number)
for(i=1; i<s->avctx->thread_count; i++){
merge_context_after_me(s, s->thread_context[i]);
}
- s->current_picture.mc_mb_var_sum= s->current_picture_ptr->mc_mb_var_sum= s->mc_mb_var_sum_temp;
- s->current_picture. mb_var_sum= s->current_picture_ptr-> mb_var_sum= s-> mb_var_sum_temp;
+ s->current_picture.mc_mb_var_sum= s->current_picture_ptr->mc_mb_var_sum= s->me.mc_mb_var_sum_temp;
+ s->current_picture. mb_var_sum= s->current_picture_ptr-> mb_var_sum= s->me. mb_var_sum_temp;
emms_c();
- if(s->scene_change_score > s->avctx->scenechange_threshold && s->pict_type == P_TYPE){
+ if(s->me.scene_change_score > s->avctx->scenechange_threshold && s->pict_type == P_TYPE){
s->pict_type= I_TYPE;
for(i=0; i<s->mb_stride*s->mb_height; i++)
s->mb_type[i]= CANDIDATE_MB_TYPE_INTRA;
@@ -4729,6 +4732,7 @@ static void encode_picture(MpegEncContext *s, int picture_number)
ff_fix_long_p_mvs(s);
ff_fix_long_mvs(s, NULL, 0, s->p_mv_table, s->f_code, CANDIDATE_MB_TYPE_INTER, 0);
if(s->flags & CODEC_FLAG_INTERLACED_ME){
+ int j;
for(i=0; i<2; i++){
for(j=0; j<2; j++)
ff_fix_long_mvs(s, s->p_field_select_table[i], j,
@@ -4753,7 +4757,7 @@ static void encode_picture(MpegEncContext *s, int picture_number)
ff_fix_long_mvs(s, NULL, 0, s->b_bidir_forw_mv_table, s->f_code, CANDIDATE_MB_TYPE_BIDIR, 1);
ff_fix_long_mvs(s, NULL, 0, s->b_bidir_back_mv_table, s->b_code, CANDIDATE_MB_TYPE_BIDIR, 1);
if(s->flags & CODEC_FLAG_INTERLACED_ME){
- int dir;
+ int dir, j;
for(dir=0; dir<2; dir++){
for(i=0; i<2; i++){
for(j=0; j<2; j++){
@@ -5328,7 +5332,7 @@ STOP_TIMER("init rem[]")
int best_score=s->dsp.try_8x8basis(rem, weight, basis[0], 0);
int best_coeff=0;
int best_change=0;
- int run2, best_unquant_change, analyze_gradient;
+ int run2, best_unquant_change=0, analyze_gradient;
#ifdef REFINE_STATS
{START_TIMER
#endif
diff --git a/src/libffmpeg/libavcodec/mpegvideo.h b/src/libffmpeg/libavcodec/mpegvideo.h
index 85952fe4c..715fb6d92 100644
--- a/src/libffmpeg/libavcodec/mpegvideo.h
+++ b/src/libffmpeg/libavcodec/mpegvideo.h
@@ -196,6 +196,7 @@ struct MpegEncContext;
* Motion estimation context.
*/
typedef struct MotionEstContext{
+ AVCodecContext *avctx;
int skip; ///< set if ME is skiped for the current MB
int co_located_mv[4][2]; ///< mv from last p frame for direct mode ME
int direct_basis_mv[4][2];
@@ -226,6 +227,10 @@ typedef struct MotionEstContext{
uint8_t *ref[4][4];
int stride;
int uvstride;
+ /* temp variables for picture complexity calculation */
+ int mc_mb_var_sum_temp;
+ int mb_var_sum_temp;
+ int scene_change_score;
/* cmp, chroma_cmp;*/
op_pixels_func (*hpel_put)[4];
op_pixels_func (*hpel_avg)[4];
@@ -393,7 +398,6 @@ typedef struct MpegEncContext {
uint8_t (*p_field_select_table[2]);
uint8_t (*b_field_select_table[2][2]);
int me_method; ///< ME algorithm
- int scene_change_score;
int mv_dir;
#define MV_DIR_BACKWARD 1
#define MV_DIR_FORWARD 2
@@ -508,10 +512,6 @@ typedef struct MpegEncContext {
int misc_bits; ///< cbp, mb_type
int last_bits; ///< temp var used for calculating the above vars
- /* temp variables for picture complexity calculation */
- int mc_mb_var_sum_temp;
- int mb_var_sum_temp;
-
/* error concealment / resync */
int error_count;
uint8_t *error_status_table; ///< table of the error status of each MB
@@ -813,6 +813,7 @@ void mpeg1_encode_mb(MpegEncContext *s,
void ff_mpeg1_encode_init(MpegEncContext *s);
void ff_mpeg1_encode_slice_header(MpegEncContext *s);
void ff_mpeg1_clean_buffers(MpegEncContext *s);
+int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size);
/** RLTable. */
@@ -852,6 +853,7 @@ extern const uint8_t ff_h263_chroma_qscale_table[32];
extern const uint8_t ff_h263_loop_filter_strength[32];
+/* h263.c, h263dec.c */
int ff_h263_decode_init(AVCodecContext *avctx);
int ff_h263_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
@@ -903,6 +905,8 @@ int ff_h263_resync(MpegEncContext *s);
int ff_h263_get_gob_height(MpegEncContext *s);
int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my);
int ff_h263_round_chroma(int x);
+void ff_h263_encode_motion(MpegEncContext * s, int val, int f_code);
+int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size);
/* rv10.c */
diff --git a/src/libffmpeg/libavcodec/msmpeg4.c b/src/libffmpeg/libavcodec/msmpeg4.c
index c6cfebe16..7df276ca7 100644
--- a/src/libffmpeg/libavcodec/msmpeg4.c
+++ b/src/libffmpeg/libavcodec/msmpeg4.c
@@ -425,9 +425,7 @@ void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
#ifdef DEBUG
intra_count = 0;
-/*
printf("*****frame %d:\n", frame_count++);
-*/
#endif
}
@@ -658,21 +656,6 @@ void msmpeg4_encode_mb(MpegEncContext * s,
#endif //CONFIG_ENCODERS
-/* old ffmpeg msmpeg4v3 mode */
-static void ff_old_msmpeg4_dc_scale(MpegEncContext * s)
-{
- if (s->qscale < 5){
- s->y_dc_scale = 8;
- s->c_dc_scale = 8;
- }else if (s->qscale < 9){
- s->y_dc_scale = 2 * s->qscale;
- s->c_dc_scale = (s->qscale + 13)>>1;
- }else{
- s->y_dc_scale = s->qscale + 8;
- s->c_dc_scale = (s->qscale + 13)>>1;
- }
-}
-
static inline int msmpeg4v1_pred_dc(MpegEncContext * s, int n,
int32_t **dc_val_ptr)
{
diff --git a/src/libffmpeg/libavcodec/os_support.h b/src/libffmpeg/libavcodec/os_support.h
deleted file mode 100644
index 93930f03b..000000000
--- a/src/libffmpeg/libavcodec/os_support.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef _OS_SUPPORT_H
-#define _OS_SUPPORT_H
-
-/**
- * @file os_support.h
- * miscellaneous OS support macros and functions.
- *
- * - usleep() (Win32, BeOS, OS/2)
- * - floatf() (OS/2)
- * - strcasecmp() (OS/2)
- */
-
-#ifdef __MINGW32__
-# undef DATADIR /* clashes with /usr/include/w32api/objidl.h */
-# include <windows.h>
-# define usleep(t) Sleep((t) / 1000)
-#endif
-
-#ifdef __BEOS__
-# ifndef usleep
-# include <OS.h>
-# define usleep(t) snooze((bigtime_t)(t))
-# endif
-#endif
-
-#if defined(CONFIG_OS2)
-#include <stdlib.h>
-static inline int usleep(unsigned int t) { return _sleep2(t / 1000); }
-static inline float floorf(float f) { return floor(f); }
-static inline int strcasecmp(const char* s1, const char* s2) { return stricmp(s1,s2); }
-#endif
-
-#if defined(CONFIG_SUNOS)
-static inline float floorf(float f) { return floor(f); }
-#endif
-
-#endif /* _OS_SUPPORT_H */
diff --git a/src/libffmpeg/libavcodec/parser.c b/src/libffmpeg/libavcodec/parser.c
index 88894884c..ed386611a 100644
--- a/src/libffmpeg/libavcodec/parser.c
+++ b/src/libffmpeg/libavcodec/parser.c
@@ -60,6 +60,7 @@ AVCodecParserContext *av_parser_init(int codec_id)
return NULL;
}
}
+ s->fetch_timestamp=1;
return s;
}
@@ -87,7 +88,8 @@ int av_parser_parse(AVCodecParserContext *s,
s->cur_frame_dts[k] = dts;
/* fill first PTS/DTS */
- if (s->cur_offset == 0) {
+ if (s->fetch_timestamp){
+ s->fetch_timestamp=0;
s->last_pts = pts;
s->last_dts = dts;
}
@@ -95,6 +97,7 @@ int av_parser_parse(AVCodecParserContext *s,
/* WARNING: the returned index can be negative */
index = s->parser->parser_parse(s, avctx, poutbuf, poutbuf_size, buf, buf_size);
+//av_log(NULL, AV_LOG_DEBUG, "parser: in:%lld, %lld, out:%lld, %lld, in:%d out:%d %d\n", pts, dts, s->last_pts, s->last_dts, buf_size, *poutbuf_size, avctx->codec_id);
/* update the file pointer */
if (*poutbuf_size) {
/* fill the data for the current frame */
@@ -116,8 +119,15 @@ int av_parser_parse(AVCodecParserContext *s,
break;
k = (k - 1) & (AV_PARSER_PTS_NB - 1);
}
+
s->last_pts = s->cur_frame_pts[k];
s->last_dts = s->cur_frame_dts[k];
+
+ /* some parsers tell us the packet size even before seeing the first byte of the next packet,
+ so the next pts/dts is in the next chunk */
+ if(index == buf_size){
+ s->fetch_timestamp=1;
+ }
}
if (index < 0)
index = 0;
@@ -426,7 +436,7 @@ static int av_mpeg4_decode_header(AVCodecParserContext *s1,
return ret;
}
-int mpeg4video_parse_init(AVCodecParserContext *s)
+static int mpeg4video_parse_init(AVCodecParserContext *s)
{
ParseContext1 *pc = s->priv_data;
diff --git a/src/libffmpeg/libavcodec/pcm.c b/src/libffmpeg/libavcodec/pcm.c
index a6c0d343b..4c999b430 100644
--- a/src/libffmpeg/libavcodec/pcm.c
+++ b/src/libffmpeg/libavcodec/pcm.c
@@ -334,7 +334,6 @@ static int pcm_decode_frame(AVCodecContext *avctx,
}
break;
default:
- *data_size = 0;
return -1;
}
*data_size = (uint8_t *)samples - (uint8_t *)data;
diff --git a/src/libffmpeg/libavcodec/ra288.c b/src/libffmpeg/libavcodec/ra288.c
index a44eb96f1..09ecc7aac 100644
--- a/src/libffmpeg/libavcodec/ra288.c
+++ b/src/libffmpeg/libavcodec/ra288.c
@@ -206,7 +206,7 @@ static void prodsum(float *tgt, float *src, int len, int n)
}
}
-void * decode_block(AVCodecContext * avctx, unsigned char *in, signed short int *out,unsigned len)
+static void * decode_block(AVCodecContext * avctx, unsigned char *in, signed short int *out,unsigned len)
{
int x,y;
Real288_internal *glob=avctx->priv_data;
@@ -255,7 +255,7 @@ static int ra288_decode_frame(AVCodecContext * avctx,
data=decode_block(avctx,&buf[j*cfs+cfs*i*h/2],(signed short *)data,cfs);
bret += cfs;
}
- *data_size = data - datao;
+ *data_size = (char *)data - (char *)datao;
return bret;
}
else
diff --git a/src/libffmpeg/libavcodec/raw.c b/src/libffmpeg/libavcodec/raw.c
new file mode 100644
index 000000000..8c554c41c
--- /dev/null
+++ b/src/libffmpeg/libavcodec/raw.c
@@ -0,0 +1,175 @@
+/*
+ * Raw Video Codec
+ * Copyright (c) 2001 Fabrice Bellard.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/**
+ * @file raw.c
+ * Raw Video Codec
+ */
+
+#include "avcodec.h"
+
+typedef struct RawVideoContext {
+ unsigned char * buffer; /* block of memory for holding one frame */
+ unsigned char * p; /* current position in buffer */
+ int length; /* number of bytes in buffer */
+ AVFrame pic; ///< AVCodecContext.coded_frame
+} RawVideoContext;
+
+typedef struct PixleFormatTag {
+ int pix_fmt;
+ unsigned int fourcc;
+} PixelFormatTag;
+
+const PixelFormatTag pixelFormatTags[] = {
+ { PIX_FMT_YUV420P, MKTAG('I', '4', '2', '0') }, /* Planar formats */
+ { PIX_FMT_YUV420P, MKTAG('I', 'Y', 'U', 'V') },
+ { PIX_FMT_YUV410P, MKTAG('Y', 'U', 'V', '9') },
+ { PIX_FMT_YUV411P, MKTAG('Y', '4', '1', 'B') },
+ { PIX_FMT_YUV422P, MKTAG('Y', '4', '2', 'B') },
+ { PIX_FMT_GRAY8, MKTAG('Y', '8', '0', '0') },
+ { PIX_FMT_GRAY8, MKTAG(' ', ' ', 'Y', '8') },
+
+
+ { PIX_FMT_YUV422, MKTAG('Y', '4', '2', '2') }, /* Packed formats */
+ { PIX_FMT_YUV422, MKTAG('U', 'Y', 'V', 'Y') },
+ { PIX_FMT_GRAY8, MKTAG('G', 'R', 'E', 'Y') },
+
+ { -1, 0 },
+};
+
+static int findPixelFormat(unsigned int fourcc)
+{
+ const PixelFormatTag * tags = pixelFormatTags;
+ while (tags->pix_fmt >= 0) {
+ if (tags->fourcc == fourcc)
+ return tags->pix_fmt;
+ tags++;
+ }
+ return PIX_FMT_YUV420P;
+}
+
+static unsigned int findFourCC(int fmt)
+{
+ const PixelFormatTag * tags = pixelFormatTags;
+ while (tags->pix_fmt >= 0) {
+ if (tags->pix_fmt == fmt)
+ return tags->fourcc;
+ tags++;
+ }
+ return 0;
+}
+
+/* RAW Decoder Implementation */
+
+static int raw_init_decoder(AVCodecContext *avctx)
+{
+ RawVideoContext *context = avctx->priv_data;
+
+ if (avctx->codec_tag)
+ avctx->pix_fmt = findPixelFormat(avctx->codec_tag);
+
+ context->length = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);
+ context->buffer = av_malloc(context->length);
+ context->p = context->buffer;
+ context->pic.pict_type = FF_I_TYPE;
+ context->pic.key_frame = 1;
+
+ avctx->coded_frame= &context->pic;
+
+ if (!context->buffer)
+ return -1;
+
+ return 0;
+}
+
+static int raw_decode(AVCodecContext *avctx,
+ void *data, int *data_size,
+ uint8_t *buf, int buf_size)
+{
+ RawVideoContext *context = avctx->priv_data;
+ int bytesNeeded;
+
+ AVPicture * picture = (AVPicture *) data;
+
+ /* Early out without copy if packet size == frame size */
+ if (buf_size == context->length && context->p == context->buffer) {
+ avpicture_fill(picture, buf, avctx->pix_fmt, avctx->width, avctx->height);
+ *data_size = sizeof(AVPicture);
+ return buf_size;
+ }
+
+ bytesNeeded = context->length - (context->p - context->buffer);
+ if (buf_size < bytesNeeded) {
+ memcpy(context->p, buf, buf_size);
+ context->p += buf_size;
+ return buf_size;
+ }
+
+ memcpy(context->p, buf, bytesNeeded);
+ context->p = context->buffer;
+ avpicture_fill(picture, context->buffer, avctx->pix_fmt, avctx->width, avctx->height);
+ *data_size = sizeof(AVPicture);
+ return bytesNeeded;
+}
+
+static int raw_close_decoder(AVCodecContext *avctx)
+{
+ RawVideoContext *context = avctx->priv_data;
+
+ av_freep(&context->buffer);
+ return 0;
+}
+
+/* RAW Encoder Implementation */
+
+static int raw_init_encoder(AVCodecContext *avctx)
+{
+ avctx->coded_frame = (AVFrame *)avctx->priv_data;
+ avctx->coded_frame->pict_type = FF_I_TYPE;
+ avctx->coded_frame->key_frame = 1;
+ avctx->codec_tag = findFourCC(avctx->pix_fmt);
+ return 0;
+}
+
+static int raw_encode(AVCodecContext *avctx,
+ unsigned char *frame, int buf_size, void *data)
+{
+ return avpicture_layout((AVPicture *)data, avctx->pix_fmt, avctx->width,
+ avctx->height, frame, buf_size);
+}
+
+AVCodec rawvideo_encoder = {
+ "rawvideo",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_RAWVIDEO,
+ sizeof(AVFrame),
+ raw_init_encoder,
+ raw_encode,
+};
+
+AVCodec rawvideo_decoder = {
+ "rawvideo",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_RAWVIDEO,
+ sizeof(RawVideoContext),
+ raw_init_decoder,
+ NULL,
+ raw_close_decoder,
+ raw_decode,
+};
diff --git a/src/libffmpeg/libavcodec/roqvideo.c b/src/libffmpeg/libavcodec/roqvideo.c
index bd26961dc..7d6b518ee 100644
--- a/src/libffmpeg/libavcodec/roqvideo.c
+++ b/src/libffmpeg/libavcodec/roqvideo.c
@@ -450,8 +450,6 @@ static int roq_decode_frame(AVCodecContext *avctx,
{
RoqContext *s = avctx->priv_data;
- *data_size = 0;
-
if (avctx->get_buffer(avctx, &s->current_frame)) {
av_log(avctx, AV_LOG_ERROR, " RoQ: get_buffer() failed\n");
return -1;
diff --git a/src/libffmpeg/libavcodec/rpza.c b/src/libffmpeg/libavcodec/rpza.c
index 1c429f624..2be26346a 100644
--- a/src/libffmpeg/libavcodec/rpza.c
+++ b/src/libffmpeg/libavcodec/rpza.c
@@ -106,7 +106,7 @@ static void rpza_decode_stream(RpzaContext *s)
chunk_size = s->size;
/* Number of 4x4 blocks in frame. */
- total_blocks = (s->avctx->width * s->avctx->height) / (4 * 4);
+ total_blocks = ((s->avctx->width + 3) / 4) * ((s->avctx->height + 3) / 4);
/* Process chunk data */
while (stream_ptr < chunk_size) {
diff --git a/src/libffmpeg/libavcodec/rv10.c b/src/libffmpeg/libavcodec/rv10.c
index b67ec3974..58c5db7f4 100644
--- a/src/libffmpeg/libavcodec/rv10.c
+++ b/src/libffmpeg/libavcodec/rv10.c
@@ -528,15 +528,9 @@ static int rv10_decode_packet(AVCodecContext *avctx,
uint8_t *buf, int buf_size)
{
MpegEncContext *s = avctx->priv_data;
- int i, mb_count, mb_pos, left;
+ int mb_count, mb_pos, left;
init_get_bits(&s->gb, buf, buf_size*8);
-#if 0
- for(i=0; i<buf_size*8 && i<200; i++)
- printf("%d", get_bits1(&s->gb));
- printf("\n");
- return 0;
-#endif
if(s->codec_id ==CODEC_ID_RV10)
mb_count = rv10_decode_picture_header(s);
else
@@ -651,7 +645,6 @@ static int rv10_decode_frame(AVCodecContext *avctx,
/* no supplementary picture */
if (buf_size == 0) {
- *data_size = 0;
return 0;
}
@@ -685,8 +678,6 @@ static int rv10_decode_frame(AVCodecContext *avctx,
}
*data_size = sizeof(AVFrame);
- }else{
- *data_size = 0;
}
return buf_size;
diff --git a/src/libffmpeg/libavcodec/svq1.c b/src/libffmpeg/libavcodec/svq1.c
index 8fec2a31e..a841816af 100644
--- a/src/libffmpeg/libavcodec/svq1.c
+++ b/src/libffmpeg/libavcodec/svq1.c
@@ -48,6 +48,8 @@
#undef NDEBUG
#include <assert.h>
+extern const uint8_t mvtab[33][2];
+
static VLC svq1_block_type;
static VLC svq1_motion_component;
static VLC svq1_intra_multistage[6];
@@ -55,15 +57,13 @@ static VLC svq1_inter_multistage[6];
static VLC svq1_intra_mean;
static VLC svq1_inter_mean;
-#define MEDIAN(a,b,c) (((a < b) != (b >= c)) ? b : (((a < c) != (c > b)) ? c : a))
-
#define SVQ1_BLOCK_SKIP 0
#define SVQ1_BLOCK_INTER 1
#define SVQ1_BLOCK_INTER_4V 2
#define SVQ1_BLOCK_INTRA 3
typedef struct SVQ1Context {
-
+ MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to make the motion estimation eventually independant of MpegEncContext, so this will be removed then (FIXME/XXX)
AVCodecContext *avctx;
DSPContext dsp;
AVFrame picture;
@@ -84,8 +84,11 @@ typedef struct SVQ1Context {
/* U & V plane (C planes) block dimensions */
int c_block_width;
int c_block_height;
-
- unsigned char *c_plane;
+
+ uint16_t *mb_type;
+ uint32_t *dummy;
+ int16_t (*motion_val8[3])[2];
+ int16_t (*motion_val16[3])[2];
int64_t rd_total;
} SVQ1Context;
@@ -349,13 +352,18 @@ static int svq1_decode_motion_vector (GetBitContext *bitbuf, svq1_pmv_t *mv, svq
for (i=0; i < 2; i++) {
/* get motion code */
- diff = get_vlc2(bitbuf, svq1_motion_component.table, 7, 2) - 32;
+ diff = get_vlc2(bitbuf, svq1_motion_component.table, 7, 2);
+ if(diff<0)
+ return -1;
+ else if(diff){
+ if(get_bits1(bitbuf)) diff= -diff;
+ }
/* add median of motion vector predictors and clip result */
if (i == 1)
- mv->y = ((diff + MEDIAN(pmv[0]->y, pmv[1]->y, pmv[2]->y)) << 26) >> 26;
+ mv->y = ((diff + mid_pred(pmv[0]->y, pmv[1]->y, pmv[2]->y)) << 26) >> 26;
else
- mv->x = ((diff + MEDIAN(pmv[0]->x, pmv[1]->x, pmv[2]->x)) << 26) >> 26;
+ mv->x = ((diff + mid_pred(pmv[0]->x, pmv[1]->x, pmv[2]->x)) << 26) >> 26;
}
return 0;
@@ -705,6 +713,10 @@ static int svq1_decode_frame(AVCodecContext *avctx,
int result, i, x, y, width, height;
AVFrame *pict = data;
+ if(buf==NULL && buf_size==0){
+ return 0;
+ }
+
/* initialize bit buffer */
init_get_bits(&s->gb,buf,buf_size*8);
@@ -834,9 +846,9 @@ static int svq1_decode_init(AVCodecContext *avctx)
&svq1_block_type_vlc[0][1], 2, 1,
&svq1_block_type_vlc[0][0], 2, 1);
- init_vlc(&svq1_motion_component, 7, 65,
- &svq1_motion_component_vlc[0][1], 2, 1,
- &svq1_motion_component_vlc[0][0], 2, 1);
+ init_vlc(&svq1_motion_component, 7, 33,
+ &mvtab[0][1], 2, 1,
+ &mvtab[0][0], 2, 1);
for (i = 0; i < 6; i++) {
init_vlc(&svq1_intra_multistage[i], 3, 8,
@@ -898,419 +910,10 @@ static void svq1_write_header(SVQ1Context *s, int frame_type)
put_bits(&s->pb, 2, 0);
}
-int level_sizes[6] = { 8, 16, 32, 64, 128, 256 };
-int level_log2_sizes[6] = { 3, 4, 5, 6, 7, 8 };
-
-#define IABS(x) ((x < 0) ? (-(x)) : x)
-
-
-
-//#define USE_MAD_ALGORITHM
-
-#ifdef USE_MAD_ALGORITHM
#define QUALITY_THRESHOLD 100
#define THRESHOLD_MULTIPLIER 0.6
-/* This function calculates vector differences using mean absolute
- * difference (MAD). */
-
-static int encode_vector(SVQ1Context *s, unsigned char *vector,
- unsigned int level, int threshold)
-{
- int i, j, k;
- int mean;
- signed short work_vector[256];
- int best_codebook;
- int best_score;
- int multistage_codebooks[6];
- int number_of_stages = 0;
- int8_t *current_codebook;
- int total_deviation;
- int ret;
-
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, " ** recursive entry point: encoding level %d vector at threshold %d\n",
- level, threshold);
-#endif
- if (level > 5) {
- av_log(s->avctx, AV_LOG_INFO, " help! level %d > 5\n", level);
- return 0;
- }
-
-#ifdef DEBUG_SVQ1
-for (i = 0; i < level_sizes[level]; i++)
- av_log(s->avctx, AV_LOG_INFO, " %02X", vector[i]);
-av_log(s->avctx, AV_LOG_INFO, "\n");
-#endif
-
- /* calculate the mean */
- mean = 0;
- for (i = 0; i < level_sizes[level]; i++)
- mean += vector[i];
- mean >>= level_log2_sizes[level];
-
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, " vector mean = 0x%02X\n", mean);
-#endif
-
- /* remove the mean from the vector */
- total_deviation = 0;
- for (i = 0; i < level_sizes[level]; i++) {
- work_vector[i] = (signed short)vector[i] - mean;
- total_deviation += IABS(work_vector[i]);
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, " %d", work_vector[i]);
-#endif
- }
-
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, "\n total deviation = %d\n", total_deviation);
-#endif
-
- if (total_deviation < threshold) {
-
-#ifdef DEBUG_SVQ1
- av_log(s->avctx, AV_LOG_INFO, " mean-only encoding found for level %d vector, mean = %d\n",
- level, mean);
-#endif
-
- /* indicate that this is the end of the subdivisions */
- if (level > 0)
- put_bits(&s->pb, 1, 0);
-
- /* index 1 in the table indicates mean-only encoding */
- put_bits(&s->pb, svq1_intra_multistage_vlc[level][1][1],
- svq1_intra_multistage_vlc[level][1][0]);
- put_bits(&s->pb, svq1_intra_mean_vlc[mean][1],
- svq1_intra_mean_vlc[mean][0]);
-
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, " mean-only L%d, VLC = (0x%X, %d), mean = %d (0x%X, %d)\n",
- level,
- svq1_intra_multistage_vlc[level][1 + number_of_stages][0],
- svq1_intra_multistage_vlc[level][1 + number_of_stages][1],
- mean,
- svq1_intra_mean_vlc[mean][0],
- svq1_intra_mean_vlc[mean][1]);
-#endif
-
- ret = 0;
-
- } else {
-
- if (level <= 3) {
-
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, " multistage VQ search...\n");
-#endif
- /* conduct multistage VQ search, for each stage... */
- for (i = 0; i < 6; i++) {
-
- best_codebook = 0;
- best_score = 0x7FFFFFFF;
- /* for each codebook in stage */
- for (j = 0; j < 16; j++) {
-
- total_deviation = 0;
- current_codebook =
- &svq1_intra_codebooks[level]
- [i * level_sizes[level] * 16 + j * level_sizes[level]];
- /* calculate the total deviation for the vector */
- for (k = 0; k < level_sizes[level]; k++) {
- total_deviation +=
- IABS(work_vector[k] - current_codebook[k]);
- }
-
- /* lowest score so far? */
- if (total_deviation < best_score) {
- best_score = total_deviation;
- best_codebook = j;
- }
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, " after %d, %d, best codebook is %d with a score of %d (score was %d)\n",
- i, j, best_codebook, best_score, total_deviation);
-#endif
- }
-
- /* apply the winning codebook to the work vector and check if
- * the vector meets the quality threshold */
- total_deviation = 0;
- current_codebook =
- &svq1_intra_codebooks[level]
- [i * level_sizes[level] * 16 + j * level_sizes[level]];
- multistage_codebooks[number_of_stages++] = best_codebook;
- for (j = 0; j < level_sizes[level]; j++) {
- work_vector[j] = work_vector[j] - current_codebook[j];
- total_deviation += IABS(work_vector[j]);
- }
-
- /* do not go forward with the rest of the search if an acceptable
- * codebook combination has been found */
- if (total_deviation < threshold)
- break;
- }
- }
-
- if ((total_deviation < threshold) || (level == 0)) {
-#ifdef DEBUG_SVQ1
- av_log(s->avctx, AV_LOG_INFO, " level %d VQ encoding found using mean %d and codebooks", level, mean);
- for (i = 0; i < number_of_stages; i++)
- av_log(s->avctx, AV_LOG_INFO, " %d", multistage_codebooks[i]);
- av_log(s->avctx, AV_LOG_INFO, "\n");
-#endif
-
- /* indicate that this is the end of the subdivisions */
- if (level > 0)
- put_bits(&s->pb, 1, 0);
-
- /* output the encoding */
- put_bits(&s->pb,
- svq1_intra_multistage_vlc[level][1 + number_of_stages][1],
- svq1_intra_multistage_vlc[level][1 + number_of_stages][0]);
- put_bits(&s->pb, svq1_intra_mean_vlc[mean][1],
- svq1_intra_mean_vlc[mean][0]);
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, " L%d: multistage = %d (0x%X, %d), mean = %d (0x%X, %d), codebooks = ",
- level,
- number_of_stages,
- svq1_intra_multistage_vlc[level][1 + number_of_stages][0],
- svq1_intra_multistage_vlc[level][1 + number_of_stages][1],
- mean,
- svq1_intra_mean_vlc[mean][0],
- svq1_intra_mean_vlc[mean][1]);
-#endif
-
- for (i = 0; i < number_of_stages; i++)
-{
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, "%d ", multistage_codebooks[i]);
-#endif
- put_bits(&s->pb, 4, multistage_codebooks[i]);
-}
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, "\n");
-#endif
-
- ret = 0;
-
- } else {
-
- /* output a subdivision bit to the encoded stream and signal to
- * the calling function that this vector could not be
- * coded at the requested threshold and needs to be subdivided */
- put_bits(&s->pb, 1, 1);
- ret = 1;
- }
- }
-
- return ret;
-}
-
-#else
-
-#define QUALITY_THRESHOLD 100
-#define THRESHOLD_MULTIPLIER 0.6
-
-/* This function calculates vector differences using mean square
- * error (MSE). */
-
-static int encode_vector(SVQ1Context *s, unsigned char *vector,
- unsigned int level, int threshold)
-{
- int i, j, k;
- int mean;
- signed short work_vector[256];
- int best_codebook;
- int best_score;
- int multistage_codebooks[6];
- int number_of_stages = 0;
- int8_t *current_codebook;
- int mse;
- int diff;
- int ret;
-
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, " ** recursive entry point: encoding level %d vector at threshold %d\n",
- level, threshold);
-#endif
- if (level > 5) {
- av_log(s->avctx, AV_LOG_INFO, " help! level %d > 5\n", level);
- return 0;
- }
-
-#ifdef DEBUG_SVQ1
-for (i = 0; i < level_sizes[level]; i++)
- av_log(s->avctx, AV_LOG_INFO, " %02X", vector[i]);
-av_log(s->avctx, AV_LOG_INFO, "\n");
-#endif
-
- /* calculate the mean */
- mean = 0;
- for (i = 0; i < level_sizes[level]; i++)
- mean += vector[i];
- mean >>= level_log2_sizes[level];
-
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, " vector mean = 0x%02X\n", mean);
-#endif
-
- /* remove the mean from the vector and compute the resulting MSE */
- mse = 0;
- for (i = 0; i < level_sizes[level]; i++) {
- work_vector[i] = (signed short)vector[i] - mean;
- mse += (work_vector[i] * work_vector[i]);
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, " %d", work_vector[i]);
-#endif
- }
- mse >>= level_log2_sizes[level];
-
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, "\n MSE = %d\n", mse);
-#endif
-
- if (mse < threshold) {
-
-#ifdef DEBUG_SVQ1
- av_log(s->avctx, AV_LOG_INFO, " mean-only encoding found for level %d vector, mean = %d\n",
- level, mean);
-#endif
-
- /* indicate that this is the end of the subdivisions */
- if (level > 0)
- put_bits(&s->pb, 1, 0);
-
- /* index 1 in the table indicates mean-only encoding */
- put_bits(&s->pb, svq1_intra_multistage_vlc[level][1][1],
- svq1_intra_multistage_vlc[level][1][0]);
- put_bits(&s->pb, svq1_intra_mean_vlc[mean][1],
- svq1_intra_mean_vlc[mean][0]);
-
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, " mean-only L%d, VLC = (0x%X, %d), mean = %d (0x%X, %d)\n",
- level,
- svq1_intra_multistage_vlc[level][1 + number_of_stages][0],
- svq1_intra_multistage_vlc[level][1 + number_of_stages][1],
- mean,
- svq1_intra_mean_vlc[mean][0],
- svq1_intra_mean_vlc[mean][1]);
-#endif
-
- ret = 0;
-
- } else {
-
- if (level <= 3) {
-
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, " multistage VQ search...\n");
-#endif
- /* conduct multistage VQ search, for each stage... */
- for (i = 0; i < 6; i++) {
-
- best_codebook = 0;
- best_score = 0x7FFFFFFF;
- /* for each codebook in stage */
- for (j = 0; j < 16; j++) {
-
- mse = 0;
- current_codebook =
- &svq1_intra_codebooks[level]
- [i * level_sizes[level] * 16 + j * level_sizes[level]];
- /* calculate the MSE for this vector */
- for (k = 0; k < level_sizes[level]; k++) {
- diff = work_vector[k] - current_codebook[k];
- mse += (diff * diff);
- }
- mse >>= level_log2_sizes[level];
-
- /* lowest score so far? */
- if (mse < best_score) {
- best_score = mse;
- best_codebook = j;
- }
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, " after %d, %d, best codebook is %d with a score of %d (score was %d)\n",
- i, j, best_codebook, best_score, mse);
-#endif
- }
-
- /* apply the winning codebook to the work vector and check if
- * the vector meets the quality threshold */
- mse = 0;
- current_codebook =
- &svq1_intra_codebooks[level]
- [i * level_sizes[level] * 16 + j * level_sizes[level]];
- multistage_codebooks[number_of_stages++] = best_codebook;
- for (j = 0; j < level_sizes[level]; j++) {
- work_vector[j] = work_vector[j] - current_codebook[j];
- mse += (work_vector[j] * work_vector[j]);
- }
- mse >>= level_log2_sizes[level];
-
- /* do not go forward with the rest of the search if an acceptable
- * codebook combination has been found */
- if (mse < threshold)
- break;
- }
- }
-
- if ((mse < threshold) || (level == 0)) {
-#ifdef DEBUG_SVQ1
- av_log(s->avctx, AV_LOG_INFO, " level %d VQ encoding found using mean %d and codebooks", level, mean);
- for (i = 0; i < number_of_stages; i++)
- av_log(s->avctx, AV_LOG_INFO, " %d", multistage_codebooks[i]);
- av_log(s->avctx, AV_LOG_INFO, "\n");
-#endif
-
- /* indicate that this is the end of the subdivisions */
- if (level > 0)
- put_bits(&s->pb, 1, 0);
-
- /* output the encoding */
- put_bits(&s->pb,
- svq1_intra_multistage_vlc[level][1 + number_of_stages][1],
- svq1_intra_multistage_vlc[level][1 + number_of_stages][0]);
- put_bits(&s->pb, svq1_intra_mean_vlc[mean][1],
- svq1_intra_mean_vlc[mean][0]);
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, " L%d: multistage = %d (0x%X, %d), mean = %d (0x%X, %d), codebooks = ",
- level,
- number_of_stages,
- svq1_intra_multistage_vlc[level][1 + number_of_stages][0],
- svq1_intra_multistage_vlc[level][1 + number_of_stages][1],
- mean,
- svq1_intra_mean_vlc[mean][0],
- svq1_intra_mean_vlc[mean][1]);
-#endif
-
- for (i = 0; i < number_of_stages; i++)
-{
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, "%d ", multistage_codebooks[i]);
-#endif
- put_bits(&s->pb, 4, multistage_codebooks[i]);
-}
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, "\n");
-#endif
-
- ret = 0;
-
- } else {
-
- /* output a subdivision bit to the encoded stream and signal to
- * the calling function that this vector could not be
- * coded at the requested threshold and needs to be subdivided */
- put_bits(&s->pb, 1, 1);
- ret = 1;
- }
- }
-
- return ret;
-}
-#endif
static int encode_block(SVQ1Context *s, uint8_t *src, uint8_t *ref, uint8_t *decoded, int stride, int level, int threshold, int lambda, int intra){
int count, y, x, i, j, split, best_mean, best_score, best_count;
@@ -1461,30 +1064,16 @@ static int encode_block(SVQ1Context *s, uint8_t *src, uint8_t *ref, uint8_t *dec
return best_score;
}
-static void svq1_encode_plane(SVQ1Context *s, unsigned char *src_plane, unsigned char *ref_plane, unsigned char *decoded_plane,
+static void svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plane, unsigned char *ref_plane, unsigned char *decoded_plane,
int width, int height, int src_stride, int stride)
{
- unsigned char buffer0[256];
- unsigned char buffer1[256];
- int current_buffer;
- unsigned char *vector;
- unsigned char *subvectors;
- int vector_count;
- int subvector_count;
int x, y;
- int i, j;
+ int i;
int block_width, block_height;
- int left_edge;
int level;
int threshold[6];
const int lambda= (s->picture.quality*s->picture.quality) >> (2*FF_LAMBDA_SHIFT);
-static int frame = 0;
-
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, "********* frame #%d\n", frame++);
-#endif
-
/* figure out the acceptable level thresholds in advance */
threshold[5] = QUALITY_THRESHOLD;
for (level = 4; level >= 0; level--)
@@ -1493,6 +1082,75 @@ av_log(s->avctx, AV_LOG_INFO, "********* frame #%d\n", frame++);
block_width = (width + 15) / 16;
block_height = (height + 15) / 16;
+ if(s->picture.pict_type == P_TYPE){
+ s->m.avctx= s->avctx;
+ s->m.current_picture_ptr= &s->m.current_picture;
+ s->m.last_picture_ptr = &s->m.last_picture;
+ s->m.last_picture.data[0]= ref_plane;
+ s->m.linesize=
+ s->m.last_picture.linesize[0]=
+ s->m.new_picture.linesize[0]=
+ s->m.current_picture.linesize[0]= stride;
+ s->m.width= width;
+ s->m.height= height;
+ s->m.mb_width= block_width;
+ s->m.mb_height= block_height;
+ s->m.mb_stride= s->m.mb_width+1;
+ s->m.b8_stride= 2*s->m.mb_width+1;
+ s->m.f_code=1;
+ s->m.pict_type= s->picture.pict_type;
+ s->m.qscale= s->picture.quality/FF_QP2LAMBDA;
+ s->m.me_method= s->avctx->me_method;
+
+ if(!s->motion_val8[plane]){
+ s->motion_val8 [plane]= av_mallocz(s->m.b8_stride*block_height*2*2*sizeof(int16_t));
+ s->motion_val16[plane]= av_mallocz(s->m.mb_stride*block_height*2*sizeof(int16_t));
+ }
+
+ s->m.mb_type= s->mb_type;
+
+ //dummies, to avoid segfaults
+ s->m.current_picture.mb_mean= (uint8_t *)s->dummy;
+ s->m.current_picture.mb_var= (uint16_t*)s->dummy;
+ s->m.current_picture.mc_mb_var= (uint16_t*)s->dummy;
+ s->m.current_picture.mb_type= s->dummy;
+
+ s->m.current_picture.motion_val[0]= s->motion_val8[plane];
+ s->m.p_mv_table= s->motion_val16[plane];
+ s->m.dsp= s->dsp; //move
+ ff_init_me(&s->m);
+
+ s->m.me.dia_size= s->avctx->dia_size;
+ s->m.first_slice_line=1;
+ for (y = 0; y < block_height; y++) {
+ uint8_t src[stride*16];
+
+ s->m.new_picture.data[0]= src - y*16*stride; //ugly
+ s->m.mb_y= y;
+
+ for(i=0; i<16 && i + 16*y<height; i++){
+ memcpy(&src[i*stride], &src_plane[(i+16*y)*src_stride], width);
+ for(x=width; x<16*block_width; x++)
+ src[i*stride+x]= src[i*stride+x-1];
+ }
+ for(; i<16 && i + 16*y<16*block_height; i++)
+ memcpy(&src[i*stride], &src[(i-1)*stride], 16*block_width);
+
+ for (x = 0; x < block_width; x++) {
+ s->m.mb_x= x;
+ ff_init_block_index(&s->m);
+ ff_update_block_index(&s->m);
+
+ ff_estimate_p_frame_motion(&s->m, x, y);
+ }
+ s->m.first_slice_line=0;
+ }
+
+ ff_fix_long_p_mvs(&s->m);
+ ff_fix_long_mvs(&s->m, NULL, 0, s->m.p_mv_table, s->m.f_code, CANDIDATE_MB_TYPE_INTER, 0);
+ }
+
+ s->m.first_slice_line=1;
for (y = 0; y < block_height; y++) {
uint8_t src[stride*16];
@@ -1504,53 +1162,95 @@ av_log(s->avctx, AV_LOG_INFO, "********* frame #%d\n", frame++);
for(; i<16 && i + 16*y<16*block_height; i++)
memcpy(&src[i*stride], &src[(i-1)*stride], 16*block_width);
+ s->m.mb_y= y;
for (x = 0; x < block_width; x++) {
- uint8_t reorder_buffer[2][6][7*32];
- int count[2][6];
+ uint8_t reorder_buffer[3][6][7*32];
+ int count[3][6];
int offset = y * 16 * stride + x * 16;
uint8_t *decoded= decoded_plane + offset;
uint8_t *ref= ref_plane + offset;
- int score[2]={0,0}, best;
+ int score[4]={0,0,0,0}, best;
uint8_t temp[16*stride];
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, "* level 5 vector @ %d, %d:\n", x * 16, y * 16);
-#endif
+ s->m.mb_x= x;
+ ff_init_block_index(&s->m);
+ ff_update_block_index(&s->m);
+
+ if(s->picture.pict_type == I_TYPE || (s->m.mb_type[x + y*s->m.mb_stride]&CANDIDATE_MB_TYPE_INTRA)){
+ for(i=0; i<6; i++){
+ init_put_bits(&s->reorder_pb[i], reorder_buffer[0][i], 7*32);
+ }
+ if(s->picture.pict_type == P_TYPE){
+ const uint8_t *vlc= svq1_block_type_vlc[SVQ1_BLOCK_INTRA];
+ put_bits(&s->reorder_pb[5], vlc[1], vlc[0]);
+ score[0]= vlc[1]*lambda;
+ }
+ score[0]+= encode_block(s, src+16*x, NULL, temp, stride, 5, 64, lambda, 1);
+ for(i=0; i<6; i++){
+ count[0][i]= put_bits_count(&s->reorder_pb[i]);
+ flush_put_bits(&s->reorder_pb[i]);
+ }
+ }else
+ score[0]= INT_MAX;
+
+ best=0;
- for(i=0; i<6; i++){
- init_put_bits(&s->reorder_pb[i], reorder_buffer[0][i], 7*32);
- }
- if(s->picture.pict_type == P_TYPE){
- const uint8_t *vlc= svq1_block_type_vlc[SVQ1_BLOCK_INTRA];
- put_bits(&s->reorder_pb[5], vlc[1], vlc[0]);
- score[0]= vlc[1]*lambda;
- }
- score[0]+= encode_block(s, src+16*x, ref, temp, stride, 5, 64, lambda, 1);
- for(i=0; i<6; i++){
- count[0][i]= put_bits_count(&s->reorder_pb[i]);
- flush_put_bits(&s->reorder_pb[i]);
- init_put_bits(&s->reorder_pb[i], reorder_buffer[1][i], 7*32);
- }
if(s->picture.pict_type == P_TYPE){
const uint8_t *vlc= svq1_block_type_vlc[SVQ1_BLOCK_INTER];
- put_bits(&s->reorder_pb[5], vlc[1], vlc[0]);
- score[1] = vlc[1]*lambda;
- for(i=0; i<2; i++){
- vlc= svq1_motion_component_vlc[32];
+ int mx, my, pred_x, pred_y, dxy;
+ int16_t *motion_ptr;
+
+ motion_ptr= h263_pred_motion(&s->m, 0, 0, &pred_x, &pred_y);
+ if(s->m.mb_type[x + y*s->m.mb_stride]&CANDIDATE_MB_TYPE_INTER){
+ for(i=0; i<6; i++)
+ init_put_bits(&s->reorder_pb[i], reorder_buffer[1][i], 7*32);
+
put_bits(&s->reorder_pb[5], vlc[1], vlc[0]);
- score[1] += vlc[1]*lambda;
+
+ s->m.pb= s->reorder_pb[5];
+ mx= motion_ptr[0];
+ my= motion_ptr[1];
+ assert(mx>=-32 && mx<=31);
+ assert(my>=-32 && my<=31);
+ assert(pred_x>=-32 && pred_x<=31);
+ assert(pred_y>=-32 && pred_y<=31);
+ ff_h263_encode_motion(&s->m, mx - pred_x, 1);
+ ff_h263_encode_motion(&s->m, my - pred_y, 1);
+ s->reorder_pb[5]= s->m.pb;
+ score[1] += lambda*put_bits_count(&s->reorder_pb[5]);
+
+ dxy= (mx&1) + 2*(my&1);
+
+ s->dsp.put_pixels_tab[0][dxy](temp+16, ref + (mx>>1) + stride*(my>>1), stride, 16);
+
+ score[1]+= encode_block(s, src+16*x, temp+16, decoded, stride, 5, 64, lambda, 0);
+ best= score[1] <= score[0];
+
+ vlc= svq1_block_type_vlc[SVQ1_BLOCK_SKIP];
+ score[2]= s->dsp.sse[0](NULL, src+16*x, ref, stride, 16);
+ score[2]+= vlc[1]*lambda;
+ if(score[2] < score[best] && mx==0 && my==0){
+ best=2;
+ s->dsp.put_pixels_tab[0][0](decoded, ref, stride, 16);
+ for(i=0; i<6; i++){
+ count[2][i]=0;
+ }
+ put_bits(&s->pb, vlc[1], vlc[0]);
+ }
}
- score[1]+= encode_block(s, src+16*x, ref, decoded, stride, 5, 64, lambda, 0);
- best= score[1] <= score[0];
if(best==1){
for(i=0; i<6; i++){
count[1][i]= put_bits_count(&s->reorder_pb[i]);
flush_put_bits(&s->reorder_pb[i]);
}
+ }else{
+ motion_ptr[0 ] = motion_ptr[1 ]=
+ motion_ptr[2 ] = motion_ptr[3 ]=
+ motion_ptr[0+2*s->m.b8_stride] = motion_ptr[1+2*s->m.b8_stride]=
+ motion_ptr[2+2*s->m.b8_stride] = motion_ptr[3+2*s->m.b8_stride]=0;
}
- }else
- best= 0;
+ }
s->rd_total += score[best];
@@ -1560,124 +1260,14 @@ av_log(s->avctx, AV_LOG_INFO, "* level 5 vector @ %d, %d:\n", x * 16, y * 16);
if(best==0){
s->dsp.put_pixels_tab[0][0](decoded, temp, stride, 16);
}
-
-#if 0
- for (i = 0; i < 256; i += 16) {
- memcpy(&buffer0[i], &plane[left_edge], 16);
- left_edge += stride;
- }
- current_buffer = 1; /* this will toggle to 0 immediately */
-
- /* perform a breadth-first tree encoding for each vector level */
- subvector_count = 1; /* one subvector at level 5 */
- for (level = 5; level >= 0; level--) {
-
- vector_count = subvector_count;
- subvector_count = 0;
-
- if (current_buffer == 0) {
- current_buffer = 1;
- vector = buffer1;
- subvectors = buffer0;
- } else {
- current_buffer = 0;
- vector = buffer0;
- subvectors = buffer1;
- }
-
- /* iterate through each vector in the list */
- for (i = 0; i < vector_count; i++) {
-
- if (encode_vector(s, vector, level, threshold[level])) {
-
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, " split to level %d\n", level - 1);
-#endif
- /* subdivide into 2 subvectors for later processing */
- subvector_count += 2;
-
- if (level - 1 == 3) {
- /* subdivide 16x8 -> 2 8x8 */
- for (j = 0; j < 8; j++) {
- /* left half */
- memcpy(subvectors + j * 8, vector + j * 16, 8);
- /* right half */
- memcpy(subvectors + 64 + j * 8,
- vector + 8 + j * 16, 8);
- }
- subvectors += 128;
- } else if (level - 1 == 1) {
- /* subdivide 8x4 -> 2 4x4 */
- for (j = 0; j < 4; j++) {
- /* left half */
- memcpy(subvectors + j * 4, vector + j * 8, 4);
- /* right half */
- memcpy(subvectors + 16 + j * 4,
- vector + 4 + j * 8, 4);
- }
- subvectors += 32;
- } else {
- /* first half */
- memcpy(subvectors, vector, level_sizes[level - 1]);
- subvectors += level_sizes[level - 1];
- /* second half */
- memcpy(subvectors, vector + level_sizes[level - 1],
- level_sizes[level - 1]);
- subvectors += level_sizes[level - 1];
- }
- }
-
- vector += level_sizes[level];
- }
-
- /* if there are no more subvectors, break early */
- if (!subvector_count)
- break;
- }
-#endif
}
- }
-}
-
-/* output a plane with a constant mean value; good for debugging and for
- * greyscale encoding but only valid for intra frames */
-static void svq1_output_intra_constant_mean(SVQ1Context *s, int block_width,
- int block_height, unsigned char mean)
-{
- int i;
-
- /* for each level 5 vector, output the specified mean value */
- for (i = 0; i < block_width * block_height; i++) {
-
- /* output a 0 before each vector indicating no subdivision */
- put_bits(&s->pb, 1, 0);
-
- /* output a 0 indicating mean-only encoding; use index 1 as that
- * maps to code 0 */
- put_bits(&s->pb, svq1_intra_multistage_vlc[5][1][1],
- svq1_intra_multistage_vlc[5][1][0]);
-
- /* output a constant mean */
- put_bits(&s->pb, svq1_intra_mean_vlc[mean][1],
- svq1_intra_mean_vlc[mean][0]);
-#ifdef DEBUG_SVQ1
-av_log(s->avctx, AV_LOG_INFO, " const L5 %d/%d: multistage = 0 (0x%X, %d), mean = %d (0x%X, %d)\n",
- i, block_width * block_height,
- svq1_intra_multistage_vlc[5][1][0],
- svq1_intra_multistage_vlc[5][1][1],
- mean,
- svq1_intra_mean_vlc[mean][0],
- svq1_intra_mean_vlc[mean][1]);
-#endif
+ s->m.first_slice_line=0;
}
}
static int svq1_encode_init(AVCodecContext *avctx)
{
SVQ1Context * const s = avctx->priv_data;
- int i;
- unsigned char least_bits_value = 0;
- int least_bits;
dsputil_init(&s->dsp, avctx);
avctx->coded_frame= (AVFrame*)&s->picture;
@@ -1691,27 +1281,19 @@ static int svq1_encode_init(AVCodecContext *avctx)
s->c_block_width = (s->frame_width / 4 + 15) / 16;
s->c_block_height = (s->frame_height / 4 + 15) / 16;
+ s->avctx= avctx;
+ s->m.me.scratchpad= av_mallocz((avctx->width+64)*2*16*2*sizeof(uint8_t));
+ s->m.me.map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t));
+ s->m.me.score_map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t));
+ s->mb_type = av_mallocz((s->y_block_width+1)*s->y_block_height*sizeof(int16_t));
+ s->dummy = av_mallocz((s->y_block_width+1)*s->y_block_height*sizeof(int32_t));
+ h263_encode_init(&s->m); //mv_penalty
+
av_log(s->avctx, AV_LOG_INFO, " Hey: %d x %d, %d x %d, %d x %d\n",
s->frame_width, s->frame_height,
s->y_block_width, s->y_block_height,
s->c_block_width, s->c_block_height);
- /* allocate a plane for the U & V planes (color, or C, planes) and
- * initialize them to the value that is represented by the fewest bits
- * in the mean table; the reasoning behind this is that when the border
- * vectors are operated upon and possibly subdivided, the mean will be
- * removed resulting in a perfect deviation score of 0 and encoded with
- * the minimal possible bits */
- s->c_plane = av_malloc(s->c_block_width * s->c_block_height * 16 * 16);
- least_bits = 10000;
- for (i = 0; i < 256; i++)
- if (svq1_intra_mean_vlc[i][1] < least_bits) {
- least_bits = svq1_intra_mean_vlc[i][1];
- least_bits_value = i;
- }
- memset(s->c_plane, least_bits_value,
- s->c_block_width * s->c_block_height * 16 * 16);
-
return 0;
}
@@ -1746,7 +1328,7 @@ static int svq1_encode_frame(AVCodecContext *avctx, unsigned char *buf,
svq1_write_header(s, p->pict_type);
for(i=0; i<3; i++){
- svq1_encode_plane(s,
+ svq1_encode_plane(s, i,
s->picture.data[i], s->last_picture.data[i], s->current_picture.data[i],
s->frame_width / (i?4:1), s->frame_height / (i?4:1),
s->picture.linesize[i], s->current_picture.linesize[i]);
@@ -1764,10 +1346,20 @@ static int svq1_encode_frame(AVCodecContext *avctx, unsigned char *buf,
static int svq1_encode_end(AVCodecContext *avctx)
{
SVQ1Context * const s = avctx->priv_data;
+ int i;
av_log(avctx, AV_LOG_DEBUG, "RD: %f\n", s->rd_total/(double)(avctx->width*avctx->height*avctx->frame_number));
- av_free(s->c_plane);
+ av_freep(&s->m.me.scratchpad);
+ av_freep(&s->m.me.map);
+ av_freep(&s->m.me.score_map);
+ av_freep(&s->mb_type);
+ av_freep(&s->dummy);
+
+ for(i=0; i<3; i++){
+ av_freep(&s->motion_val8[i]);
+ av_freep(&s->motion_val16[i]);
+ }
return 0;
}
@@ -1783,6 +1375,7 @@ AVCodec svq1_decoder = {
svq1_decode_frame,
CODEC_CAP_DR1,
.flush= ff_mpeg_flush,
+ .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV410P, -1},
};
#ifdef CONFIG_ENCODERS
@@ -1795,6 +1388,7 @@ AVCodec svq1_encoder = {
svq1_encode_init,
svq1_encode_frame,
svq1_encode_end,
+ .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV410P, -1},
};
#endif //CONFIG_ENCODERS
diff --git a/src/libffmpeg/libavcodec/svq1_cb.h b/src/libffmpeg/libavcodec/svq1_cb.h
index 0f766aa88..c6735fe8e 100644
--- a/src/libffmpeg/libavcodec/svq1_cb.h
+++ b/src/libffmpeg/libavcodec/svq1_cb.h
@@ -769,7 +769,7 @@ static const int8_t* const svq1_inter_codebooks[4] = {
svq1_inter_codebook_8x4, svq1_inter_codebook_8x8
};
-static const int8_t const svq1_inter_codebook_sum[4][16*6] = {
+static const int8_t svq1_inter_codebook_sum[4][16*6] = {
{
-1, 1, -2, 0, 1, -1, -1, -1, -2, -1, 1, -1, -1, 0, -1, -1,
0, -1, -1, -1, -1, 0, -1, 0, 0, 0, -3, 1, -1, 0, 1, -1,
@@ -1543,7 +1543,7 @@ static const int8_t* const svq1_intra_codebooks[4] = {
svq1_intra_codebook_8x4, svq1_intra_codebook_8x8
};
-static const int8_t const svq1_intra_codebook_sum[4][16*6] = {
+static const int8_t svq1_intra_codebook_sum[4][16*6] = {
{
0, 0, 0, -1, -1, -1, -1, -2, 0, -1, -1, 0, -1, 0, 1, 0,
1, 0, -1, 1, 0, 0, -1, 1, -1, 0, 0, 0, -1, 1, 0, 0,
diff --git a/src/libffmpeg/libavcodec/svq1_vlc.h b/src/libffmpeg/libavcodec/svq1_vlc.h
index d15ac07fb..8a30acb26 100644
--- a/src/libffmpeg/libavcodec/svq1_vlc.h
+++ b/src/libffmpeg/libavcodec/svq1_vlc.h
@@ -8,28 +8,6 @@ static const uint8_t svq1_block_type_vlc[4][2] = {
};
-/* values in this table range from -32..32; adjust retrieved value by -32 */
-static const uint8_t svq1_motion_component_vlc[65][2] = {
- /* { code, length } */
- { 0x5, 13 }, { 0x7, 13 }, { 0x5, 12 }, { 0x7, 12 },
- { 0x9, 12 }, { 0xB, 12 }, { 0xD, 12 }, { 0xF, 12 },
- { 0x9, 11 }, { 0xB, 11 }, { 0xD, 11 }, { 0xF, 11 },
- { 0x11, 11 }, { 0x13, 11 }, { 0x15, 11 }, { 0x17, 11 },
- { 0x19, 11 }, { 0x1B, 11 }, { 0x1D, 11 }, { 0x1F, 11 },
- { 0x21, 11 }, { 0x23, 11 }, { 0x13, 10 }, { 0x15, 10 },
- { 0x17, 10 }, { 0x7, 8 }, { 0x9, 8 }, { 0xB, 8 },
- { 0x7, 7 }, { 0x3, 5 }, { 0x3, 4 }, { 0x3, 3 },
- { 0x1, 1 }, { 0x2, 3 }, { 0x2, 4 }, { 0x2, 5 },
- { 0x6, 7 }, { 0xA, 8 }, { 0x8, 8 }, { 0x6, 8 },
- { 0x16, 10 }, { 0x14, 10 }, { 0x12, 10 }, { 0x22, 11 },
- { 0x20, 11 }, { 0x1E, 11 }, { 0x1C, 11 }, { 0x1A, 11 },
- { 0x18, 11 }, { 0x16, 11 }, { 0x14, 11 }, { 0x12, 11 },
- { 0x10, 11 }, { 0xE, 11 }, { 0xC, 11 }, { 0xA, 11 },
- { 0x8, 11 }, { 0xE, 12 }, { 0xC, 12 }, { 0xA, 12 },
- { 0x8, 12 }, { 0x6, 12 }, { 0x4, 12 }, { 0x6, 13 },
- { 0x4, 13 }
-};
-
/* values in this table range from -1..6; adjust retrieved value by -1 */
static const uint8_t svq1_intra_multistage_vlc[6][8][2] = {
/* { code, length } */
diff --git a/src/libffmpeg/libavcodec/svq3.c b/src/libffmpeg/libavcodec/svq3.c
index 413cc8963..e064626fc 100644
--- a/src/libffmpeg/libavcodec/svq3.c
+++ b/src/libffmpeg/libavcodec/svq3.c
@@ -769,8 +769,6 @@ static int svq3_decode_frame (AVCodecContext *avctx,
unsigned char *extradata;
unsigned int size;
- *data_size = 0;
-
s->flags = avctx->flags;
s->flags2 = avctx->flags2;
s->unrestricted_mv = 1;
diff --git a/src/libffmpeg/libavcodec/truemotion1.c b/src/libffmpeg/libavcodec/truemotion1.c
index 2f6310192..b742d80be 100644
--- a/src/libffmpeg/libavcodec/truemotion1.c
+++ b/src/libffmpeg/libavcodec/truemotion1.c
@@ -547,8 +547,6 @@ static int truemotion1_decode_frame(AVCodecContext *avctx,
if (buf_size == 0)
return 0;
- *data_size = 0;
-
if (truemotion1_decode_header(s) == -1)
return -1;
diff --git a/src/libffmpeg/libavcodec/utils.c b/src/libffmpeg/libavcodec/utils.c
index ffcefb46b..a45d57de0 100644
--- a/src/libffmpeg/libavcodec/utils.c
+++ b/src/libffmpeg/libavcodec/utils.c
@@ -488,6 +488,7 @@ int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture,
{
int ret;
+ *got_picture_ptr= 0;
ret = avctx->codec->decode(avctx, picture, got_picture_ptr,
buf, buf_size);
@@ -508,6 +509,7 @@ int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples,
{
int ret;
+ *frame_size_ptr= 0;
ret = avctx->codec->decode(avctx, samples, frame_size_ptr,
buf, buf_size);
avctx->frame_number++;
@@ -572,7 +574,7 @@ AVCodec *avcodec_find_decoder_by_name(const char *name)
return NULL;
}
-AVCodec *avcodec_find(enum CodecID id)
+static AVCodec *avcodec_find(enum CodecID id)
{
AVCodec *p;
p = first_avcodec;
@@ -849,11 +851,11 @@ static void av_log_default_callback(void* ptr, int level, const char* fmt, va_li
AVClass* avc= ptr ? *(AVClass**)ptr : NULL;
if(level>av_log_level)
return;
-/* #undef fprintf */
+#undef fprintf
if(print_prefix && avc) {
fprintf(stderr, "[%s @ %p]", avc->item_name(ptr), avc);
}
-/* #define fprintf please_use_av_log */
+#define fprintf please_use_av_log
print_prefix= strstr(fmt, "\n") != NULL;
@@ -890,3 +892,8 @@ void av_log_set_callback(void (*callback)(void*, int, const char*, va_list))
av_log_callback = callback;
}
+#if !defined(HAVE_PTHREADS) && !defined(HAVE_W32THREADS)
+int avcodec_thread_init(AVCodecContext *s, int thread_count){
+ return -1;
+}
+#endif
diff --git a/src/libffmpeg/libavcodec/vcr1.c b/src/libffmpeg/libavcodec/vcr1.c
index 05539452a..9a706af31 100644
--- a/src/libffmpeg/libavcodec/vcr1.c
+++ b/src/libffmpeg/libavcodec/vcr1.c
@@ -45,8 +45,6 @@ static int decode_frame(AVCodecContext *avctx,
uint8_t *bytestream= buf;
int i, x, y;
- *data_size = 0;
-
/* special case for last picture */
if (buf_size == 0) {
return 0;
diff --git a/src/libffmpeg/libavcodec/vmdav.c b/src/libffmpeg/libavcodec/vmdav.c
index c09af1369..c11f80af6 100644
--- a/src/libffmpeg/libavcodec/vmdav.c
+++ b/src/libffmpeg/libavcodec/vmdav.c
@@ -522,7 +522,6 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx,
if (buf_size < 16)
return buf_size;
- *data_size = 0;
if (buf[6] == 1) {
/* the chunk contains audio */
*data_size = vmdaudio_loadsound(s, output_samples, p, 0);
diff --git a/src/libffmpeg/libavcodec/vp3.c b/src/libffmpeg/libavcodec/vp3.c
index 59d183505..5b3f1b926 100644
--- a/src/libffmpeg/libavcodec/vp3.c
+++ b/src/libffmpeg/libavcodec/vp3.c
@@ -2056,7 +2056,7 @@ static void render_fragments(Vp3DecodeContext *s,
unsigned char *last_plane;
unsigned char *golden_plane;
int stride;
- int motion_x, motion_y;
+ int motion_x = 0xdeadbeef, motion_y = 0xdeadbeef;
int upper_motion_limit, lower_motion_limit;
int motion_halfpel_index;
uint8_t *motion_source;
@@ -2474,8 +2474,6 @@ static int vp3_decode_frame(AVCodecContext *avctx,
GetBitContext gb;
static int counter = 0;
- *data_size = 0;
-
init_get_bits(&gb, buf, buf_size * 8);
if (s->theora && get_bits1(&gb))
diff --git a/src/libffmpeg/libavcodec/vp3data.h b/src/libffmpeg/libavcodec/vp3data.h
index a25c9f06e..1dd511fa0 100644
--- a/src/libffmpeg/libavcodec/vp3data.h
+++ b/src/libffmpeg/libavcodec/vp3data.h
@@ -3,7 +3,7 @@
/* these coefficients dequantize intraframe Y plane coefficients
* (note: same as JPEG) */
-static int16_t vp31_intra_y_dequant[64] =
+static const int16_t vp31_intra_y_dequant[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,
@@ -16,7 +16,7 @@ static int16_t vp31_intra_y_dequant[64] =
/* these coefficients dequantize intraframe C plane coefficients
* (note: same as JPEG) */
-static int16_t vp31_intra_c_dequant[64] =
+static const int16_t vp31_intra_c_dequant[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,
@@ -28,7 +28,7 @@ static int16_t vp31_intra_c_dequant[64] =
};
/* these coefficients dequantize interframe coefficients (all planes) */
-static int16_t vp31_inter_dequant[64] =
+static const int16_t vp31_inter_dequant[64] =
{ 16, 16, 16, 20, 24, 28, 32, 40,
16, 16, 20, 24, 28, 32, 40, 48,
16, 20, 24, 28, 32, 40, 48, 64,
@@ -39,7 +39,7 @@ static int16_t vp31_inter_dequant[64] =
40, 48, 64, 64, 64, 96, 128, 128
};
-static int16_t vp31_dc_scale_factor[64] =
+static const int16_t vp31_dc_scale_factor[64] =
{ 220, 200, 190, 180, 170, 170, 160, 160,
150, 150, 140, 140, 130, 130, 120, 120,
110, 110, 100, 100, 90, 90, 90, 80,
@@ -50,7 +50,7 @@ static int16_t vp31_dc_scale_factor[64] =
20, 10, 10, 10, 10, 10, 10, 10
};
-static uint32_t vp31_ac_scale_factor[64] =
+static const uint32_t vp31_ac_scale_factor[64] =
{ 500, 450, 400, 370, 340, 310, 285, 265,
245, 225, 210, 195, 185, 180, 170, 160,
150, 145, 135, 130, 125, 115, 110, 107,
@@ -74,7 +74,7 @@ static const int dezigzag_index[64] =
};
/* inverse of dezigzag index */
-static int zigzag_index[64];
+static __attribute__((unused)) int zigzag_index[64];
static const uint16_t dc_bias[16][32][2] = {
{ /* DC bias table 0 */
diff --git a/src/libffmpeg/libavcodec/vp3dsp.c b/src/libffmpeg/libavcodec/vp3dsp.c
index 3ead73280..9c9530d05 100644
--- a/src/libffmpeg/libavcodec/vp3dsp.c
+++ b/src/libffmpeg/libavcodec/vp3dsp.c
@@ -24,6 +24,7 @@
#include "common.h"
#include "avcodec.h"
+#include "dsputil.h"
#include "vp3data.h"
#define IdctAdjustBeforeShift 8
diff --git a/src/libffmpeg/libavcodec/wmadec.c b/src/libffmpeg/libavcodec/wmadec.c
index 11576b47a..cf2db1494 100644
--- a/src/libffmpeg/libavcodec/wmadec.c
+++ b/src/libffmpeg/libavcodec/wmadec.c
@@ -31,12 +31,6 @@
* should be 4 extra bytes for v1 data and 6 extra bytes for v2 data.
*/
-/* xine: some glibc versions require _ISOC9X_SOURCE for
- * prototyping lrintf(). failure to declare it will result
- * in static noise being produced by wmadec.c.
- */
-#define _ISOC9X_SOURCE 1
-
#include "avcodec.h"
#include "dsputil.h"
diff --git a/src/libffmpeg/libavcodec/wmv2.c b/src/libffmpeg/libavcodec/wmv2.c
index 376f0706e..13a112d1f 100644
--- a/src/libffmpeg/libavcodec/wmv2.c
+++ b/src/libffmpeg/libavcodec/wmv2.c
@@ -59,6 +59,8 @@ static void wmv2_common_init(Wmv2Context * w){
ff_init_scantable(s->dsp.idct_permutation, &w->abt_scantable[1], wmv2_scantableB);
}
+#ifdef CONFIG_ENCODERS
+
static int encode_ext_header(Wmv2Context *w){
MpegEncContext * const s= &w->s;
PutBitContext pb;
@@ -84,7 +86,6 @@ static int encode_ext_header(Wmv2Context *w){
return 0;
}
-#ifdef CONFIG_ENCODERS
static int wmv2_encode_init(AVCodecContext *avctx){
Wmv2Context * const w= avctx->priv_data;
@@ -478,9 +479,6 @@ s->picture_number++; //FIXME ?
return 0;
}
-static void ff_wmv2_decode_init(MpegEncContext *s){
-}
-
static inline int wmv2_decode_motion(Wmv2Context *w, int *mx_ptr, int *my_ptr){
MpegEncContext * const s= &w->s;
int ret;