diff options
author | Michael Roitzsch <mroi@users.sourceforge.net> | 2004-05-30 19:24:17 +0000 |
---|---|---|
committer | Michael Roitzsch <mroi@users.sourceforge.net> | 2004-05-30 19:24:17 +0000 |
commit | df5fbeb013e70f14090cec1998a5f923d6713a1d (patch) | |
tree | de31c29919f53b88f27bdb7add18706b1b51ddcc | |
parent | 26de73d1e48ab23af83e352cdc6e9eac41bf8c3b (diff) | |
download | xine-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
69 files changed, 4576 insertions, 1191 deletions
@@ -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; |