[llvm-commits] CVS: llvm-test/MultiSource/Applications/JM/lencod/Makefile annexb.c annexb.h biariencode.c biariencode.h block.c block.h cabac.c cabac.h configfile.c configfile.h context_ini.c context_ini.h contributors.h ctx_tables.h decoder.c defines.h elements.h epzs.c epzs.h explicit_gop.c explicit_gop.h fast_me.c fast_me.h filehandle.c fmo.c fmo.h global.h header.c header.h image.c image.h intrarefresh.c intrarefresh.h leaky_bucket.c leaky_bucket.h lencod.c loopFilter.c macroblock.c macroblock.h mb_access.c mb_access.h mbuffer.c mbuffer.h memalloc.c memalloc.h minmax.h mode_decision.c mode_decision.h mv-search.c mv-search.h nal.c nalu.c nalu.h nalucommon.c nalucommon.h output.c output.h parset.c parset.h parsetcommon.c parsetcommon.h q_matrix.c q_matrix.h q_offsets.c q_offsets.h ratectl.c ratectl.h rdopt.c rdopt_coding_state.c rdopt_coding_state.h rdpicdecision.c refbuf.c refbuf.h rtp.c rtp.h sei.c sei.h simplified_fast_me.c simplified_fast_me.h slice.c transform8x8.c transfo! rm8x8.h vlc.c vlc.h weighted_prediction.c
Evan Cheng
evan.cheng at apple.com
Sat Feb 11 02:33:43 PST 2006
Changes in directory llvm-test/MultiSource/Applications/JM/lencod:
Makefile added (r1.1)
annexb.c added (r1.1)
annexb.h added (r1.1)
biariencode.c added (r1.1)
biariencode.h added (r1.1)
block.c added (r1.1)
block.h added (r1.1)
cabac.c added (r1.1)
cabac.h added (r1.1)
configfile.c added (r1.1)
configfile.h added (r1.1)
context_ini.c added (r1.1)
context_ini.h added (r1.1)
contributors.h added (r1.1)
ctx_tables.h added (r1.1)
decoder.c added (r1.1)
defines.h added (r1.1)
elements.h added (r1.1)
epzs.c added (r1.1)
epzs.h added (r1.1)
explicit_gop.c added (r1.1)
explicit_gop.h added (r1.1)
fast_me.c added (r1.1)
fast_me.h added (r1.1)
filehandle.c added (r1.1)
fmo.c added (r1.1)
fmo.h added (r1.1)
global.h added (r1.1)
header.c added (r1.1)
header.h added (r1.1)
image.c added (r1.1)
image.h added (r1.1)
intrarefresh.c added (r1.1)
intrarefresh.h added (r1.1)
leaky_bucket.c added (r1.1)
leaky_bucket.h added (r1.1)
lencod.c added (r1.1)
loopFilter.c added (r1.1)
macroblock.c added (r1.1)
macroblock.h added (r1.1)
mb_access.c added (r1.1)
mb_access.h added (r1.1)
mbuffer.c added (r1.1)
mbuffer.h added (r1.1)
memalloc.c added (r1.1)
memalloc.h added (r1.1)
minmax.h added (r1.1)
mode_decision.c added (r1.1)
mode_decision.h added (r1.1)
mv-search.c added (r1.1)
mv-search.h added (r1.1)
nal.c added (r1.1)
nalu.c added (r1.1)
nalu.h added (r1.1)
nalucommon.c added (r1.1)
nalucommon.h added (r1.1)
output.c added (r1.1)
output.h added (r1.1)
parset.c added (r1.1)
parset.h added (r1.1)
parsetcommon.c added (r1.1)
parsetcommon.h added (r1.1)
q_matrix.c added (r1.1)
q_matrix.h added (r1.1)
q_offsets.c added (r1.1)
q_offsets.h added (r1.1)
ratectl.c added (r1.1)
ratectl.h added (r1.1)
rdopt.c added (r1.1)
rdopt_coding_state.c added (r1.1)
rdopt_coding_state.h added (r1.1)
rdpicdecision.c added (r1.1)
refbuf.c added (r1.1)
refbuf.h added (r1.1)
rtp.c added (r1.1)
rtp.h added (r1.1)
sei.c added (r1.1)
sei.h added (r1.1)
simplified_fast_me.c added (r1.1)
simplified_fast_me.h added (r1.1)
slice.c added (r1.1)
transform8x8.c added (r1.1)
transform8x8.h added (r1.1)
vlc.c added (r1.1)
vlc.h added (r1.1)
weighted_prediction.c added (r1.1)
---
Log message:
Added H.264 reference encoder / decoder from ITU to LLVM test suite.
---
Diffs of the changes: (+55883 -0)
Makefile | 8
annexb.c | 117 +
annexb.h | 25
biariencode.c | 342 +++
biariencode.h | 138 +
block.c | 2800 +++++++++++++++++++++++++++++++
block.h | 179 ++
cabac.c | 1503 ++++++++++++++++
cabac.h | 65
configfile.c | 1162 +++++++++++++
configfile.h | 271 +++
context_ini.c | 365 ++++
context_ini.h | 32
contributors.h | 212 ++
ctx_tables.h | 729 ++++++++
decoder.c | 655 +++++++
defines.h | 207 ++
elements.h | 109 +
epzs.c | 2321 ++++++++++++++++++++++++++
epzs.h | 71
explicit_gop.c | 472 +++++
explicit_gop.h | 25
fast_me.c | 914 ++++++++++
fast_me.h | 168 +
filehandle.c | 140 +
fmo.c | 730 ++++++++
fmo.h | 39
global.h | 1430 ++++++++++++++++
header.c | 564 ++++++
header.h | 22
image.c | 2640 +++++++++++++++++++++++++++++
image.h | 34
intrarefresh.c | 136 +
intrarefresh.h | 26
leaky_bucket.c | 296 +++
leaky_bucket.h | 29
lencod.c | 2421 +++++++++++++++++++++++++++
loopFilter.c | 482 +++++
macroblock.c | 4435 ++++++++++++++++++++++++++++++++++++++++++++++++++
macroblock.h | 112 +
mb_access.c | 683 +++++++
mb_access.h | 30
mbuffer.c | 3865 +++++++++++++++++++++++++++++++++++++++++++
mbuffer.h | 193 ++
memalloc.c | 763 ++++++++
memalloc.h | 63
minmax.h | 19
mode_decision.c | 1844 ++++++++++++++++++++
mode_decision.h | 87
mv-search.c | 3873 +++++++++++++++++++++++++++++++++++++++++++
mv-search.h | 76
nal.c | 147 +
nalu.c | 78
nalu.h | 28
nalucommon.c | 72
nalucommon.h | 55
output.c | 468 +++++
output.h | 24
parset.c | 908 ++++++++++
parset.h | 45
parsetcommon.c | 100 +
parsetcommon.h | 194 ++
q_matrix.c | 633 +++++++
q_matrix.h | 40
q_offsets.c | 550 ++++++
q_offsets.h | 28
ratectl.c | 1803 ++++++++++++++++++++
ratectl.h | 146 +
rdopt.c | 3568 ++++++++++++++++++++++++++++++++++++++++
rdopt_coding_state.c | 203 ++
rdopt_coding_state.h | 53
rdpicdecision.c | 64
refbuf.c | 167 +
refbuf.h | 28
rtp.c | 613 ++++++
rtp.h | 72
sei.c | 1644 ++++++++++++++++++
sei.h | 267 +++
simplified_fast_me.c | 825 +++++++++
simplified_fast_me.h | 90 +
slice.c | 1134 ++++++++++++
transform8x8.c | 1801 ++++++++++++++++++++
transform8x8.h | 32
vlc.c | 1265 ++++++++++++++
vlc.h | 52
weighted_prediction.c | 764 ++++++++
86 files changed, 55883 insertions(+)
Index: llvm-test/MultiSource/Applications/JM/lencod/Makefile
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/Makefile:1.1
*** /dev/null Sat Feb 11 04:33:32 2006
--- llvm-test/MultiSource/Applications/JM/lencod/Makefile Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,8 ----
+ LEVEL = ../../../..
+ PROG = lencod
+ CPPFLAGS = -D __USE_LARGEFILE64 -D _FILE_OFFSET_BITS=64
+ LDFLAGS = -lm $(TOOLLINKOPTS)
+
+ RUN_OPTIONS = -d $(PROJ_SRC_DIR)/data/encoder.cfg -p InputFile=$(PROJ_SRC_DIR)/data/foreman_part_qcif.yuv
+
+ include ../../../Makefile.multisrc
Index: llvm-test/MultiSource/Applications/JM/lencod/annexb.c
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/annexb.c:1.1
*** /dev/null Sat Feb 11 04:33:41 2006
--- llvm-test/MultiSource/Applications/JM/lencod/annexb.c Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,117 ----
+
+ /*!
+ *************************************************************************************
+ * \file annexb.c
+ *
+ * \brief
+ * Annex B Byte Stream format NAL Unit writing routines
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Stephan Wenger <stewe at cs.tu-berlin.de>
+ *************************************************************************************
+ */
+
+ #include <stdlib.h>
+ #include <assert.h>
+
+ #include "global.h"
+ #include "nalucommon.h"
+
+ static FILE *f = NULL; // the output file
+
+
+ /*!
+ ********************************************************************************************
+ * \brief
+ * Writes a NALU to the Annex B Byte Stream
+ *
+ * \return
+ * number of bits written
+ *
+ ********************************************************************************************
+ */
+ int WriteAnnexbNALU (NALU_t *n)
+ {
+ int BitsWritten = 0;
+
+ assert (n != NULL);
+ assert (n->forbidden_bit == 0);
+ assert (f != NULL);
+ assert (n->startcodeprefix_len == 3 || n->startcodeprefix_len == 4);
+
+ // printf ("WriteAnnexbNALU: writing %d bytes w/ startcode_len %d\n", n->len+1, n->startcodeprefix_len);
+ if (n->startcodeprefix_len > 3)
+ {
+ putc (0, f);
+ BitsWritten =+ 8;
+ }
+ putc (0, f);
+ putc (0, f);
+ putc (1, f);
+ BitsWritten += 24;
+
+ n->buf[0] =
+ n->forbidden_bit << 7 |
+ n->nal_reference_idc << 5 |
+ n->nal_unit_type;
+
+ // printf ("First Byte %x, nal_ref_idc %x, nal_unit_type %d\n", n->buf[0], n->nal_reference_idc, n->nal_unit_type);
+
+ if (n->len != fwrite (n->buf, 1, n->len, f))
+ {
+ printf ("Fatal: cannot write %d bytes to bitstream file, exit (-1)\n", n->len);
+ exit (-1);
+ }
+ BitsWritten += n->len * 8;
+
+ fflush (f);
+ #if TRACE
+ fprintf (p_trace, "\n\nAnnex B NALU w/ %s startcode, len %d, forbidden_bit %d, nal_reference_idc %d, nal_unit_type %d\n\n",
+ n->startcodeprefix_len == 4?"long":"short", n->len, n->forbidden_bit, n->nal_reference_idc, n->nal_unit_type);
+ fflush (p_trace);
+ #endif
+ return BitsWritten;
+ }
+
+
+ /*!
+ ********************************************************************************************
+ * \brief
+ * Opens the output file for the bytestream
+ *
+ * \param Filename
+ * The filename of the file to be opened
+ *
+ * \return
+ * none. Function terminates the program in case of an error
+ *
+ ********************************************************************************************
+ */
+ void OpenAnnexbFile (char *Filename)
+ {
+ if ((f = fopen (Filename, "wb")) == NULL)
+ {
+ printf ("Fatal: cannot open Annex B bytestream file '%s', exit (-1)\n", Filename);
+ exit (-1);
+ }
+ }
+
+
+ /*!
+ ********************************************************************************************
+ * \brief
+ * Closes the output bit stream file
+ *
+ * \return
+ * none. Funtion trerminates the program in case of an error
+ ********************************************************************************************
+ */
+ void CloseAnnexbFile() {
+ if (fclose (f))
+ {
+ printf ("Fatal: cannot close Annex B bytestream file, exit (-1)\n");
+ exit (-1);
+ }
+ }
+
Index: llvm-test/MultiSource/Applications/JM/lencod/annexb.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/annexb.h:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/annexb.h Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,25 ----
+
+ /*!
+ **************************************************************************************
+ * \file
+ * annexb.h
+ * \brief
+ * Byte stream operations support
+ * This code reflects JVT version xxx
+ * \date 7 December 2002
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Stephan Wenger <stewe at cs.tu-berlin.de>
+ ***************************************************************************************
+ */
+
+ #ifndef _ANNEXB_H_
+ #define _ANNEXB_H_
+
+ #include "nalucommon.h"
+
+ int WriteAnnexbNALU (NALU_t *n);
+ void CloseAnnexbFile();
+ void OpenAnnexbFile (char *Filename);
+
+ #endif //_ANNEXB_H_
Index: llvm-test/MultiSource/Applications/JM/lencod/biariencode.c
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/biariencode.c:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/biariencode.c Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,342 ----
+
+ /*!
+ *************************************************************************************
+ * \file biariencode.c
+ *
+ * \brief
+ * Routines for binary arithmetic encoding
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Detlev Marpe <marpe at hhi.de>
+ * - Gabi Blaettermann <blaetter at hhi.de>
+ *************************************************************************************
+ */
+
+ #include <stdlib.h>
+ #include <stdio.h>
+
+ #include "global.h"
+ #include "biariencode.h"
+
+ int binCount = 0;
+
+ /*!
+ ************************************************************************
+ * Macro for writing bytes of code
+ ***********************************************************************
+ */
+
+ #define put_byte() { \
+ Ecodestrm[(*Ecodestrm_len)++] = Ebuffer; \
+ Ebits_to_go = 8; \
+ while (eep->C > 7) { \
+ eep->C-=8; \
+ eep->E++; \
+ } \
+ }
+
+ #define put_one_bit(b) { \
+ Ebuffer <<= 1; Ebuffer |= (b); \
+ if (--Ebits_to_go == 0) \
+ put_byte(); \
+ }
+
+ #define put_one_bit_plus_outstanding(b) { \
+ put_one_bit(b); \
+ while (Ebits_to_follow > 0) \
+ { \
+ Ebits_to_follow--; \
+ put_one_bit(!(b)); \
+ } \
+ }
+
+ int pic_bin_count;
+
+ void reset_pic_bin_count()
+ {
+ pic_bin_count = 0;
+ }
+
+ int get_pic_bin_count()
+ {
+ return pic_bin_count;
+ }
+
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Allocates memory for the EncodingEnvironment struct
+ ************************************************************************
+ */
+ EncodingEnvironmentPtr arienco_create_encoding_environment()
+ {
+ EncodingEnvironmentPtr eep;
+
+ if ( (eep = (EncodingEnvironmentPtr) calloc(1,sizeof(EncodingEnvironment))) == NULL)
+ no_mem_exit("arienco_create_encoding_environment: eep");
+
+ return eep;
+ }
+
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Frees memory of the EncodingEnvironment struct
+ ************************************************************************
+ */
+ void arienco_delete_encoding_environment(EncodingEnvironmentPtr eep)
+ {
+ if (eep == NULL)
+ {
+ snprintf(errortext, ET_SIZE, "Error freeing eep (NULL pointer)");
+ error (errortext, 200);
+ }
+ else
+ free(eep);
+ }
+
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Initializes the EncodingEnvironment for the arithmetic coder
+ ************************************************************************
+ */
+ void arienco_start_encoding(EncodingEnvironmentPtr eep,
+ unsigned char *code_buffer,
+ int *code_len )
+ {
+ Elow = 0;
+ Ebits_to_follow = 0;
+ Ebuffer = 0;
+ Ebits_to_go = 9; // to swallow first redundant bit
+
+ Ecodestrm = code_buffer;
+ Ecodestrm_len = code_len;
+
+ Erange = HALF-2;
+
+ eep->C = 0;
+ eep->E = 0;
+
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Returns the number of currently written bits
+ ************************************************************************
+ */
+ int arienco_bits_written(EncodingEnvironmentPtr eep)
+ {
+ return (8 * (*Ecodestrm_len) + Ebits_to_follow + 8 - Ebits_to_go);
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Terminates the arithmetic codeword, writes stop bit and stuffing bytes (if any)
+ ************************************************************************
+ */
+ void arienco_done_encoding(EncodingEnvironmentPtr eep)
+ {
+ put_one_bit_plus_outstanding((Elow >> (B_BITS-1)) & 1);
+ put_one_bit((Elow >> (B_BITS-2))&1);
+ put_one_bit(1);
+
+ stats->bit_use_stuffingBits[img->type]+=(8-Ebits_to_go);
+
+ while (Ebits_to_go != 8)
+ put_one_bit(0);
+
+ pic_bin_count += eep->E*8 + eep->C; // no of processed bins
+ }
+
+ extern int cabac_encoding;
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Actually arithmetic encoding of one binary symbol by using
+ * the probability estimate of its associated context model
+ ************************************************************************
+ */
+ void biari_encode_symbol(EncodingEnvironmentPtr eep, signed short symbol, BiContextTypePtr bi_ct )
+ {
+ register unsigned int range = Erange;
+ register unsigned int low = Elow;
+ unsigned int rLPS = rLPS_table_64x4[bi_ct->state][(range>>6) & 3];
+
+ #if (2==TRACE)
+ if (cabac_encoding)
+ fprintf(p_trace, "%d 0x%04x %d %d\n", binCount++, Erange , bi_ct->state, bi_ct->MPS );
+ #endif
+
+ range -= rLPS;
+ bi_ct->count += cabac_encoding;
+
+ /* covers all cases where code does not bother to shift down symbol to be
+ * either 0 or 1, e.g. in some cases for cbp, mb_Type etc the code simply
+ * masks off the bit position and passes in the resulting value */
+ symbol = (symbol != 0);
+
+ if (symbol != bi_ct->MPS)
+ {
+ low += range;
+ range = rLPS;
+
+ if (!bi_ct->state)
+ bi_ct->MPS = bi_ct->MPS ^ 1; // switch LPS if necessary
+ bi_ct->state = AC_next_state_LPS_64[bi_ct->state]; // next state
+ }
+ else
+ bi_ct->state = AC_next_state_MPS_64[bi_ct->state]; // next state
+
+ /* renormalisation */
+ while (range < QUARTER)
+ {
+ if (low >= HALF)
+ {
+ put_one_bit_plus_outstanding(1);
+ low -= HALF;
+ }
+ else if (low < QUARTER)
+ {
+ put_one_bit_plus_outstanding(0);
+ }
+ else
+ {
+ Ebits_to_follow++;
+ low -= QUARTER;
+ }
+ low <<= 1;
+ range <<= 1;
+ }
+ Erange = range;
+ Elow = low;
+ eep->C++;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Arithmetic encoding of one binary symbol assuming
+ * a fixed prob. distribution with p(symbol) = 0.5
+ ************************************************************************
+ */
+ void biari_encode_symbol_eq_prob(EncodingEnvironmentPtr eep, signed short symbol)
+ {
+ register unsigned int low = (Elow<<1);
+
+ #if (2==TRACE)
+ extern int cabac_encoding;
+ if (cabac_encoding)
+ fprintf(p_trace, "%d 0x%04x\n", binCount++, Erange );
+ #endif
+
+ if (symbol != 0)
+ low += Erange;
+
+ /* renormalisation as for biari_encode_symbol;
+ note that low has already been doubled */
+ if (low >= ONE)
+ {
+ put_one_bit_plus_outstanding(1);
+ low -= ONE;
+ }
+ else
+ if (low < HALF)
+ {
+ put_one_bit_plus_outstanding(0);
+ }
+ else
+ {
+ Ebits_to_follow++;
+ low -= HALF;
+ }
+ Elow = low;
+ eep->C++;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Arithmetic encoding for last symbol before termination
+ ************************************************************************
+ */
+ void biari_encode_symbol_final(EncodingEnvironmentPtr eep, signed short symbol)
+ {
+ register unsigned int range = Erange-2;
+ register unsigned int low = Elow;
+
+ #if (2==TRACE)
+ extern int cabac_encoding;
+ if (cabac_encoding)
+ fprintf(p_trace, "%d 0x%04x\n", binCount++, Erange);
+ #endif
+
+ if (symbol) {
+ low += range;
+ range = 2;
+ }
+
+ while (range < QUARTER)
+ {
+ if (low >= HALF)
+ {
+ put_one_bit_plus_outstanding(1);
+ low -= HALF;
+ }
+ else
+ if (low < QUARTER)
+ {
+ put_one_bit_plus_outstanding(0);
+ }
+ else
+ {
+ Ebits_to_follow++;
+ low -= QUARTER;
+ }
+ low <<= 1;
+ range <<= 1;
+ }
+ Erange = range;
+ Elow = low;
+ eep->C++;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Initializes a given context with some pre-defined probability state
+ ************************************************************************
+ */
+ void biari_init_context (BiContextTypePtr ctx, const int* ini)
+ {
+ int pstate;
+
+ pstate = ((ini[0]* max(0, img->qp)) >> 4) + ini[1];
+ pstate = min (max ( 1, pstate), 126);
+
+ if ( pstate >= 64 )
+ {
+ ctx->state = pstate - 64;
+ ctx->MPS = 1;
+ }
+ else
+ {
+ ctx->state = 63 - pstate;
+ ctx->MPS = 0;
+ }
+
+ ctx->count = 0;
+ }
+
Index: llvm-test/MultiSource/Applications/JM/lencod/biariencode.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/biariencode.h:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/biariencode.h Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,138 ----
+
+ /*!
+ ***************************************************************************
+ * \file
+ * biariencode.h
+ *
+ * \brief
+ * Headerfile for binary arithmetic encoding routines
+ *
+ * \author
+ * Detlev Marpe,
+ * Gabi Blaettermann
+ * Copyright (C) 2000 HEINRICH HERTZ INSTITUTE All Rights Reserved.
+ *
+ * \date
+ * 21. Oct 2000
+ **************************************************************************
+ */
+
+
+ #ifndef _BIARIENCOD_H_
+ #define _BIARIENCOD_H_
+
+
+ /************************************************************************
+ * D e f i n i t i o n s
+ ***********************************************************************
+ */
+
+ // some definitions to increase the readability of the source code
+
+ #define Elow (eep->Elow)
+ #define Erange (eep->Erange)
+ #define Ebits_to_follow (eep->Ebits_to_follow)
+ #define Ebuffer (eep->Ebuffer)
+ #define Ebits_to_go (eep->Ebits_to_go)
+ #define Ecodestrm (eep->Ecodestrm)
+ #define Ecodestrm_len (eep->Ecodestrm_len)
+ #define Ecodestrm_laststartcode (eep->Ecodestrm_laststartcode)
+ #define B_BITS 10 // Number of bits to represent the whole coding interval
+ #define ONE (1 << B_BITS)
+ #define HALF (1 << (B_BITS-1))
+ #define QUARTER (1 << (B_BITS-2))
+
+ /* Range table for LPS */
+ const byte rLPS_table_64x4[64][4]=
+ {
+ { 128, 176, 208, 240},
+ { 128, 167, 197, 227},
+ { 128, 158, 187, 216},
+ { 123, 150, 178, 205},
+ { 116, 142, 169, 195},
+ { 111, 135, 160, 185},
+ { 105, 128, 152, 175},
+ { 100, 122, 144, 166},
+ { 95, 116, 137, 158},
+ { 90, 110, 130, 150},
+ { 85, 104, 123, 142},
+ { 81, 99, 117, 135},
+ { 77, 94, 111, 128},
+ { 73, 89, 105, 122},
+ { 69, 85, 100, 116},
+ { 66, 80, 95, 110},
+ { 62, 76, 90, 104},
+ { 59, 72, 86, 99},
+ { 56, 69, 81, 94},
+ { 53, 65, 77, 89},
+ { 51, 62, 73, 85},
+ { 48, 59, 69, 80},
+ { 46, 56, 66, 76},
+ { 43, 53, 63, 72},
+ { 41, 50, 59, 69},
+ { 39, 48, 56, 65},
+ { 37, 45, 54, 62},
+ { 35, 43, 51, 59},
+ { 33, 41, 48, 56},
+ { 32, 39, 46, 53},
+ { 30, 37, 43, 50},
+ { 29, 35, 41, 48},
+ { 27, 33, 39, 45},
+ { 26, 31, 37, 43},
+ { 24, 30, 35, 41},
+ { 23, 28, 33, 39},
+ { 22, 27, 32, 37},
+ { 21, 26, 30, 35},
+ { 20, 24, 29, 33},
+ { 19, 23, 27, 31},
+ { 18, 22, 26, 30},
+ { 17, 21, 25, 28},
+ { 16, 20, 23, 27},
+ { 15, 19, 22, 25},
+ { 14, 18, 21, 24},
+ { 14, 17, 20, 23},
+ { 13, 16, 19, 22},
+ { 12, 15, 18, 21},
+ { 12, 14, 17, 20},
+ { 11, 14, 16, 19},
+ { 11, 13, 15, 18},
+ { 10, 12, 15, 17},
+ { 10, 12, 14, 16},
+ { 9, 11, 13, 15},
+ { 9, 11, 12, 14},
+ { 8, 10, 12, 14},
+ { 8, 9, 11, 13},
+ { 7, 9, 11, 12},
+ { 7, 9, 10, 12},
+ { 7, 8, 10, 11},
+ { 6, 8, 9, 11},
+ { 6, 7, 9, 10},
+ { 6, 7, 8, 9},
+ { 2, 2, 2, 2}
+ };
+
+ const unsigned short AC_next_state_MPS_64[64] =
+ {
+ 1,2,3,4,5,6,7,8,9,10,
+ 11,12,13,14,15,16,17,18,19,20,
+ 21,22,23,24,25,26,27,28,29,30,
+ 31,32,33,34,35,36,37,38,39,40,
+ 41,42,43,44,45,46,47,48,49,50,
+ 51,52,53,54,55,56,57,58,59,60,
+ 61,62,62,63
+ };
+
+ const unsigned short AC_next_state_LPS_64[64] =
+ {
+ 0, 0, 1, 2, 2, 4, 4, 5, 6, 7,
+ 8, 9, 9,11,11,12,13,13,15,15,
+ 16,16,18,18,19,19,21,21,22,22,
+ 23,24,24,25,26,26,27,27,28,29,
+ 29,30,30,30,31,32,32,33,33,33,
+ 34,34,35,35,35,36,36,36,37,37,
+ 37,38,38,63
+ };
+
+
+ #endif // BIARIENCOD_H
+
Index: llvm-test/MultiSource/Applications/JM/lencod/block.c
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/block.c:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/block.c Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,2800 ----
+
+ /*!
+ *************************************************************************************
+ * \file block.c
+ *
+ * \brief
+ * Process one block
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Inge Lille-Langoy <inge.lille-langoy at telenor.com>
+ * - Rickard Sjoberg <rickard.sjoberg at era.ericsson.se>
+ * - Stephan Wenger <stewe at cs.tu-berlin.de>
+ * - Jani Lainema <jani.lainema at nokia.com>
+ * - Detlev Marpe <marpe at hhi.de>
+ * - Thomas Wedi <wedi at tnt.uni-hannover.de>
+ * - Ragip Kurceren <ragip.kurceren at nokia.com>
+ * - Greg Conklin <gregc at real.com>
+ *************************************************************************************
+ */
+
+ #include "contributors.h"
+
+
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <memory.h>
+ #include <string.h>
+ #include <math.h>
+
+ #include "global.h"
+
+ #include "image.h"
+ #include "mb_access.h"
+ #include "block.h"
+ #include "vlc.h"
+
+
+ const int quant_coef[6][4][4] = {
+ {{13107, 8066,13107, 8066},{ 8066, 5243, 8066, 5243},{13107, 8066,13107, 8066},{ 8066, 5243, 8066, 5243}},
+ {{11916, 7490,11916, 7490},{ 7490, 4660, 7490, 4660},{11916, 7490,11916, 7490},{ 7490, 4660, 7490, 4660}},
+ {{10082, 6554,10082, 6554},{ 6554, 4194, 6554, 4194},{10082, 6554,10082, 6554},{ 6554, 4194, 6554, 4194}},
+ {{ 9362, 5825, 9362, 5825},{ 5825, 3647, 5825, 3647},{ 9362, 5825, 9362, 5825},{ 5825, 3647, 5825, 3647}},
+ {{ 8192, 5243, 8192, 5243},{ 5243, 3355, 5243, 3355},{ 8192, 5243, 8192, 5243},{ 5243, 3355, 5243, 3355}},
+ {{ 7282, 4559, 7282, 4559},{ 4559, 2893, 4559, 2893},{ 7282, 4559, 7282, 4559},{ 4559, 2893, 4559, 2893}}
+ };
+
+ const int dequant_coef[6][4][4] = {
+ {{10, 13, 10, 13},{ 13, 16, 13, 16},{10, 13, 10, 13},{ 13, 16, 13, 16}},
+ {{11, 14, 11, 14},{ 14, 18, 14, 18},{11, 14, 11, 14},{ 14, 18, 14, 18}},
+ {{13, 16, 13, 16},{ 16, 20, 16, 20},{13, 16, 13, 16},{ 16, 20, 16, 20}},
+ {{14, 18, 14, 18},{ 18, 23, 18, 23},{14, 18, 14, 18},{ 18, 23, 18, 23}},
+ {{16, 20, 16, 20},{ 20, 25, 20, 25},{16, 20, 16, 20},{ 20, 25, 20, 25}},
+ {{18, 23, 18, 23},{ 23, 29, 23, 29},{18, 23, 18, 23},{ 23, 29, 23, 29}}
+ };
+ static const int A[4][4] = {
+ { 16, 20, 16, 20},
+ { 20, 25, 20, 25},
+ { 16, 20, 16, 20},
+ { 20, 25, 20, 25}
+ };
+
+
+ // Notation for comments regarding prediction and predictors.
+ // The pels of the 4x4 block are labelled a..p. The predictor pels above
+ // are labelled A..H, from the left I..P, and from above left X, as follows:
+ //
+ // X A B C D E F G H
+ // I a b c d
+ // J e f g h
+ // K i j k l
+ // L m n o p
+ //
+
+ // Predictor array index definitions
+ #define P_X (PredPel[0])
+ #define P_A (PredPel[1])
+ #define P_B (PredPel[2])
+ #define P_C (PredPel[3])
+ #define P_D (PredPel[4])
+ #define P_E (PredPel[5])
+ #define P_F (PredPel[6])
+ #define P_G (PredPel[7])
+ #define P_H (PredPel[8])
+ #define P_I (PredPel[9])
+ #define P_J (PredPel[10])
+ #define P_K (PredPel[11])
+ #define P_L (PredPel[12])
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Make intra 4x4 prediction according to all 9 prediction modes.
+ * The routine uses left and upper neighbouring points from
+ * previous coded blocks to do this (if available). Notice that
+ * inaccessible neighbouring points are signalled with a negative
+ * value in the predmode array .
+ *
+ * \par Input:
+ * Starting point of current 4x4 block image posision
+ *
+ * \par Output:
+ * none
+ ************************************************************************
+ */
+ void intrapred_luma(int img_x,int img_y, int *left_available, int *up_available, int *all_available)
+ {
+ int i,j;
+ int s0;
+ int PredPel[13]; // array of predictor pels
+ imgpel **imgY = enc_picture->imgY; // For MB level frame/field coding tools -- set default to imgY
+
+ int ioff = (img_x & 15);
+ int joff = (img_y & 15);
+ int mb_nr=img->current_mb_nr;
+
+ PixelPos pix_a[4];
+ PixelPos pix_b, pix_c, pix_d;
+
+ int block_available_up;
+ int block_available_left;
+ int block_available_up_left;
+ int block_available_up_right;
+
+ for (i=0;i<4;i++)
+ {
+ getNeighbour(mb_nr, ioff -1 , joff +i , 1, &pix_a[i]);
+ }
+
+ getNeighbour(mb_nr, ioff , joff -1 , 1, &pix_b);
+ getNeighbour(mb_nr, ioff +4 , joff -1 , 1, &pix_c);
+ getNeighbour(mb_nr, ioff -1 , joff -1 , 1, &pix_d);
+
+ pix_c.available = pix_c.available && !(((ioff==4)||(ioff==12)) && ((joff==4)||(joff==12)));
+
+ if (input->UseConstrainedIntraPred)
+ {
+ for (i=0, block_available_left=1; i<4;i++)
+ block_available_left &= pix_a[i].available ? img->intra_block[pix_a[i].mb_addr]: 0;
+ block_available_up = pix_b.available ? img->intra_block [pix_b.mb_addr] : 0;
+ block_available_up_right = pix_c.available ? img->intra_block [pix_c.mb_addr] : 0;
+ block_available_up_left = pix_d.available ? img->intra_block [pix_d.mb_addr] : 0;
+ }
+ else
+ {
+ block_available_left = pix_a[0].available;
+ block_available_up = pix_b.available;
+ block_available_up_right = pix_c.available;
+ block_available_up_left = pix_d.available;
+ }
+
+ *left_available = block_available_left;
+ *up_available = block_available_up;
+ *all_available = block_available_up && block_available_left && block_available_up_left;
+
+ i = (img_x & 15);
+ j = (img_y & 15);
+
+ // form predictor pels
+ if (block_available_up)
+ {
+ P_A = imgY[pix_b.pos_y][pix_b.pos_x+0];
+ P_B = imgY[pix_b.pos_y][pix_b.pos_x+1];
+ P_C = imgY[pix_b.pos_y][pix_b.pos_x+2];
+ P_D = imgY[pix_b.pos_y][pix_b.pos_x+3];
+
+ }
+ else
+ {
+ P_A = P_B = P_C = P_D = img->dc_pred_value;
+ }
+
+ if (block_available_up_right)
+ {
+ P_E = imgY[pix_c.pos_y][pix_c.pos_x+0];
+ P_F = imgY[pix_c.pos_y][pix_c.pos_x+1];
+ P_G = imgY[pix_c.pos_y][pix_c.pos_x+2];
+ P_H = imgY[pix_c.pos_y][pix_c.pos_x+3];
+ }
+ else
+ {
+ P_E = P_F = P_G = P_H = P_D;
+ }
+
+ if (block_available_left)
+ {
+ P_I = imgY[pix_a[0].pos_y][pix_a[0].pos_x];
+ P_J = imgY[pix_a[1].pos_y][pix_a[1].pos_x];
+ P_K = imgY[pix_a[2].pos_y][pix_a[2].pos_x];
+ P_L = imgY[pix_a[3].pos_y][pix_a[3].pos_x];
+ }
+ else
+ {
+ P_I = P_J = P_K = P_L = img->dc_pred_value;
+ }
+
+ if (block_available_up_left)
+ {
+ P_X = imgY[pix_d.pos_y][pix_d.pos_x];
+ }
+ else
+ {
+ P_X = img->dc_pred_value;
+ }
+
+ for(i=0;i<9;i++)
+ img->mprr[i][0][0]=-1;
+
+ ///////////////////////////////
+ // make DC prediction
+ ///////////////////////////////
+ s0 = 0;
+ if (block_available_up && block_available_left)
+ {
+ // no edge
+ s0 = (P_A + P_B + P_C + P_D + P_I + P_J + P_K + P_L + 4) >> (BLOCK_SHIFT + 1);
+ }
+ else if (!block_available_up && block_available_left)
+ {
+ // upper edge
+ s0 = (P_I + P_J + P_K + P_L + 2) >> BLOCK_SHIFT;;
+ }
+ else if (block_available_up && !block_available_left)
+ {
+ // left edge
+ s0 = (P_A + P_B + P_C + P_D + 2) >> BLOCK_SHIFT;
+ }
+ else //if (!block_available_up && !block_available_left)
+ {
+ // top left corner, nothing to predict from
+ s0 = img->dc_pred_value;
+ }
+
+ // store DC prediction
+ for (j=0; j < BLOCK_SIZE; j++)
+ {
+ for (i=0; i < BLOCK_SIZE; i++)
+ img->mprr[DC_PRED][j][i] = s0;
+ }
+
+ ///////////////////////////////
+ // make horiz and vert prediction
+ ///////////////////////////////
+
+ for (i=0; i < BLOCK_SIZE; i++)
+ {
+ img->mprr[VERT_PRED][0][i] =
+ img->mprr[VERT_PRED][1][i] =
+ img->mprr[VERT_PRED][2][i] =
+ img->mprr[VERT_PRED][3][i] = (&P_A)[i];
+ img->mprr[HOR_PRED][i][0] =
+ img->mprr[HOR_PRED][i][1] =
+ img->mprr[HOR_PRED][i][2] =
+ img->mprr[HOR_PRED][i][3] = (&P_I)[i];
+ }
+
+ if(!block_available_up)
+ img->mprr[VERT_PRED][0][0]=-1;
+ if(!block_available_left)
+ img->mprr[HOR_PRED][0][0]=-1;
+
+ if (block_available_up)
+ {
+ // Mode DIAG_DOWN_LEFT_PRED
+ img->mprr[DIAG_DOWN_LEFT_PRED][0][0] = (P_A + P_C + 2*(P_B) + 2) >> 2;
+ img->mprr[DIAG_DOWN_LEFT_PRED][0][1] =
+ img->mprr[DIAG_DOWN_LEFT_PRED][1][0] = (P_B + P_D + 2*(P_C) + 2) >> 2;
+ img->mprr[DIAG_DOWN_LEFT_PRED][0][2] =
+ img->mprr[DIAG_DOWN_LEFT_PRED][1][1] =
+ img->mprr[DIAG_DOWN_LEFT_PRED][2][0] = (P_C + P_E + 2*(P_D) + 2) >> 2;
+ img->mprr[DIAG_DOWN_LEFT_PRED][0][3] =
+ img->mprr[DIAG_DOWN_LEFT_PRED][1][2] =
+ img->mprr[DIAG_DOWN_LEFT_PRED][2][1] =
+ img->mprr[DIAG_DOWN_LEFT_PRED][3][0] = (P_D + P_F + 2*(P_E) + 2) >> 2;
+ img->mprr[DIAG_DOWN_LEFT_PRED][1][3] =
+ img->mprr[DIAG_DOWN_LEFT_PRED][2][2] =
+ img->mprr[DIAG_DOWN_LEFT_PRED][3][1] = (P_E + P_G + 2*(P_F) + 2) >> 2;
+ img->mprr[DIAG_DOWN_LEFT_PRED][2][3] =
+ img->mprr[DIAG_DOWN_LEFT_PRED][3][2] = (P_F + P_H + 2*(P_G) + 2) >> 2;
+ img->mprr[DIAG_DOWN_LEFT_PRED][3][3] = (P_G + 3*(P_H) + 2) >> 2;
+
+ // Mode VERT_LEFT_PRED
+ img->mprr[VERT_LEFT_PRED][0][0] = (P_A + P_B + 1) >> 1;
+ img->mprr[VERT_LEFT_PRED][0][1] =
+ img->mprr[VERT_LEFT_PRED][2][0] = (P_B + P_C + 1) >> 1;
+ img->mprr[VERT_LEFT_PRED][0][2] =
+ img->mprr[VERT_LEFT_PRED][2][1] = (P_C + P_D + 1) >> 1;
+ img->mprr[VERT_LEFT_PRED][0][3] =
+ img->mprr[VERT_LEFT_PRED][2][2] = (P_D + P_E + 1) >> 1;
+ img->mprr[VERT_LEFT_PRED][2][3] = (P_E + P_F + 1) >> 1;
+ img->mprr[VERT_LEFT_PRED][1][0] = (P_A + 2*P_B + P_C + 2) >> 2;
+ img->mprr[VERT_LEFT_PRED][1][1] =
+ img->mprr[VERT_LEFT_PRED][3][0] = (P_B + 2*P_C + P_D + 2) >> 2;
+ img->mprr[VERT_LEFT_PRED][1][2] =
+ img->mprr[VERT_LEFT_PRED][3][1] = (P_C + 2*P_D + P_E + 2) >> 2;
+ img->mprr[VERT_LEFT_PRED][1][3] =
+ img->mprr[VERT_LEFT_PRED][3][2] = (P_D + 2*P_E + P_F + 2) >> 2;
+ img->mprr[VERT_LEFT_PRED][3][3] = (P_E + 2*P_F + P_G + 2) >> 2;
+
+ }
+
+ /* Prediction according to 'diagonal' modes */
+ if (block_available_left)
+ {
+ // Mode HOR_UP_PRED
+ img->mprr[HOR_UP_PRED][0][0] = (P_I + P_J + 1) >> 1;
+ img->mprr[HOR_UP_PRED][0][1] = (P_I + 2*P_J + P_K + 2) >> 2;
+ img->mprr[HOR_UP_PRED][0][2] =
+ img->mprr[HOR_UP_PRED][1][0] = (P_J + P_K + 1) >> 1;
+ img->mprr[HOR_UP_PRED][0][3] =
+ img->mprr[HOR_UP_PRED][1][1] = (P_J + 2*P_K + P_L + 2) >> 2;
+ img->mprr[HOR_UP_PRED][1][2] =
+ img->mprr[HOR_UP_PRED][2][0] = (P_K + P_L + 1) >> 1;
+ img->mprr[HOR_UP_PRED][1][3] =
+ img->mprr[HOR_UP_PRED][2][1] = (P_K + 2*P_L + P_L + 2) >> 2;
+ img->mprr[HOR_UP_PRED][3][0] =
+ img->mprr[HOR_UP_PRED][2][2] =
+ img->mprr[HOR_UP_PRED][2][3] =
+ img->mprr[HOR_UP_PRED][3][1] =
+ img->mprr[HOR_UP_PRED][3][2] =
+ img->mprr[HOR_UP_PRED][3][3] = P_L;
+ }
+
+ /* Prediction according to 'diagonal' modes */
+ if (block_available_up && block_available_left && block_available_up_left)
+ {
+ // Mode DIAG_DOWN_RIGHT_PRED
+ img->mprr[DIAG_DOWN_RIGHT_PRED][3][0] = (P_L + 2*P_K + P_J + 2) >> 2;
+ img->mprr[DIAG_DOWN_RIGHT_PRED][2][0] =
+ img->mprr[DIAG_DOWN_RIGHT_PRED][3][1] = (P_K + 2*P_J + P_I + 2) >> 2;
+ img->mprr[DIAG_DOWN_RIGHT_PRED][1][0] =
+ img->mprr[DIAG_DOWN_RIGHT_PRED][2][1] =
+ img->mprr[DIAG_DOWN_RIGHT_PRED][3][2] = (P_J + 2*P_I + P_X + 2) >> 2;
+ img->mprr[DIAG_DOWN_RIGHT_PRED][0][0] =
+ img->mprr[DIAG_DOWN_RIGHT_PRED][1][1] =
+ img->mprr[DIAG_DOWN_RIGHT_PRED][2][2] =
+ img->mprr[DIAG_DOWN_RIGHT_PRED][3][3] = (P_I + 2*P_X + P_A + 2) >> 2;
+ img->mprr[DIAG_DOWN_RIGHT_PRED][0][1] =
+ img->mprr[DIAG_DOWN_RIGHT_PRED][1][2] =
+ img->mprr[DIAG_DOWN_RIGHT_PRED][2][3] = (P_X + 2*P_A + P_B + 2) >> 2;
+ img->mprr[DIAG_DOWN_RIGHT_PRED][0][2] =
+ img->mprr[DIAG_DOWN_RIGHT_PRED][1][3] = (P_A + 2*P_B + P_C + 2) >> 2;
+ img->mprr[DIAG_DOWN_RIGHT_PRED][0][3] = (P_B + 2*P_C + P_D + 2) >> 2;
+
+ // Mode VERT_RIGHT_PRED
+ img->mprr[VERT_RIGHT_PRED][0][0] =
+ img->mprr[VERT_RIGHT_PRED][2][1] = (P_X + P_A + 1) >> 1;
+ img->mprr[VERT_RIGHT_PRED][0][1] =
+ img->mprr[VERT_RIGHT_PRED][2][2] = (P_A + P_B + 1) >> 1;
+ img->mprr[VERT_RIGHT_PRED][0][2] =
+ img->mprr[VERT_RIGHT_PRED][2][3] = (P_B + P_C + 1) >> 1;
+ img->mprr[VERT_RIGHT_PRED][0][3] = (P_C + P_D + 1) >> 1;
+ img->mprr[VERT_RIGHT_PRED][1][0] =
+ img->mprr[VERT_RIGHT_PRED][3][1] = (P_I + 2*P_X + P_A + 2) >> 2;
+ img->mprr[VERT_RIGHT_PRED][1][1] =
+ img->mprr[VERT_RIGHT_PRED][3][2] = (P_X + 2*P_A + P_B + 2) >> 2;
+ img->mprr[VERT_RIGHT_PRED][1][2] =
+ img->mprr[VERT_RIGHT_PRED][3][3] = (P_A + 2*P_B + P_C + 2) >> 2;
+ img->mprr[VERT_RIGHT_PRED][1][3] = (P_B + 2*P_C + P_D + 2) >> 2;
+ img->mprr[VERT_RIGHT_PRED][2][0] = (P_X + 2*P_I + P_J + 2) >> 2;
+ img->mprr[VERT_RIGHT_PRED][3][0] = (P_I + 2*P_J + P_K + 2) >> 2;
+
+ // Mode HOR_DOWN_PRED
+ img->mprr[HOR_DOWN_PRED][0][0] =
+ img->mprr[HOR_DOWN_PRED][1][2] = (P_X + P_I + 1) >> 1;
+ img->mprr[HOR_DOWN_PRED][0][1] =
+ img->mprr[HOR_DOWN_PRED][1][3] = (P_I + 2*P_X + P_A + 2) >> 2;
+ img->mprr[HOR_DOWN_PRED][0][2] = (P_X + 2*P_A + P_B + 2) >> 2;
+ img->mprr[HOR_DOWN_PRED][0][3] = (P_A + 2*P_B + P_C + 2) >> 2;
+ img->mprr[HOR_DOWN_PRED][1][0] =
+ img->mprr[HOR_DOWN_PRED][2][2] = (P_I + P_J + 1) >> 1;
+ img->mprr[HOR_DOWN_PRED][1][1] =
+ img->mprr[HOR_DOWN_PRED][2][3] = (P_X + 2*P_I + P_J + 2) >> 2;
+ img->mprr[HOR_DOWN_PRED][2][0] =
+ img->mprr[HOR_DOWN_PRED][3][2] = (P_J + P_K + 1) >> 1;
+ img->mprr[HOR_DOWN_PRED][2][1] =
+ img->mprr[HOR_DOWN_PRED][3][3] = (P_I + 2*P_J + P_K + 2) >> 2;
+ img->mprr[HOR_DOWN_PRED][3][0] = (P_K + P_L + 1) >> 1;
+ img->mprr[HOR_DOWN_PRED][3][1] = (P_J + 2*P_K + P_L + 2) >> 2;
+ }
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * 16x16 based luma prediction
+ *
+ * \par Input:
+ * Image parameters
+ *
+ * \par Output:
+ * none
+ ************************************************************************
+ */
+ void intrapred_luma_16x16()
+ {
+ int s0=0,s1,s2;
+ imgpel s[2][16];
+ int i,j;
+
+ int ih,iv;
+ int ib,ic,iaa;
+
+ imgpel **imgY_pred = enc_picture->imgY; // For Mb level field/frame coding tools -- default to frame pred
+ int mb_nr = img->current_mb_nr;
+
+ PixelPos up; //!< pixel position p(0,-1)
+ PixelPos left[17]; //!< pixel positions p(-1, -1..15)
+
+ int up_avail, left_avail, left_up_avail;
+
+ for (i=0;i<17;i++)
+ {
+ getNeighbour(mb_nr, -1, i-1, 1, &left[i]);
+ }
+
+ getNeighbour(mb_nr, 0, -1, 1, &up);
+
+ if (!(input->UseConstrainedIntraPred))
+ {
+ up_avail = up.available;
+ left_avail = left[1].available;
+ left_up_avail = left[0].available;
+ }
+ else
+ {
+ up_avail = up.available ? img->intra_block[up.mb_addr] : 0;
+ for (i=1, left_avail=1; i<17;i++)
+ left_avail &= left[i].available ? img->intra_block[left[i].mb_addr]: 0;
+ left_up_avail = left[0].available ? img->intra_block[left[0].mb_addr]: 0;
+ }
+
+ s1=s2=0;
+ // make DC prediction
+ if (up_avail)
+ {
+ for (i=0; i < MB_BLOCK_SIZE; i++)
+ s1 += imgY_pred[up.pos_y][up.pos_x+i]; // sum hor pix
+ }
+
+ if (left_avail)
+ {
+ for (i=0; i < MB_BLOCK_SIZE; i++)
+ s2 += imgY_pred[left[i+1].pos_y][left[i+1].pos_x]; // sum vert pix
+ }
+
+ if (up_avail && left_avail)
+ s0=(s1+s2+16)/(2*MB_BLOCK_SIZE); // no edge
+
+ if (!up_avail && left_avail)
+ s0=(s2+8)/MB_BLOCK_SIZE; // upper edge
+
+ if (up_avail && !left_avail)
+ s0=(s1+8)/MB_BLOCK_SIZE; // left edge
+
+ if (!up_avail && !left_avail)
+ s0=img->dc_pred_value; // top left corner, nothing to predict from
+
+ // vertical prediction
+ if (up_avail)
+ memcpy(s[0], &imgY_pred[up.pos_y][up.pos_x], MB_BLOCK_SIZE * sizeof(imgpel));
+
+ // horizontal prediction
+ if (left_avail)
+ {
+ for (i=0; i < MB_BLOCK_SIZE; i++)
+ s[1][i]=imgY_pred[left[i+1].pos_y][left[i+1].pos_x];
+ }
+
+ for (j=0; j < MB_BLOCK_SIZE; j++)
+ {
+ memcpy(img->mprr_2[VERT_PRED_16][j], s[0], MB_BLOCK_SIZE * sizeof(imgpel)); // store vertical prediction
+ for (i=0; i < MB_BLOCK_SIZE; i++)
+ {
+ img->mprr_2[HOR_PRED_16 ][j][i]=s[1][j]; // store horizontal prediction
+ img->mprr_2[DC_PRED_16 ][j][i]=s0; // store DC prediction
+ }
+ }
+ if (!up_avail || !left_avail || !left_up_avail) // edge
+ return;
+
+ // 16 bit integer plan pred
+
+ ih=0;
+ iv=0;
+ for (i=1;i<9;i++)
+ {
+ if (i<8)
+ ih += i*(imgY_pred[up.pos_y][up.pos_x+7+i] - imgY_pred[up.pos_y][up.pos_x+7-i]);
+ else
+ ih += i*(imgY_pred[up.pos_y][up.pos_x+7+i] - imgY_pred[left[0].pos_y][left[0].pos_x]);
+
+ iv += i*(imgY_pred[left[8+i].pos_y][left[8+i].pos_x] - imgY_pred[left[8-i].pos_y][left[8-i].pos_x]);
+ }
+ ib=(5*ih+32)>>6;
+ ic=(5*iv+32)>>6;
+
+ iaa=16*(imgY_pred[up.pos_y][up.pos_x+15]+imgY_pred[left[16].pos_y][left[16].pos_x]);
+
+ for (j=0;j< MB_BLOCK_SIZE;j++)
+ {
+ for (i=0;i< MB_BLOCK_SIZE;i++)
+ {
+ img->mprr_2[PLANE_16][j][i]=max(0,min((int)img->max_imgpel_value,(iaa+(i-7)*ib +(j-7)*ic + 16)/32));// store plane prediction
+ }
+ }
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * For new intra pred routines
+ *
+ * \par Input:
+ * Image par, 16x16 based intra mode
+ *
+ * \par Output:
+ * none
+ ************************************************************************
+ */
+ int dct_luma_16x16(int new_intra_mode)
+ {
+ //int qp_const;
+ int i,j;
+ int ii,jj;
+ int jdiv, jmod;
+ int M1[16][16];
+ int M4[4][4];
+ int M5[4],M6[4];
+ int M0[4][4][4][4];
+ int run,scan_pos,coeff_ctr,level;
+ int qp_per,qp_rem,q_bits;
+ int ac_coef = 0;
+
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ short is_field_mode = (img->field_picture || ( img->MbaffFrameFlag && currMB->mb_field));
+
+ int b8, b4;
+ int* DCLevel = img->cofDC[0][0];
+ int* DCRun = img->cofDC[0][1];
+ int* ACLevel;
+ int* ACRun;
+ int **levelscale,**leveloffset;
+ int **invlevelscale;
+ Boolean lossless_qpprime = ((currMB->qp + img->bitdepth_luma_qp_scale)==0 && img->lossless_qpprime_flag==1);
+
+ qp_per = (currMB->qp + img->bitdepth_luma_qp_scale - MIN_QP)/6;
+ qp_rem = (currMB->qp + img->bitdepth_luma_qp_scale - MIN_QP)%6;
+ q_bits = Q_BITS+qp_per;
+ levelscale = LevelScale4x4Luma[1][qp_rem];
+ leveloffset = LevelOffset4x4Luma[1][qp_per];
+ invlevelscale = InvLevelScale4x4Luma[1][qp_rem];
+
+
+ for (j=0;j<16;j++)
+ {
+ jdiv = j >> 2;
+ jmod = j & 0x03;
+ jj = img->opix_y+j;
+ for (i=0;i<16;i++)
+ {
+ // Residue Color Transform
+ if(!img->residue_transform_flag)
+ M1[j][i]=imgY_org[jj][img->opix_x+i]-img->mprr_2[new_intra_mode][j][i];
+ else
+ M1[j][i]=img->m7[j][i];
+
+ M0[jdiv][i >> 2][jmod][i & 0x03]=M1[j][i];
+ }
+ }
+
+ for (jj=0;jj<4 && !lossless_qpprime;jj++)
+ {
+ for (ii=0;ii<4;ii++)
+ {
+ for (j=0;j<4;j++)
+ {
+ M5[0] = M0[jj][ii][j][0] + M0[jj][ii][j][3];
+ M5[1] = M0[jj][ii][j][1] + M0[jj][ii][j][2];
+ M5[2] = M0[jj][ii][j][1] - M0[jj][ii][j][2];
+ M5[3] = M0[jj][ii][j][0] - M0[jj][ii][j][3];
+
+ M4[j][0] = M5[0] + M5[1];
+ M4[j][2] = M5[0] - M5[1];
+ M4[j][1] = M5[3]*2 + M5[2];
+ M4[j][3] = M5[3] - M5[2]*2;
+ }
+ // vertical
+ for (i=0;i<4;i++)
+ {
+ M5[0] = M4[0][i] + M4[3][i];
+ M5[1] = M4[1][i] + M4[2][i];
+ M5[2] = M4[1][i] - M4[2][i];
+ M5[3] = M4[0][i] - M4[3][i];
+
+ M0[jj][ii][0][i] = M5[0] + M5[1];
+ M0[jj][ii][2][i] = M5[0] - M5[1];
+ M0[jj][ii][1][i] = M5[3]*2 + M5[2];
+ M0[jj][ii][3][i] = M5[3] - M5[2]*2;
+ }
+ }
+ }
+
+ // pick out DC coeff
+
+ for (j=0;j<4;j++)
+ {
+ for (i=0;i<4;i++)
+ M4[j][i]= M0[j][i][0][0];
+ }
+
+ if (!lossless_qpprime)
+ {
+ for (j=0;j<4;j++)
+ {
+ M5[0] = M4[j][0]+M4[j][3];
+ M5[1] = M4[j][1]+M4[j][2];
+ M5[2] = M4[j][1]-M4[j][2];
+ M5[3] = M4[j][0]-M4[j][3];
+
+ M4[j][0] = M5[0]+M5[1];
+ M4[j][2] = M5[0]-M5[1];
+ M4[j][1] = M5[3]+M5[2];
+ M4[j][3] = M5[3]-M5[2];
+ }
+
+ // vertical
+
+ for (i=0;i<4;i++)
+ {
+ M5[0] = M4[0][i]+M4[3][i];
+ M5[1] = M4[1][i]+M4[2][i];
+ M5[2] = M4[1][i]-M4[2][i];
+ M5[3] = M4[0][i]-M4[3][i];
+
+ M4[0][i]=(M5[0]+M5[1])>>1;
+ M4[2][i]=(M5[0]-M5[1])>>1;
+ M4[1][i]=(M5[3]+M5[2])>>1;
+ M4[3][i]=(M5[3]-M5[2])>>1;
+ }
+ }
+ // quant
+
+ run=-1;
+ scan_pos=0;
+
+ for (coeff_ctr=0;coeff_ctr<16;coeff_ctr++)
+ {
+ if (is_field_mode)
+ { // Alternate scan for field coding
+ i=FIELD_SCAN[coeff_ctr][0];
+ j=FIELD_SCAN[coeff_ctr][1];
+ }
+ else
+ {
+ i=SNGL_SCAN[coeff_ctr][0];
+ j=SNGL_SCAN[coeff_ctr][1];
+ }
+
+ run++;
+
+ if(lossless_qpprime)
+ level= absm(M4[j][i]);
+ else
+ level= (absm(M4[j][i]) * levelscale[0][0] + (leveloffset[0][0]<<1)) >> (q_bits+1);
+
+ if (input->symbol_mode == UVLC && img->qp < 10)
+ {
+ if (level > CAVLC_LEVEL_LIMIT)
+ level = CAVLC_LEVEL_LIMIT;
+ }
+
+ if (level != 0)
+ {
+ DCLevel[scan_pos] = sign(level,M4[j][i]);
+ DCRun [scan_pos] = run;
+ ++scan_pos;
+ run=-1;
+ }
+ if(!lossless_qpprime)
+ M4[j][i]=sign(level,M4[j][i]);
+ }
+ DCLevel[scan_pos]=0;
+
+ // invers DC transform
+ for (j=0;j<4 && !lossless_qpprime;j++)
+ {
+ M6[0]=M4[j][0]+M4[j][2];
+ M6[1]=M4[j][0]-M4[j][2];
+ M6[2]=M4[j][1]-M4[j][3];
+ M6[3]=M4[j][1]+M4[j][3];
+
+ M4[j][0] = M6[0]+M6[3];
+ M4[j][1] = M6[1]+M6[2];
+ M4[j][2] = M6[1]-M6[2];
+ M4[j][3] = M6[0]-M6[3];
+ }
+
+ for (i=0;i<4 && !lossless_qpprime;i++)
+ {
+
+ M6[0]=M4[0][i]+M4[2][i];
+ M6[1]=M4[0][i]-M4[2][i];
+ M6[2]=M4[1][i]-M4[3][i];
+ M6[3]=M4[1][i]+M4[3][i];
+
+ if(qp_per<6)
+ {
+ M0[0][i][0][0] = ((M6[0]+M6[3])*invlevelscale[0][0]+(1<<(5-qp_per)))>>(6-qp_per);
+ M0[1][i][0][0] = ((M6[1]+M6[2])*invlevelscale[0][0]+(1<<(5-qp_per)))>>(6-qp_per);
+ M0[2][i][0][0] = ((M6[1]-M6[2])*invlevelscale[0][0]+(1<<(5-qp_per)))>>(6-qp_per);
+ M0[3][i][0][0] = ((M6[0]-M6[3])*invlevelscale[0][0]+(1<<(5-qp_per)))>>(6-qp_per);
+ }
+ else
+ {
+ M0[0][i][0][0] = ((M6[0]+M6[3])*invlevelscale[0][0])<<(qp_per-6);
+ M0[1][i][0][0] = ((M6[1]+M6[2])*invlevelscale[0][0])<<(qp_per-6);
+ M0[2][i][0][0] = ((M6[1]-M6[2])*invlevelscale[0][0])<<(qp_per-6);
+ M0[3][i][0][0] = ((M6[0]-M6[3])*invlevelscale[0][0])<<(qp_per-6);
+ }
+ }
+
+ // AC inverse trans/quant for MB
+ for (jj=0;jj<4;jj++)
+ {
+ for (ii=0;ii<4;ii++)
+ {
+ for (j=0;j<4;j++)
+ {
+ memcpy(M4[j],M0[jj][ii][j], BLOCK_SIZE * sizeof(int));
+ }
+
+ run = -1;
+ scan_pos = 0;
+ b8 = 2*(jj >> 1) + (ii >> 1);
+ b4 = 2*(jj & 0x01) + (ii & 0x01);
+ ACLevel = img->cofAC [b8][b4][0];
+ ACRun = img->cofAC [b8][b4][1];
+
+ for (coeff_ctr=1;coeff_ctr<16;coeff_ctr++) // set in AC coeff
+ {
+
+ if (is_field_mode)
+ { // Alternate scan for field coding
+ i=FIELD_SCAN[coeff_ctr][0];
+ j=FIELD_SCAN[coeff_ctr][1];
+ }
+ else
+ {
+ i=SNGL_SCAN[coeff_ctr][0];
+ j=SNGL_SCAN[coeff_ctr][1];
+ }
+ run++;
+
+ if(lossless_qpprime)
+ level= absm( M4[j][i]);
+ else
+ level= ( absm( M4[j][i]) * levelscale[i][j] + leveloffset[i][j]) >> q_bits;
+
+ if (img->AdaptiveRounding)
+ {
+ if (lossless_qpprime || level == 0 )
+ {
+ img->fadjust4x4[2][jj*BLOCK_SIZE+j][ii*BLOCK_SIZE+i] = 0;
+ }
+ else
+ {
+ img->fadjust4x4[2][jj*BLOCK_SIZE+j][ii*BLOCK_SIZE+i] =
+ (AdaptRndWeight * (absm(M4[j][i]) * levelscale[i][j] - (level << q_bits)) + (1<< (q_bits))) >> (q_bits + 1);
+ }
+ }
+
+ if (level != 0)
+ {
+ ac_coef = 15;
+ ACLevel[scan_pos] = sign(level,M4[j][i]);
+ ACRun [scan_pos] = run;
+ ++scan_pos;
+ run=-1;
+ }
+
+ if(!lossless_qpprime)
+ {
+ level=sign(level, M4[j][i]);
+ if(qp_per<4)
+ M4[j][i]=(level*invlevelscale[i][j]+(1<<(3-qp_per)))>>(4-qp_per);
+ else
+ M4[j][i]=(level*invlevelscale[i][j])<<(qp_per-4);
+ }
+ }
+ ACLevel[scan_pos] = 0;
+
+
+ // IDCT horizontal
+ for (j=0;j<4 && !lossless_qpprime;j++)
+ {
+ M6[0] = M4[j][0] + M4[j][2];
+ M6[1] = M4[j][0] - M4[j][2];
+ M6[2] =(M4[j][1]>>1) - M4[j][3];
+ M6[3] = M4[j][1] + (M4[j][3]>>1);
+
+ M4[j][0] = M6[0] + M6[3];
+ M4[j][1] = M6[1] + M6[2];
+ M4[j][2] = M6[1] - M6[2];
+ M4[j][3] = M6[0] - M6[3];
+ }
+
+ // vert
+ for (i=0;i<4 && !lossless_qpprime;i++)
+ {
+ M6[0]= M4[0][i] + M4[2][i];
+ M6[1]= M4[0][i] - M4[2][i];
+ M6[2]=(M4[1][i]>>1) - M4[3][i];
+ M6[3]= M4[1][i] + (M4[3][i]>>1);
+
+ M0[jj][ii][0][i] = M6[0] + M6[3];
+ M0[jj][ii][1][i] = M6[1] + M6[2];
+ M0[jj][ii][2][i] = M6[1] - M6[2];
+ M0[jj][ii][3][i] = M6[0] - M6[3];
+ }
+ }
+ }
+
+ // Residue Color Transform
+ if(!img->residue_transform_flag)
+ {
+ for (jj=0;jj<BLOCK_MULTIPLE; jj++)
+ for (ii=0;ii<BLOCK_MULTIPLE; ii++)
+ for (j=0;j<BLOCK_SIZE;j++)
+ {
+ memcpy(&M1[jj*BLOCK_SIZE + j][ii*BLOCK_SIZE], M0[jj][ii][j], BLOCK_SIZE * sizeof(int));
+ }
+ }
+ else
+ {
+ if(lossless_qpprime)
+ {
+ for (j=0;j<MB_BLOCK_SIZE;j++)
+ {
+ jdiv = j >> 2;
+ jmod = j & 0x03;
+ for (i=0;i<MB_BLOCK_SIZE;i++)
+ img->m7[j][i]=M0[jdiv][i >> 2][jmod][i & 0x03];
+ }
+ }
+ else
+ {
+ for (j=0;j<MB_BLOCK_SIZE;j++)
+ {
+ jdiv = j >> 2;
+ jmod = j & 0x03;
+ for (i=0;i<MB_BLOCK_SIZE;i++)
+ img->m7[j][i]=((M0[jdiv][i >> 2][jmod][i & 0x03]+DQ_ROUND)>>DQ_BITS);
+ }
+ }
+ }
+
+ if(!img->residue_transform_flag)
+ {
+ if(lossless_qpprime)
+ {
+ for (j=0;j<16;j++)
+ {
+ jj = img->pix_y+j;
+ for (i=0;i<16;i++)
+ enc_picture->imgY[jj][img->pix_x+i]=(imgpel)(M1[j][i]+img->mprr_2[new_intra_mode][j][i]);
+ }
+ }
+ else
+ {
+ for (j=0;j<16;j++)
+ {
+ jj = img->pix_y+j;
+ for (i=0;i<16;i++)
+ enc_picture->imgY[jj][img->pix_x+i]=(imgpel)clip1a((M1[j][i]+((long)img->mprr_2[new_intra_mode][j][i]<<DQ_BITS)+DQ_ROUND)>>DQ_BITS);
+ }
+ }
+ }
+ return ac_coef;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * The routine performs transform,quantization,inverse transform, adds the diff.
+ * to the prediction and writes the result to the decoded luma frame. Includes the
+ * RD constrained quantization also.
+ *
+ * \par Input:
+ * block_x,block_y: Block position inside a macro block (0,4,8,12).
+ *
+ * \par Output_
+ * nonzero: 0 if no levels are nonzero. 1 if there are nonzero levels. \n
+ * coeff_cost: Counter for nonzero coefficients, used to discard expensive levels.
+ ************************************************************************
+ */
+ int dct_luma(int block_x,int block_y,int *coeff_cost, int intra)
+ {
+ int sign(int a,int b);
+
+ int i,j,ilev, m4[4][4], m5[4],m6[4],coeff_ctr;
+ int ii;
+ //int qp_const;
+ int level,scan_pos,run;
+ int nonzero;
+ int qp_per,qp_rem,q_bits;
+
+ int pos_x = block_x >> BLOCK_SHIFT;
+ int pos_y = block_y >> BLOCK_SHIFT;
+ int b8 = 2*(pos_y >> 1) + (pos_x >> 1);
+ int b4 = 2*(pos_y & 0x01) + (pos_x & 0x01);
+ int* ACLevel = img->cofAC[b8][b4][0];
+ int* ACRun = img->cofAC[b8][b4][1];
+ short pix_y;
+
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ short is_field_mode = (img->field_picture || ( img->MbaffFrameFlag && currMB->mb_field));
+
+ Boolean lossless_qpprime = ((currMB->qp + img->bitdepth_luma_qp_scale)==0 && img->lossless_qpprime_flag==1);
+ int **levelscale,**leveloffset;
+ int **invlevelscale;
+
+ qp_per = (currMB->qp + img->bitdepth_luma_qp_scale - MIN_QP)/6;
+ qp_rem = (currMB->qp + img->bitdepth_luma_qp_scale - MIN_QP)%6;
+ q_bits = Q_BITS+qp_per;
+
+ levelscale = LevelScale4x4Luma[intra][qp_rem];
+ leveloffset = LevelOffset4x4Luma[intra][qp_per];
+ invlevelscale = InvLevelScale4x4Luma[intra][qp_rem];
+
+ // Horizontal transform
+ if (!lossless_qpprime)
+ {
+ for (j=0; j < BLOCK_SIZE; j++)
+ {
+ m5[0] = img->m7[j][0]+img->m7[j][3];
+ m5[1] = img->m7[j][1]+img->m7[j][2];
+ m5[2] = img->m7[j][1]-img->m7[j][2];
+ m5[3] = img->m7[j][0]-img->m7[j][3];
+
+ m4[j][0] = m5[0] + m5[1];
+ m4[j][2] = m5[0] - m5[1];
+ m4[j][1] = m5[3]*2 + m5[2];
+ m4[j][3] = m5[3] - m5[2]*2;
+ }
+
+ // Vertical transform
+ for (i=0; i < BLOCK_SIZE; i++)
+ {
+ m5[0] = m4[0][i] + m4[3][i];
+ m5[1] = m4[1][i] + m4[2][i];
+ m5[2] = m4[1][i] - m4[2][i];
+ m5[3] = m4[0][i] - m4[3][i];
+
+ m4[0][i] = m5[0] + m5[1];
+ m4[2][i] = m5[0] - m5[1];
+ m4[1][i] = m5[3]*2 + m5[2];
+ m4[3][i] = m5[3] - m5[2]*2;
+ }
+ }
+ // Quant
+
+ nonzero=FALSE;
+
+ run=-1;
+ scan_pos=0;
+
+ for (coeff_ctr=0;coeff_ctr < 16;coeff_ctr++)
+ {
+
+ if (is_field_mode)
+ {
+ // Alternate scan for field coding
+ i=FIELD_SCAN[coeff_ctr][0];
+ j=FIELD_SCAN[coeff_ctr][1];
+ }
+ else
+ {
+ i=SNGL_SCAN[coeff_ctr][0];
+ j=SNGL_SCAN[coeff_ctr][1];
+ }
+
+ run++;
+ ilev=0;
+
+ if(lossless_qpprime)
+ level = absm (img->m7[j][i]);
+ else
+ level = (absm (m4[j][i]) * levelscale[i][j] + leveloffset[i][j]) >> q_bits;
+
+ if (img->AdaptiveRounding)
+ {
+ if (lossless_qpprime || level == 0 )
+ {
+ img->fadjust4x4[intra][block_y+j][block_x+i] = 0;
+ }
+ else
+ {
+ img->fadjust4x4[intra][block_y+j][block_x+i] =
+ (AdaptRndWeight * (absm(m4[j][i]) * levelscale[i][j] - (level << q_bits)) + (1<< (q_bits))) >> (q_bits + 1);
+ }
+ }
+
+ if (level != 0)
+ {
+ nonzero=TRUE;
+
+ *coeff_cost += (level > 1 || lossless_qpprime) ? MAX_VALUE : COEFF_COST[input->disthres][run];
+
+ if(lossless_qpprime)
+ ACLevel[scan_pos] = sign(level,img->m7[j][i]);
+ else
+ ACLevel[scan_pos] = sign(level,m4[j][i]);
+
+ ACRun [scan_pos] = run;
+ ++scan_pos;
+ run=-1; // reset zero level counter
+
+ level=sign(level, m4[j][i]);
+
+ if(lossless_qpprime)
+ {
+ ilev=level;
+ }
+ else if(qp_per<4)
+ {
+ ilev=(level*invlevelscale[i][j]+(1<<(3-qp_per)))>>(4-qp_per);
+ }
+ else
+ {
+ ilev=(level*invlevelscale[i][j])<<(qp_per-4);
+ }
+ }
+ if(!lossless_qpprime)
+ m4[j][i]=ilev;
+ }
+
+ ACLevel[scan_pos] = 0;
+
+ // IDCT.
+ // horizontal
+
+ if (!lossless_qpprime)
+ {
+ for (j=0; j < BLOCK_SIZE; j++)
+ {
+ m6[0]=(m4[j][0] + m4[j][2]);
+ m6[1]=(m4[j][0] - m4[j][2]);
+ m6[2]=(m4[j][1]>>1) - m4[j][3];
+ m6[3]= m4[j][1] + (m4[j][3]>>1);
+
+ m4[j][0] = m6[0] + m6[3];
+ m4[j][1] = m6[1] + m6[2];
+ m4[j][2] = m6[1] - m6[2];
+ m4[j][3] = m6[0] - m6[3];
+ }
+
+ // vertical
+ for (i=0; i < BLOCK_SIZE; i++)
+ {
+
+ m6[0]=(m4[0][i] + m4[2][i]);
+ m6[1]=(m4[0][i] - m4[2][i]);
+ m6[2]=(m4[1][i]>>1) - m4[3][i];
+ m6[3]= m4[1][i] + (m4[3][i]>>1);
+
+ ii = i + block_x;
+
+ if (!img->residue_transform_flag)
+ {
+ img->m7[0][i] = min(img->max_imgpel_value,max(0,(m6[0]+m6[3]+((long)img->mpr[0 + block_y][ii] << DQ_BITS)+DQ_ROUND)>>DQ_BITS));
+ img->m7[1][i] = min(img->max_imgpel_value,max(0,(m6[1]+m6[2]+((long)img->mpr[1 + block_y][ii] << DQ_BITS)+DQ_ROUND)>>DQ_BITS));
+ img->m7[2][i] = min(img->max_imgpel_value,max(0,(m6[1]-m6[2]+((long)img->mpr[2 + block_y][ii] << DQ_BITS)+DQ_ROUND)>>DQ_BITS));
+ img->m7[3][i] = min(img->max_imgpel_value,max(0,(m6[0]-m6[3]+((long)img->mpr[3 + block_y][ii] << DQ_BITS)+DQ_ROUND)>>DQ_BITS));
+ }
+ else
+ {
+ if(lossless_qpprime)
+ {
+ img->m7[0][i] = m6[0]+m6[3];
+ img->m7[1][i] = m6[1]+m6[2];
+ img->m7[2][i] = m6[1]-m6[2];
+ img->m7[3][i] = m6[0]-m6[3];
+ }
+ else
+ {
+ img->m7[0][i] =(m6[0]+m6[3]+DQ_ROUND)>>DQ_BITS;
+ img->m7[1][i] =(m6[1]+m6[2]+DQ_ROUND)>>DQ_BITS;
+ img->m7[2][i] =(m6[1]-m6[2]+DQ_ROUND)>>DQ_BITS;
+ img->m7[3][i] =(m6[0]-m6[3]+DQ_ROUND)>>DQ_BITS;
+ }
+ }
+ }
+ }
+ // Decoded block moved to frame memory
+ if (!img->residue_transform_flag)
+ {
+ if(lossless_qpprime)
+ {
+ for (j=0; j < BLOCK_SIZE; j++)
+ {
+ pix_y = img->pix_y+block_y+j;
+ for (i=0; i < BLOCK_SIZE; i++)
+ {
+ enc_picture->imgY[pix_y][img->pix_x+block_x+i]=img->m7[j][i]+img->mpr[j+block_y][i+block_x];
+ }
+ }
+ }
+ else
+ {
+ for (j=0; j < BLOCK_SIZE; j++)
+ {
+ pix_y = img->pix_y+block_y+j;
+ for (i=0; i < BLOCK_SIZE; i++)
+ {
+ enc_picture->imgY[pix_y][img->pix_x+block_x+i]=img->m7[j][i];
+ }
+ }
+ }
+
+ }
+ return nonzero;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Transform,quantization,inverse transform for chroma.
+ * The main reason why this is done in a separate routine is the
+ * additional 2x2 transform of DC-coeffs. This routine is called
+ * ones for each of the chroma components.
+ *
+ * \par Input:
+ * uv : Make difference between the U and V chroma component \n
+ * cr_cbp: chroma coded block pattern
+ *
+ * \par Output:
+ * cr_cbp: Updated chroma coded block pattern.
+ ************************************************************************
+ */
+ int dct_chroma(int uv,int cr_cbp)
+ {
+ int i,j,i1,j2,ilev,n2,n1,j1,mb_y,coeff_ctr,level ,scan_pos,run;
+ int m1[BLOCK_SIZE],m5[BLOCK_SIZE],m6[BLOCK_SIZE];
+ int coeff_cost;
+ int cr_cbp_tmp;
+ int DCcoded=0 ;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+
+ int qp_per,qp_rem,q_bits;
+ int qp_c;
+
+ int b4;
+ int* DCLevel = img->cofDC[uv+1][0];
+ int* DCRun = img->cofDC[uv+1][1];
+ int* ACLevel;
+ int* ACRun;
+ int intra = IS_INTRA (currMB);
+ int uv_scale = uv*(img->num_blk8x8_uv >> 1);
+
+ //FRExt
+ int64 cbpblk_pattern[4]={0, 0xf0000, 0xff0000, 0xffff0000};
+ int yuv = img->yuv_format;
+ int b8;
+ int m3[4][4];
+ int m4[4][4];
+ int qp_per_dc = 0;
+ int qp_rem_dc = 0;
+ int q_bits_422 = 0;
+ int ***levelscale, ***leveloffset;
+ int ***invlevelscale;
+ short pix_c_x, pix_c_y;
+ short is_field_mode = (img->field_picture || ( img->MbaffFrameFlag && currMB->mb_field));
+
+ Boolean lossless_qpprime = ((currMB->qp + img->bitdepth_luma_qp_scale)==0 && img->lossless_qpprime_flag==1);
+
+ qp_c = currMB->qp + img->chroma_qp_offset[uv];
+ qp_c = Clip3(-img->bitdepth_chroma_qp_scale,51,qp_c);
+ qp_c = (qp_c < 0)? qp_c : QP_SCALE_CR[qp_c - MIN_QP];
+
+ qp_per = (qp_c + img->bitdepth_chroma_qp_scale)/6;
+ qp_rem = (qp_c + img->bitdepth_chroma_qp_scale)%6;
+ q_bits = Q_BITS+qp_per;
+
+ levelscale = LevelScale4x4Chroma[uv][intra];
+ leveloffset = LevelOffset4x4Chroma[uv][intra];
+ invlevelscale = InvLevelScale4x4Chroma[uv][intra];
+
+ if (img->yuv_format == YUV422)
+ {
+ //for YUV422 only
+ qp_per_dc = (qp_c + 3 + img->bitdepth_chroma_qp_scale)/6;
+ qp_rem_dc = (qp_c + 3 + img->bitdepth_chroma_qp_scale)%6;
+
+ q_bits_422 = Q_BITS+qp_per_dc;
+ }
+
+
+ //============= dct transform ===============
+ for (n2=0; n2 < img->mb_cr_size_y; n2 += BLOCK_SIZE)
+ {
+ for (n1=0; n1 < img->mb_cr_size_x; n1 += BLOCK_SIZE)
+ {
+
+ // Horizontal transform.
+ for (j=0; j < BLOCK_SIZE && !lossless_qpprime; j++)
+ {
+ mb_y=n2+j;
+
+ m5[0]=img->m7[mb_y][n1 ]+img->m7[mb_y][n1+3];
+ m5[1]=img->m7[mb_y][n1+1]+img->m7[mb_y][n1+2];
+ m5[2]=img->m7[mb_y][n1+1]-img->m7[mb_y][n1+2];
+ m5[3]=img->m7[mb_y][n1 ]-img->m7[mb_y][n1+3];
+
+ img->m7[mb_y][n1 ] = (m5[0] + m5[1]);
+ img->m7[mb_y][n1+2] = (m5[0] - m5[1]);
+ img->m7[mb_y][n1+1] = m5[3]*2 + m5[2];
+ img->m7[mb_y][n1+3] = m5[3] - m5[2]*2;
+ }
+
+ // Vertical transform.
+
+ for (i=0; i < BLOCK_SIZE && !lossless_qpprime; i++)
+ {
+ j1=n1+i;
+ m5[0] = img->m7[n2 ][j1] + img->m7[n2+3][j1];
+ m5[1] = img->m7[n2+1][j1] + img->m7[n2+2][j1];
+ m5[2] = img->m7[n2+1][j1] - img->m7[n2+2][j1];
+ m5[3] = img->m7[n2 ][j1] - img->m7[n2+3][j1];
+
+ img->m7[n2+0][j1] = (m5[0] + m5[1]);
+ img->m7[n2+2][j1] = (m5[0] - m5[1]);
+ img->m7[n2+1][j1] = m5[3]*2 + m5[2];
+ img->m7[n2+3][j1] = m5[3] - m5[2]*2;
+ }
+ }
+ }
+
+ if (yuv == YUV420)
+ {
+ //================== CHROMA DC YUV420 ===================
+ // 2X2 transform of DC coeffs.
+ if(lossless_qpprime)
+ {
+ m1[0]=img->m7[0][0];
+ m1[1]=img->m7[0][4];
+ m1[2]=img->m7[4][0];
+ m1[3]=img->m7[4][4];
+ }
+ else
+ {
+ m1[0]=(img->m7[0][0] + img->m7[0][4] + img->m7[4][0] + img->m7[4][4]);
+ m1[1]=(img->m7[0][0] - img->m7[0][4] + img->m7[4][0] - img->m7[4][4]);
+ m1[2]=(img->m7[0][0] + img->m7[0][4] - img->m7[4][0] - img->m7[4][4]);
+ m1[3]=(img->m7[0][0] - img->m7[0][4] - img->m7[4][0] + img->m7[4][4]);
+ }
+
+ // Quant of chroma 2X2 coeffs.
+ run=-1;
+ scan_pos=0;
+
+ for (coeff_ctr=0; coeff_ctr < 4; coeff_ctr++)
+ {
+ run++;
+ ilev=0;
+
+ if(lossless_qpprime)
+ level =absm(m1[coeff_ctr]);
+ else
+ level =(absm(m1[coeff_ctr]) * levelscale[qp_rem][0][0] + (leveloffset[qp_per][0][0]<<1)) >> (q_bits+1);
+
+ if (input->symbol_mode == UVLC && img->qp < 4)
+ {
+ if (level > CAVLC_LEVEL_LIMIT)
+ level = CAVLC_LEVEL_LIMIT;
+ }
+
+ if (level != 0)
+ {
+ currMB->cbp_blk |= 0xf0000 << (uv << 2) ; // if one of the 2x2-DC levels is != 0 set the
+ cr_cbp=max(1,cr_cbp); // coded-bit all 4 4x4 blocks (bit 16-19 or 20-23)
+ DCcoded = 1 ;
+ DCLevel[scan_pos] = sign(level ,m1[coeff_ctr]);
+ DCRun [scan_pos] = run;
+ scan_pos++;
+ run=-1;
+
+ ilev=sign(level, m1[coeff_ctr]);
+ }
+ if(!lossless_qpprime)
+ m1[coeff_ctr]=ilev;
+ }
+ DCLevel[scan_pos] = 0;
+
+ // Inverse transform of 2x2 DC levels
+ if(!lossless_qpprime)
+ {
+ m5[0]=(m1[0] + m1[1] + m1[2] + m1[3]);
+ m5[1]=(m1[0] - m1[1] + m1[2] - m1[3]);
+ m5[2]=(m1[0] + m1[1] - m1[2] - m1[3]);
+ m5[3]=(m1[0] - m1[1] - m1[2] + m1[3]);
+ if(qp_per<5)
+ {
+ for(i=0; i<4; i++)
+ m1[i]=(m5[i] * invlevelscale[qp_rem][0][0])>>(5-qp_per);
+ }
+ else
+ {
+ for(i=0; i<4; i++)
+ m1[i]=(m5[i] * invlevelscale[qp_rem][0][0])<<(qp_per-5);
+ }
+
+ img->m7[0][0] = m1[0];
+ img->m7[0][4] = m1[1];
+ img->m7[4][0] = m1[2];
+ img->m7[4][4] = m1[3];
+ }
+ }
+ else if(yuv == YUV422)
+ {
+ //================== CHROMA DC YUV422 ===================
+ //transform DC coeff
+ //horizontal
+
+ //pick out DC coeff
+ for (j=0; j < img->mb_cr_size_y; j+=BLOCK_SIZE)
+ {
+ for (i=0; i < img->mb_cr_size_x; i+=BLOCK_SIZE)
+ m3[i>>2][j>>2]= img->m7[j][i];
+ }
+ //horizontal
+ if(!lossless_qpprime)
+ {
+ m4[0][0] = m3[0][0] + m3[1][0];
+ m4[0][1] = m3[0][1] + m3[1][1];
+ m4[0][2] = m3[0][2] + m3[1][2];
+ m4[0][3] = m3[0][3] + m3[1][3];
+
+ m4[1][0] = m3[0][0] - m3[1][0];
+ m4[1][1] = m3[0][1] - m3[1][1];
+ m4[1][2] = m3[0][2] - m3[1][2];
+ m4[1][3] = m3[0][3] - m3[1][3];
+
+ // vertical
+ for (i=0;i<2;i++)
+ {
+ m5[0] = m4[i][0] + m4[i][3];
+ m5[1] = m4[i][1] + m4[i][2];
+ m5[2] = m4[i][1] - m4[i][2];
+ m5[3] = m4[i][0] - m4[i][3];
+
+ m4[i][0] = (m5[0] + m5[1]);
+ m4[i][2] = (m5[0] - m5[1]);
+ m4[i][1] = (m5[3] + m5[2]);
+ m4[i][3] = (m5[3] - m5[2]);
+ }
+ }
+
+ run=-1;
+ scan_pos=0;
+
+ //quant of chroma DC-coeffs
+ for (coeff_ctr=0;coeff_ctr<8;coeff_ctr++)
+ {
+ i=SCAN_YUV422[coeff_ctr][0];
+ j=SCAN_YUV422[coeff_ctr][1];
+
+ run++;
+
+ if(lossless_qpprime)
+ {
+ level = absm(m3[i][j]);
+ m4[i][j]=m3[i][j];
+ }
+ else
+ level =(absm(m4[i][j]) * levelscale[qp_rem_dc][0][0] + (leveloffset[qp_per_dc][0][0]*2)) >> (q_bits_422+1);
+
+ if (level != 0)
+ {
+ //YUV422
+ currMB->cbp_blk |= 0xff0000 << (uv << 3) ; // if one of the DC levels is != 0 set the
+ cr_cbp=max(1,cr_cbp); // coded-bit all 4 4x4 blocks (bit 16-31 or 32-47) //YUV444
+ DCcoded = 1 ;
+
+ DCLevel[scan_pos] = sign(level,m4[i][j]);
+ DCRun [scan_pos] = run;
+ ++scan_pos;
+ run=-1;
+ }
+ if(!lossless_qpprime)
+ m3[i][j]=sign(level,m4[i][j]);
+ }
+ DCLevel[scan_pos]=0;
+
+ //inverse DC transform
+ //horizontal
+ if(!lossless_qpprime)
+ {
+ m4[0][0] = m3[0][0] + m3[1][0];
+ m4[0][1] = m3[0][1] + m3[1][1];
+ m4[0][2] = m3[0][2] + m3[1][2];
+ m4[0][3] = m3[0][3] + m3[1][3];
+
+ m4[1][0] = m3[0][0] - m3[1][0];
+ m4[1][1] = m3[0][1] - m3[1][1];
+ m4[1][2] = m3[0][2] - m3[1][2];
+ m4[1][3] = m3[0][3] - m3[1][3];
+
+ // vertical
+ for (i=0;i<2;i++)
+ {
+ m6[0]=m4[i][0]+m4[i][2];
+ m6[1]=m4[i][0]-m4[i][2];
+ m6[2]=m4[i][1]-m4[i][3];
+ m6[3]=m4[i][1]+m4[i][3];
+
+ if(qp_per_dc<4)
+ {
+ img->m7[0 ][i*4]=((((m6[0]+m6[3])*invlevelscale[qp_rem_dc][0][0]+(1<<(3-qp_per_dc)))>>(4-qp_per_dc))+2)>>2;
+ img->m7[4 ][i*4]=((((m6[1]+m6[2])*invlevelscale[qp_rem_dc][0][0]+(1<<(3-qp_per_dc)))>>(4-qp_per_dc))+2)>>2;
+ img->m7[8 ][i*4]=((((m6[1]-m6[2])*invlevelscale[qp_rem_dc][0][0]+(1<<(3-qp_per_dc)))>>(4-qp_per_dc))+2)>>2;
+ img->m7[12][i*4]=((((m6[0]-m6[3])*invlevelscale[qp_rem_dc][0][0]+(1<<(3-qp_per_dc)))>>(4-qp_per_dc))+2)>>2;
+ }
+ else
+ {
+ img->m7[0 ][i*4]=((((m6[0]+m6[3])*invlevelscale[qp_rem_dc][0][0])<<(qp_per_dc-4))+2)>>2;
+ img->m7[4 ][i*4]=((((m6[1]+m6[2])*invlevelscale[qp_rem_dc][0][0])<<(qp_per_dc-4))+2)>>2;
+ img->m7[8 ][i*4]=((((m6[1]-m6[2])*invlevelscale[qp_rem_dc][0][0])<<(qp_per_dc-4))+2)>>2;
+ img->m7[12][i*4]=((((m6[0]-m6[3])*invlevelscale[qp_rem_dc][0][0])<<(qp_per_dc-4))+2)>>2;
+ }
+ }//for (i=0;i<2;i++)
+ }
+ }
+ else if(yuv == YUV444)
+ {
+ //================== CHROMA DC YUV444 ===================
+ //transform DC coeff
+ //pick out DC coeff
+ for (j=0; j < img->mb_cr_size_y; j+=BLOCK_SIZE)
+ {
+ for (i=0; i < img->mb_cr_size_x; i+=BLOCK_SIZE)
+ m4[i>>2][j>>2]= img->m7[j][i];
+ }
+
+ //horizontal
+ for (j=0;j<4 && !lossless_qpprime;j++)
+ {
+ m5[0] = m4[0][j] + m4[3][j];
+ m5[1] = m4[1][j] + m4[2][j];
+ m5[2] = m4[1][j] - m4[2][j];
+ m5[3] = m4[0][j] - m4[3][j];
+
+ m4[0][j]=m5[0]+m5[1];
+ m4[2][j]=m5[0]-m5[1];
+ m4[1][j]=m5[3]+m5[2];
+ m4[3][j]=m5[3]-m5[2];
+ }
+ // vertical
+ for (i=0;i<4 && !lossless_qpprime;i++)
+ {
+ m5[0] = m4[i][0] + m4[i][3];
+ m5[1] = m4[i][1] + m4[i][2];
+ m5[2] = m4[i][1] - m4[i][2];
+ m5[3] = m4[i][0] - m4[i][3];
+
+ m4[i][0]=(m5[0]+m5[1])>>1;
+ m4[i][2]=(m5[0]-m5[1])>>1;
+ m4[i][1]=(m5[3]+m5[2])>>1;
+ m4[i][3]=(m5[3]-m5[2])>>1;
+ }
+
+ run=-1;
+ scan_pos=0;
+
+ //quant of chroma DC-coeffs
+ for (coeff_ctr=0;coeff_ctr<16;coeff_ctr++)
+ {
+ i=SNGL_SCAN[coeff_ctr][0];
+ j=SNGL_SCAN[coeff_ctr][1];
+
+ run++;
+
+ if(lossless_qpprime)
+ level = absm(m4[i][j]);
+ else
+ level =(absm(m4[i][j]) * levelscale[qp_rem][0][0] + (leveloffset[qp_per][0][0]*2)) >> (q_bits+1);
+
+ if (level != 0)
+ {
+ //YUV444
+ currMB->cbp_blk |= ((int64)0xffff0000) << (uv << 4) ; // if one of the DC levels is != 0 set the
+ cr_cbp=max(1,cr_cbp); // coded-bit all 4 4x4 blocks (bit 16-31 or 32-47) //YUV444
+ DCcoded = 1 ;
+
+ DCLevel[scan_pos] = sign(level,m4[i][j]);
+ DCRun [scan_pos] = run;
+ ++scan_pos;
+ run=-1;
+ }
+ if(!lossless_qpprime)
+ m4[i][j]=sign(level,m4[i][j]);
+ }
+ DCLevel[scan_pos]=0;
+
+ // inverse DC transform
+ //horizontal
+ for (j=0;j<4 && !lossless_qpprime;j++)
+ {
+ m6[0] = m4[0][j] + m4[2][j];
+ m6[1] = m4[0][j] - m4[2][j];
+ m6[2] = m4[1][j] - m4[3][j];
+ m6[3] = m4[1][j] + m4[3][j];
+
+ m4[0][j] = m6[0] + m6[3];
+ m4[1][j] = m6[1] + m6[2];
+ m4[2][j] = m6[1] - m6[2];
+ m4[3][j] = m6[0] - m6[3];
+ }
+
+ //vertical
+ for (i=0;i<4 && !lossless_qpprime;i++)
+ {
+ m6[0]=m4[i][0]+m4[i][2];
+ m6[1]=m4[i][0]-m4[i][2];
+ m6[2]=m4[i][1]-m4[i][3];
+ m6[3]=m4[i][1]+m4[i][3];
+
+ if(qp_per<4)
+ {
+ img->m7[0 ][i*4] = ((((m6[0] + m6[3])*invlevelscale[qp_rem][0][0]+(1<<(3-qp_per)))>>(4-qp_per))+2)>>2;
+ img->m7[4 ][i*4] = ((((m6[1] + m6[2])*invlevelscale[qp_rem][0][0]+(1<<(3-qp_per)))>>(4-qp_per))+2)>>2;
+ img->m7[8 ][i*4] = ((((m6[1] - m6[2])*invlevelscale[qp_rem][0][0]+(1<<(3-qp_per)))>>(4-qp_per))+2)>>2;
+ img->m7[12][i*4] = ((((m6[0] - m6[3])*invlevelscale[qp_rem][0][0]+(1<<(3-qp_per)))>>(4-qp_per))+2)>>2;
+ }
+ else
+ {
+ img->m7[0 ][i*4] = ((((m6[0]+m6[3])*invlevelscale[qp_rem][0][0])<<(qp_per-4))+2)>>2;
+ img->m7[4 ][i*4] = ((((m6[1]+m6[2])*invlevelscale[qp_rem][0][0])<<(qp_per-4))+2)>>2;
+ img->m7[8 ][i*4] = ((((m6[1]-m6[2])*invlevelscale[qp_rem][0][0])<<(qp_per-4))+2)>>2;
+ img->m7[12][i*4] = ((((m6[0]-m6[3])*invlevelscale[qp_rem][0][0])<<(qp_per-4))+2)>>2;
+ }
+ }
+ }
+
+ // Quant of chroma AC-coeffs.
+ coeff_cost=0;
+ cr_cbp_tmp=0;
+
+ for (b8=0; b8 < (img->num_blk8x8_uv >> 1); b8++)
+ {
+ for (b4=0; b4 < 4; b4++)
+ {
+ n1 = hor_offset[yuv][b8][b4];
+ n2 = ver_offset[yuv][b8][b4];
+ ACLevel = img->cofAC[4+b8+uv_scale][b4][0];
+ ACRun = img->cofAC[4+b8+uv_scale][b4][1];
+ run=-1;
+ scan_pos=0;
+
+ for (coeff_ctr=1; coeff_ctr < 16; coeff_ctr++)// start change rd_quant
+ {
+
+ if (is_field_mode)
+ { // Alternate scan for field coding
+ i=FIELD_SCAN[coeff_ctr][0];
+ j=FIELD_SCAN[coeff_ctr][1];
+ }
+ else
+ {
+ i=SNGL_SCAN[coeff_ctr][0];
+ j=SNGL_SCAN[coeff_ctr][1];
+ }
+ ++run;
+ ilev=0;
+
+ if(lossless_qpprime)
+ level = absm(img->m7[n2+j][n1+i]);
+ else
+ level=(absm(img->m7[n2+j][n1+i])*levelscale[qp_rem][i][j]+leveloffset[qp_per][i][j])>>q_bits;
+
+ if (img->AdaptiveRounding)
+ {
+ if (lossless_qpprime || level == 0 )
+ {
+ img->fadjust4x4Cr[intra][uv][n2+j][n1+i] = 0;
+ }
+ else
+ {
+ img->fadjust4x4Cr[intra][uv][n2+j][n1+i] =
+ (AdaptRndWeight * (absm(img->m7[n2+j][n1+i]) * levelscale[qp_rem][i][j] - (level << q_bits)) + (1<< (q_bits))) >> (q_bits + 1);
+ }
+ }
+
+ if (level != 0)
+ {
+ currMB->cbp_blk |= ((int64)1) << cbp_blk_chroma[b8 + uv_scale][b4];
+ if (level > 1 || lossless_qpprime)
+ coeff_cost += MAX_VALUE; // set high cost, shall not be discarded
+ else
+ coeff_cost += COEFF_COST[input->disthres][run];
+
+ cr_cbp_tmp=2;
+ ACLevel[scan_pos] = sign(level,img->m7[n2+j][n1+i]);
+ ACRun [scan_pos] = run;
+ ++scan_pos;
+ run=-1;
+
+ level=sign(level, img->m7[n2+j][n1+i]);
+ if(lossless_qpprime)
+ {
+ ilev = level;
+ }
+ else if(qp_per<4)
+ {
+ ilev=(level*invlevelscale[qp_rem][i][j]+(1<<(3-qp_per)))>>(4-qp_per);
+ }
+ else
+ {
+ ilev=(level*invlevelscale[qp_rem][i][j])<<(qp_per-4);
+ }
+ }
+ if(!lossless_qpprime)
+ img->m7[n2+j][n1+i]=ilev;
+ }
+ ACLevel[scan_pos] = 0;
+ }
+ }
+
+ // * reset chroma coeffs
+ if(coeff_cost < _CHROMA_COEFF_COST_ && !lossless_qpprime)
+ {
+ cr_cbp_tmp = 0 ;
+
+ for (b8=0; b8 < (img->num_blk8x8_uv >> 1); b8++)
+ {
+ for (b4=0; b4 < 4; b4++)
+ {
+ n1 = hor_offset[yuv][b8][b4];
+ n2 = ver_offset[yuv][b8][b4];
+ ACLevel = img->cofAC[4+b8+uv_scale][b4][0];
+ ACRun = img->cofAC[4+b8+uv_scale][b4][1];
+ if( DCcoded == 0)
+ currMB->cbp_blk &= ~((int64)cbpblk_pattern[yuv] << (uv << (1+yuv))); // if no chroma DC's: then reset coded-bits of this chroma subblock
+
+ ACLevel[0] = 0;
+ for (coeff_ctr=1; coeff_ctr < 16; coeff_ctr++)// ac coeff
+ {
+
+ if (is_field_mode)
+ { // Alternate scan for field coding
+ i=FIELD_SCAN[coeff_ctr][0];
+ j=FIELD_SCAN[coeff_ctr][1];
+ }
+ else
+ {
+ i=SNGL_SCAN[coeff_ctr][0];
+ j=SNGL_SCAN[coeff_ctr][1];
+ }
+ img->m7[n2+j][n1+i]=0;
+ ACLevel[coeff_ctr] = 0;
+ }
+ }
+ }
+ }
+
+ if(cr_cbp_tmp==2)
+ cr_cbp = 2;
+
+ // IDCT.
+ // Horizontal.
+ for (n2=0; n2 < img->mb_cr_size_y && !lossless_qpprime; n2 += BLOCK_SIZE)
+ {
+ for (n1=0; n1 < img->mb_cr_size_x; n1 += BLOCK_SIZE)
+ {
+ for (j=0; j < BLOCK_SIZE; j++)
+ {
+ j2 = n2 + j;
+ for (i=0; i < BLOCK_SIZE; i++)
+ {
+ m5[i]=img->m7[j2][n1+i];
+ }
+
+ m6[0] = (m5[0] + m5[2]);
+ m6[1] = (m5[0] - m5[2]);
+ m6[2] = (m5[1]>>1) - m5[3];
+ m6[3] = m5[1] + (m5[3]>>1);
+
+ img->m7[j2][n1 ] = m6[0] + m6[3];
+ img->m7[j2][n1+1] = m6[1] + m6[2];
+ img->m7[j2][n1+2] = m6[1] - m6[2];
+ img->m7[j2][n1+3] = m6[0] - m6[3];
+ }
+
+ // Vertical.
+ for (i=0; i < BLOCK_SIZE && !lossless_qpprime; i++)
+ {
+ i1 = n1 + i;
+ for (j=0; j < BLOCK_SIZE; j++)
+ {
+ m5[j]=img->m7[n2+j][i1];
+ }
+ m6[0]=(m5[0]+m5[2]);
+ m6[1]=(m5[0]-m5[2]);
+ m6[2]=(m5[1]>>1)-m5[3];
+ m6[3]=m5[1]+(m5[3]>>1);
+
+ // Residue Color Transform
+ if (!img->residue_transform_flag)
+ {
+ img->m7[n2 ][i1] = min(img->max_imgpel_value_uv,max(0,(m6[0]+m6[3]+((long)img->mpr[n2 ][i1] << DQ_BITS)+DQ_ROUND)>>DQ_BITS));
+ img->m7[n2+1][i1] = min(img->max_imgpel_value_uv,max(0,(m6[1]+m6[2]+((long)img->mpr[n2+1][i1] << DQ_BITS)+DQ_ROUND)>>DQ_BITS));
+ img->m7[n2+2][i1] = min(img->max_imgpel_value_uv,max(0,(m6[1]-m6[2]+((long)img->mpr[n2+2][i1] << DQ_BITS)+DQ_ROUND)>>DQ_BITS));
+ img->m7[n2+3][i1] = min(img->max_imgpel_value_uv,max(0,(m6[0]-m6[3]+((long)img->mpr[n2+3][i1] << DQ_BITS)+DQ_ROUND)>>DQ_BITS));
+ }
+ else
+ {
+ if(lossless_qpprime)
+ {
+ img->m7[n2 ][i1] = m6[0]+m6[3];
+ img->m7[n2+1][i1] = m6[1]+m6[2];
+ img->m7[n2+2][i1] = m6[1]-m6[2];
+ img->m7[n2+3][i1] = m6[0]-m6[3];
+ }
+ else
+ {
+ img->m7[n2 ][i1] = (m6[0]+m6[3]+DQ_ROUND)>>DQ_BITS;
+ img->m7[n2+1][i1] = (m6[1]+m6[2]+DQ_ROUND)>>DQ_BITS;
+ img->m7[n2+2][i1] = (m6[1]-m6[2]+DQ_ROUND)>>DQ_BITS;
+ img->m7[n2+3][i1] = (m6[0]-m6[3]+DQ_ROUND)>>DQ_BITS;
+ }
+ }
+ }
+ }
+ }
+
+ // Decoded block moved to memory
+ if (!img->residue_transform_flag)
+ {
+ for (j=0; j < img->mb_cr_size_y; j++)
+ {
+ pix_c_y = img->pix_c_y+j;
+ for (i=0; i < img->mb_cr_size_x; i++)
+ {
+ pix_c_x = img->pix_c_x+i;
+ if(lossless_qpprime)
+ enc_picture->imgUV[uv][pix_c_y][pix_c_x]= img->m7[j][i]+img->mpr[j][i];
+ else
+ enc_picture->imgUV[uv][pix_c_y][pix_c_x]= img->m7[j][i];
+ }
+ }
+ }
+ return cr_cbp;
+ }
+
+
+ // Residue Color Transform
+ int dct_chroma4x4(int uv, int b8, int b4)
+ {
+ int sign(int a,int b);
+
+ int i,j,i1,j1,ilev,m5[4],m6[4],coeff_ctr;
+ int level,scan_pos,run;
+ int nonzeroAC;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ int intra = IS_INTRA (currMB);
+
+ int qp_per,qp_rem,q_bits;
+ int qp_c;
+
+ int* ACLevel = img->cofAC[b8][b4][0];
+ int* ACRun = img->cofAC[b8][b4][1];
+
+ int **levelscale, **leveloffset;
+ int **invlevelscale;
+
+ Boolean lossless_qpprime = ((img->qp + img->bitdepth_luma_qp_scale)==0 && img->lossless_qpprime_flag==1);
+
+ qp_c = currMB->qp + img->chroma_qp_offset[uv];
+ qp_c = (qp_c < 0)? qp_c : QP_SCALE_CR[qp_c - MIN_QP];
+
+ qp_per = (qp_c + img->bitdepth_chroma_qp_scale)/6;
+ qp_rem = (qp_c + img->bitdepth_chroma_qp_scale)%6;
+ q_bits = Q_BITS+qp_per;
+
+ levelscale = LevelScale4x4Chroma[uv][intra][qp_rem];
+ leveloffset = LevelOffset4x4Chroma[uv][intra][qp_per];
+ invlevelscale = InvLevelScale4x4Chroma[uv][intra][qp_rem];
+
+ // Horizontal transform
+ if(!lossless_qpprime)
+ for (j=0; j < BLOCK_SIZE; j++)
+ {
+ for (i=0; i < 2; i++)
+ {
+ i1=3-i;
+ m5[i]=img->m7[j][i]+img->m7[j][i1];
+ m5[i1]=img->m7[j][i]-img->m7[j][i1];
+ }
+ img->m7[j][0]=(m5[0]+m5[1]);
+ img->m7[j][2]=(m5[0]-m5[1]);
+ img->m7[j][1]=m5[3]*2+m5[2];
+ img->m7[j][3]=m5[3]-m5[2]*2;
+ }
+
+ // Vertical transform
+ if(!lossless_qpprime)
+ for (i=0; i < BLOCK_SIZE; i++)
+ {
+ for (j=0; j < 2; j++)
+ {
+ j1=3-j;
+ m5[j]=img->m7[j][i]+img->m7[j1][i];
+ m5[j1]=img->m7[j][i]-img->m7[j1][i];
+ }
+ img->m7[0][i]=(m5[0]+m5[1]);
+ img->m7[2][i]=(m5[0]-m5[1]);
+ img->m7[1][i]=m5[3]*2+m5[2];
+ img->m7[3][i]=m5[3]-m5[2]*2;
+ }
+
+ // Quant
+
+ nonzeroAC=FALSE;
+
+ run=-1;
+ scan_pos=0;
+
+ if(lossless_qpprime)
+ level = absm(img->m7[0][0]);
+ else
+ level =(absm(img->m7[0][0]) * levelscale[0][0] + leveloffset[0][0]) >> q_bits;
+
+ b8 -= 4*(uv+1);
+ dc_level_temp[uv][2*(b8 & 0x01)+(b4 & 0x01)][2*(b8 >> 1)+(b4 >> 1)] = sign(level, img->m7[0][0]);
+
+ /* Inverse Quantization */
+ if(lossless_qpprime)
+ {
+ img->m7[0][0] = sign( level, img->m7[0][0]);
+ }
+ else
+ {
+ if(qp_per<4)
+ {
+ img->m7[0][0] = sign( ((level*invlevelscale[0][0]+(1<<(3-qp_per)))>>(4-qp_per)), img->m7[0][0]);
+ }
+ else
+ {
+ img->m7[0][0] = sign( ((level*invlevelscale[0][0])<<(qp_per-4)), img->m7[0][0]);
+ }
+ }
+
+ for (coeff_ctr=1;coeff_ctr < 16;coeff_ctr++)
+ {
+ i=SNGL_SCAN[coeff_ctr][0];
+ j=SNGL_SCAN[coeff_ctr][1];
+
+ run++;
+ ilev=0;
+
+ if(lossless_qpprime)
+ level = absm (img->m7[j][i]);
+ else
+ level = (absm(img->m7[j][i])*levelscale[i][j]+leveloffset[i][j])>>q_bits;
+
+ if (level != 0)
+ {
+ if(i||j) nonzeroAC=TRUE;
+
+ ACLevel[scan_pos] = sign(level,img->m7[j][i]);
+ ACRun [scan_pos] = run;
+ ++scan_pos;
+ run=-1; // reset zero level counter
+
+ level=sign(level, img->m7[j][i]);
+ if(lossless_qpprime)
+ {
+ ilev=level;
+ }
+ else if(qp_per<4)
+ {
+ ilev=(level*invlevelscale[i][j]+(1<<(3-qp_per)))>>(4-qp_per);
+ }
+ else
+ {
+ ilev=(level*invlevelscale[i][j])<<(qp_per-4);
+ }
+ }
+ if(!lossless_qpprime)
+ img->m7[j][i]=ilev;
+ }
+ ACLevel[scan_pos] = 0;
+
+
+ // IDCT.
+ // horizontal
+ if(!lossless_qpprime)
+ for (j=0; j < BLOCK_SIZE; j++)
+ {
+ for (i=0; i < BLOCK_SIZE; i++)
+ {
+ m5[i]=img->m7[j][i];
+ }
+ m6[0]=(m5[0]+m5[2]);
+ m6[1]=(m5[0]-m5[2]);
+ m6[2]=(m5[1]>>1)-m5[3];
+ m6[3]=m5[1]+(m5[3]>>1);
+
+ for (i=0; i < 2; i++)
+ {
+ i1=3-i;
+ img->m7[j][i]=m6[i]+m6[i1];
+ img->m7[j][i1]=m6[i]-m6[i1];
+ }
+ }
+
+ // vertical
+ if(!lossless_qpprime)
+ for (i=0; i < BLOCK_SIZE; i++)
+ {
+ for (j=0; j < BLOCK_SIZE; j++)
+ {
+ m5[j]=img->m7[j][i];
+ }
+ m6[0]=(m5[0]+m5[2]);
+ m6[1]=(m5[0]-m5[2]);
+ m6[2]=(m5[1]>>1)-m5[3];
+ m6[3]=m5[1]+(m5[3]>>1);
+
+ for (j=0; j < 2; j++)
+ {
+ j1=3-j;
+ img->m7[j][i] =(m6[j]+m6[j1]+DQ_ROUND)>>DQ_BITS;
+ img->m7[j1][i]=(m6[j]-m6[j1]+DQ_ROUND)>>DQ_BITS;
+ }
+ }
+
+ return nonzeroAC;
+ }
+
+ // Residue Color Transform
+ int dct_chroma_DC(int uv, int cr_cbp)
+ {
+ int run, scan_pos, coeff_ctr, level, i, j;
+ int* DCLevel = img->cofDC[uv+1][0];
+ int* DCRun = img->cofDC[uv+1][1];
+
+ run=-1;
+ scan_pos=0;
+
+ for (coeff_ctr=0; coeff_ctr < 16; coeff_ctr++)
+ {
+ i=SNGL_SCAN[coeff_ctr][0];
+ j=SNGL_SCAN[coeff_ctr][1];
+
+ run++;
+
+ level = absm(dc_level[uv][i][j]);
+
+ if (level != 0)
+ {
+ cr_cbp=max(1,cr_cbp);
+ DCLevel[scan_pos] = sign(level ,dc_level[uv][i][j]);
+ DCRun [scan_pos] = run;
+ scan_pos++;
+ run=-1;
+ }
+ }
+ DCLevel[scan_pos] = 0;
+
+ return cr_cbp;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * The routine performs transform,quantization,inverse transform, adds the diff.
+ * to the prediction and writes the result to the decoded luma frame. Includes the
+ * RD constrained quantization also.
+ *
+ * \par Input:
+ * block_x,block_y: Block position inside a macro block (0,4,8,12).
+ *
+ * \par Output:
+ * nonzero: 0 if no levels are nonzero. 1 if there are nonzero levels. \n
+ * coeff_cost: Counter for nonzero coefficients, used to discard expensive levels.
+ *
+ *
+ ************************************************************************
+ */
+ int dct_luma_sp(int block_x,int block_y,int *coeff_cost)
+ {
+ int sign(int a,int b);
+
+ int i,j,i1,j1,ilev,m5[4],m6[4],coeff_ctr;
+ int qp_const,level,scan_pos,run;
+ int nonzero;
+
+ int predicted_block[BLOCK_SIZE][BLOCK_SIZE],c_err,qp_const2;
+ int qp_per,qp_rem,q_bits;
+ int qp_per_sp,qp_rem_sp,q_bits_sp;
+
+ int pos_x = block_x >> BLOCK_SHIFT;
+ int pos_y = block_y >> BLOCK_SHIFT;
+ int b8 = 2*(pos_y >> 1) + (pos_x >> 1);
+ int b4 = 2*(pos_y & 0x01) + (pos_x & 0x01);
+ int* ACLevel = img->cofAC[b8][b4][0];
+ int* ACRun = img->cofAC[b8][b4][1];
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ short is_field_mode = (img->field_picture || ( img->MbaffFrameFlag && currMB->mb_field));
+
+ // For encoding optimization
+ int c_err1, c_err2, level1, level2;
+ double D_dis1, D_dis2;
+ int len, info;
+ double lambda_mode = 0.85 * pow (2, (currMB->qp - SHIFT_QP)/3.0) * 4;
+
+ qp_per = (currMB->qp-MIN_QP)/6;
+ qp_rem = (currMB->qp-MIN_QP)%6;
+ q_bits = Q_BITS+qp_per;
+ qp_per_sp = (currMB->qpsp-MIN_QP)/6;
+ qp_rem_sp = (currMB->qpsp-MIN_QP)%6;
+ q_bits_sp = Q_BITS+qp_per_sp;
+
+ qp_const=(1<<q_bits)/6; // inter
+ qp_const2=(1<<q_bits_sp)/2; //sp_pred
+
+ // Horizontal transform
+ for (j=0; j< BLOCK_SIZE; j++)
+ for (i=0; i< BLOCK_SIZE; i++)
+ {
+ img->m7[j][i]+=img->mpr[j+block_y][i+block_x];
+ predicted_block[i][j]=img->mpr[j+block_y][i+block_x];
+ }
+
+ for (j=0; j < BLOCK_SIZE; j++)
+ {
+ for (i=0; i < 2; i++)
+ {
+ i1=3-i;
+ m5[i]=img->m7[j][i]+img->m7[j][i1];
+ m5[i1]=img->m7[j][i]-img->m7[j][i1];
+ }
+ img->m7[j][0]=(m5[0]+m5[1]);
+ img->m7[j][2]=(m5[0]-m5[1]);
+ img->m7[j][1]=m5[3]*2+m5[2];
+ img->m7[j][3]=m5[3]-m5[2]*2;
+ }
+
+ // Vertical transform
+
+ for (i=0; i < BLOCK_SIZE; i++)
+ {
+ for (j=0; j < 2; j++)
+ {
+ j1=3-j;
+ m5[j]=img->m7[j][i]+img->m7[j1][i];
+ m5[j1]=img->m7[j][i]-img->m7[j1][i];
+ }
+ img->m7[0][i]=(m5[0]+m5[1]);
+ img->m7[2][i]=(m5[0]-m5[1]);
+ img->m7[1][i]=m5[3]*2+m5[2];
+ img->m7[3][i]=m5[3]-m5[2]*2;
+ }
+
+ for (j=0; j < BLOCK_SIZE; j++)
+ {
+ for (i=0; i < 2; i++)
+ {
+ i1=3-i;
+ m5[i]=predicted_block[i][j]+predicted_block[i1][j];
+ m5[i1]=predicted_block[i][j]-predicted_block[i1][j];
+ }
+ predicted_block[0][j]=(m5[0]+m5[1]);
+ predicted_block[2][j]=(m5[0]-m5[1]);
+ predicted_block[1][j]=m5[3]*2+m5[2];
+ predicted_block[3][j]=m5[3]-m5[2]*2;
+ }
+
+ // Vertical transform
+
+ for (i=0; i < BLOCK_SIZE; i++)
+ {
+ for (j=0; j < 2; j++)
+ {
+ j1=3-j;
+ m5[j]=predicted_block[i][j]+predicted_block[i][j1];
+ m5[j1]=predicted_block[i][j]-predicted_block[i][j1];
+ }
+ predicted_block[i][0]=(m5[0]+m5[1]);
+ predicted_block[i][2]=(m5[0]-m5[1]);
+ predicted_block[i][1]=m5[3]*2+m5[2];
+ predicted_block[i][3]=m5[3]-m5[2]*2;
+ }
+
+ // Quant
+ nonzero=FALSE;
+
+ run=-1;
+ scan_pos=0;
+
+ for (coeff_ctr=0;coeff_ctr < 16;coeff_ctr++) // 8 times if double scan, 16 normal scan
+ {
+
+ if (is_field_mode)
+ { // Alternate scan for field coding
+ i=FIELD_SCAN[coeff_ctr][0];
+ j=FIELD_SCAN[coeff_ctr][1];
+ }
+ else
+ {
+ i=SNGL_SCAN[coeff_ctr][0];
+ j=SNGL_SCAN[coeff_ctr][1];
+ }
+
+ run++;
+ ilev=0;
+
+ // decide prediction
+
+ // case 1
+ level1 = (absm (predicted_block[i][j]) * quant_coef[qp_rem_sp][i][j] + qp_const2) >> q_bits_sp;
+ level1 = (level1 << q_bits_sp) / quant_coef[qp_rem_sp][i][j];
+ c_err1 = img->m7[j][i]-sign(level1, predicted_block[i][j]);
+ level1 = (absm (c_err1) * quant_coef[qp_rem][i][j] + qp_const) >> q_bits;
+
+ // case 2
+ c_err2=img->m7[j][i]-predicted_block[i][j];
+ level2 = (absm (c_err2) * quant_coef[qp_rem][i][j] + qp_const) >> q_bits;
+
+ // select prediction
+ if ((level1 != level2) && (level1 != 0) && (level2 != 0))
+ {
+ D_dis1 = img->m7[j][i] - ((sign(level1,c_err1)*dequant_coef[qp_rem][i][j]*A[i][j]<< qp_per) >>6) - predicted_block[i][j];
+ levrun_linfo_inter(level1, run, &len, &info);
+ D_dis1 = D_dis1*D_dis1 + lambda_mode * len;
+
+ D_dis2 = img->m7[j][i] - ((sign(level2,c_err2)*dequant_coef[qp_rem][i][j]*A[i][j]<< qp_per) >>6) - predicted_block[i][j];
+ levrun_linfo_inter(level2, run, &len, &info);
+ D_dis2 = D_dis2 * D_dis2 + lambda_mode * len;
+
+ if (D_dis1 == D_dis2)
+ level = (absm(level1) < absm(level2)) ? level1 : level2;
+ else
+ {
+ if (D_dis1 < D_dis2)
+ level = level1;
+ else
+ level = level2;
+ }
+ c_err = (level == level1) ? c_err1 : c_err2;
+ }
+ else if (level1 == level2)
+ {
+ level = level1;
+ c_err = c_err1;
+ }
+ else
+ {
+ level = (level1 == 0) ? level1 : level2;
+ c_err = (level1 == 0) ? c_err1 : c_err2;
+ }
+
+ if (level != 0)
+ {
+ nonzero=TRUE;
+ if (level > 1)
+ *coeff_cost += MAX_VALUE; // set high cost, shall not be discarded
+ else
+ *coeff_cost += COEFF_COST[input->disthres][run];
+ ACLevel[scan_pos] = sign(level,c_err);
+ ACRun [scan_pos] = run;
+ ++scan_pos;
+ run=-1; // reset zero level counter
+ ilev=((sign(level,c_err)*dequant_coef[qp_rem][i][j]*A[i][j]<< qp_per) >>6);
+ }
+ ilev+=predicted_block[i][j] ;
+ img->m7[j][i] = sign((absm(ilev) * quant_coef[qp_rem_sp][i][j] + qp_const2)>> q_bits_sp, ilev) * dequant_coef[qp_rem_sp][i][j] << qp_per_sp;
+ }
+ ACLevel[scan_pos] = 0;
+
+
+ // IDCT.
+ // horizontal
+
+ for (j=0; j < BLOCK_SIZE; j++)
+ {
+ for (i=0; i < BLOCK_SIZE; i++)
+ {
+ m5[i]=img->m7[j][i];
+ }
+ m6[0]=(m5[0]+m5[2]);
+ m6[1]=(m5[0]-m5[2]);
+ m6[2]=(m5[1]>>1)-m5[3];
+ m6[3]=m5[1]+(m5[3]>>1);
+
+ for (i=0; i < 2; i++)
+ {
+ i1=3-i;
+ img->m7[j][i]=m6[i]+m6[i1];
+ img->m7[j][i1]=m6[i]-m6[i1];
+ }
+ }
+
+ // vertical
+
+ for (i=0; i < BLOCK_SIZE; i++)
+ {
+ for (j=0; j < BLOCK_SIZE; j++)
+ {
+ m5[j]=img->m7[j][i];
+ }
+ m6[0]=(m5[0]+m5[2]);
+ m6[1]=(m5[0]-m5[2]);
+ m6[2]=(m5[1]>>1)-m5[3];
+ m6[3]=m5[1]+(m5[3]>>1);
+
+ for (j=0; j < 2; j++)
+ {
+ j1=3-j;
+ img->m7[j][i] =min(img->max_imgpel_value,max(0,(m6[j]+m6[j1]+DQ_ROUND)>>DQ_BITS));
+ img->m7[j1][i]=min(img->max_imgpel_value,max(0,(m6[j]-m6[j1]+DQ_ROUND)>>DQ_BITS));
+ }
+ }
+
+ // Decoded block moved to frame memory
+
+ for (j=0; j < BLOCK_SIZE; j++)
+ for (i=0; i < BLOCK_SIZE; i++)
+ enc_picture->imgY[img->pix_y+block_y+j][img->pix_x+block_x+i]=img->m7[j][i];
+
+ return nonzero;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Transform,quantization,inverse transform for chroma.
+ * The main reason why this is done in a separate routine is the
+ * additional 2x2 transform of DC-coeffs. This routine is called
+ * ones for each of the chroma components.
+ *
+ * \par Input:
+ * uv : Make difference between the U and V chroma component \n
+ * cr_cbp: chroma coded block pattern
+ *
+ * \par Output:
+ * cr_cbp: Updated chroma coded block pattern.
+ ************************************************************************
+ */
+ int dct_chroma_sp(int uv,int cr_cbp)
+ {
+ int i,j,i1,j2,ilev,n2,n1,j1,mb_y,coeff_ctr,qp_const,c_err,level ,scan_pos,run;
+ int m1[BLOCK_SIZE],m5[BLOCK_SIZE],m6[BLOCK_SIZE];
+ int coeff_cost;
+ int cr_cbp_tmp;
+ int predicted_chroma_block[MB_BLOCK_SIZE>>1][MB_BLOCK_SIZE>>1],qp_const2,mp1[BLOCK_SIZE];
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ short is_field_mode = (img->field_picture || ( img->MbaffFrameFlag && currMB->mb_field));
+
+ int qp_per,qp_rem,q_bits;
+ int qp_per_sp,qp_rem_sp,q_bits_sp;
+
+ int b4;
+ int* DCLevel = img->cofDC[uv+1][0];
+ int* DCRun = img->cofDC[uv+1][1];
+ int* ACLevel;
+ int* ACRun;
+
+ int c_err1, c_err2, level1, level2;
+ int len, info;
+ double D_dis1, D_dis2;
+ double lambda_mode = 0.85 * pow (2, (currMB->qp -SHIFT_QP)/3.0) * 4;
+
+
+ int qpChroma=Clip3(0, 51, currMB->qp + active_pps->chroma_qp_index_offset);
+ int qpChromaSP=Clip3(0, 51, currMB->qpsp + active_pps->chroma_qp_index_offset);
+
+ qp_per = ((qpChroma<0?qpChroma:QP_SCALE_CR[qpChroma])-MIN_QP)/6;
+ qp_rem = ((qpChroma<0?qpChroma:QP_SCALE_CR[qpChroma])-MIN_QP)%6;
+ q_bits = Q_BITS+qp_per;
+ qp_const=(1<<q_bits)/6; // inter
+ qp_per_sp = ((qpChromaSP<0?currMB->qpsp:QP_SCALE_CR[qpChromaSP])-MIN_QP)/6;
+ qp_rem_sp = ((qpChromaSP<0?currMB->qpsp:QP_SCALE_CR[qpChromaSP])-MIN_QP)%6;
+ q_bits_sp = Q_BITS+qp_per_sp;
+ qp_const2=(1<<q_bits_sp)/2; //sp_pred
+
+
+ for (j=0; j < MB_BLOCK_SIZE>>1; j++)
+ for (i=0; i < MB_BLOCK_SIZE>>1; i++)
+ {
+ img->m7[j][i]+=img->mpr[j][i];
+ predicted_chroma_block[i][j]=img->mpr[j][i];
+ }
+
+ for (n2=0; n2 <= BLOCK_SIZE; n2 += BLOCK_SIZE)
+ {
+ for (n1=0; n1 <= BLOCK_SIZE; n1 += BLOCK_SIZE)
+ {
+
+ // Horizontal transform.
+ for (j=0; j < BLOCK_SIZE; j++)
+ {
+ mb_y=n2+j;
+ for (i=0; i < 2; i++)
+ {
+ i1=3-i;
+ m5[i]=img->m7[mb_y][i+n1]+img->m7[mb_y][i1+n1];
+ m5[i1]=img->m7[mb_y][i+n1]-img->m7[mb_y][i1+n1];
+ }
+ img->m7[mb_y][n1] =(m5[0]+m5[1]);
+ img->m7[mb_y][n1+2]=(m5[0]-m5[1]);
+ img->m7[mb_y][n1+1]=m5[3]*2+m5[2];
+ img->m7[mb_y][n1+3]=m5[3]-m5[2]*2;
+ }
+
+ // Vertical transform.
+
+ for (i=0; i < BLOCK_SIZE; i++)
+ {
+ j1=n1+i;
+ for (j=0; j < 2; j++)
+ {
+ j2=3-j;
+ m5[j]=img->m7[n2+j][j1]+img->m7[n2+j2][j1];
+ m5[j2]=img->m7[n2+j][j1]-img->m7[n2+j2][j1];
+ }
+ img->m7[n2+0][j1]=(m5[0]+m5[1]);
+ img->m7[n2+2][j1]=(m5[0]-m5[1]);
+ img->m7[n2+1][j1]=m5[3]*2+m5[2];
+ img->m7[n2+3][j1]=m5[3]-m5[2]*2;
+ }
+ }
+ }
+ for (n2=0; n2 <= BLOCK_SIZE; n2 += BLOCK_SIZE)
+ {
+ for (n1=0; n1 <= BLOCK_SIZE; n1 += BLOCK_SIZE)
+ {
+
+ // Horizontal transform.
+ for (j=0; j < BLOCK_SIZE; j++)
+ {
+ mb_y=n2+j;
+ for (i=0; i < 2; i++)
+ {
+ i1=3-i;
+ m5[i]=predicted_chroma_block[i+n1][mb_y]+predicted_chroma_block[i1+n1][mb_y];
+ m5[i1]=predicted_chroma_block[i+n1][mb_y]-predicted_chroma_block[i1+n1][mb_y];
+ }
+ predicted_chroma_block[n1][mb_y] =(m5[0]+m5[1]);
+ predicted_chroma_block[n1+2][mb_y]=(m5[0]-m5[1]);
+ predicted_chroma_block[n1+1][mb_y]=m5[3]*2+m5[2];
+ predicted_chroma_block[n1+3][mb_y]=m5[3]-m5[2]*2;
+ }
+
+ // Vertical transform.
+
+ for (i=0; i < BLOCK_SIZE; i++)
+ {
+ j1=n1+i;
+ for (j=0; j < 2; j++)
+ {
+ j2=3-j;
+ m5[j]=predicted_chroma_block[j1][n2+j]+predicted_chroma_block[j1][n2+j2];
+ m5[j2]=predicted_chroma_block[j1][n2+j]-predicted_chroma_block[j1][n2+j2];
+ }
+ predicted_chroma_block[j1][n2+0]=(m5[0]+m5[1]);
+ predicted_chroma_block[j1][n2+2]=(m5[0]-m5[1]);
+ predicted_chroma_block[j1][n2+1]=m5[3]*2+m5[2];
+ predicted_chroma_block[j1][n2+3]=m5[3]-m5[2]*2;
+ }
+ }
+ }
+
+ // 2X2 transform of DC coeffs.
+ m1[0]=(img->m7[0][0]+img->m7[0][4]+img->m7[4][0]+img->m7[4][4]);
+ m1[1]=(img->m7[0][0]-img->m7[0][4]+img->m7[4][0]-img->m7[4][4]);
+ m1[2]=(img->m7[0][0]+img->m7[0][4]-img->m7[4][0]-img->m7[4][4]);
+ m1[3]=(img->m7[0][0]-img->m7[0][4]-img->m7[4][0]+img->m7[4][4]);
+
+ // 2X2 transform of DC coeffs.
+ mp1[0]=(predicted_chroma_block[0][0]+predicted_chroma_block[4][0]+predicted_chroma_block[0][4]+predicted_chroma_block[4][4]);
+ mp1[1]=(predicted_chroma_block[0][0]-predicted_chroma_block[4][0]+predicted_chroma_block[0][4]-predicted_chroma_block[4][4]);
+ mp1[2]=(predicted_chroma_block[0][0]+predicted_chroma_block[4][0]-predicted_chroma_block[0][4]-predicted_chroma_block[4][4]);
+ mp1[3]=(predicted_chroma_block[0][0]-predicted_chroma_block[4][0]-predicted_chroma_block[0][4]+predicted_chroma_block[4][4]);
+
+ run=-1;
+ scan_pos=0;
+
+ for (coeff_ctr=0; coeff_ctr < 4; coeff_ctr++)
+ {
+ run++;
+ ilev=0;
+
+ // case 1
+ c_err1 = (absm (mp1[coeff_ctr]) * quant_coef[qp_rem_sp][0][0] + 2 * qp_const2) >> (q_bits_sp + 1);
+ c_err1 = (c_err1 << (q_bits_sp + 1)) / quant_coef[qp_rem_sp][0][0];
+ c_err1 = m1[coeff_ctr] - sign(c_err1, mp1[coeff_ctr]);
+ level1 = (absm(c_err1) * quant_coef[qp_rem][0][0] + 2 * qp_const) >> (q_bits+1);
+
+ // case 2
+ c_err2 = m1[coeff_ctr] - mp1[coeff_ctr];
+ level2 = (absm(c_err2) * quant_coef[qp_rem][0][0] + 2 * qp_const) >> (q_bits+1);
+
+ if (level1 != level2 && level1 != 0 && level2 != 0)
+ {
+ D_dis1 = m1[coeff_ctr] - ((sign(level1,c_err1)*dequant_coef[qp_rem][0][0]*A[0][0]<< qp_per) >>5)- mp1[coeff_ctr];
+ levrun_linfo_c2x2(level1, run, &len, &info);
+ D_dis1 = D_dis1 * D_dis1 + lambda_mode * len;
+
+ D_dis2 = m1[coeff_ctr] - ((sign(level2,c_err2)*dequant_coef[qp_rem][0][0]*A[0][0]<< qp_per) >>5)- mp1[coeff_ctr];
+ levrun_linfo_c2x2(level2, run, &len, &info);
+ D_dis2 = D_dis2 * D_dis2 + lambda_mode * len;
+
+ if (D_dis1 == D_dis2)
+ level = (absm(level1) < absm(level2)) ? level1 : level2;
+ else
+ {
+ if (D_dis1 < D_dis2)
+ level = level1;
+ else
+ level = level2;
+ }
+ c_err = (level == level1) ? c_err1 : c_err2;
+ }
+ else if (level1 == level2)
+ {
+ level = level1;
+ c_err = c_err1;
+ }
+ else
+ {
+ level = (level1 == 0) ? level1 : level2;
+ c_err = (level1 == 0) ? c_err1 : c_err2;
+ }
+
+ if (input->symbol_mode == UVLC && img->qp < 4)
+ {
+ if (level > CAVLC_LEVEL_LIMIT)
+ {
+ level = CAVLC_LEVEL_LIMIT;
+ }
+ }
+
+ if (level != 0)
+ {
+ currMB->cbp_blk |= 0xf0000 << (uv << 2) ; // if one of the 2x2-DC levels is != 0 the coded-bit
+ cr_cbp=max(1,cr_cbp);
+ DCLevel[scan_pos] = sign(level ,c_err);
+ DCRun [scan_pos] = run;
+ scan_pos++;
+ run=-1;
+ ilev=((sign(level,c_err)*dequant_coef[qp_rem][0][0]*A[0][0]<< qp_per) >>5);
+ }
+ ilev+= mp1[coeff_ctr];
+ m1[coeff_ctr]=sign((absm(ilev) * quant_coef[qp_rem_sp][0][0] + 2 * qp_const2) >> (q_bits_sp+1), ilev) * dequant_coef[qp_rem_sp][0][0] << qp_per_sp;
+ }
+ DCLevel[scan_pos] = 0;
+
+ // Invers transform of 2x2 DC levels
+
+ img->m7[0][0]=(m1[0]+m1[1]+m1[2]+m1[3])/2;
+ img->m7[0][4]=(m1[0]-m1[1]+m1[2]-m1[3])/2;
+ img->m7[4][0]=(m1[0]+m1[1]-m1[2]-m1[3])/2;
+ img->m7[4][4]=(m1[0]-m1[1]-m1[2]+m1[3])/2;
+
+ // Quant of chroma AC-coeffs.
+ coeff_cost=0;
+ cr_cbp_tmp=0;
+
+ for (n2=0; n2 <= BLOCK_SIZE; n2 += BLOCK_SIZE)
+ {
+ for (n1=0; n1 <= BLOCK_SIZE; n1 += BLOCK_SIZE)
+ {
+ b4 = 2*(n2 >> 2) + (n1 >> 2);
+ ACLevel = img->cofAC[uv+4][b4][0];
+ ACRun = img->cofAC[uv+4][b4][1];
+
+ run = -1;
+ scan_pos = 0;
+
+ for (coeff_ctr=1; coeff_ctr < 16; coeff_ctr++)// start change rd_quant
+ {
+
+ if (is_field_mode)
+ { // Alternate scan for field coding
+ i=FIELD_SCAN[coeff_ctr][0];
+ j=FIELD_SCAN[coeff_ctr][1];
+ }
+ else
+ {
+ i=SNGL_SCAN[coeff_ctr][0];
+ j=SNGL_SCAN[coeff_ctr][1];
+ }
+ ++run;
+ ilev=0;
+
+ // quantization on prediction
+ c_err1 = (absm(predicted_chroma_block[n1+i][n2+j]) * quant_coef[qp_rem_sp][i][j] + qp_const2) >> q_bits_sp;
+ c_err1 = (c_err1 << q_bits_sp) / quant_coef[qp_rem_sp][i][j];
+ c_err1 = img->m7[n2+j][n1+i] - sign(c_err1, predicted_chroma_block[n1+i][n2+j]);
+ level1 = (absm(c_err1) * quant_coef[qp_rem][i][j] + qp_const) >> q_bits;
+
+ // no quantization on prediction
+ c_err2 = img->m7[n2+j][n1+i] - predicted_chroma_block[n1+i][n2+j];
+ level2 = (absm(c_err2) * quant_coef[qp_rem][i][j] + qp_const) >> q_bits;
+
+ if (level1 != level2 && level1 != 0 && level2 != 0)
+ {
+ D_dis1 = img->m7[n2+j][n1+i] - ((sign(level1,c_err1)*dequant_coef[qp_rem][i][j]*A[i][j]<< qp_per) >>6) - predicted_chroma_block[n1+i][n2+j];
+
+ levrun_linfo_inter(level1, run, &len, &info);
+ D_dis1 = D_dis1 * D_dis1 + lambda_mode * len;
+
+ D_dis2 = img->m7[n2+j][n1+i] - ((sign(level2,c_err2)*dequant_coef[qp_rem][i][j]*A[i][j]<< qp_per) >>6) - predicted_chroma_block[n1+i][n2+j];
+ levrun_linfo_inter(level2, run, &len, &info);
+ D_dis2 = D_dis2 * D_dis2 + lambda_mode * len;
+
+ if (D_dis1 == D_dis2)
+ level = (absm(level1) < absm(level2)) ? level1 : level2;
+ else
+ {
+ if (D_dis1 < D_dis2)
+ level = level1;
+ else
+ level = level2;
+ }
+ c_err = (level == level1) ? c_err1 : c_err2;
+ }
+ else if (level1 == level2)
+ {
+ level = level1;
+ c_err = c_err1;
+ }
+ else
+ {
+ level = (level1 == 0) ? level1 : level2;
+ c_err = (level1 == 0) ? c_err1 : c_err2;
+ }
+
+ if (level != 0)
+ {
+ currMB->cbp_blk |= 1 << (16 + (uv << 2) + ((n2 >> 1) + (n1 >> 2))) ;
+ if (level > 1)
+ coeff_cost += MAX_VALUE; // set high cost, shall not be discarded
+ else
+ coeff_cost += COEFF_COST[input->disthres][run];
+
+ cr_cbp_tmp=2;
+ ACLevel[scan_pos] = sign(level,c_err);
+ ACRun [scan_pos] = run;
+ ++scan_pos;
+ run=-1;
+ ilev=((sign(level,c_err)*dequant_coef[qp_rem][i][j]*A[i][j]<< qp_per) >>6);
+ }
+ ilev+=predicted_chroma_block[n1+i][n2+j];
+ img->m7[n2+j][n1+i] = sign((absm(ilev) * quant_coef[qp_rem_sp][i][j] + qp_const2) >> q_bits_sp,ilev) * dequant_coef[qp_rem_sp][i][j] << qp_per_sp;
+ }
+ ACLevel[scan_pos] = 0;
+ }
+ }
+
+ // * reset chroma coeffs
+
+ if(cr_cbp_tmp==2)
+ cr_cbp=2;
+ // IDCT.
+
+ // Horizontal.
+ for (n2=0; n2 <= BLOCK_SIZE; n2 += BLOCK_SIZE)
+ {
+ for (n1=0; n1 <= BLOCK_SIZE; n1 += BLOCK_SIZE)
+ {
+ for (j=0; j < BLOCK_SIZE; j++)
+ {
+ for (i=0; i < BLOCK_SIZE; i++)
+ {
+ m5[i]=img->m7[n2+j][n1+i];
+ }
+ m6[0]=(m5[0]+m5[2]);
+ m6[1]=(m5[0]-m5[2]);
+ m6[2]=(m5[1]>>1)-m5[3];
+ m6[3]=m5[1]+(m5[3]>>1);
+
+ for (i=0; i < 2; i++)
+ {
+ i1=3-i;
+ img->m7[n2+j][n1+i]=m6[i]+m6[i1];
+ img->m7[n2+j][n1+i1]=m6[i]-m6[i1];
+ }
+ }
+
+ // Vertical.
+ for (i=0; i < BLOCK_SIZE; i++)
+ {
+ for (j=0; j < BLOCK_SIZE; j++)
+ {
+ m5[j]=img->m7[n2+j][n1+i];
+ }
+ m6[0]=(m5[0]+m5[2]);
+ m6[1]=(m5[0]-m5[2]);
+ m6[2]=(m5[1]>>1)-m5[3];
+ m6[3]=m5[1]+(m5[3]>>1);
+
+ for (j=0; j < 2; j++)
+ {
+ j2=3-j;
+ img->m7[n2+j][n1+i] =min(img->max_imgpel_value_uv,max(0,(m6[j]+m6[j2]+DQ_ROUND)>>DQ_BITS));
+ img->m7[n2+j2][n1+i]=min(img->max_imgpel_value_uv,max(0,(m6[j]-m6[j2]+DQ_ROUND)>>DQ_BITS));
+ }
+ }
+ }
+ }
+
+ // Decoded block moved to memory
+ for (j=0; j < BLOCK_SIZE*2; j++)
+ for (i=0; i < BLOCK_SIZE*2; i++)
+ {
+ enc_picture->imgUV[uv][img->pix_c_y+j][img->pix_c_x+i]= img->m7[j][i];
+ }
+
+ return cr_cbp;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * The routine performs transform,quantization,inverse transform, adds the diff.
+ * to the prediction and writes the result to the decoded luma frame. Includes the
+ * RD constrained quantization also.
+ *
+ * \par Input:
+ * block_x,block_y: Block position inside a macro block (0,4,8,12).
+ *
+ * \par Output:
+ * nonzero: 0 if no levels are nonzero. 1 if there are nonzero levels. \n
+ * coeff_cost: Counter for nonzero coefficients, used to discard expencive levels.
+ ************************************************************************
+ */
+ void copyblock_sp(int block_x,int block_y)
+ {
+ int sign(int a,int b);
+
+ int i,j,i1,j1,m5[4],m6[4];
+
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+
+ int predicted_block[BLOCK_SIZE][BLOCK_SIZE];
+ int qp_per = (currMB->qpsp-MIN_QP)/6;
+ int qp_rem = (currMB->qpsp-MIN_QP)%6;
+ int q_bits = Q_BITS+qp_per;
+ int qp_const2=(1<<q_bits)/2; //sp_pred
+
+ // Horizontal transform
+ for (j=0; j< BLOCK_SIZE; j++)
+ for (i=0; i< BLOCK_SIZE; i++)
+ {
+ predicted_block[i][j]=img->mpr[j+block_y][i+block_x];
+ }
+
+ for (j=0; j < BLOCK_SIZE; j++)
+ {
+ for (i=0; i < 2; i++)
+ {
+ i1=3-i;
+ m5[i]=predicted_block[i][j]+predicted_block[i1][j];
+ m5[i1]=predicted_block[i][j]-predicted_block[i1][j];
+ }
+ predicted_block[0][j]=(m5[0]+m5[1]);
+ predicted_block[2][j]=(m5[0]-m5[1]);
+ predicted_block[1][j]=m5[3]*2+m5[2];
+ predicted_block[3][j]=m5[3]-m5[2]*2;
+ }
+
+ // Vertival transform
+
+ for (i=0; i < BLOCK_SIZE; i++)
+ {
+ for (j=0; j < 2; j++)
+ {
+ j1=3-j;
+ m5[j]=predicted_block[i][j]+predicted_block[i][j1];
+ m5[j1]=predicted_block[i][j]-predicted_block[i][j1];
+ }
+ predicted_block[i][0]=(m5[0]+m5[1]);
+ predicted_block[i][2]=(m5[0]-m5[1]);
+ predicted_block[i][1]=m5[3]*2+m5[2];
+ predicted_block[i][3]=m5[3]-m5[2]*2;
+ }
+
+ // Quant
+ for (j=0;j < BLOCK_SIZE; j++)
+ for (i=0; i < BLOCK_SIZE; i++)
+ img->m7[j][i]=sign((absm(predicted_block[i][j])* quant_coef[qp_rem][i][j]+qp_const2)>> q_bits,predicted_block[i][j])*dequant_coef[qp_rem][i][j]<<qp_per;
+
+ // IDCT.
+ // horizontal
+
+ for (j=0;j<BLOCK_SIZE;j++)
+ {
+ for (i=0;i<BLOCK_SIZE;i++)
+ {
+ m5[i]=img->m7[j][i];
+ }
+ m6[0]=(m5[0]+m5[2]);
+ m6[1]=(m5[0]-m5[2]);
+ m6[2]=(m5[1]>>1)-m5[3];
+ m6[3]=m5[1]+(m5[3]>>1);
+
+ for (i=0;i<2;i++)
+ {
+ i1=3-i;
+ img->m7[j][i]=m6[i]+m6[i1];
+ img->m7[j][i1]=m6[i]-m6[i1];
+ }
+ }
+ // vertical
+ for (i=0;i<BLOCK_SIZE;i++)
+ {
+ for (j=0;j<BLOCK_SIZE;j++)
+ m5[j]=img->m7[j][i];
+
+ m6[0]=(m5[0]+m5[2]);
+ m6[1]=(m5[0]-m5[2]);
+ m6[2]=(m5[1]>>1)-m5[3];
+ m6[3]=m5[1]+(m5[3]>>1);
+
+ for (j=0;j<2;j++)
+ {
+ j1=3-j;
+ img->m7[j][i] =min(img->max_imgpel_value,max(0,(m6[j]+m6[j1]+DQ_ROUND)>>DQ_BITS));
+ img->m7[j1][i]=min(img->max_imgpel_value,max(0,(m6[j]-m6[j1]+DQ_ROUND)>>DQ_BITS));
+ }
+ }
+
+ // Decoded block moved to frame memory
+
+ for (j=0; j < BLOCK_SIZE; j++)
+ for (i=0; i < BLOCK_SIZE; i++)
+ enc_picture->imgY[img->pix_y+block_y+j][img->pix_x+block_x+i]=img->m7[j][i];
+ }
+
+
+
+ int writeIPCMBytes(Bitstream *currStream)
+ {
+ int i,j, jj;
+ int len = 0, uv;
+ int mb_nr = img->current_mb_nr;
+ Macroblock* currMB = &img->mb_data[mb_nr];
+ SyntaxElement *currSE = &img->MB_SyntaxElements[currMB->currSEnr];
+
+
+ for (j=0;j<16;j++)
+ {
+ jj = img->pix_y+j;
+ for (i=0;i<16;i++)
+ {
+ currSE->len = img->bitdepth_luma;
+ len += currSE->len;
+ currSE->bitpattern = enc_picture->imgY[jj][img->pix_x+i];
+ writeSyntaxElement2Buf_Fixed(currSE, currStream);
+ }
+ }
+
+ for (uv = 0; uv < 2; uv ++)
+ {
+ for (j=0;j<img->mb_cr_size_y;j++)
+ {
+ jj = img->pix_c_y+j;
+ for (i=0;i<img->mb_cr_size_x;i++)
+ {
+ currSE->len = img->bitdepth_chroma;
+ len += currSE->len;
+ currSE->bitpattern = enc_picture->imgUV[uv][jj][img->pix_c_x+i];
+ writeSyntaxElement2Buf_Fixed(currSE, currStream);
+ }
+ }
+ }
+ return len;
+ }
+
+ int writePCMByteAlign(Bitstream *currStream)
+ {
+ int len = 0;
+ if (currStream->bits_to_go < 8)
+ { // trailing bits to process
+ len = 8 - currStream->bits_to_go;
+ currStream->byte_buf = (currStream->byte_buf <<currStream->bits_to_go) | (0xff >> (8 - currStream->bits_to_go));
+ stats->bit_use_stuffingBits[img->type]+=currStream->bits_to_go;
+ currStream->streamBuffer[currStream->byte_pos++]=currStream->byte_buf;
+ currStream->bits_to_go = 8;
+ }
+ return len;
+ }
+
Index: llvm-test/MultiSource/Applications/JM/lencod/block.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/block.h:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/block.h Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,179 ----
+
+ /*!
+ ************************************************************************
+ * \file block.h
+ *
+ * \brief
+ * constant arrays for single block processing
+ *
+ * \author
+ * Inge Lille-Langoy <inge.lille-langoy at telenor.com> \n
+ * Telenor Satellite Services \n
+ * P.O.Box 6914 St.Olavs plass \n
+ * N-0130 Oslo, Norway
+ *
+ ************************************************************************
+ */
+
+ #ifndef _BLOCK_H_
+ #define _BLOCK_H_
+
+ //! make chroma QP from quant
+ const byte QP_SCALE_CR[52]=
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,
+ 12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,
+ 28,29,29,30,31,32,32,33,34,34,35,35,36,36,37,37,
+ 37,38,38,38,39,39,39,39
+ };
+
+
+ //! single scan pattern
+ const byte SNGL_SCAN[16][2] =
+ {
+ {0,0},{1,0},{0,1},{0,2},
+ {1,1},{2,0},{3,0},{2,1},
+ {1,2},{0,3},{1,3},{2,2},
+ {3,1},{3,2},{2,3},{3,3}
+ };
+
+ //! field scan pattern
+ const byte FIELD_SCAN[16][2] =
+ {
+ {0,0},{0,1},{1,0},{0,2},
+ {0,3},{1,1},{1,2},{1,3},
+ {2,0},{2,1},{2,2},{2,3},
+ {3,0},{3,1},{3,2},{3,3}
+ };
+
+
+ //! array used to find expencive coefficients
+ const byte COEFF_COST[2][16] =
+ {
+ {3,2,2,1,1,1,0,0,0,0,0,0,0,0,0,0},
+ {9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9}
+ };
+
+
+
+ //! bit cost for coefficients
+ const byte COEFF_BIT_COST[3][16][16]=
+ {
+ { // 2x2 scan (corrested per Gisle's Email 11/23/2000 by StW
+ { 3, 5, 7, 9, 9,11,11,11,11,13,13,13,13,13,13,13},
+ { 5, 7, 9, 9,11,11,11,11,13,13,13,13,13,13,13,13},
+ { 7, 9, 9,11,11,11,11,13,13,13,13,13,13,13,13,15},
+ { 7, 9, 9,11,11,11,11,13,13,13,13,13,13,13,13,15},
+ { 7, 7, 9, 9, 9, 9,11,11,11,11,11,11,11,11,13,13},
+ { 7, 7, 9, 9, 9, 9,11,11,11,11,11,11,11,11,13,13},
+ { 7, 7, 9, 9, 9, 9,11,11,11,11,11,11,11,11,13,13},
+ { 7, 7, 9, 9, 9, 9,11,11,11,11,11,11,11,11,13,13},
+ { 7, 7, 9, 9, 9, 9,11,11,11,11,11,11,11,11,13,13},
+ { 7, 7, 9, 9, 9, 9,11,11,11,11,11,11,11,11,13,13},
+ { 7, 7, 9, 9, 9, 9,11,11,11,11,11,11,11,11,13,13},
+ { 7, 7, 9, 9, 9, 9,11,11,11,11,11,11,11,11,13,13},
+ { 7, 7, 9, 9, 9, 9,11,11,11,11,11,11,11,11,13,13},
+ { 7, 7, 9, 9, 9, 9,11,11,11,11,11,11,11,11,13,13},
+ { 7, 7, 9, 9, 9, 9,11,11,11,11,11,11,11,11,13,13},
+ { 7, 7, 9, 9, 9, 9,11,11,11,11,11,11,11,11,13,13},
+ },
+ { // double scan
+ { 3, 5, 7, 7, 7, 9, 9, 9, 9,11,11,13,13,13,13,15},
+ { 5, 9, 9,11,11,13,13,13,13,15,15,15,15,15,15,15},
+ { 7,11,11,13,13,13,13,15,15,15,15,15,15,15,15,17},
+ { 9,11,11,13,13,13,13,15,15,15,15,15,15,15,15,17},
+ { 9,11,11,13,13,13,13,15,15,15,15,15,15,15,15,17},
+ {11,11,13,13,13,13,15,15,15,15,15,15,15,15,17,17},
+ {11,11,13,13,13,13,15,15,15,15,15,15,15,15,17,17},
+ {11,11,13,13,13,13,15,15,15,15,15,15,15,15,17,17},
+ {11,11,13,13,13,13,15,15,15,15,15,15,15,15,17,17},
+ {11,11,13,13,13,13,15,15,15,15,15,15,15,15,17,17},
+ {11,11,13,13,13,13,15,15,15,15,15,15,15,15,17,17},
+ {11,11,13,13,13,13,15,15,15,15,15,15,15,15,17,17},
+ {11,11,13,13,13,13,15,15,15,15,15,15,15,15,17,17},
+ {11,11,13,13,13,13,15,15,15,15,15,15,15,15,17,17},
+ },
+ { // single scan
+ { 3, 7, 9, 9,11,13,13,15,15,15,15,17,17,17,17,17},
+ { 5, 9,11,13,13,15,15,15,15,17,17,17,17,17,17,17},
+ { 5, 9,11,13,13,15,15,15,15,17,17,17,17,17,17,17},
+ { 7,11,13,13,15,15,15,15,17,17,17,17,17,17,17,17},
+ { 7,11,13,13,15,15,15,15,17,17,17,17,17,17,17,17},
+ { 7,11,13,13,15,15,15,15,17,17,17,17,17,17,17,17},
+ { 9,11,13,13,15,15,15,15,17,17,17,17,17,17,17,17},
+ { 9,11,13,13,15,15,15,15,17,17,17,17,17,17,17,17},
+ { 9,11,13,13,15,15,15,15,17,17,17,17,17,17,17,17},
+ { 9,11,13,13,15,15,15,15,17,17,17,17,17,17,17,17},
+ {11,13,13,15,15,15,15,17,17,17,17,17,17,17,17,19},
+ {11,13,13,15,15,15,15,17,17,17,17,17,17,17,17,19},
+ {11,13,13,15,15,15,15,17,17,17,17,17,17,17,17,19},
+ {11,13,13,15,15,15,15,17,17,17,17,17,17,17,17,19},
+ {11,13,13,15,15,15,15,17,17,17,17,17,17,17,17,19},
+ {11,13,13,15,15,15,15,17,17,17,17,17,17,17,17,19},
+ },
+ };
+
+ //! single scan pattern
+ const byte SCAN_YUV422 [8][2] =
+ {
+ {0,0},{0,1},
+ {1,0},{0,2},
+ {0,3},{1,1},
+ {1,2},{1,3}
+ };
+
+ //! look up tables for FRExt-chroma support
+ const unsigned char hor_offset[4][4][4] =
+ {{{0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}},
+
+ {{0, 4, 0, 4},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}},
+
+ {{0, 4, 0, 4},
+ {0, 4, 0, 4},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}},
+
+ {{0, 4, 0, 4},
+ {8,12, 8,12},
+ {0, 4, 0, 4},
+ {8,12, 8,12}}};
+
+ const unsigned char ver_offset[4][4][4] =
+ { {{0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}},
+
+ {{0, 0, 4, 4},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}},
+
+ {{0, 0, 4, 4},
+ {8, 8,12,12},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}},
+
+ {{0, 0, 4, 4},
+ {0, 0, 4, 4},
+ {8, 8,12,12},
+ {8, 8,12,12}}};
+
+ static unsigned char cbp_blk_chroma[8][4] =
+ { {16, 17, 18, 19},
+ {20, 21, 22, 23},
+ {24, 25, 26, 27},
+ {28, 29, 30, 31},
+ {32, 33, 34, 35},
+ {36, 37, 38, 39},
+ {40, 41, 42, 43},
+ {44, 45, 46, 47} };
+
+ #endif
+
Index: llvm-test/MultiSource/Applications/JM/lencod/cabac.c
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/cabac.c:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/cabac.c Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,1503 ----
+
+ /*!
+ *************************************************************************************
+ * \file cabac.c
+ *
+ * \brief
+ * CABAC entropy coding routines
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Detlev Marpe <marpe at hhi.de>
+ **************************************************************************************
+ */
+
+ #include <stdlib.h>
+ #include <assert.h>
+ #include <memory.h>
+ #include "global.h"
+
+ #include "cabac.h"
+ #include "image.h"
+ #include "mb_access.h"
+
+ int last_dquant = 0;
+
+ /***********************************************************************
+ * L O C A L L Y D E F I N E D F U N C T I O N P R O T O T Y P E S
+ ***********************************************************************
+ */
+
+
+ void unary_bin_encode(EncodingEnvironmentPtr eep_frame,
+ unsigned int symbol,
+ BiContextTypePtr ctx,
+ int ctx_offset);
+
+ void unary_bin_max_encode(EncodingEnvironmentPtr eep_frame,
+ unsigned int symbol,
+ BiContextTypePtr ctx,
+ int ctx_offset,
+ unsigned int max_symbol);
+
+ void unary_exp_golomb_level_encode( EncodingEnvironmentPtr eep_dp,
+ unsigned int symbol,
+ BiContextTypePtr ctx);
+
+ void unary_exp_golomb_mv_encode(EncodingEnvironmentPtr eep_dp,
+ unsigned int symbol,
+ BiContextTypePtr ctx,
+ unsigned int max_bin);
+
+
+ void cabac_new_slice()
+ {
+ last_dquant=0;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Check for available neighbouring blocks
+ * and set pointers in current macroblock
+ ************************************************************************
+ */
+ void CheckAvailabilityOfNeighborsCABAC()
+ {
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ PixelPos up, left;
+
+ getNeighbour(img->current_mb_nr, -1, 0, 1, &left);
+ getNeighbour(img->current_mb_nr, 0, -1, 1, &up);
+
+ if (up.available)
+ currMB->mb_available_up = &img->mb_data[up.mb_addr];
+ else
+ currMB->mb_available_up = NULL;
+
+ if (left.available)
+ currMB->mb_available_left = &img->mb_data[left.mb_addr];
+ else
+ currMB->mb_available_left = NULL;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Allocation of contexts models for the motion info
+ * used for arithmetic encoding
+ ************************************************************************
+ */
+ MotionInfoContexts* create_contexts_MotionInfo(void)
+ {
+ MotionInfoContexts* enco_ctx;
+
+ enco_ctx = (MotionInfoContexts*) calloc(1, sizeof(MotionInfoContexts) );
+ if( enco_ctx == NULL )
+ no_mem_exit("create_contexts_MotionInfo: enco_ctx");
+
+ return enco_ctx;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Allocates of contexts models for the texture info
+ * used for arithmetic encoding
+ ************************************************************************
+ */
+ TextureInfoContexts* create_contexts_TextureInfo(void)
+ {
+ TextureInfoContexts* enco_ctx;
+
+ enco_ctx = (TextureInfoContexts*) calloc(1, sizeof(TextureInfoContexts) );
+ if( enco_ctx == NULL )
+ no_mem_exit("create_contexts_TextureInfo: enco_ctx");
+
+ return enco_ctx;
+ }
+
+
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Frees the memory of the contexts models
+ * used for arithmetic encoding of the motion info.
+ ************************************************************************
+ */
+ void delete_contexts_MotionInfo(MotionInfoContexts *enco_ctx)
+ {
+ if( enco_ctx == NULL )
+ return;
+
+ free( enco_ctx );
+
+ return;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Frees the memory of the contexts models
+ * used for arithmetic encoding of the texture info.
+ ************************************************************************
+ */
+ void delete_contexts_TextureInfo(TextureInfoContexts *enco_ctx)
+ {
+ if( enco_ctx == NULL )
+ return;
+
+ free( enco_ctx );
+
+ return;
+ }
+
+
+ /*!
+ **************************************************************************
+ * \brief
+ * generates arithmetic code and passes the code to the buffer
+ **************************************************************************
+ */
+ int writeSyntaxElement_CABAC(SyntaxElement *se, DataPartition *this_dataPart)
+ {
+ EncodingEnvironmentPtr eep_dp = &(this_dataPart->ee_cabac);
+ int curr_len = arienco_bits_written(eep_dp);
+
+ // perform the actual coding by calling the appropriate method
+ se->writing(se, eep_dp);
+
+ if(se->type != SE_HEADER)
+ this_dataPart->bitstream->write_flag = 1;
+
+ return (se->len = (arienco_bits_written(eep_dp) - curr_len));
+ }
+
+ /*!
+ ***************************************************************************
+ * \brief
+ * This function is used to arithmetically encode the field
+ * mode info of a given MB in the case of mb-based frame/field decision
+ ***************************************************************************
+ */
+ void writeFieldModeInfo_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
+ {
+ int a,b,act_ctx;
+ MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ int mb_field = se->value1;
+
+ a = currMB->mbAvailA ? img->mb_data[currMB->mbAddrA].mb_field : 0;
+ b = currMB->mbAvailB ? img->mb_data[currMB->mbAddrB].mb_field : 0;
+
+ act_ctx = a + b;
+
+ biari_encode_symbol(eep_dp, (signed short) (mb_field != 0),&ctx->mb_aff_contexts[act_ctx]);
+
+ se->context = act_ctx;
+
+ return;
+ }
+
+ /*!
+ ***************************************************************************
+ * \brief
+ * This function is used to arithmetically encode the mb_skip_flag.
+ ***************************************************************************
+ */
+ void writeMB_skip_flagInfo_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
+ {
+ int a,b,act_ctx;
+ int bframe = (img->type==B_SLICE);
+ MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ int curr_mb_type = se->value1;
+
+ if (bframe)
+ {
+ if (currMB->mb_available_up == NULL)
+ b = 0;
+ else
+ b = (currMB->mb_available_up->skip_flag==0 ? 1 : 0);
+ if (currMB->mb_available_left == NULL)
+ a = 0;
+ else
+ a = (currMB->mb_available_left->skip_flag==0 ? 1 : 0);
+
+ act_ctx = 7 + a + b;
+
+ if (se->value1==0 && se->value2==0) // DIRECT mode, no coefficients
+ biari_encode_symbol (eep_dp, 1, &ctx->mb_type_contexts[2][act_ctx]);
+ else
+ biari_encode_symbol (eep_dp, 0, &ctx->mb_type_contexts[2][act_ctx]);
+
+ currMB->skip_flag = (se->value1==0 && se->value2==0)?1:0;
+ }
+ else
+ {
+ if (currMB->mb_available_up == NULL)
+ b = 0;
+ else
+ b = (( (currMB->mb_available_up)->skip_flag == 0) ? 1 : 0 );
+ if (currMB->mb_available_left == NULL)
+ a = 0;
+ else
+ a = (( (currMB->mb_available_left)->skip_flag == 0) ? 1 : 0 );
+
+ act_ctx = a + b;
+
+ if (curr_mb_type==0) // SKIP
+ biari_encode_symbol(eep_dp, 1,&ctx->mb_type_contexts[1][act_ctx]);
+ else
+ biari_encode_symbol(eep_dp, 0,&ctx->mb_type_contexts[1][act_ctx]);
+
+ currMB->skip_flag = (curr_mb_type==0)?1:0;
+ }
+ se->context = act_ctx;
+
+ return;
+ }
+
+ /*!
+ ***************************************************************************
+ * \brief
+ * This function is used to arithmetically encode the macroblock
+ * intra_pred_size flag info of a given MB.
+ ***************************************************************************
+ */
+
+ void writeMB_transform_size_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
+ {
+ int a, b;
+ int act_ctx = 0;
+ int act_sym;
+
+ MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+
+
+ b = (currMB->mb_available_up == NULL) ? 0 : currMB->mb_available_up->luma_transform_size_8x8_flag;
+ a = (currMB->mb_available_left == NULL) ? 0 :currMB->mb_available_left->luma_transform_size_8x8_flag;
+
+ act_ctx = a + b;
+ act_sym = currMB->luma_transform_size_8x8_flag;
+ se->context = act_ctx; // store context
+ biari_encode_symbol(eep_dp, (signed short) (act_sym != 0), ctx->transform_size_contexts + act_ctx );
+ }
+
+ /*!
+ ***************************************************************************
+ * \brief
+ * This function is used to arithmetically encode the macroblock
+ * type info of a given MB.
+ ***************************************************************************
+ */
+
+ void writeMB_typeInfo_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
+ {
+ int a, b;
+ int act_ctx = 0;
+ int act_sym;
+ signed short csym;
+ int bframe = (img->type==B_SLICE);
+ int mode_sym = 0;
+ int mode16x16;
+
+
+ MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ int curr_mb_type = se->value1;
+
+ if(img->type == I_SLICE) // INTRA-frame
+ {
+ if (currMB->mb_available_up == NULL)
+ b = 0;
+ else
+ b = ((currMB->mb_available_up->mb_type != I4MB && currMB->mb_available_up->mb_type != I8MB) ? 1 : 0 );
+
+ if (currMB->mb_available_left == NULL)
+ a = 0;
+ else
+ a = ((currMB->mb_available_left->mb_type != I4MB && currMB->mb_available_left->mb_type != I8MB) ? 1 : 0 );
+
+ act_ctx = a + b;
+ act_sym = curr_mb_type;
+ se->context = act_ctx; // store context
+
+ if (act_sym==0) // 4x4 Intra
+ {
+ biari_encode_symbol(eep_dp, 0, ctx->mb_type_contexts[0] + act_ctx );
+ }
+ else if( act_sym == 25 ) // PCM-MODE
+ {
+ biari_encode_symbol(eep_dp, 1, ctx->mb_type_contexts[0] + act_ctx );
+ biari_encode_symbol_final(eep_dp, 1);
+ }
+ else // 16x16 Intra
+ {
+ biari_encode_symbol(eep_dp, 1, ctx->mb_type_contexts[0] + act_ctx );
+
+ biari_encode_symbol_final(eep_dp, 0);
+
+ mode_sym = act_sym-1; // Values in the range of 0...23
+ act_ctx = 4;
+ act_sym = mode_sym/12;
+ biari_encode_symbol(eep_dp, (signed short) act_sym, ctx->mb_type_contexts[0] + act_ctx ); // coding of AC/no AC
+ mode_sym = mode_sym % 12;
+ act_sym = mode_sym / 4; // coding of cbp: 0,1,2
+ act_ctx = 5;
+ if (act_sym==0)
+ {
+ biari_encode_symbol(eep_dp, 0, ctx->mb_type_contexts[0] + act_ctx );
+ }
+ else
+ {
+ biari_encode_symbol(eep_dp, 1, ctx->mb_type_contexts[0] + act_ctx );
+ act_ctx=6;
+ biari_encode_symbol(eep_dp, (signed short) (act_sym!=1), ctx->mb_type_contexts[0] + act_ctx );
+ }
+ mode_sym = mode_sym & 0x03; // coding of I pred-mode: 0,1,2,3
+ act_sym = mode_sym >> 1;
+ act_ctx = 7;
+ biari_encode_symbol(eep_dp, (signed short) act_sym, ctx->mb_type_contexts[0] + act_ctx );
+ act_ctx = 8;
+ act_sym = mode_sym & 0x01;
+ biari_encode_symbol(eep_dp, (signed short) act_sym, ctx->mb_type_contexts[0] + act_ctx );
+ }
+ }
+ else // INTER
+ {
+
+ if (bframe)
+ {
+ if (currMB->mb_available_up == NULL)
+ b = 0;
+ else
+ b = ((currMB->mb_available_up->mb_type != 0) ? 1 : 0 );
+
+ if (currMB->mb_available_left == NULL)
+ a = 0;
+ else
+ a = ((currMB->mb_available_left->mb_type != 0) ? 1 : 0 );
+ act_ctx = a + b;
+ se->context = act_ctx; // store context
+ }
+ act_sym = curr_mb_type;
+
+ if (act_sym>=(mode16x16=(bframe?24:7)))
+ {
+ mode_sym = act_sym-mode16x16;
+ act_sym = mode16x16; // 16x16 mode info
+ }
+
+ if (!bframe)
+ {
+ switch (act_sym)
+ {
+ case 0:
+ break;
+ case 1:
+ biari_encode_symbol (eep_dp, 0, &ctx->mb_type_contexts[1][4]);
+ biari_encode_symbol (eep_dp, 0, &ctx->mb_type_contexts[1][5]);
+ biari_encode_symbol (eep_dp, 0, &ctx->mb_type_contexts[1][6]);
+ break;
+ case 2:
+ biari_encode_symbol (eep_dp, 0, &ctx->mb_type_contexts[1][4]);
+ biari_encode_symbol (eep_dp, 1, &ctx->mb_type_contexts[1][5]);
+ biari_encode_symbol (eep_dp, 1, &ctx->mb_type_contexts[1][7]);
+ break;
+ case 3:
+ biari_encode_symbol (eep_dp, 0, &ctx->mb_type_contexts[1][4]);
+ biari_encode_symbol (eep_dp, 1, &ctx->mb_type_contexts[1][5]);
+ biari_encode_symbol (eep_dp, 0, &ctx->mb_type_contexts[1][7]);
+ break;
+ case 4:
+ case 5:
+ biari_encode_symbol (eep_dp, 0, &ctx->mb_type_contexts[1][4]);
+ biari_encode_symbol (eep_dp, 0, &ctx->mb_type_contexts[1][5]);
+ biari_encode_symbol (eep_dp, 1, &ctx->mb_type_contexts[1][6]);
+ break;
+ case 6:
+ biari_encode_symbol (eep_dp, 1, &ctx->mb_type_contexts[1][4]);
+ biari_encode_symbol (eep_dp, 0, &ctx->mb_type_contexts[1][7]);
+ break;
+ case 7:
+ biari_encode_symbol (eep_dp, 1, &ctx->mb_type_contexts[1][4]);
+ biari_encode_symbol (eep_dp, 1, &ctx->mb_type_contexts[1][7]);
+ break;
+ default:
+ printf ("Unsupported MB-MODE in writeMB_typeInfo_CABAC!\n");
+ exit (1);
+ }
+ }
+ else //===== B-FRAMES =====
+ {
+ if (act_sym==0)
+ {
+ biari_encode_symbol (eep_dp, 0, &ctx->mb_type_contexts[2][act_ctx]);
+ }
+ else if (act_sym<=2)
+ {
+ biari_encode_symbol (eep_dp, 1, &ctx->mb_type_contexts[2][act_ctx]);
+ biari_encode_symbol (eep_dp, 0, &ctx->mb_type_contexts[2][4]);
+ csym = (act_sym-1 != 0);
+ biari_encode_symbol (eep_dp, csym, &ctx->mb_type_contexts[2][6]);
+ }
+ else if (act_sym<=10)
+ {
+ biari_encode_symbol (eep_dp, 1, &ctx->mb_type_contexts[2][act_ctx]);
+ biari_encode_symbol (eep_dp, 1, &ctx->mb_type_contexts[2][4]);
+ biari_encode_symbol (eep_dp, 0, &ctx->mb_type_contexts[2][5]);
+ csym=(((act_sym-3)>>2)&0x01) != 0;
+ biari_encode_symbol (eep_dp, csym, &ctx->mb_type_contexts[2][6]);
+ csym=(((act_sym-3)>>1)&0x01) != 0;
+ biari_encode_symbol (eep_dp, csym, &ctx->mb_type_contexts[2][6]);
+ csym=((act_sym-3)&0x01) != 0;
+ biari_encode_symbol (eep_dp, csym, &ctx->mb_type_contexts[2][6]);
+ }
+ else if (act_sym==11 || act_sym==22)
+ {
+ biari_encode_symbol (eep_dp, 1, &ctx->mb_type_contexts[2][act_ctx]);
+ biari_encode_symbol (eep_dp, 1, &ctx->mb_type_contexts[2][4]);
+ biari_encode_symbol (eep_dp, 1, &ctx->mb_type_contexts[2][5]);
+ biari_encode_symbol (eep_dp, 1, &ctx->mb_type_contexts[2][6]);
+ biari_encode_symbol (eep_dp, 1, &ctx->mb_type_contexts[2][6]);
+ csym = (act_sym != 11);
+ biari_encode_symbol (eep_dp, csym, &ctx->mb_type_contexts[2][6]);
+ }
+ else
+ {
+ if (act_sym > 22) act_sym--;
+ biari_encode_symbol (eep_dp, 1, &ctx->mb_type_contexts[2][act_ctx]);
+ biari_encode_symbol (eep_dp, 1, &ctx->mb_type_contexts[2][4]);
+ biari_encode_symbol (eep_dp, 1, &ctx->mb_type_contexts[2][5]);
+ csym=(((act_sym-12)>>3)&0x01) != 0;
+ biari_encode_symbol (eep_dp, csym, &ctx->mb_type_contexts[2][6]);
+ csym=(((act_sym-12)>>2)&0x01) != 0;
+ biari_encode_symbol (eep_dp, csym, &ctx->mb_type_contexts[2][6]);
+ csym=(((act_sym-12)>>1)&0x01) != 0;
+ biari_encode_symbol (eep_dp, csym, &ctx->mb_type_contexts[2][6]);
+ csym=((act_sym-12)&0x01) != 0;
+ biari_encode_symbol (eep_dp, csym, &ctx->mb_type_contexts[2][6]);
+ if (act_sym >=22) act_sym++;
+ }
+ }
+
+ if(act_sym==mode16x16) // additional info for 16x16 Intra-mode
+ {
+ if( mode_sym==25 )
+ {
+ biari_encode_symbol_final(eep_dp, 1 );
+ return;
+ }
+ biari_encode_symbol_final(eep_dp, 0 );
+
+ act_ctx = 8;
+ act_sym = mode_sym/12;
+ biari_encode_symbol(eep_dp, (signed short) act_sym, ctx->mb_type_contexts[1] + act_ctx ); // coding of AC/no AC
+ mode_sym = mode_sym % 12;
+
+ act_sym = mode_sym / 4; // coding of cbp: 0,1,2
+ act_ctx = 9;
+ if (act_sym==0)
+ {
+ biari_encode_symbol(eep_dp, 0, ctx->mb_type_contexts[1] + act_ctx );
+ }
+ else
+ {
+ biari_encode_symbol(eep_dp, 1, ctx->mb_type_contexts[1] + act_ctx );
+ biari_encode_symbol(eep_dp, (signed short) (act_sym!=1), ctx->mb_type_contexts[1] + act_ctx );
+ }
+
+ mode_sym = mode_sym % 4; // coding of I pred-mode: 0,1,2,3
+ act_ctx = 10;
+ act_sym = mode_sym/2;
+ biari_encode_symbol(eep_dp, (signed short) act_sym, ctx->mb_type_contexts[1] + act_ctx );
+ act_sym = mode_sym%2;
+ biari_encode_symbol(eep_dp, (signed short) act_sym, ctx->mb_type_contexts[1] + act_ctx );
+ }
+ }
+ }
+
+
+ /*!
+ ***************************************************************************
+ * \brief
+ * This function is used to arithmetically encode the 8x8 block
+ * type info
+ ***************************************************************************
+ */
+ void writeB8_typeInfo_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
+ {
+ int act_ctx;
+ int act_sym;
+ signed short csym;
+ int bframe=(img->type==B_SLICE);
+
+ MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx;
+
+ act_sym = se->value1;
+ act_ctx = 0;
+
+ if (!bframe)
+ {
+ switch (act_sym)
+ {
+ case 0:
+ biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[0][1]);
+ break;
+ case 1:
+ biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[0][1]);
+ biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[0][3]);
+ break;
+ case 2:
+ biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[0][1]);
+ biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[0][3]);
+ biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[0][4]);
+ break;
+ case 3:
+ biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[0][1]);
+ biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[0][3]);
+ biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[0][4]);
+ break;
+ }
+ }
+ else //===== B-FRAME =====
+ {
+ if (act_sym==0)
+ {
+ biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[1][0]);
+ return;
+ }
+ else
+ {
+ biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[1][0]);
+ act_sym--;
+ }
+ if (act_sym<2)
+ {
+ biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[1][1]);
+ biari_encode_symbol (eep_dp, (signed short) (act_sym!=0), &ctx->b8_type_contexts[1][3]);
+ }
+ else if (act_sym<6)
+ {
+ biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[1][1]);
+ biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[1][2]);
+ csym=(((act_sym-2)>>1)&0x01) != 0;
+ biari_encode_symbol (eep_dp, csym, &ctx->b8_type_contexts[1][3]);
+ csym=((act_sym-2)&0x01) != 0;
+ biari_encode_symbol (eep_dp, csym, &ctx->b8_type_contexts[1][3]);
+ }
+ else
+ {
+ biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[1][1]);
+ biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[1][2]);
+ csym=(((act_sym-6)>>2)&0x01);
+ if (csym)
+ {
+ biari_encode_symbol (eep_dp, 1, &ctx->b8_type_contexts[1][3]);
+ csym=((act_sym-6)&0x01) != 0;
+ biari_encode_symbol (eep_dp, csym, &ctx->b8_type_contexts[1][3]);
+ }
+ else
+ {
+ biari_encode_symbol (eep_dp, 0, &ctx->b8_type_contexts[1][3]);
+ csym=(((act_sym-6)>>1)&0x01) != 0;
+ biari_encode_symbol (eep_dp, csym, &ctx->b8_type_contexts[1][3]);
+ csym=((act_sym-6)&0x01) != 0;
+ biari_encode_symbol (eep_dp, csym, &ctx->b8_type_contexts[1][3]);
+ }
+ }
+ }
+ }
+
+
+ /*!
+ ****************************************************************************
+ * \brief
+ * This function is used to arithmetically encode a pair of
+ * intra prediction modes of a given MB.
+ ****************************************************************************
+ */
+ void writeIntraPredMode_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
+ {
+ TextureInfoContexts *ctx = img->currentSlice->tex_ctx;
+
+ // use_most_probable_mode
+ if (se->value1 == -1)
+ biari_encode_symbol(eep_dp, 1, ctx->ipr_contexts);
+ else
+ {
+ biari_encode_symbol(eep_dp, 0, ctx->ipr_contexts);
+
+ // remaining_mode_selector
+ biari_encode_symbol(eep_dp,(signed short)( se->value1 & 0x1 ), ctx->ipr_contexts+1);
+ biari_encode_symbol(eep_dp,(signed short)((se->value1 & 0x2)>>1), ctx->ipr_contexts+1);
+ biari_encode_symbol(eep_dp,(signed short)((se->value1 & 0x4)>>2), ctx->ipr_contexts+1);
+ }
+ }
+ /*!
+ ****************************************************************************
+ * \brief
+ * This function is used to arithmetically encode the reference
+ * parameter of a given MB.
+ ****************************************************************************
+ */
+ void writeRefFrame_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
+ {
+ MotionInfoContexts *ctx = img->currentSlice->mot_ctx;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ int addctx = 0;
+
+ int a, b;
+ int act_ctx;
+ int act_sym;
+ char** refframe_array = enc_picture->ref_idx[se->value2];
+
+ int bslice = (img->type==B_SLICE);
+
+ int b8a, b8b;
+
+ PixelPos block_a, block_b;
+
+ getLuma4x4Neighbour(img->current_mb_nr, img->subblock_x, img->subblock_y, -1, 0, &block_a);
+ getLuma4x4Neighbour(img->current_mb_nr, img->subblock_x, img->subblock_y, 0, -1, &block_b);
+
+ b8a=((block_a.x >> 1) & 0x01)+2*((block_a.y >> 1) & 0x01);
+ b8b=((block_b.x >> 1) & 0x01)+2*((block_b.y >> 1) & 0x01);
+
+
+ if (!block_b.available)
+ b=0;
+ else if (IS_DIRECT(&img->mb_data[block_b.mb_addr]) || (img->mb_data[block_b.mb_addr].b8mode[b8b]==0 && bslice))
+ b=0;
+ else
+ {
+ if (img->MbaffFrameFlag && (currMB->mb_field == 0) && (img->mb_data[block_b.mb_addr].mb_field == 1))
+ b = (refframe_array[block_b.pos_y][block_b.pos_x] > 1 ? 1 : 0);
+ else
+ b = (refframe_array[block_b.pos_y][block_b.pos_x] > 0 ? 1 : 0);
+ }
+
+ if (!block_a.available)
+ a=0;
+ else if (IS_DIRECT(&img->mb_data[block_a.mb_addr]) || (img->mb_data[block_a.mb_addr].b8mode[b8a]==0 && bslice))
+ a=0;
+ else
+ {
+ if (img->MbaffFrameFlag && (currMB->mb_field == 0) && (img->mb_data[block_a.mb_addr].mb_field == 1))
+ a = (refframe_array[block_a.pos_y][block_a.pos_x] > 1 ? 1 : 0);
+ else
+ a = (refframe_array[block_a.pos_y][block_a.pos_x] > 0 ? 1 : 0);
+ }
+
+ act_ctx = a + 2*b;
+ se->context = act_ctx; // store context
+ act_sym = se->value1;
+
+ if (act_sym==0)
+ {
+ biari_encode_symbol(eep_dp, 0, ctx->ref_no_contexts[addctx] + act_ctx );
+ }
+ else
+ {
+ biari_encode_symbol(eep_dp, 1, ctx->ref_no_contexts[addctx] + act_ctx);
+ act_sym--;
+ act_ctx=4;
+ unary_bin_encode(eep_dp, act_sym,ctx->ref_no_contexts[addctx]+act_ctx,1);
+ }
+ }
+
+ /*!
+ ****************************************************************************
+ * \brief
+ * This function is used to arithmetically encode the coded
+ * block pattern of a given delta quant.
+ ****************************************************************************
+ */
+ void writeDquant_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
+ {
+ MotionInfoContexts *ctx = img->currentSlice->mot_ctx;
+
+ int act_ctx;
+ int act_sym;
+ int dquant = se->value1;
+ int sign=0;
+
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+
+ last_dquant=currMB->prev_delta_qp;
+
+ if (dquant <= 0)
+ sign = 1;
+ act_sym = absm(dquant) << 1;
+
+ act_sym += sign;
+ act_sym --;
+
+ act_ctx = ( (last_dquant != 0) ? 1 : 0);
+
+ if (act_sym==0)
+ {
+ biari_encode_symbol(eep_dp, 0, ctx->delta_qp_contexts + act_ctx );
+ }
+ else
+ {
+ biari_encode_symbol(eep_dp, 1, ctx->delta_qp_contexts + act_ctx);
+ act_ctx=2;
+ act_sym--;
+ unary_bin_encode(eep_dp, act_sym,ctx->delta_qp_contexts+act_ctx,1);
+ }
+ }
+
+ /*!
+ ****************************************************************************
+ * \brief
+ * This function is used to arithmetically encode the motion
+ * vector data of a B-frame MB.
+ ****************************************************************************
+ */
+ void writeMVD_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
+ {
+ int i = img->subblock_x;
+ int j = img->subblock_y;
+ int a, b;
+ int act_ctx;
+ int act_sym;
+ int mv_pred_res;
+ int mv_local_err;
+ int mv_sign;
+ int list_idx = se->value2 & 0x01;
+ int k = (se->value2>>1); // MVD component
+
+ PixelPos block_a, block_b;
+
+ MotionInfoContexts *ctx = img->currentSlice->mot_ctx;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+
+ getLuma4x4Neighbour(img->current_mb_nr, i, j, -1, 0, &block_a);
+ getLuma4x4Neighbour(img->current_mb_nr, i, j, 0, -1, &block_b);
+
+ if (block_b.available)
+ {
+ b = absm(img->mb_data[block_b.mb_addr].mvd[list_idx][block_b.y][block_b.x][k]);
+ if (img->MbaffFrameFlag && (k==1))
+ {
+ if ((currMB->mb_field==0) && (img->mb_data[block_b.mb_addr].mb_field==1))
+ b *= 2;
+ else if ((currMB->mb_field==1) && (img->mb_data[block_b.mb_addr].mb_field==0))
+ b /= 2;
+ }
+ }
+ else
+ b=0;
+
+ if (block_a.available)
+ {
+ a = absm(img->mb_data[block_a.mb_addr].mvd[list_idx][block_a.y][block_a.x][k]);
+ if (img->MbaffFrameFlag && (k==1))
+ {
+ if ((currMB->mb_field==0) && (img->mb_data[block_a.mb_addr].mb_field==1))
+ a *= 2;
+ else if ((currMB->mb_field==1) && (img->mb_data[block_a.mb_addr].mb_field==0))
+ a /= 2;
+ }
+ }
+ else
+ a = 0;
+
+ if ((mv_local_err=a+b)<3)
+ act_ctx = 5*k;
+ else
+ {
+ if (mv_local_err>32)
+ act_ctx=5*k+3;
+ else
+ act_ctx=5*k+2;
+ }
+
+ mv_pred_res = se->value1;
+ se->context = act_ctx;
+
+ act_sym = absm(mv_pred_res);
+
+ if (act_sym == 0)
+ biari_encode_symbol(eep_dp, 0, &ctx->mv_res_contexts[0][act_ctx] );
+ else
+ {
+ biari_encode_symbol(eep_dp, 1, &ctx->mv_res_contexts[0][act_ctx] );
+ act_sym--;
+ act_ctx=5*k;
+ unary_exp_golomb_mv_encode(eep_dp,act_sym,ctx->mv_res_contexts[1]+act_ctx,3);
+ mv_sign = (mv_pred_res<0) ? 1: 0;
+ biari_encode_symbol_eq_prob(eep_dp, (signed short) mv_sign);
+ }
+ }
+
+
+ /*!
+ ****************************************************************************
+ * \brief
+ * This function is used to arithmetically encode the chroma
+ * intra prediction mode of an 8x8 block
+ ****************************************************************************
+ */
+ void writeCIPredMode_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
+ {
+ TextureInfoContexts *ctx = img->currentSlice->tex_ctx;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ int act_ctx,a,b;
+ int act_sym = se->value1;
+
+ if (currMB->mb_available_up == NULL) b = 0;
+ else b = ( ((currMB->mb_available_up)->c_ipred_mode != 0) ? 1 : 0);
+
+ if (currMB->mb_available_left == NULL) a = 0;
+ else a = ( ((currMB->mb_available_left)->c_ipred_mode != 0) ? 1 : 0);
+
+ act_ctx = a+b;
+
+ if (act_sym==0)
+ biari_encode_symbol(eep_dp, 0, ctx->cipr_contexts + act_ctx );
+ else
+ {
+ biari_encode_symbol(eep_dp, 1, ctx->cipr_contexts + act_ctx );
+ unary_bin_max_encode(eep_dp,(unsigned int) (act_sym-1),ctx->cipr_contexts+3,0,2);
+ }
+ }
+
+
+ /*!
+ ****************************************************************************
+ * \brief
+ * This function is used to arithmetically encode the coded
+ * block pattern of an 8x8 block
+ ****************************************************************************
+ */
+ void writeCBP_BIT_CABAC (int b8, int bit, int cbp, Macroblock* currMB, int inter, EncodingEnvironmentPtr eep_dp)
+ {
+ PixelPos block_a;
+ int a, b;
+
+ int mb_x=(b8 & 0x01)<<1;
+ int mb_y=(b8 >> 1)<<1;
+
+ if (mb_y == 0)
+ {
+ if (currMB->mb_available_up == NULL)
+ b = 0;
+ else
+ {
+ if((currMB->mb_available_up)->mb_type==IPCM)
+ b=0;
+ else
+ b = (( ((currMB->mb_available_up)->cbp & (1<<(2+(mb_x>>1)))) == 0) ? 1 : 0); //VG-ADD
+ }
+
+ }
+ else
+ b = ( ((cbp & (1<<(mb_x/2))) == 0) ? 1: 0);
+
+ if (mb_x == 0)
+ {
+ getLuma4x4Neighbour(img->current_mb_nr, mb_x, mb_y, -1, 0, &block_a);
+ if (block_a.available)
+ {
+ {
+ if(img->mb_data[block_a.mb_addr].mb_type==IPCM)
+ a=0;
+ else
+ a = (( (img->mb_data[block_a.mb_addr].cbp & (1<<(2*(block_a.y>>1)+1))) == 0) ? 1 : 0); //VG-ADD
+ }
+
+ }
+ else
+ a=0;
+ }
+ else
+ a = ( ((cbp & (1<<mb_y)) == 0) ? 1: 0);
+
+ //===== WRITE BIT =====
+ biari_encode_symbol (eep_dp, (signed short) bit,
+ img->currentSlice->tex_ctx->cbp_contexts[0] + a+2*b);
+ }
+
+ /*!
+ ****************************************************************************
+ * \brief
+ * This function is used to arithmetically encode the coded
+ * block pattern of a macroblock
+ ****************************************************************************
+ */
+ void writeCBP_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
+ {
+ TextureInfoContexts *ctx = img->currentSlice->tex_ctx;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+
+ int a, b;
+ int curr_cbp_ctx, curr_cbp_idx;
+ int cbp = se->value1; // symbol to encode
+ int cbp_bit;
+ int b8;
+
+ for (b8=0; b8<4; b8++)
+ {
+ curr_cbp_idx = (currMB->b8mode[b8] == IBLOCK ? 0 : 1);
+ writeCBP_BIT_CABAC (b8, cbp&(1<<b8), cbp, currMB, curr_cbp_idx, eep_dp);
+ }
+
+ if (img->yuv_format != YUV400)
+ {
+ // coding of chroma part
+ b = 0;
+ if (currMB->mb_available_up != NULL)
+ {
+ if((currMB->mb_available_up)->mb_type==IPCM)
+ b=1;
+ else
+ b = ((currMB->mb_available_up)->cbp > 15) ? 1 : 0;
+ }
+
+
+ a = 0;
+ if (currMB->mb_available_left != NULL)
+ {
+ if((currMB->mb_available_left)->mb_type==IPCM)
+ a=1;
+ else
+ a = ((currMB->mb_available_left)->cbp > 15) ? 1 : 0;
+ }
+
+ curr_cbp_ctx = a+2*b;
+ cbp_bit = (cbp > 15 ) ? 1 : 0;
+ biari_encode_symbol(eep_dp, (signed short) cbp_bit, ctx->cbp_contexts[1] + curr_cbp_ctx );
+
+ if (cbp > 15)
+ {
+ b = 0;
+ if (currMB->mb_available_up != NULL)
+ {
+ if((currMB->mb_available_up)->mb_type==IPCM)
+ b=1;
+ else
+ if ((currMB->mb_available_up)->cbp > 15)
+ b = (( ((currMB->mb_available_up)->cbp >> 4) == 2) ? 1 : 0);
+ }
+
+
+ a = 0;
+ if (currMB->mb_available_left != NULL)
+ {
+ if((currMB->mb_available_left)->mb_type==IPCM)
+ a=1;
+ else
+ if ((currMB->mb_available_left)->cbp > 15)
+ a = (( ((currMB->mb_available_left)->cbp >> 4) == 2) ? 1 : 0);
+ }
+
+ curr_cbp_ctx = a+2*b;
+ cbp_bit = ((cbp>>4) == 2) ? 1 : 0;
+ biari_encode_symbol(eep_dp, (signed short) cbp_bit, ctx->cbp_contexts[2] + curr_cbp_ctx );
+ }
+ }
+ }
+
+ static const int maxpos [] = {16, 15, 64, 32, 32, 16, 4, 15, 8, 16};
+ static const int c1isdc [] = { 1, 0, 1, 1, 1, 1, 1, 0, 1, 1};
+
+ static const int type2ctx_bcbp[] = { 0, 1, 2, 2, 3, 4, 5, 6, 5, 5}; // 7
+ static const int type2ctx_map [] = { 0, 1, 2, 3, 4, 5, 6, 7, 6, 6}; // 8
+ static const int type2ctx_last[] = { 0, 1, 2, 3, 4, 5, 6, 7, 6, 6}; // 8
+ static const int type2ctx_one [] = { 0, 1, 2, 3, 3, 4, 5, 6, 5, 5}; // 7
+ static const int type2ctx_abs [] = { 0, 1, 2, 3, 3, 4, 5, 6, 5, 5}; // 7
+ static const int max_c2 [] = { 4, 4, 4, 4, 4, 4, 3, 4, 3, 3}; // 9
+
+
+
+ /*!
+ ****************************************************************************
+ * \brief
+ * Write CBP4-BIT
+ ****************************************************************************
+ */
+ void write_and_store_CBP_block_bit (Macroblock* currMB, EncodingEnvironmentPtr eep_dp, int type, int cbp_bit)
+ {
+ #define BIT_SET(x,n) ((int)(((x)&((int64)1<<(n)))>>(n)))
+
+ int y_ac = (type==LUMA_16AC || type==LUMA_8x8 || type==LUMA_8x4 || type==LUMA_4x8 || type==LUMA_4x4);
+ int y_dc = (type==LUMA_16DC);
+ int u_ac = (type==CHROMA_AC && !img->is_v_block);
+ int v_ac = (type==CHROMA_AC && img->is_v_block);
+ int chroma_dc = (type==CHROMA_DC || type==CHROMA_DC_2x4 || type==CHROMA_DC_4x4);
+ int u_dc = (chroma_dc && !img->is_v_block);
+ int v_dc = (chroma_dc && img->is_v_block);
+ int j = (y_ac || u_ac || v_ac ? img->subblock_y : 0);
+ int i = (y_ac || u_ac || v_ac ? img->subblock_x : 0);
+ int bit = (y_dc ? 0 : y_ac ? 1 : u_dc ? 17 : v_dc ? 18 : u_ac ? 19 : 23);
+ int default_bit = (img->is_intra_block ? 1 : 0);
+ int upper_bit = default_bit;
+ int left_bit = default_bit;
+ int ctx;
+
+ int bit_pos_a = 0;
+ int bit_pos_b = 0;
+
+ PixelPos block_a, block_b;
+
+ if (y_ac || y_dc)
+ {
+ getLuma4x4Neighbour(img->current_mb_nr, i, j, -1, 0, &block_a);
+ getLuma4x4Neighbour(img->current_mb_nr, i, j, 0, -1, &block_b);
+ if (y_ac)
+ {
+ if (block_a.available)
+ bit_pos_a = 4*block_a.y + block_a.x;
+ if (block_b.available)
+ bit_pos_b = 4*block_b.y + block_b.x;
+ }
+ }
+ else
+ {
+ getChroma4x4Neighbour(img->current_mb_nr, i, j, -1, 0, &block_a);
+ getChroma4x4Neighbour(img->current_mb_nr, i, j, 0, -1, &block_b);
+ if (u_ac||v_ac)
+ {
+ if (block_a.available)
+ bit_pos_a = 4*block_a.y + block_a.x;
+ if (block_b.available)
+ bit_pos_b = 4*block_b.y + block_b.x;
+ }
+ }
+
+ bit = (y_dc ? 0 : y_ac ? 1+4*j+i : u_dc ? 17 : v_dc ? 18 : u_ac ? 19+4*j+i : 35+4*j+i);
+ //--- set bits for current block ---
+ if (cbp_bit)
+ {
+ if (type==LUMA_8x8)
+ {
+ currMB->cbp_bits |= (1<< bit );
+ currMB->cbp_bits |= (1<<(bit+1));
+ currMB->cbp_bits |= (1<<(bit+4));
+ currMB->cbp_bits |= (1<<(bit+5));
+ }
+ else if (type==LUMA_8x4)
+ {
+ currMB->cbp_bits |= (1<< bit );
+ currMB->cbp_bits |= (1<<(bit+1));
+ }
+ else if (type==LUMA_4x8)
+ {
+ currMB->cbp_bits |= (1<< bit );
+ currMB->cbp_bits |= (1<<(bit+4));
+ }
+ else
+ {
+ currMB->cbp_bits |= ((int64)1<<bit);
+ }
+ }
+
+ bit = (y_dc ? 0 : y_ac ? 1 : u_dc ? 17 : v_dc ? 18 : u_ac ? 19 : 35);
+ if (type!=LUMA_8x8)
+ {
+ if (block_b.available)
+ {
+ if(img->mb_data[block_b.mb_addr].mb_type==IPCM)
+ upper_bit=1;
+ else
+ upper_bit = BIT_SET(img->mb_data[block_b.mb_addr].cbp_bits,bit+bit_pos_b);
+ }
+
+
+ if (block_a.available)
+ {
+ if(img->mb_data[block_a.mb_addr].mb_type==IPCM)
+ left_bit=1;
+ else
+ left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits,bit+bit_pos_a);
+ }
+
+ ctx = 2*upper_bit+left_bit;
+
+ //===== encode symbol =====
+ biari_encode_symbol (eep_dp, (short)cbp_bit, img->currentSlice->tex_ctx->bcbp_contexts[type2ctx_bcbp[type]]+ctx);
+ }
+ }
+
+
+
+
+ //===== position -> ctx for MAP =====
+ //--- zig-zag scan ----
+ static const int pos2ctx_map8x8 [] = { 0, 1, 2, 3, 4, 5, 5, 4, 4, 3, 3, 4, 4, 4, 5, 5,
+ 4, 4, 4, 4, 3, 3, 6, 7, 7, 7, 8, 9, 10, 9, 8, 7,
+ 7, 6, 11, 12, 13, 11, 6, 7, 8, 9, 14, 10, 9, 8, 6, 11,
+ 12, 13, 11, 6, 9, 14, 10, 9, 11, 12, 13, 11 ,14, 10, 12, 14}; // 15 CTX
+ static const int pos2ctx_map8x4 [] = { 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 9, 8, 6, 7, 8,
+ 9, 10, 11, 9, 8, 6, 12, 8, 9, 10, 11, 9, 13, 13, 14, 14}; // 15 CTX
+ static const int pos2ctx_map4x4 [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14}; // 15 CTX
+ static const int pos2ctx_map2x4c[] = { 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; // 15 CTX
+ static const int pos2ctx_map4x4c[] = { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2}; // 15 CTX
+ static const int* pos2ctx_map [] = {pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map8x8, pos2ctx_map8x4,
+ pos2ctx_map8x4, pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map4x4,
+ pos2ctx_map2x4c, pos2ctx_map4x4c};
+
+ //--- interlace scan ----
+ //Taken from ABT
+ static const int pos2ctx_map8x8i[] = { 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 7, 8, 4, 5,
+ 6, 9, 10, 10, 8, 11, 12, 11, 9, 9, 10, 10, 8, 11, 12, 11,
+ 9, 9, 10, 10, 8, 11, 12, 11, 9, 9, 10, 10, 8, 13, 13, 9,
+ 9, 10, 10, 8, 13, 13, 9, 9, 10, 10, 14, 14, 14, 14, 14, 14}; // 15 CTX
+
+ static const int pos2ctx_map8x4i[] = { 0, 1, 2, 3, 4, 5, 6, 3, 4, 5, 6, 3, 4, 7, 6, 8,
+ 9, 7, 6, 8, 9, 10, 11, 12, 12, 10, 11, 13, 13, 14, 14, 14}; // 15 CTX
+ static const int pos2ctx_map4x8i[] = { 0, 1, 1, 1, 2, 3, 3, 4, 4, 4, 5, 6, 2, 7, 7, 8,
+ 8, 8, 5, 6, 9, 10, 10, 11, 11, 11, 12, 13, 13, 14, 14, 14}; // 15 CTX
+ static const int* pos2ctx_map_int[] = {pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map8x8i,pos2ctx_map8x4i,
+ pos2ctx_map4x8i,pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map4x4,
+ pos2ctx_map2x4c, pos2ctx_map4x4c};
+
+
+ //===== position -> ctx for LAST =====
+ static const int pos2ctx_last8x8 [] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8}; // 9 CTX
+ static const int pos2ctx_last8x4 [] = { 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8}; // 9 CTX
+ static const int pos2ctx_last4x4 [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; // 15 CTX
+ static const int pos2ctx_last2x4c[] = { 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; // 15 CTX
+ static const int pos2ctx_last4x4c[] = { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2}; // 15 CTX
+ static const int* pos2ctx_last [] = {pos2ctx_last4x4, pos2ctx_last4x4, pos2ctx_last8x8, pos2ctx_last8x4,
+ pos2ctx_last8x4, pos2ctx_last4x4, pos2ctx_last4x4, pos2ctx_last4x4,
+ pos2ctx_last2x4c, pos2ctx_last4x4c};
+
+
+
+
+ /*!
+ ****************************************************************************
+ * \brief
+ * Write Significance MAP
+ ****************************************************************************
+ */
+ void write_significance_map (Macroblock* currMB, EncodingEnvironmentPtr eep_dp, int type, int coeff[], int coeff_ctr)
+ {
+ int k;
+ unsigned short sig, last;
+ int k0 = 0;
+ int k1 = maxpos[type]-1;
+
+ int fld = ( img->structure!=FRAME || currMB->mb_field );
+ BiContextTypePtr map_ctx = ( fld ? img->currentSlice->tex_ctx->fld_map_contexts[type2ctx_map [type]]
+ : img->currentSlice->tex_ctx->map_contexts[type2ctx_map [type]] );
+ BiContextTypePtr last_ctx = ( fld ? img->currentSlice->tex_ctx->fld_last_contexts[type2ctx_last[type]]
+ : img->currentSlice->tex_ctx->last_contexts[type2ctx_last[type]] );
+
+ if (!c1isdc[type])
+ {
+ k0++; k1++; coeff--;
+ }
+
+ if (!fld)
+ {
+ for (k=k0; k<k1; k++) // if last coeff is reached, it has to be significant
+ {
+ sig = (coeff[k] != 0);
+ biari_encode_symbol (eep_dp, sig, map_ctx+pos2ctx_map [type][k]);
+ if (sig)
+ {
+ last = (--coeff_ctr == 0);
+
+ biari_encode_symbol(eep_dp, last, last_ctx+pos2ctx_last[type][k]);
+ if (last) return;
+ }
+ }
+ return;
+ }
+ else
+ {
+ for (k=k0; k<k1; k++) // if last coeff is reached, it has to be significant
+ {
+ sig = (coeff[k] != 0);
+
+ biari_encode_symbol (eep_dp, sig, map_ctx+pos2ctx_map_int [type][k]);
+ if (sig)
+ {
+ last = (--coeff_ctr == 0);
+
+ biari_encode_symbol(eep_dp, last, last_ctx+pos2ctx_last[type][k]);
+ if (last) return;
+ }
+ }
+ }
+ }
+
+
+ /*!
+ ****************************************************************************
+ * \brief
+ * Write Levels
+ ****************************************************************************
+ */
+ void write_significant_coefficients (Macroblock* currMB, EncodingEnvironmentPtr eep_dp, int type, int coeff[])
+ {
+ int i;
+ int absLevel;
+ int ctx;
+ short sign;
+ short greater_one;
+ int c1 = 1;
+ int c2 = 0;
+
+ for (i=maxpos[type]-1; i>=0; i--)
+ {
+ if (coeff[i]!=0)
+ {
+ if (coeff[i]>0) {absLevel = coeff[i]; sign = 0;}
+ else {absLevel = -coeff[i]; sign = 1;}
+
+ greater_one = (absLevel>1);
+
+ //--- if coefficient is one ---
+ ctx = min(c1,4);
+ biari_encode_symbol (eep_dp, greater_one, img->currentSlice->tex_ctx->one_contexts[type2ctx_one[type]] + ctx);
+
+ if (greater_one)
+ {
+ ctx = min(c2, max_c2[type]);
+ unary_exp_golomb_level_encode(eep_dp, absLevel-2, img->currentSlice->tex_ctx->abs_contexts[type2ctx_abs[type]] + ctx);
+ c1 = 0;
+ c2++;
+ }
+ else if (c1)
+ {
+ c1++;
+ }
+ biari_encode_symbol_eq_prob (eep_dp, sign);
+ }
+ }
+ }
+
+
+
+ /*!
+ ****************************************************************************
+ * \brief
+ * Write Block-Transform Coefficients
+ ****************************************************************************
+ */
+ void writeRunLevel_CABAC (SyntaxElement *se, EncodingEnvironmentPtr eep_dp)
+ {
+ static int coeff[64];
+ static int coeff_ctr = 0;
+ static int pos = 0;
+
+ //--- accumulate run-level information ---
+ if (se->value1 != 0)
+ {
+ pos += se->value2;
+ coeff[pos++] = se->value1;
+ coeff_ctr++;
+ //return;
+ }
+ else
+ {
+ Macroblock* currMB = &img->mb_data[img->current_mb_nr];
+ //===== encode CBP-BIT =====
+ if (coeff_ctr>0)
+ {
+ write_and_store_CBP_block_bit (currMB, eep_dp, se->context, 1);
+ //===== encode significance map =====
+ write_significance_map (currMB, eep_dp, se->context, coeff, coeff_ctr);
+ //===== encode significant coefficients =====
+ write_significant_coefficients (currMB, eep_dp, se->context, coeff);
+ }
+ else
+ write_and_store_CBP_block_bit (currMB, eep_dp, se->context, 0);
+
+ //--- reset counters ---
+ pos = coeff_ctr = 0;
+ memset(coeff, 0 , 64 * sizeof(int));
+ }
+ }
+
+
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Unary binarization and encoding of a symbol by using
+ * one or two distinct models for the first two and all
+ * remaining bins
+ *
+ ************************************************************************/
+ void unary_bin_encode(EncodingEnvironmentPtr eep_dp,
+ unsigned int symbol,
+ BiContextTypePtr ctx,
+ int ctx_offset)
+ {
+ unsigned int l;
+ BiContextTypePtr ictx;
+
+ if (symbol==0)
+ {
+ biari_encode_symbol(eep_dp, 0, ctx );
+ return;
+ }
+ else
+ {
+ biari_encode_symbol(eep_dp, 1, ctx );
+ l = symbol;
+ ictx = ctx+ctx_offset;
+ while ((--l)>0)
+ biari_encode_symbol(eep_dp, 1, ictx);
+ biari_encode_symbol(eep_dp, 0, ictx);
+ }
+ return;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Unary binarization and encoding of a symbol by using
+ * one or two distinct models for the first two and all
+ * remaining bins; no terminating "0" for max_symbol
+ * (finite symbol alphabet)
+ ************************************************************************
+ */
+ void unary_bin_max_encode(EncodingEnvironmentPtr eep_dp,
+ unsigned int symbol,
+ BiContextTypePtr ctx,
+ int ctx_offset,
+ unsigned int max_symbol)
+ {
+ unsigned int l;
+ BiContextTypePtr ictx;
+
+ if (symbol==0)
+ {
+ biari_encode_symbol(eep_dp, 0, ctx );
+ return;
+ }
+ else
+ {
+ biari_encode_symbol(eep_dp, 1, ctx );
+ l=symbol;
+ ictx=ctx+ctx_offset;
+ while ((--l)>0)
+ biari_encode_symbol(eep_dp, 1, ictx);
+ if (symbol<max_symbol)
+ biari_encode_symbol(eep_dp, 0, ictx);
+ }
+ return;
+ }
+
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Exp Golomb binarization and encoding
+ ************************************************************************
+ */
+ void exp_golomb_encode_eq_prob( EncodingEnvironmentPtr eep_dp,
+ unsigned int symbol,
+ int k)
+ {
+ while(1)
+ {
+ if (symbol >= (unsigned int)(1<<k))
+ {
+ biari_encode_symbol_eq_prob(eep_dp, 1); //first unary part
+ symbol = symbol - (1<<k);
+ k++;
+ }
+ else
+ {
+ biari_encode_symbol_eq_prob(eep_dp, 0); //now terminated zero of unary part
+ while (k--) //next binary part
+ biari_encode_symbol_eq_prob(eep_dp, (signed short)((symbol>>k)&1));
+ break;
+ }
+ }
+
+ return;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Exp-Golomb for Level Encoding
+ *
+ ************************************************************************/
+ void unary_exp_golomb_level_encode( EncodingEnvironmentPtr eep_dp,
+ unsigned int symbol,
+ BiContextTypePtr ctx)
+ {
+ unsigned int l,k;
+ unsigned int exp_start = 13; // 15-2 : 0,1 level decision always sent
+
+ if (symbol==0)
+ {
+ biari_encode_symbol(eep_dp, 0, ctx );
+ return;
+ }
+ else
+ {
+ biari_encode_symbol(eep_dp, 1, ctx );
+ l=symbol;
+ k=1;
+ while (((--l)>0) && (++k <= exp_start))
+ biari_encode_symbol(eep_dp, 1, ctx);
+ if (symbol < exp_start) biari_encode_symbol(eep_dp, 0, ctx);
+ else exp_golomb_encode_eq_prob(eep_dp,symbol-exp_start,0);
+ }
+ return;
+ }
+
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Exp-Golomb for MV Encoding
+ *
+ ************************************************************************/
+ void unary_exp_golomb_mv_encode(EncodingEnvironmentPtr eep_dp,
+ unsigned int symbol,
+ BiContextTypePtr ctx,
+ unsigned int max_bin)
+ {
+ unsigned int l,k;
+ unsigned int bin=1;
+ BiContextTypePtr ictx=ctx;
+ unsigned int exp_start = 8; // 9-1 : 0 mvd decision always sent
+
+ if (symbol==0)
+ {
+ biari_encode_symbol(eep_dp, 0, ictx );
+ return;
+ }
+ else
+ {
+ biari_encode_symbol(eep_dp, 1, ictx );
+ l=symbol;
+ k=1;
+ ictx++;
+ while (((--l)>0) && (++k <= exp_start))
+ {
+ biari_encode_symbol(eep_dp, 1, ictx );
+ if ((++bin)==2) ictx++;
+ if (bin==max_bin) ictx++;
+ }
+ if (symbol < exp_start) biari_encode_symbol(eep_dp, 0, ictx);
+ else exp_golomb_encode_eq_prob(eep_dp,symbol-exp_start,3);
+ }
+ return;
+ }
+
Index: llvm-test/MultiSource/Applications/JM/lencod/cabac.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/cabac.h:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/cabac.h Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,65 ----
+
+ /*!
+ ***************************************************************************
+ * \file
+ * cabac.h
+ *
+ * \brief
+ * Headerfile for entropy coding routines
+ *
+ * \author
+ * Detlev Marpe \n
+ * Copyright (C) 2000 HEINRICH HERTZ INSTITUTE All Rights Reserved.
+ *
+ * \date
+ * 21. Oct 2000 (Changes by Tobias Oelbaum 28.08.2001)
+ ***************************************************************************
+ */
+
+
+ #ifndef _CABAC_H_
+ #define _CABAC_H_
+
+ // CABAC
+ int get_pic_bin_count();
+ void reset_pic_bin_count();
+
+ void arienco_start_encoding(EncodingEnvironmentPtr eep, unsigned char *code_buffer, int *code_len);
+ int arienco_bits_written(EncodingEnvironmentPtr eep);
+ void arienco_done_encoding(EncodingEnvironmentPtr eep);
+ void biari_init_context (BiContextTypePtr ctx, const int* ini);
+ void rescale_cum_freq(BiContextTypePtr bi_ct);
+ void biari_encode_symbol(EncodingEnvironmentPtr eep, signed short symbol, BiContextTypePtr bi_ct );
+ void biari_encode_symbol_eq_prob(EncodingEnvironmentPtr eep, signed short symbol);
+ void biari_encode_symbol_final(EncodingEnvironmentPtr eep, signed short symbol);
+ MotionInfoContexts* create_contexts_MotionInfo(void);
+ TextureInfoContexts* create_contexts_TextureInfo(void);
+ void init_contexts_MotionInfo (MotionInfoContexts *enco_ctx);
+ void init_contexts_TextureInfo(TextureInfoContexts *enco_ctx);
+ void delete_contexts_MotionInfo(MotionInfoContexts *enco_ctx);
+ void delete_contexts_TextureInfo(TextureInfoContexts *enco_ctx);
+ void writeHeaderToBuffer();
+ int writeSyntaxElement_CABAC(SyntaxElement *se, DataPartition *this_dataPart);
+ void writeMB_typeInfo_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp);
+ void writeIntraPredMode_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp);
+ void writeB8_typeInfo_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp);
+ void writeRefFrame2Buffer_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp);
+ void writeRefFrame_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp);
+ void writeMVD_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp);
+ void writeCBP_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp);
+ void writeDquant_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp);
+ void writeRunLevel_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp);
+ void writeBiDirBlkSize_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp);
+ void writeCIPredMode_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp);
+ void print_ctx_TextureInfo(TextureInfoContexts *enco_ctx);
+ void writeMB_skip_flagInfo_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp);
+ void writeFieldModeInfo_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp); //GB
+ void writeCBP_BIT_CABAC (int b8, int bit, int cbp, Macroblock* currMB, int inter, EncodingEnvironmentPtr eep_dp);
+ void cabac_new_slice();
+ void CheckAvailabilityOfNeighborsCABAC();
+
+ void writeMB_transform_size_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp);
+
+
+ #endif // CABAC_H
+
Index: llvm-test/MultiSource/Applications/JM/lencod/configfile.c
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/configfile.c:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/configfile.c Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,1162 ----
+
+ /*!
+ ***********************************************************************
+ * \file
+ * configfile.c
+ * \brief
+ * Configuration handling.
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Stephan Wenger <stewe at cs.tu-berlin.de>
+ * \note
+ * In the future this module should hide the Parameters and offer only
+ * Functions for their access. Modules which make frequent use of some parameters
+ * (e.g. picture size in macroblocks) are free to buffer them on local variables.
+ * This will not only avoid global variable and make the code more readable, but also
+ * speed it up. It will also greatly facilitate future enhancements such as the
+ * handling of different picture sizes in the same sequence. \n
+ * \n
+ * For now, everything is just copied to the inp_par structure (gulp)
+ *
+ **************************************************************************************
+ * \par Configuration File Format
+ **************************************************************************************
+ * Format is line oriented, maximum of one parameter per line \n
+ * \n
+ * Lines have the following format: \n
+ * \<ParameterName\> = \<ParameterValue\> # Comments \\n \n
+ * Whitespace is space and \\t
+ * \par
+ * \<ParameterName\> are the predefined names for Parameters and are case sensitive.
+ * See configfile.h for the definition of those names and their mapping to
+ * configinput->values.
+ * \par
+ * \<ParameterValue\> are either integers [0..9]* or strings.
+ * Integers must fit into the wordlengths, signed values are generally assumed.
+ * Strings containing no whitespace characters can be used directly. Strings containing
+ * whitespace characters are to be inclosed in double quotes ("string with whitespace")
+ * The double quote character is forbidden (may want to implement something smarter here).
+ * \par
+ * Any Parameters whose ParameterName is undefined lead to the termination of the program
+ * with an error message.
+ *
+ * \par Known bug/Shortcoming:
+ * zero-length strings (i.e. to signal an non-existing file
+ * have to be coded as "".
+ *
+ * \par Rules for using command files
+ * \n
+ * All Parameters are initially taken from DEFAULTCONFIGFILENAME, defined in configfile.h.
+ * If an -f \<config\> parameter is present in the command line then this file is used to
+ * update the defaults of DEFAULTCONFIGFILENAME. There can be more than one -f parameters
+ * present. If -p <ParameterName = ParameterValue> parameters are present then these
+ * override the default and the additional config file's settings, and are themselves
+ * overridden by future -p parameters. There must be whitespace between -f and -p commands
+ * and their respective parameters
+ ***********************************************************************
+ */
+
+ #define INCLUDED_BY_CONFIGFILE_C
+
+ #include <stdlib.h>
+ #include <string.h>
+ #include <assert.h>
+
+ #if defined WIN32
+ #include <io.h>
+ #define strcasecmp strcmpi
+ #else
+ #include <unistd.h>
+ #endif
+ #include <fcntl.h>
+ #include <sys/stat.h>
+
+ #include "global.h"
+ #include "configfile.h"
+
+ #include "fmo.h"
+
+ char *GetConfigFileContent (char *Filename);
+ static void ParseContent (char *buf, int bufsize);
+ static int ParameterNameToMapIndex (char *s);
+ static int InitEncoderParams();
+ static int TestEncoderParams(int bitdepth_qp_scale);
+ static int DisplayEncoderParams();
+ static void PatchInp ();
+ static void ProfileCheck();
+ static void LevelCheck();
+
+
+ #define MAX_ITEMS_TO_PARSE 10000
+
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * print help message and exit
+ ***********************************************************************
+ */
+ void JMHelpExit ()
+ {
+ fprintf( stderr, "\n lencod [-h] [-d defenc.cfg] {[-f curenc1.cfg]...[-f curencN.cfg]}"
+ " {[-p EncParam1=EncValue1]..[-p EncParamM=EncValueM]}\n\n"
+ "## Parameters\n\n"
+
+ "## Options\n"
+ " -h : prints function usage\n"
+ " -d : use <defenc.cfg> as default file for parameter initializations.\n"
+ " If not used then file defaults to encoder.cfg in local directory.\n"
+ " -f : read <curencM.cfg> for reseting selected encoder parameters.\n"
+ " Multiple files could be used that set different parameters\n"
+ " -p : Set parameter <EncParamM> to <EncValueM>.\n"
+ " See default encoder.cfg file for description of all parameters.\n\n"
+
+ "## Supported video file formats\n"
+ " RAW: .yuv -> YUV 4:2:0\n\n"
+
+ "## Examples of usage:\n"
+ " lencod\n"
+ " lencod -h\n"
+ " lencod -d default.cfg\n"
+ " lencod -f curenc1.cfg\n"
+ " lencod -f curenc1.cfg -p InputFile=\"e:\\data\\container_qcif_30.yuv\" -p SourceWidth=176 -p SourceHeight=144\n"
+ " lencod -f curenc1.cfg -p FramesToBeEncoded=30 -p QPISlice=28 -p QPPSlice=28 -p QPBSlice=30\n");
+
+ exit(-1);
+ }
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * Parse the command line parameters and read the config files.
+ * \param ac
+ * number of command line parameters
+ * \param av
+ * command line parameters
+ ***********************************************************************
+ */
+ void Configure (int ac, char *av[])
+ {
+ char *content;
+ int CLcount, ContentLen, NumberParams;
+ char *filename=DEFAULTCONFIGFILENAME;
+
+ memset (&configinput, 0, sizeof (InputParameters));
+ //Set default parameters.
+ printf ("Setting Default Parameters...\n");
+ InitEncoderParams();
+
+ // Process default config file
+ CLcount = 1;
+
+ if (ac==2)
+ {
+ if (0 == strncmp (av[1], "-h", 2))
+ {
+ JMHelpExit();
+ }
+ }
+
+ if (ac>=3)
+ {
+ if (0 == strncmp (av[1], "-d", 2))
+ {
+ filename=av[2];
+ CLcount = 3;
+ }
+ if (0 == strncmp (av[1], "-h", 2))
+ {
+ JMHelpExit();
+ }
+ }
+ printf ("Parsing Configfile %s", filename);
+ content = GetConfigFileContent (filename);
+ if (NULL==content)
+ error (errortext, 300);
+ ParseContent (content, strlen(content));
+ printf ("\n");
+ free (content);
+
+ // Parse the command line
+
+ while (CLcount < ac)
+ {
+ if (0 == strncmp (av[CLcount], "-h", 2))
+ {
+ JMHelpExit();
+ }
+
+ if (0 == strncmp (av[CLcount], "-f", 2)) // A file parameter?
+ {
+ content = GetConfigFileContent (av[CLcount+1]);
+ if (NULL==content)
+ error (errortext, 300);
+ printf ("Parsing Configfile %s", av[CLcount+1]);
+ ParseContent (content, strlen (content));
+ printf ("\n");
+ free (content);
+ CLcount += 2;
+ } else
+ {
+ if (0 == strncmp (av[CLcount], "-p", 2)) // A config change?
+ {
+ // Collect all data until next parameter (starting with -<x> (x is any character)),
+ // put it into content, and parse content.
+
+ CLcount++;
+ ContentLen = 0;
+ NumberParams = CLcount;
+
+ // determine the necessary size for content
+ while (NumberParams < ac && av[NumberParams][0] != '-')
+ ContentLen += strlen (av[NumberParams++]); // Space for all the strings
+ ContentLen += 1000; // Additional 1000 bytes for spaces and \0s
+
+
+ if ((content = malloc (ContentLen))==NULL) no_mem_exit("Configure: content");;
+ content[0] = '\0';
+
+ // concatenate all parameters identified before
+
+ while (CLcount < NumberParams)
+ {
+ char *source = &av[CLcount][0];
+ char *destin = &content[strlen (content)];
+
+ while (*source != '\0')
+ {
+ if (*source == '=') // The Parser expects whitespace before and after '='
+ {
+ *destin++=' '; *destin++='='; *destin++=' '; // Hence make sure we add it
+ } else
+ *destin++=*source;
+ source++;
+ }
+ *destin = '\0';
+ CLcount++;
+ }
+ printf ("Parsing command line string '%s'", content);
+ ParseContent (content, strlen(content));
+ free (content);
+ printf ("\n");
+ }
+ else
+ {
+ snprintf (errortext, ET_SIZE, "Error in command line, ac %d, around string '%s', missing -f or -p parameters?", CLcount, av[CLcount]);
+ error (errortext, 300);
+ }
+ }
+ }
+ printf ("\n");
+ PatchInp();
+ if (input->DisplayEncParams)
+ DisplayEncoderParams();
+ }
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * allocates memory buf, opens file Filename in f, reads contents into
+ * buf and returns buf
+ * \param Filename
+ * name of config file
+ * \return
+ * if successfull, content of config file
+ * NULL in case of error. Error message will be set in errortext
+ ***********************************************************************
+ */
+ char *GetConfigFileContent (char *Filename)
+ {
+ long FileSize;
+ FILE *f;
+ char *buf;
+
+ if (NULL == (f = fopen (Filename, "r")))
+ {
+ snprintf (errortext, ET_SIZE, "Cannot open configuration file %s.", Filename);
+ return NULL;
+ }
+
+ if (0 != fseek (f, 0, SEEK_END))
+ {
+ snprintf (errortext, ET_SIZE, "Cannot fseek in configuration file %s.", Filename);
+ return NULL;
+ }
+
+ FileSize = ftell (f);
+ if (FileSize < 0 || FileSize > 60000)
+ {
+ snprintf (errortext, ET_SIZE, "Unreasonable Filesize %ld reported by ftell for configuration file %s.", FileSize, Filename);
+ return NULL;
+ }
+ if (0 != fseek (f, 0, SEEK_SET))
+ {
+ snprintf (errortext, ET_SIZE, "Cannot fseek in configuration file %s.", Filename);
+ return NULL;
+ }
+
+ if ((buf = malloc (FileSize + 1))==NULL) no_mem_exit("GetConfigFileContent: buf");
+
+ // Note that ftell() gives us the file size as the file system sees it. The actual file size,
+ // as reported by fread() below will be often smaller due to CR/LF to CR conversion and/or
+ // control characters after the dos EOF marker in the file.
+
+ FileSize = fread (buf, 1, FileSize, f);
+ buf[FileSize] = '\0';
+
+
+ fclose (f);
+ return buf;
+ }
+
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * Parses the character array buf and writes global variable input, which is defined in
+ * configfile.h. This hack will continue to be necessary to facilitate the addition of
+ * new parameters through the Map[] mechanism (Need compiler-generated addresses in map[]).
+ * \param buf
+ * buffer to be parsed
+ * \param bufsize
+ * buffer size of buffer
+ ***********************************************************************
+ */
+ void ParseContent (char *buf, int bufsize)
+ {
+
+ char *items[MAX_ITEMS_TO_PARSE];
+ int MapIdx;
+ int item = 0;
+ int InString = 0, InItem = 0;
+ char *p = buf;
+ char *bufend = &buf[bufsize];
+ int IntContent;
+ double DoubleContent;
+ int i;
+
+ // Stage one: Generate an argc/argv-type list in items[], without comments and whitespace.
+ // This is context insensitive and could be done most easily with lex(1).
+
+ while (p < bufend)
+ {
+ switch (*p)
+ {
+ case 13:
+ p++;
+ break;
+ case '#': // Found comment
+ *p = '\0'; // Replace '#' with '\0' in case of comment immediately following integer or string
+ while (*p != '\n' && p < bufend) // Skip till EOL or EOF, whichever comes first
+ p++;
+ InString = 0;
+ InItem = 0;
+ break;
+ case '\n':
+ InItem = 0;
+ InString = 0;
+ *p++='\0';
+ break;
+ case ' ':
+ case '\t': // Skip whitespace, leave state unchanged
+ if (InString)
+ p++;
+ else
+ { // Terminate non-strings once whitespace is found
+ *p++ = '\0';
+ InItem = 0;
+ }
+ break;
+
+ case '"': // Begin/End of String
+ *p++ = '\0';
+ if (!InString)
+ {
+ items[item++] = p;
+ InItem = ~InItem;
+ }
+ else
+ InItem = 0;
+ InString = ~InString; // Toggle
+ break;
+
+ default:
+ if (!InItem)
+ {
+ items[item++] = p;
+ InItem = ~InItem;
+ }
+ p++;
+ }
+ }
+
+ item--;
+
+ for (i=0; i<item; i+= 3)
+ {
+ if (0 > (MapIdx = ParameterNameToMapIndex (items[i])))
+ {
+ snprintf (errortext, ET_SIZE, " Parsing error in config file: Parameter Name '%s' not recognized.", items[i]);
+ error (errortext, 300);
+ }
+ if (strcasecmp ("=", items[i+1]))
+ {
+ snprintf (errortext, ET_SIZE, " Parsing error in config file: '=' expected as the second token in each line.");
+ error (errortext, 300);
+ }
+
+ // Now interpret the Value, context sensitive...
+
+ switch (Map[MapIdx].Type)
+ {
+ case 0: // Numerical
+ if (1 != sscanf (items[i+2], "%d", &IntContent))
+ {
+ snprintf (errortext, ET_SIZE, " Parsing error: Expected numerical value for Parameter of %s, found '%s'.", items[i], items[i+2]);
+ error (errortext, 300);
+ }
+ * (int *) (Map[MapIdx].Place) = IntContent;
+ printf (".");
+ break;
+ case 1:
+ strncpy ((char *) Map[MapIdx].Place, items [i+2], FILE_NAME_SIZE);
+ printf (".");
+ break;
+ case 2: // Numerical double
+ if (1 != sscanf (items[i+2], "%lf", &DoubleContent))
+ {
+ snprintf (errortext, ET_SIZE, " Parsing error: Expected numerical value for Parameter of %s, found '%s'.", items[i], items[i+2]);
+ error (errortext, 300);
+ }
+ * (double *) (Map[MapIdx].Place) = DoubleContent;
+ printf (".");
+ break;
+ default:
+ assert ("Unknown value type in the map definition of configfile.h");
+ }
+ }
+ memcpy (input, &configinput, sizeof (InputParameters));
+ }
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * Returns the index number from Map[] for a given parameter name.
+ * \param s
+ * parameter name string
+ * \return
+ * the index number if the string is a valid parameter name, \n
+ * -1 for error
+ ***********************************************************************
+ */
+ static int ParameterNameToMapIndex (char *s)
+ {
+ int i = 0;
+
+ while (Map[i].TokenName != NULL)
+ if (0==strcasecmp (Map[i].TokenName, s))
+ return i;
+ else
+ i++;
+ return -1;
+ };
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * Sets initial values for encoding parameters.
+ * \return
+ * -1 for error
+ ***********************************************************************
+ */
+ static int InitEncoderParams()
+ {
+ int i = 0;
+
+ while (Map[i].TokenName != NULL)
+ {
+ if (Map[i].Type == 0)
+ * (int *) (Map[i].Place) = (int) Map[i].Default;
+ else if (Map[i].Type == 2)
+ * (double *) (Map[i].Place) = Map[i].Default;
+ i++;
+ }
+ return -1;
+ };
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * Validates encoding parameters.
+ * \return
+ * -1 for error
+ ***********************************************************************
+ */
+ static int TestEncoderParams(int bitdepth_qp_scale)
+ {
+ int i = 0;
+
+ while (Map[i].TokenName != NULL)
+ {
+ if (Map[i].param_limits == 1)
+ {
+ if (Map[i].Type == 0)
+ {
+ if ( * (int *) (Map[i].Place) < (int) Map[i].min_limit || * (int *) (Map[i].Place) > (int) Map[i].max_limit )
+ {
+ snprintf(errortext, ET_SIZE, "Error in input parameter %s. Check configuration file. Value should be in [%d, %d] range.", Map[i].TokenName, (int) Map[i].min_limit,(int)Map[i].max_limit );
+ error (errortext, 400);
+ }
+
+ }
+ else if (Map[i].Type == 2)
+ {
+ if ( * (double *) (Map[i].Place) < Map[i].min_limit || * (double *) (Map[i].Place) > Map[i].max_limit )
+ {
+ snprintf(errortext, ET_SIZE, "Error in input parameter %s. Check configuration file. Value should be in [%.2f, %.2f] range.", Map[i].TokenName,Map[i].min_limit ,Map[i].max_limit );
+ error (errortext, 400);
+ }
+ }
+ }
+ else if (Map[i].param_limits == 2)
+ {
+ if (Map[i].Type == 0)
+ {
+ if ( * (int *) (Map[i].Place) < (int) Map[i].min_limit )
+ {
+ snprintf(errortext, ET_SIZE, "Error in input parameter %s. Check configuration file. Value should not be smaller than %d.", Map[i].TokenName, (int) Map[i].min_limit);
+ error (errortext, 400);
+ }
+
+ }
+ else if (Map[i].Type == 2)
+ {
+ if ( * (double *) (Map[i].Place) < Map[i].min_limit )
+ {
+ snprintf(errortext, ET_SIZE, "Error in input parameter %s. Check configuration file. Value should not be smaller than %2.f.", Map[i].TokenName,Map[i].min_limit);
+ error (errortext, 400);
+ }
+ }
+ }
+ else if (Map[i].param_limits == 3) // Only used for QPs
+ {
+ if (Map[i].Type == 0)
+ {
+ if ( * (int *) (Map[i].Place) < (int) (Map[i].min_limit - bitdepth_qp_scale) || * (int *) (Map[i].Place) > (int) Map[i].max_limit )
+ {
+ snprintf(errortext, ET_SIZE, "Error in input parameter %s. Check configuration file. Value should be in [%d, %d] range.", Map[i].TokenName, (int) (Map[i].min_limit - bitdepth_qp_scale),(int)Map[i].max_limit );
+ error (errortext, 400);
+ }
+
+ }
+ }
+
+ i++;
+ }
+ return -1;
+ };
+
+
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * Outputs encoding parameters.
+ * \return
+ * -1 for error
+ ***********************************************************************
+ */
+ static int DisplayEncoderParams()
+ {
+ int i = 0;
+
+ printf("******************************************************\n");
+ printf("* Encoder Parameters *\n");
+ printf("******************************************************\n");
+ while (Map[i].TokenName != NULL)
+ {
+ if (Map[i].Type == 0)
+ printf("Parameter %s = %d\n",Map[i].TokenName,* (int *) (Map[i].Place));
+ else if (Map[i].Type == 1)
+ printf("Parameter %s = ""%s""\n",Map[i].TokenName,(char *) (Map[i].Place));
+ else if (Map[i].Type == 2)
+ printf("Parameter %s = %.2f\n",Map[i].TokenName,* (double *) (Map[i].Place));
+ i++;
+ }
+ printf("******************************************************\n");
+ return -1;
+ };
+
+ /*!
+ ************************************************************************
+ * \brief
+ * calculate Ceil(Log2(uiVal))
+ ************************************************************************
+ */
+ unsigned CeilLog2( unsigned uiVal)
+ {
+ unsigned uiTmp = uiVal-1;
+ unsigned uiRet = 0;
+
+ while( uiTmp != 0 )
+ {
+ uiTmp >>= 1;
+ uiRet++;
+ }
+ return uiRet;
+ }
+
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * Checks the input parameters for consistency.
+ ***********************************************************************
+ */
+ static void PatchInp ()
+ {
+ int bitdepth_qp_scale = 6*(input->BitDepthLuma - 8);
+
+ // These variables are added for FMO
+ FILE * sgfile=NULL;
+ int i,j;
+ int frame_mb_only;
+ int mb_width, mb_height, mapunit_height;
+ int storedBplus1;
+
+ TestEncoderParams(bitdepth_qp_scale);
+
+ if (input->FrameRate == 0.0)
+ input->FrameRate = INIT_FRAME_RATE;
+
+ // Set block sizes
+
+ // Skip/Direct16x16
+ input->part_size[0][0] = 4;
+ input->part_size[0][1] = 4;
+ // 16x16
+ input->part_size[1][0] = 4;
+ input->part_size[1][1] = 4;
+ // 16x8
+ input->part_size[2][0] = 4;
+ input->part_size[2][1] = 2;
+ // 8x16
+ input->part_size[3][0] = 2;
+ input->part_size[3][1] = 4;
+ // 8x8
+ input->part_size[4][0] = 2;
+ input->part_size[4][1] = 2;
+ // 8x4
+ input->part_size[5][0] = 2;
+ input->part_size[5][1] = 1;
+ // 4x8
+ input->part_size[6][0] = 1;
+ input->part_size[6][1] = 2;
+ // 4x4
+ input->part_size[7][0] = 1;
+ input->part_size[7][1] = 1;
+
+ for (j = 0; j<8;j++)
+ {
+ for (i = 0; i<2; i++)
+ {
+ input->blc_size[j][i] = input->part_size[j][i] * BLOCK_SIZE;
+ }
+ }
+
+ // set proper log2_max_frame_num_minus4.
+ storedBplus1 = (input->BRefPictures ) ? input->successive_Bframe + 1: 1;
+
+ if (input->Log2MaxFNumMinus4 == -1)
+ log2_max_frame_num_minus4 = Clip3(0,12, (int) (CeilLog2(input->no_frames * storedBplus1) - 4));
+ else
+ log2_max_frame_num_minus4 = input->Log2MaxFNumMinus4;
+
+ if (log2_max_frame_num_minus4 == 0 && input->num_ref_frames == 16)
+ {
+ snprintf(errortext, ET_SIZE, " NumberReferenceFrames=%d and Log2MaxFNumMinus4=%d may lead to an invalid value of frame_num.", input->num_ref_frames, input-> Log2MaxFNumMinus4);
+ error (errortext, 500);
+ }
+
+ // set proper log2_max_pic_order_cnt_lsb_minus4.
+ if (input->Log2MaxPOCLsbMinus4 == - 1)
+ log2_max_pic_order_cnt_lsb_minus4 = Clip3(0,12, (int) (CeilLog2( 2*input->no_frames * (input->jumpd + 1)) - 4));
+ else
+ log2_max_pic_order_cnt_lsb_minus4 = input->Log2MaxPOCLsbMinus4;
+
+ if (((1<<(log2_max_pic_order_cnt_lsb_minus4 + 3)) < input->jumpd * 4) && input->Log2MaxPOCLsbMinus4 != -1)
+ error("log2_max_pic_order_cnt_lsb_minus4 might not be sufficient for encoding. Increase value.",400);
+
+ // B picture consistency check
+ if(input->successive_Bframe > input->jumpd)
+ {
+ snprintf(errortext, ET_SIZE, "Number of B-frames %d can not exceed the number of frames skipped", input->successive_Bframe);
+ error (errortext, 400);
+ }
+
+ // Direct Mode consistency check
+ if(input->successive_Bframe && input->direct_spatial_mv_pred_flag != DIR_SPATIAL && input->direct_spatial_mv_pred_flag != DIR_TEMPORAL)
+ {
+ snprintf(errortext, ET_SIZE, "Unsupported direct mode=%d, use TEMPORAL=0 or SPATIAL=1", input->direct_spatial_mv_pred_flag);
+ error (errortext, 400);
+ }
+
+ if (input->PicInterlace>0 || input->MbInterlace>0)
+ {
+ if (input->directInferenceFlag==0)
+ printf("\nDirectInferenceFlag set to 1 due to interlace coding.");
+ input->directInferenceFlag=1;
+ }
+
+ if (input->PicInterlace>0)
+ {
+ if (input->IntraBottom!=0 && input->IntraBottom!=1)
+ {
+ snprintf(errortext, ET_SIZE, "Incorrect value %d for IntraBottom. Use 0 (disable) or 1 (enable).", input->IntraBottom);
+ error (errortext, 400);
+ }
+ }
+ // Cabac/UVLC consistency check
+ if (input->symbol_mode != UVLC && input->symbol_mode != CABAC)
+ {
+ snprintf (errortext, ET_SIZE, "Unsupported symbol mode=%d, use UVLC=0 or CABAC=1",input->symbol_mode);
+ error (errortext, 400);
+ }
+
+ // Open Files
+ if ((p_in=open(input->infile, OPENFLAGS_READ))==-1)
+ {
+ snprintf(errortext, ET_SIZE, "Input file %s does not exist",input->infile);
+ error (errortext, 500);
+ }
+
+ if (strlen (input->ReconFile) > 0 && (p_dec=open(input->ReconFile, OPENFLAGS_WRITE, OPEN_PERMISSIONS))==-1)
+ {
+ snprintf(errortext, ET_SIZE, "Error open file %s", input->ReconFile);
+ error (errortext, 500);
+ }
+
+ #if TRACE
+ if (strlen (input->TraceFile) > 0 && (p_trace=fopen(input->TraceFile,"w"))==NULL)
+ {
+ snprintf(errortext, ET_SIZE, "Error open file %s", input->TraceFile);
+ error (errortext, 500);
+ }
+ #endif
+
+ if (input->img_width % 16 != 0)
+ {
+ img->auto_crop_right = 16-(input->img_width % 16);
+ }
+ else
+ {
+ img->auto_crop_right=0;
+ }
+ if (input->PicInterlace || input->MbInterlace)
+ {
+ if (input->img_height % 2 != 0)
+ {
+ error ("even number of lines required for interlaced coding", 500);
+ }
+ if (input->img_height % 32 != 0)
+ {
+ img->auto_crop_bottom = 32-(input->img_height % 32);
+ }
+ else
+ {
+ img->auto_crop_bottom=0;
+ }
+ }
+ else
+ {
+ if (input->img_height % 16 != 0)
+ {
+ img->auto_crop_bottom = 16-(input->img_height % 16);
+ }
+ else
+ {
+ img->auto_crop_bottom=0;
+ }
+ }
+ if (img->auto_crop_bottom || img->auto_crop_right)
+ {
+ printf ("Warning: Automatical cropping activated: Coded frame Size: %dx%d\n", input->img_width+img->auto_crop_right, input->img_height+img->auto_crop_bottom);
+ }
+
+ /*
+ // add check for MAXSLICEGROUPIDS
+ if(input->num_slice_groups_minus1>=MAXSLICEGROUPIDS)
+ {
+ snprintf(errortext, ET_SIZE, "num_slice_groups_minus1 exceeds MAXSLICEGROUPIDS");
+ error (errortext, 500);
+ }
+ */
+
+ // Following codes are to read slice group configuration from SliceGroupConfigFileName for slice group type 0,2 or 6
+ if( (input->num_slice_groups_minus1!=0)&&
+ ((input->slice_group_map_type == 0) || (input->slice_group_map_type == 2) || (input->slice_group_map_type == 6)) )
+ {
+ if (strlen (input->SliceGroupConfigFileName) > 0 && (sgfile=fopen(input->SliceGroupConfigFileName,"r"))==NULL)
+ {
+ snprintf(errortext, ET_SIZE, "Error open file %s", input->SliceGroupConfigFileName);
+ error (errortext, 500);
+ }
+ else
+ {
+ if (input->slice_group_map_type == 0)
+ {
+ input->run_length_minus1=(int *)malloc(sizeof(int)*(input->num_slice_groups_minus1+1));
+ if (NULL==input->run_length_minus1)
+ no_mem_exit("PatchInp: input->run_length_minus1");
+
+ // each line contains one 'run_length_minus1' value
+ for(i=0;i<=input->num_slice_groups_minus1;i++)
+ {
+ fscanf(sgfile,"%d",(input->run_length_minus1+i));
+ fscanf(sgfile,"%*[^\n]");
+
+ }
+ }
+ else if (input->slice_group_map_type == 2)
+ {
+ input->top_left=(int *)malloc(sizeof(int)*input->num_slice_groups_minus1);
+ input->bottom_right=(int *)malloc(sizeof(int)*input->num_slice_groups_minus1);
+ if (NULL==input->top_left)
+ no_mem_exit("PatchInp: input->top_left");
+ if (NULL==input->bottom_right)
+ no_mem_exit("PatchInp: input->bottom_right");
+
+ // every two lines contain 'top_left' and 'bottom_right' value
+ for(i=0;i<input->num_slice_groups_minus1;i++)
+ {
+ fscanf(sgfile,"%d",(input->top_left+i));
+ fscanf(sgfile,"%*[^\n]");
+ fscanf(sgfile,"%d",(input->bottom_right+i));
+ fscanf(sgfile,"%*[^\n]");
+ }
+
+ }
+ else if (input->slice_group_map_type == 6)
+ {
+ int tmp;
+
+ frame_mb_only = !(input->PicInterlace || input->MbInterlace);
+ mb_width= (input->img_width+img->auto_crop_right)/16;
+ mb_height= (input->img_height+img->auto_crop_bottom)/16;
+ mapunit_height=mb_height/(2-frame_mb_only);
+
+ input->slice_group_id=(byte * ) malloc(sizeof(byte)*mapunit_height*mb_width);
+ if (NULL==input->slice_group_id)
+ no_mem_exit("PatchInp: input->slice_group_id");
+
+ // each line contains slice_group_id for one Macroblock
+ for (i=0;i<mapunit_height*mb_width;i++)
+ {
+ fscanf(sgfile,"%d", &tmp);
+ input->slice_group_id[i]= (byte) tmp;
+ if ( *(input->slice_group_id+i) > input->num_slice_groups_minus1 )
+ {
+ snprintf(errortext, ET_SIZE, "Error read slice group information from file %s", input->SliceGroupConfigFileName);
+ error (errortext, 500);
+ }
+ fscanf(sgfile,"%*[^\n]");
+ }
+ }
+ fclose(sgfile);
+ }
+ }
+
+
+ if (input->PyramidRefReorder && input->PyramidCoding && (input->PicInterlace || input->MbInterlace))
+ {
+ snprintf(errortext, ET_SIZE, "PyramidRefReorder Not supported with Interlace encoding methods\n");
+ error (errortext, 400);
+ }
+
+ if (input->PocMemoryManagement && input->PyramidCoding && (input->PicInterlace || input->MbInterlace))
+ {
+ snprintf(errortext, ET_SIZE, "PocMemoryManagement not supported with Interlace encoding methods\n");
+ error (errortext, 400);
+ }
+
+
+ // frame/field consistency check
+ if (input->PicInterlace != FRAME_CODING && input->PicInterlace != ADAPTIVE_CODING && input->PicInterlace != FIELD_CODING)
+ {
+ snprintf (errortext, ET_SIZE, "Unsupported PicInterlace=%d, use frame based coding=0 or field based coding=1 or adaptive=2",input->PicInterlace);
+ error (errortext, 400);
+ }
+
+ // frame/field consistency check
+ if (input->MbInterlace != FRAME_CODING && input->MbInterlace != ADAPTIVE_CODING && input->MbInterlace != FIELD_CODING)
+ {
+ snprintf (errortext, ET_SIZE, "Unsupported MbInterlace=%d, use frame based coding=0 or field based coding=1 or adaptive=2",input->MbInterlace);
+ error (errortext, 400);
+ }
+
+
+ if ((!input->rdopt)&&(input->MbInterlace))
+ {
+ snprintf(errortext, ET_SIZE, "MB AFF is not compatible with non-rd-optimized coding.");
+ error (errortext, 500);
+ }
+
+ if (input->rdopt>2)
+ {
+ snprintf(errortext, ET_SIZE, "RDOptimization=3 mode has been deactivated do to diverging of real and simulated decoders.");
+ error (errortext, 500);
+ }
+
+ // check RDoptimization mode and profile. FMD does not support Frex Profiles.
+ if (input->rdopt==2 && input->ProfileIDC>=FREXT_HP)
+ {
+ snprintf(errortext, ET_SIZE, "Fast Mode Decision methods does not support FREX Profiles");
+ error (errortext, 500);
+ }
+
+ // the two HEX FME schemes support FAST Subpel ME. EPZS does not but works fine with
+ // Hadamard reduction with similar speed up. Subpel FME may be added at a later stage
+ // for this scheme for further speed increase.
+ if (input->hadamard == 2 && input->FMEnable != 0 && input->FMEnable != 3)
+ {
+ snprintf(errortext, ET_SIZE, "UseHadamard=2 is not allowed when UseFME is set to 1 or 2.");
+ error (errortext, 500);
+ }
+
+ // Tian Dong: May 31, 2002
+ // The number of frames in one sub-seq in enhanced layer should not exceed
+ // the number of reference frame number.
+ if ( input->NumFramesInELSubSeq >= input->num_ref_frames || input->NumFramesInELSubSeq < 0 )
+ {
+ snprintf(errortext, ET_SIZE, "NumFramesInELSubSeq (%d) is out of range [0,%d).", input->NumFramesInELSubSeq, input->num_ref_frames);
+ error (errortext, 500);
+ }
+ // Tian Dong: Enhanced GOP is not supported in bitstream mode. September, 2002
+ if ( input->NumFramesInELSubSeq > 0 && input->of_mode == PAR_OF_ANNEXB )
+ {
+ snprintf(errortext, ET_SIZE, "Enhanced GOP is not supported in bitstream mode and RTP mode yet.");
+ error (errortext, 500);
+ }
+ // Tian Dong (Sept 2002)
+ // The AFF is not compatible with spare picture for the time being.
+ if ((input->PicInterlace || input->MbInterlace) && input->SparePictureOption == TRUE)
+ {
+ snprintf(errortext, ET_SIZE, "AFF is not compatible with spare picture.");
+ error (errortext, 500);
+ }
+
+ // Only the RTP mode is compatible with spare picture for the time being.
+ if (input->of_mode != PAR_OF_RTP && input->SparePictureOption == TRUE)
+ {
+ snprintf(errortext, ET_SIZE, "Only RTP output mode is compatible with spare picture features.");
+ error (errortext, 500);
+ }
+
+ if( (input->WeightedPrediction > 0 || input->WeightedBiprediction > 0) && (input->MbInterlace))
+ {
+ printf("Weighted prediction coding is not supported for MB AFF currently.");
+ error (errortext, 500);
+ }
+ if ( input->NumFramesInELSubSeq > 0 && input->WeightedPrediction > 0)
+ {
+ snprintf(errortext, ET_SIZE, "Enhanced GOP is not supported in weighted prediction coding mode yet.");
+ error (errortext, 500);
+ }
+
+ //! the number of slice groups is forced to be 1 for slice group type 3-5
+ if(input->num_slice_groups_minus1 > 0)
+ {
+ if( (input->slice_group_map_type >= 3) && (input->slice_group_map_type<=5) )
+ input->num_slice_groups_minus1 = 1;
+ }
+
+ // Rate control
+ if(input->RCEnable)
+ {
+ if ( ((input->img_height+img->auto_crop_bottom)*(input->img_width+img->auto_crop_right)/256)%input->basicunit!=0)
+ {
+ snprintf(errortext, ET_SIZE, "Frame size in macroblocks must be a multiple of BasicUnit.");
+ error (errortext, 500);
+ }
+ }
+
+ if ((input->successive_Bframe)&&(input->BRefPictures)&&(input->idr_enable)&&(input->intra_period)&&(input->pic_order_cnt_type!=0))
+ {
+ error("Stored B pictures combined with IDR pictures only supported in Picture Order Count type 0\n",-1000);
+ }
+
+ if( !input->direct_spatial_mv_pred_flag && input->num_ref_frames<2 && input->successive_Bframe >0)
+ error("temporal direct needs at least 2 ref frames\n",-1000);
+
+ // frext
+ if(input->Transform8x8Mode && input->sp_periodicity /*SP-frames*/)
+ {
+ snprintf(errortext, ET_SIZE, "\nThe new 8x8 mode is not implemented for sp-frames.");
+ error (errortext, 500);
+ }
+
+ if(input->Transform8x8Mode && (input->ProfileIDC<FREXT_HP || input->ProfileIDC>FREXT_Hi444))
+ {
+ snprintf(errortext, ET_SIZE, "\nTransform8x8Mode may be used only with ProfileIDC %d to %d.", FREXT_HP, FREXT_Hi444);
+ error (errortext, 500);
+ }
+ if(input->ScalingMatrixPresentFlag && (input->ProfileIDC<FREXT_HP || input->ProfileIDC>FREXT_Hi444))
+ {
+ snprintf(errortext, ET_SIZE, "\nScalingMatrixPresentFlag may be used only with ProfileIDC %d to %d.", FREXT_HP, FREXT_Hi444);
+ error (errortext, 500);
+ }
+
+ if(input->yuv_format==YUV422 && input->ProfileIDC < FREXT_Hi422)
+ {
+ snprintf(errortext, ET_SIZE, "\nFRExt Profile(YUV Format) Error!\nYUV422 can be used only with ProfileIDC %d or %d\n",FREXT_Hi422, FREXT_Hi444);
+ error (errortext, 500);
+ }
+ if(input->yuv_format==YUV444 && input->ProfileIDC < FREXT_Hi444)
+ {
+ snprintf(errortext, ET_SIZE, "\nFRExt Profile(YUV Format) Error!\nYUV444 can be used only with ProfileIDC %d.\n",FREXT_Hi444);
+ error (errortext, 500);
+ }
+
+ // Residue Color Transform
+ if(input->yuv_format!=YUV444 && input->residue_transform_flag)
+ {
+ snprintf(errortext, ET_SIZE, "\nResidue color transform is supported only in YUV444.");
+ error (errortext, 500);
+ }
+
+ if ((input->BiPredMotionEstimation) && (input->search_range < input->BiPredMESearchRange))
+ {
+ snprintf(errortext, ET_SIZE, "\nBiPredMESearchRange must be smaller or equal SearchRange.");
+ error (errortext, 500);
+ }
+
+
+ if (input->EnableOpenGOP) input->PyramidRefReorder = 1;
+ if (input->EnableOpenGOP && input->PicInterlace)
+ {
+ snprintf(errortext, ET_SIZE, "Open Gop currently not supported for Field coded pictures.");
+ error (errortext, 500);
+ }
+
+ ProfileCheck();
+ LevelCheck();
+ }
+
+ void PatchInputNoFrames()
+ {
+ // Tian Dong: May 31, 2002
+ // If the frames are grouped into two layers, "FramesToBeEncoded" in the config file
+ // will give the number of frames which are in the base layer. Here we let input->no_frames
+ // be the total frame numbers.
+ input->no_frames = 1+ (input->no_frames-1) * (input->NumFramesInELSubSeq+1);
+ if ( input->NumFrameIn2ndIGOP )
+ input->NumFrameIn2ndIGOP = 1+(input->NumFrameIn2ndIGOP-1) * (input->NumFramesInELSubSeq+1);
+ FirstFrameIn2ndIGOP = input->no_frames;
+ }
+
+ static void ProfileCheck()
+ {
+ if((input->ProfileIDC != 66 ) &&
+ (input->ProfileIDC != 77 ) &&
+ (input->ProfileIDC != 88 ) &&
+ (input->ProfileIDC != FREXT_HP ) &&
+ (input->ProfileIDC != FREXT_Hi10P ) &&
+ (input->ProfileIDC != FREXT_Hi422 ) &&
+ (input->ProfileIDC != FREXT_Hi444 ))
+ {
+ snprintf(errortext, ET_SIZE, "Profile must be baseline(66)/main(77)/extended(88) or FRExt (%d to %d).", FREXT_HP,FREXT_Hi444);
+ error (errortext, 500);
+ }
+ // baseline
+ if (input->ProfileIDC == 66 )
+ {
+ if (input->successive_Bframe || input->BRefPictures==2)
+ {
+ snprintf(errortext, ET_SIZE, "B pictures are not allowed in baseline.");
+ error (errortext, 500);
+ }
+ if (input->sp_periodicity)
+ {
+ snprintf(errortext, ET_SIZE, "SP pictures are not allowed in baseline.");
+ error (errortext, 500);
+ }
+ if (input->partition_mode)
+ {
+ snprintf(errortext, ET_SIZE, "Data partitioning is not allowed in baseline.");
+ error (errortext, 500);
+ }
+ if (input->WeightedPrediction)
+ {
+ snprintf(errortext, ET_SIZE, "Weighted prediction is not allowed in baseline.");
+ error (errortext, 500);
+ }
+ if (input->WeightedBiprediction)
+ {
+ snprintf(errortext, ET_SIZE, "Weighted prediction is not allowed in baseline.");
+ error (errortext, 500);
+ }
+ if (input->symbol_mode == CABAC)
+ {
+ snprintf(errortext, ET_SIZE, "CABAC is not allowed in baseline.");
+ error (errortext, 500);
+ }
+ }
+
+ // main
+ if (input->ProfileIDC == 77 )
+ {
+ if (input->sp_periodicity)
+ {
+ snprintf(errortext, ET_SIZE, "SP pictures are not allowed in main.");
+ error (errortext, 500);
+ }
+ if (input->partition_mode)
+ {
+ snprintf(errortext, ET_SIZE, "Data partitioning is not allowed in main.");
+ error (errortext, 500);
+ }
+ if (input->num_slice_groups_minus1)
+ {
+ snprintf(errortext, ET_SIZE, "num_slice_groups_minus1>0 (FMO) is not allowed in main.");
+ error (errortext, 500);
+ }
+ if (input->redundant_slice_flag)
+ {
+ snprintf(errortext, ET_SIZE, "Redundant pictures are not allowed in main.");
+ error (errortext, 500);
+ }
+ }
+
+ // extended
+ if (input->ProfileIDC == 88 )
+ {
+ if (!input->directInferenceFlag)
+ {
+ snprintf(errortext, ET_SIZE, "direct_8x8_inference flag must be equal to 1 in extended.");
+ error (errortext, 500);
+ }
+
+ if (input->symbol_mode == CABAC)
+ {
+ snprintf(errortext, ET_SIZE, "CABAC is not allowed in extended.");
+ error (errortext, 500);
+ }
+ }
+
+ }
+
+ static void LevelCheck()
+ {
+ if ( (input->LevelIDC>=30) && (input->directInferenceFlag==0))
+ {
+ printf("\nLevelIDC 3.0 and above require direct_8x8_inference to be set to 1. Please check your settings.\n");
+ input->directInferenceFlag=1;
+ }
+ if ( ((input->LevelIDC<21) || (input->LevelIDC>41)) && (input->PicInterlace > 0 || input->MbInterlace > 0) )
+ {
+ snprintf(errortext, ET_SIZE, "nInterlace modes only supported for LevelIDC in the range of 2.1 and 4.1. Please check your settings.\n");
+ error (errortext, 500);
+ }
+
+ }
+
Index: llvm-test/MultiSource/Applications/JM/lencod/configfile.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/configfile.h:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/configfile.h Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,271 ----
+
+ /*!
+ ***********************************************************************
+ * \file
+ * configfile.h
+ * \brief
+ * Prototypes for configfile.c and definitions of used structures.
+ ***********************************************************************
+ */
+
+ #include "fmo.h"
+
+ #ifndef _CONFIGFILE_H_
+ #define _CONFIGFILE_H_
+
+ #define DEFAULTCONFIGFILENAME "encoder.cfg"
+
+ #define PROFILE_IDC 88
+ #define LEVEL_IDC 21
+
+
+ typedef struct {
+ char *TokenName;
+ void *Place;
+ int Type;
+ double Default;
+ int param_limits; //! 0: no limits, 1: both min and max, 2: only min (i.e. no negatives), 3: specialcase for QPs since min needs bitdepth_qp_scale
+ double min_limit;
+ double max_limit;
+ } Mapping;
+
+
+
+ InputParameters configinput;
+
+
+ #ifdef INCLUDED_BY_CONFIGFILE_C
+
+ Mapping Map[] = {
+ {"ProfileIDC", &configinput.ProfileIDC, 0, (double) PROFILE_IDC, 0, 0.0, 0.0 },
+ {"LevelIDC", &configinput.LevelIDC, 0, (double) LEVEL_IDC, 0, 0.0, 0.0 },
+ {"FrameRate", &configinput.FrameRate, 2, (double) INIT_FRAME_RATE, 1, 0.0, 100.0 },
+ {"IDRIntraEnable", &configinput.idr_enable, 0, 0.0, 1, 0.0, 1.0 },
+ {"StartFrame", &configinput.start_frame, 0, 0.0, 2, 0.0, 0.0 },
+ {"IntraPeriod", &configinput.intra_period, 0, 0.0, 2, 0.0, 0.0 },
+ {"EnableOpenGOP", &configinput.EnableOpenGOP, 0, 0.0, 3, 0.0, 1.0 },
+ {"FramesToBeEncoded", &configinput.no_frames, 0, 1.0, 2, 1.0, 0.0 },
+ {"QPISlice", &configinput.qp0, 0, 24.0, 3, (double) MIN_QP, (double) MAX_QP },
+ {"QPPSlice", &configinput.qpN, 0, 24.0, 3, (double) MIN_QP, (double) MAX_QP },
+ {"QPBSlice", &configinput.qpB, 0, 24.0, 3, (double) MIN_QP, (double) MAX_QP },
+ {"FrameSkip", &configinput.jumpd, 0, 0.0, 2, 0.0, 0.0 },
+ {"UseHadamard", &configinput.hadamard, 0, 0.0, 1, 0.0, 2.0 },
+ {"DisableSubpelME", &configinput.DisableSubpelME, 0, 0.0, 1, 0.0, 1.0 },
+ {"SearchRange", &configinput.search_range, 0, 16.0, 2, 0.0, 0.0 },
+ {"NumberReferenceFrames", &configinput.num_ref_frames, 0, 1.0, 1, 1.0, 16.0 },
+ {"PList0References", &configinput.P_List0_refs, 0, 0.0, 1, 0.0, 16.0 },
+ {"BList0References", &configinput.B_List0_refs, 0, 0.0, 1, 0.0, 16.0 },
+ {"BList1References", &configinput.B_List1_refs, 0, 1.0, 1, 0.0, 16.0 },
+ {"Log2MaxFNumMinus4", &configinput.Log2MaxFNumMinus4, 0, 0.0, 1, -1.0, 12.0 },
+ {"Log2MaxPOCLsbMinus4", &configinput.Log2MaxPOCLsbMinus4, 0, 2.0, 1, -1.0, 12.0 },
+ {"GenerateMultiplePPS", &configinput.GenerateMultiplePPS, 0, 0.0, 1, 0.0, 1.0 },
+ {"ResendPPS", &configinput.ResendPPS, 0, 0.0, 1, 0.0, 1.0 },
+ {"SourceWidth", &configinput.img_width, 0, 176.0, 2, 16.0, 0.0 },
+ {"SourceHeight", &configinput.img_height, 0, 144.0, 2, 16.0, 0.0 },
+ {"MbLineIntraUpdate", &configinput.intra_upd, 0, 0.0, 1, 0.0, 1.0 },
+ {"SliceMode", &configinput.slice_mode, 0, 0.0, 1, 0.0, 3.0 },
+ {"SliceArgument", &configinput.slice_argument, 0, 0.0, 2, 1.0, 1.0 },
+ {"UseConstrainedIntraPred", &configinput.UseConstrainedIntraPred, 0, 0.0, 1, 0.0, 1.0 },
+ {"InputFile", &configinput.infile, 1, 0.0, 0, 0.0, 0.0 },
+ {"InputHeaderLength", &configinput.infile_header, 0, 0.0, 2, 0.0, 1.0 },
+ {"OutputFile", &configinput.outfile, 1, 0.0, 0, 0.0, 0.0 },
+ {"ReconFile", &configinput.ReconFile, 1, 0.0, 0, 0.0, 0.0 },
+ {"TraceFile", &configinput.TraceFile, 1, 0.0, 0, 0.0, 0.0 },
+ {"DisposableP", &configinput.DisposableP, 0, 0.0, 1, 0.0, 1.0 },
+ {"DispPQPOffset", &configinput.DispPQPOffset, 0, 0.0, 0,-51.0, 51.0 },
+ {"NumberBFrames", &configinput.successive_Bframe, 0, 0.0, 2, 0.0, 0.0 },
+ {"BRefPicQPOffset", &configinput.qpBRSOffset, 0, 0.0, 0,-51.0, 51.0 },
+ {"DirectModeType", &configinput.direct_spatial_mv_pred_flag, 0, 0.0, 1, 0.0, 1.0 },
+ {"DirectInferenceFlag", &configinput.directInferenceFlag, 0, 0.0, 1, 0.0, 1.0 },
+ {"SPPicturePeriodicity", &configinput.sp_periodicity, 0, 0.0, 2, 0.0, 0.0 },
+ {"QPSPSlice", &configinput.qpsp, 0, 24.0, 3, (double) MIN_QP, (double) MAX_QP },
+ {"QPSP2Slice", &configinput.qpsp_pred, 0, 24.0, 3, (double) MIN_QP, (double) MAX_QP },
+ {"SymbolMode", &configinput.symbol_mode, 0, 0.0, 1, (double) UVLC, (double) CABAC },
+ {"OutFileMode", &configinput.of_mode, 0, 0.0, 1, 0.0, 1.0 },
+ {"PartitionMode", &configinput.partition_mode, 0, 0.0, 1, 0.0, 1.0 },
+ {"InterSearch16x16", &configinput.InterSearch16x16, 0, 1.0, 1, 0.0, 1.0 },
+ {"InterSearch16x8", &configinput.InterSearch16x8 , 0, 1.0, 1, 0.0, 1.0 },
+ {"InterSearch8x16", &configinput.InterSearch8x16, 0, 1.0, 1, 0.0, 1.0 },
+ {"InterSearch8x8", &configinput.InterSearch8x8 , 0, 1.0, 1, 0.0, 1.0 },
+ {"InterSearch8x4", &configinput.InterSearch8x4, 0, 1.0, 1, 0.0, 1.0 },
+ {"InterSearch4x8", &configinput.InterSearch4x8, 0, 1.0, 1, 0.0, 1.0 },
+ {"InterSearch4x4", &configinput.InterSearch4x4, 0, 1.0, 1, 0.0, 1.0 },
+ {"IntraDisableInterOnly", &configinput.IntraDisableInterOnly, 0, 0.0, 1, 0.0, 1.0 },
+ {"Intra4x4ParDisable", &configinput.Intra4x4ParDisable, 0, 0.0, 1, 0.0, 1.0 },
+ {"Intra4x4DiagDisable", &configinput.Intra4x4DiagDisable, 0, 0.0, 1, 0.0, 1.0 },
+ {"Intra4x4DirDisable", &configinput.Intra4x4DirDisable, 0, 0.0, 1, 0.0, 1.0 },
+ {"Intra16x16ParDisable", &configinput.Intra16x16ParDisable, 0, 0.0, 1, 0.0, 1.0 },
+ {"Intra16x16PlaneDisable", &configinput.Intra16x16PlaneDisable, 0, 0.0, 1, 0.0, 1.0 },
+ {"EnableIPCM", &configinput.EnableIPCM, 0, 0.0, 1, 0.0, 1.0 },
+ {"ChromaIntraDisable", &configinput.ChromaIntraDisable, 0, 0.0, 1, 0.0, 1.0 },
+
+ #ifdef _FULL_SEARCH_RANGE_
+ {"RestrictSearchRange", &configinput.full_search, 0, 2.0, 1, 0.0, 2.0 },
+ #endif
+ #ifdef _ADAPT_LAST_GROUP_
+ {"LastFrameNumber", &configinput.last_frame, 0, 0.0, 2, 0.0, 0.0 },
+ #endif
+ #ifdef _CHANGE_QP_
+ {"ChangeQPI", &configinput.qp02, 0, 24.0, 3, (double) MIN_QP, (double) MAX_QP },
+ {"ChangeQPP", &configinput.qpN2, 0, 24.0, 3, (double) MIN_QP, (double) MAX_QP },
+ {"ChangeQPB", &configinput.qpB2, 0, 24.0, 3, (double) MIN_QP, (double) MAX_QP },
+ {"ChangeQPBSRefOffset", &configinput.qpBRS2Offset, 0, 0.0, 1,-51.0, 51.0 },
+ {"ChangeQPStart", &configinput.qp2start, 0, 0.0, 2, 0.0, 0.0 },
+ #endif
+ {"RDOptimization", &configinput.rdopt, 0, 0.0, 1, 0.0, 2.0 },
+ {"DisableThresholding", &configinput.disthres, 0, 0.0, 1, 0.0, 1.0 },
+ {"DisableBSkipRDO", &configinput.nobskip, 0, 0.0, 1, 0.0, 1.0 },
+ {"LossRateA", &configinput.LossRateA, 0, 0.0, 2, 0.0, 0.0 },
+ {"LossRateB", &configinput.LossRateB, 0, 0.0, 2, 0.0, 0.0 },
+ {"LossRateC", &configinput.LossRateC, 0, 0.0, 2, 0.0, 0.0 },
+ {"NumberOfDecoders", &configinput.NoOfDecoders, 0, 0.0, 2, 0.0, 0.0 },
+ {"RestrictRefFrames", &configinput.RestrictRef , 0, 0.0, 1, 0.0, 1.0 },
+ #ifdef _LEAKYBUCKET_
+ {"NumberofLeakyBuckets", &configinput.NumberLeakyBuckets, 0, 2.0, 1, 2.0, 255.0 },
+ {"LeakyBucketRateFile", &configinput.LeakyBucketRateFile, 1, 0.0, 0, 0.0, 0.0 },
+ {"LeakyBucketParamFile", &configinput.LeakyBucketParamFile, 1, 0.0, 0, 0.0, 0.0 },
+ #endif
+ {"PicInterlace", &configinput.PicInterlace, 0, 0.0, 1, 0.0, 2.0 },
+ {"MbInterlace", &configinput.MbInterlace, 0, 0.0, 1, 0.0, 2.0 },
+
+ {"IntraBottom", &configinput.IntraBottom, 0, 0.0, 1, 0.0, 1.0 },
+
+ {"NumberFramesInEnhancementLayerSubSequence", &configinput.NumFramesInELSubSeq, 0, 0.0, 2, 0.0, 0.0 },
+ {"NumberOfFrameInSecondIGOP",&configinput.NumFrameIn2ndIGOP, 0, 0.0, 2, 0.0, 0.0 },
+ {"RandomIntraMBRefresh", &configinput.RandomIntraMBRefresh, 0, 0.0, 2, 0.0, 0.0 },
+
+
+ {"WeightedPrediction", &configinput.WeightedPrediction, 0, 0.0, 1, 0.0, 1.0 },
+ {"WeightedBiprediction", &configinput.WeightedBiprediction, 0, 0.0, 1, 0.0, 2.0 },
+ {"UseWeightedReferenceME", &configinput.UseWeightedReferenceME, 0, 0.0, 1, 0.0, 1.0 },
+ {"RDPictureDecision", &configinput.RDPictureDecision, 0, 0.0, 1, 0.0, 1.0 },
+ {"RDPictureIntra", &configinput.RDPictureIntra, 0, 0.0, 1, 0.0, 1.0 },
+ {"RDPSliceWeightOnly", &configinput.RDPSliceWeightOnly, 0, 1.0, 1, 0.0, 1.0 },
+ {"RDPSliceBTest", &configinput.RDPSliceBTest, 0, 0.0, 1, 0.0, 1.0 },
+ {"RDBSliceWeightOnly", &configinput.RDBSliceWeightOnly, 0, 0.0, 1, 0.0, 1.0 },
+
+ {"SkipIntraInInterSlices", &configinput.SkipIntraInInterSlices, 0, 0.0, 1, 0.0, 1.0 },
+ {"BReferencePictures", &configinput.BRefPictures, 0, 0.0, 1, 0.0, 2.0 },
+ {"PyramidCoding", &configinput.PyramidCoding, 0, 0.0, 1, 0.0, 3.0 },
+ {"PyramidLevelQPEnable", &configinput.PyramidLevelQPEnable, 0, 0.0, 1, 0.0, 1.0 },
+ {"ExplicitPyramidFormat", &configinput.ExplicitPyramidFormat, 1, 0.0, 0, 0.0, 0.0 },
+ {"PyramidRefReorder", &configinput.PyramidRefReorder, 0, 0.0, 1, 0.0, 1.0 },
+ {"PocMemoryManagement", &configinput.PocMemoryManagement, 0, 0.0, 1, 0.0, 1.0 },
+
+ {"BiPredMotionEstimation", &configinput.BiPredMotionEstimation, 0, 0.0, 1, 0.0, 1.0 },
+ {"BiPredMERefinements", &configinput.BiPredMERefinements, 0, 0.0, 1, 0.0, 5.0 },
+ {"BiPredMESearchRange", &configinput.BiPredMESearchRange, 0, 8.0, 2, 0.0, 0.0 },
+ {"BiPredMESubPel", &configinput.BiPredMESubPel, 0, 1.0, 1, 0.0, 2.0 },
+
+ {"LoopFilterParametersFlag", &configinput.LFSendParameters, 0, 0.0, 1, 0.0, 1.0 },
+ {"LoopFilterDisable", &configinput.LFDisableIdc, 0, 0.0, 1, 0.0, 2.0 },
+ {"LoopFilterAlphaC0Offset", &configinput.LFAlphaC0Offset, 0, 0.0, 1, -6.0, 6.0 },
+ {"LoopFilterBetaOffset", &configinput.LFBetaOffset, 0, 0.0, 1, -6.0, 6.0 },
+ {"SparePictureOption", &configinput.SparePictureOption, 0, 0.0, 1, 0.0, 1.0 },
+ {"SparePictureDetectionThr", &configinput.SPDetectionThreshold, 0, 0.0, 2, 0.0, 0.0 },
+ {"SparePicturePercentageThr",&configinput.SPPercentageThreshold, 0, 0.0, 2, 0.0, 100.0 },
+
+ {"num_slice_groups_minus1", &configinput.num_slice_groups_minus1, 0, 0.0, 1, 0.0, (double)MAXSLICEGROUPIDS - 1 },
+ {"slice_group_map_type", &configinput.slice_group_map_type, 0, 0.0, 1, 0.0, 6.0 },
+ {"slice_group_change_direction_flag", &configinput.slice_group_change_direction_flag, 0, 0.0, 1, 0.0, 2.0 },
+ {"slice_group_change_rate_minus1", &configinput.slice_group_change_rate_minus1, 0, 0.0, 2, 0.0, 1.0 },
+ {"SliceGroupConfigFileName", &configinput.SliceGroupConfigFileName, 1, 0.0, 0, 0.0, 0.0 },
+
+
+ {"UseRedundantSlice", &configinput.redundant_slice_flag, 0, 0.0, 1, 0.0, 1.0 },
+ {"PicOrderCntType", &configinput.pic_order_cnt_type, 0, 0.0, 1, 0.0, 2.0 },
+
+ {"ContextInitMethod", &configinput.context_init_method, 0, 0.0, 1, 0.0, 1.0 },
+ {"FixedModelNumber", &configinput.model_number, 0, 0.0, 1, 0.0, 2.0 },
+
+ {"Transform8x8Mode", &configinput.Transform8x8Mode, 0, 0.0, 1, 0.0, 2.0 },
+ {"ReportFrameStats", &configinput.ReportFrameStats, 0, 0.0, 1, 0.0, 1.0 },
+ {"DisplayEncParams", &configinput.DisplayEncParams, 0, 0.0, 1, 0.0, 1.0 },
+ {"Verbose", &configinput.Verbose, 0, 1.0, 1, 0.0, 2.0 },
+ // Rate Control
+ {"RateControlEnable", &configinput.RCEnable, 0, 0.0, 1, 0.0, 1.0 },
+ {"Bitrate", &configinput.bit_rate, 0, 0.0, 2, 0.0, 0.0 },
+ {"InitialQP", &configinput.SeinitialQP, 0, 0.0, 3, (double) MIN_QP, (double) MAX_QP },
+ {"BasicUnit", &configinput.basicunit, 0, 0.0, 2, 0.0, 0.0 },
+ {"ChannelType", &configinput.channel_type, 0, 0.0, 1, 0.0, 1.0 },
+
+ // Q_Matrix
+ {"QmatrixFile", &configinput.QmatrixFile, 1, 0.0, 0, 0.0, 0.0 },
+ {"ScalingMatrixPresentFlag", &configinput.ScalingMatrixPresentFlag, 0, 0.0, 1, 0.0, 3.0 },
+ {"ScalingListPresentFlag0", &configinput.ScalingListPresentFlag[0], 0, 0.0, 1, 0.0, 3.0 },
+ {"ScalingListPresentFlag1", &configinput.ScalingListPresentFlag[1], 0, 0.0, 1, 0.0, 3.0 },
+ {"ScalingListPresentFlag2", &configinput.ScalingListPresentFlag[2], 0, 0.0, 1, 0.0, 3.0 },
+ {"ScalingListPresentFlag3", &configinput.ScalingListPresentFlag[3], 0, 0.0, 1, 0.0, 3.0 },
+ {"ScalingListPresentFlag4", &configinput.ScalingListPresentFlag[4], 0, 0.0, 1, 0.0, 3.0 },
+ {"ScalingListPresentFlag5", &configinput.ScalingListPresentFlag[5], 0, 0.0, 1, 0.0, 3.0 },
+ {"ScalingListPresentFlag6", &configinput.ScalingListPresentFlag[6], 0, 0.0, 1, 0.0, 3.0 },
+ {"ScalingListPresentFlag7", &configinput.ScalingListPresentFlag[7], 0, 0.0, 1, 0.0, 3.0 },
+
+ // Fast ME enable
+ {"UseFME", &configinput.FMEnable, 0, 0.0, 1, 0.0, 3.0 },
+ {"EPZSPattern", &configinput.EPZSPattern, 0, 2.0, 1, 0.0, 3.0 },
+ {"EPZSDualRefinement", &configinput.EPZSDual, 0, 3.0, 1, 0.0, 4.0 },
+ {"EPZSFixedPredictors", &configinput.EPZSFixed, 0, 2.0, 1, 0.0, 2.0 },
+ {"EPZSTemporal", &configinput.EPZSTemporal, 0, 1.0, 1, 0.0, 1.0 },
+ {"EPZSSpatialMem", &configinput.EPZSSpatialMem, 0, 1.0, 1, 0.0, 1.0 },
+ {"EPZSMinThresScale", &configinput.EPZSMinThresScale, 0, 0.0, 0, 0.0, 0.0 },
+ {"EPZSMaxThresScale", &configinput.EPZSMaxThresScale, 0, 1.0, 0, 0.0, 0.0 },
+ {"EPZSMedThresScale", &configinput.EPZSMedThresScale, 0, 1.0, 0, 0.0, 0.0 },
+ {"ChromaQPOffset", &configinput.chroma_qp_index_offset, 0, 0.0, 1,-51.0, 51.0 },
+
+ // Fidelity Range Extensions
+ {"BitDepthLuma", &configinput.BitDepthLuma, 0, 8.0, 1, 8.0, 12.0 },
+ {"BitDepthChroma", &configinput.BitDepthChroma, 0, 8.0, 1, 8.0, 12.0 },
+ {"YUVFormat", &configinput.yuv_format, 0, 1.0, 1, 0.0, 3.0 },
+ {"RGBInput", &configinput.rgb_input_flag, 0, 0.0, 1, 0.0, 1.0 },
+ {"CbQPOffset", &configinput.cb_qp_index_offset, 0, 0.0, 1,-51.0, 51.0 },
+ {"CrQPOffset", &configinput.cr_qp_index_offset, 0, 0.0, 1,-51.0, 51.0 },
+
+ // Lossless Coding
+ {"QPPrimeYZeroTransformBypassFlag", &configinput.lossless_qpprime_y_zero_flag, 0, 0.0, 1, 0.0, 1.0 },
+
+ // Residue Color Transform
+ {"ResidueTransformFlag", &configinput.residue_transform_flag , 0, 0.0, 1, 0.0, 1.0 },
+
+ // Explicit Lambda Usage
+ {"UseExplicitLambdaParams", &configinput.UseExplicitLambdaParams, 0, 0.0, 1, 0.0, 3.0 },
+ {"LambdaWeightPslice", &configinput.LambdaWeight[0], 2, 0.68, 2, 0.0, 0.0 },
+ {"LambdaWeightBslice", &configinput.LambdaWeight[1], 2, 2.00, 2, 0.0, 0.0 },
+ {"LambdaWeightIslice", &configinput.LambdaWeight[2], 2, 0.65, 2, 0.0, 0.0 },
+ {"LambdaWeightSPslice", &configinput.LambdaWeight[3], 2, 1.50, 2, 0.0, 0.0 },
+ {"LambdaWeightSIslice", &configinput.LambdaWeight[4], 2, 0.65, 2, 0.0, 0.0 },
+ {"LambdaWeightRefBslice", &configinput.LambdaWeight[5], 2, 1.50, 2, 0.0, 0.0 },
+
+ {"QOffsetMatrixFile", &configinput.QOffsetMatrixFile, 1, 0.0, 0, 0.0, 0.0 },
+ {"OffsetMatrixPresentFlag", &configinput.OffsetMatrixPresentFlag, 0, 0.0, 1, 0.0, 1.0 },
+
+ // Fast Mode Decision
+ {"EarlySkipEnable", &configinput.EarlySkipEnable, 0, 0.0, 1, 0.0, 1.0 },
+ {"SelectiveIntraEnable", &configinput.SelectiveIntraEnable, 0, 0.0, 1, 0.0, 1.0 },
+
+ // Adaptive rounding technique based on JVT-N011
+ {"AdaptiveRounding", &configinput.AdaptiveRounding, 0, 0.0, 1, 0.0, 1.0 },
+ {"AdaptRndPeriod", &configinput.AdaptRndPeriod, 0, 16.0, 2, 0.0, 0.0 },
+ {"AdaptRndChroma", &configinput.AdaptRndChroma, 0, 0.0, 1, 0.0, 1.0 },
+ {"AdaptRndWFactorIRef", &configinput.AdaptRndWFactor[1][I_SLICE], 0, 4.0, 1, 0.0, 1024.0 },
+ {"AdaptRndWFactorPRef", &configinput.AdaptRndWFactor[1][P_SLICE], 0, 4.0, 1, 0.0, 1024.0 },
+ {"AdaptRndWFactorBRef", &configinput.AdaptRndWFactor[1][B_SLICE], 0, 4.0, 1, 0.0, 1024.0 },
+ {"AdaptRndWFactorINRef", &configinput.AdaptRndWFactor[0][I_SLICE], 0, 4.0, 1, 0.0, 1024.0 },
+ {"AdaptRndWFactorPNRef", &configinput.AdaptRndWFactor[0][P_SLICE], 0, 4.0, 1, 0.0, 1024.0 },
+ {"AdaptRndWFactorBNRef", &configinput.AdaptRndWFactor[0][B_SLICE], 0, 4.0, 1, 0.0, 1024.0 },
+
+ {NULL, NULL, -1, 0.0, 0, 0.0, 0.0 }
+ };
+
+ #endif
+
+ #ifndef INCLUDED_BY_CONFIGFILE_C
+ extern Mapping Map[];
+ #endif
+
+
+ void Configure (int ac, char *av[]);
+ void PatchInputNoFrames();
+
+ #endif
+
Index: llvm-test/MultiSource/Applications/JM/lencod/context_ini.c
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/context_ini.c:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/context_ini.c Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,365 ----
+
+ /*!
+ *************************************************************************************
+ * \file context_ini.c
+ *
+ * \brief
+ * CABAC context initializations
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Detlev Marpe <marpe at hhi.de>
+ * - Heiko Schwarz <hschwarz at hhi.de>
+ **************************************************************************************
+ */
+
+ #define CONTEXT_INI_C
+
+ #include <stdlib.h>
+ #include <math.h>
+
+ #include "global.h"
+
+ #include "ctx_tables.h"
+ #include "cabac.h"
+
+ #define DEFAULT_CTX_MODEL 0
+ #define RELIABLE_COUNT 32.0
+ #define FRAME_TYPES 4
+ #define FIXED 0
+
+
+ int num_mb_per_slice;
+ int number_of_slices;
+ int*** initialized;
+ int*** model_number;
+
+
+ double entropy [128];
+ double probability[128] =
+ {
+ 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
+ 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
+ 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
+ 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
+ 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
+ 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
+ 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
+ 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
+ //--------------------------------------------------------------------------------
+ 0.500000, 0.474609, 0.450507, 0.427629, 0.405912, 0.385299, 0.365732, 0.347159,
+ 0.329530, 0.312795, 0.296911, 0.281833, 0.267520, 0.253935, 0.241039, 0.228799,
+ 0.217180, 0.206151, 0.195682, 0.185744, 0.176312, 0.167358, 0.158859, 0.150792,
+ 0.143134, 0.135866, 0.128966, 0.122417, 0.116200, 0.110299, 0.104698, 0.099381,
+ 0.094334, 0.089543, 0.084996, 0.080680, 0.076583, 0.072694, 0.069002, 0.065498,
+ 0.062172, 0.059014, 0.056018, 0.053173, 0.050473, 0.047909, 0.045476, 0.043167,
+ 0.040975, 0.038894, 0.036919, 0.035044, 0.033264, 0.031575, 0.029972, 0.028450,
+ 0.027005, 0.025633, 0.024332, 0.023096, 0.021923, 0.020810, 0.019753, 0.018750
+ };
+
+
+
+ void create_context_memory ()
+ {
+ int i, j, k;
+ int num_mb = img->FrameSizeInMbs; // number of macroblocks for frame
+
+ num_mb_per_slice = (input->slice_mode==1 ? input->slice_argument : num_mb);
+ number_of_slices = (num_mb + num_mb_per_slice - 1) / num_mb_per_slice;
+
+ if ((initialized = (int***) malloc (3 * sizeof(int**))) == NULL)
+ {
+ no_mem_exit ("create_context_memory: initialized");
+ }
+ if ((model_number = (int***) malloc (3 * sizeof(int**))) == NULL)
+ {
+ no_mem_exit ("create_context_memory: model_number");
+ }
+
+ for (k=0; k<3; k++)
+ {
+ if ((initialized[k] = (int**) malloc (FRAME_TYPES * sizeof(int*))) == NULL)
+ {
+ no_mem_exit ("create_context_memory: initialized");
+ }
+ if ((model_number[k]= (int**) malloc (FRAME_TYPES * sizeof(int*))) == NULL)
+ {
+ no_mem_exit ("create_context_memory: model_number");
+ }
+
+ for (i=0; i<FRAME_TYPES; i++)
+ {
+ if ((initialized[k][i] = (int*) malloc (number_of_slices * sizeof(int))) == NULL)
+ {
+ no_mem_exit ("create_context_memory: initialized");
+ }
+ if ((model_number[k][i]= (int*) malloc (number_of_slices * sizeof(int))) == NULL)
+ {
+ no_mem_exit ("create_context_memory: model_number");
+ }
+ }
+ }
+
+ //===== set all context sets as "uninitialized" =====
+ for (k=0; k<3; k++)
+ {
+ for (i=0; i<FRAME_TYPES; i++)
+ {
+ for (j=0; j<number_of_slices; j++)
+ {
+ initialized[k][i][j] = 0;
+ }
+ }
+ }
+
+ //----- init tables -----
+ for( k=0; k<64; k++ )
+ {
+ probability[k] = 1.0 - probability[127-k];
+ entropy [k] = log10(probability[ k])/log10(2.0);
+ entropy[127-k] = log10(probability[127-k])/log10(2.0);
+ }
+ }
+
+
+
+
+ void free_context_memory ()
+ {
+ int i, k;
+
+ for (k=0; k<3; k++)
+ {
+ for (i=0; i<FRAME_TYPES; i++)
+ {
+ free (initialized [k][i]);
+ free (model_number[k][i]);
+ }
+ free (initialized [k]);
+ free (model_number[k]);
+ }
+ free (initialized);
+ free (model_number);
+ }
+
+
+
+
+
+
+ #define BIARI_CTX_INIT2(ii,jj,ctx,tab,num) \
+ { \
+ for (i=0; i<ii; i++) \
+ for (j=0; j<jj; j++) \
+ { \
+ if (img->type==I_SLICE) biari_init_context (&(ctx[i][j]), &(tab ## _I[num][i][j][0])); \
+ else biari_init_context (&(ctx[i][j]), &(tab ## _P[num][i][j][0])); \
+ } \
+ }
+ #define BIARI_CTX_INIT1(jj,ctx,tab,num) \
+ { \
+ for (j=0; j<jj; j++) \
+ { \
+ if (img->type==I_SLICE) biari_init_context (&(ctx[j]), &(tab ## _I[num][0][j][0])); \
+ else biari_init_context (&(ctx[j]), &(tab ## _P[num][0][j][0])); \
+ } \
+ }
+
+
+
+ void SetCtxModelNumber ()
+ {
+ int frame_field = img->field_picture;
+ int img_type = img->type;
+ int ctx_number = img->currentSlice->start_mb_nr / num_mb_per_slice;
+
+ if(img->type==I_SLICE)
+ {
+ img->model_number=DEFAULT_CTX_MODEL;
+ return;
+ }
+ if(input->context_init_method==FIXED)
+ {
+ img->model_number=input->model_number;
+ return;
+ }
+
+ if (initialized [frame_field][img_type][ctx_number])
+ {
+ img->model_number = model_number[frame_field][img_type][ctx_number];
+ }
+ else if (ctx_number && initialized[frame_field][img_type][ctx_number-1])
+ {
+ img->model_number = model_number[frame_field][img_type][ctx_number-1];
+ }
+ else
+ {
+ img->model_number = DEFAULT_CTX_MODEL;
+ }
+ }
+
+
+
+ void init_contexts ()
+ {
+ MotionInfoContexts* mc = img->currentSlice->mot_ctx;
+ TextureInfoContexts* tc = img->currentSlice->tex_ctx;
+ int i, j;
+
+ //--- motion coding contexts ---
+ BIARI_CTX_INIT2 (3, NUM_MB_TYPE_CTX, mc->mb_type_contexts, INIT_MB_TYPE, img->model_number);
+ BIARI_CTX_INIT2 (2, NUM_B8_TYPE_CTX, mc->b8_type_contexts, INIT_B8_TYPE, img->model_number);
+ BIARI_CTX_INIT2 (2, NUM_MV_RES_CTX, mc->mv_res_contexts, INIT_MV_RES, img->model_number);
+ BIARI_CTX_INIT2 (2, NUM_REF_NO_CTX, mc->ref_no_contexts, INIT_REF_NO, img->model_number);
+ BIARI_CTX_INIT1 ( NUM_DELTA_QP_CTX, mc->delta_qp_contexts, INIT_DELTA_QP, img->model_number);
+ BIARI_CTX_INIT1 ( NUM_MB_AFF_CTX, mc->mb_aff_contexts, INIT_MB_AFF, img->model_number);
+ BIARI_CTX_INIT1 ( NUM_TRANSFORM_SIZE_CTX, mc->transform_size_contexts, INIT_TRANSFORM_SIZE, img->model_number);
+
+ //--- texture coding contexts ---
+ BIARI_CTX_INIT1 ( NUM_IPR_CTX, tc->ipr_contexts, INIT_IPR, img->model_number);
+ BIARI_CTX_INIT1 ( NUM_CIPR_CTX, tc->cipr_contexts, INIT_CIPR, img->model_number);
+ BIARI_CTX_INIT2 (3, NUM_CBP_CTX, tc->cbp_contexts, INIT_CBP, img->model_number);
+ BIARI_CTX_INIT2 (NUM_BLOCK_TYPES, NUM_BCBP_CTX, tc->bcbp_contexts, INIT_BCBP, img->model_number);
+ BIARI_CTX_INIT2 (NUM_BLOCK_TYPES, NUM_MAP_CTX, tc->map_contexts, INIT_MAP, img->model_number);
+ BIARI_CTX_INIT2 (NUM_BLOCK_TYPES, NUM_LAST_CTX, tc->last_contexts, INIT_LAST, img->model_number);
+ BIARI_CTX_INIT2 (NUM_BLOCK_TYPES, NUM_ONE_CTX, tc->one_contexts, INIT_ONE, img->model_number);
+ BIARI_CTX_INIT2 (NUM_BLOCK_TYPES, NUM_ABS_CTX, tc->abs_contexts, INIT_ABS, img->model_number);
+ BIARI_CTX_INIT2 (NUM_BLOCK_TYPES, NUM_MAP_CTX, tc->fld_map_contexts, INIT_FLD_MAP, img->model_number);
+ BIARI_CTX_INIT2 (NUM_BLOCK_TYPES, NUM_LAST_CTX, tc->fld_last_contexts,INIT_FLD_LAST, img->model_number);
+ }
+
+
+
+
+
+ double XRate (BiContextTypePtr ctx, const int* model)
+ {
+ int ctx_state, mod_state;
+ double weight, xr = 0.0;
+ int qp = max(0,img->qp);
+
+ weight = min (1.0, (double)ctx->count/(double)RELIABLE_COUNT);
+
+ mod_state = ((model[0]*qp)>>4)+model[1];
+ mod_state = min (max (0, mod_state), 127);
+ ctx_state = (ctx->MPS ? 64+ctx->state : 63-ctx->state);
+
+ xr -= weight * probability[ ctx_state] * entropy[ mod_state];
+ xr -= weight * probability[127-ctx_state] * entropy[127-mod_state];
+
+ return xr;
+ }
+
+ #define ADD_XRATE2(ii,jj,ctx,tab,num) \
+ { \
+ for (i=0; i<ii; i++) \
+ for (j=0; j<jj; j++) \
+ { \
+ if (img->type==I_SLICE) xr += XRate (&(ctx[i][j]), &(tab ## _I[num][i][j][0])); \
+ else xr += XRate (&(ctx[i][j]), &(tab ## _P[num][i][j][0])); \
+ } \
+ }
+ #define ADD_XRATE1(jj,ctx,tab,num) \
+ { \
+ for (j=0; j<jj; j++) \
+ { \
+ if (img->type==I_SLICE) xr += XRate (&(ctx[j]), &(tab ## _I[num][0][j][0])); \
+ else xr += XRate (&(ctx[j]), &(tab ## _P[num][0][j][0])); \
+ } \
+ }
+
+
+ void GetCtxModelNumber (int* mnumber, MotionInfoContexts* mc, TextureInfoContexts* tc)
+ {
+ int model, j, i;
+ int num_models = (img->type==I_SLICE ? NUM_CTX_MODELS_I : NUM_CTX_MODELS_P);
+ double xr, min_xr = 1e30;
+
+ for (model=0; model<num_models; model++)
+ {
+ xr = 0.0;
+ //--- motion coding contexts ---
+ ADD_XRATE2 (3, NUM_MB_TYPE_CTX, mc->mb_type_contexts, INIT_MB_TYPE, model);
+ ADD_XRATE2 (2, NUM_B8_TYPE_CTX, mc->b8_type_contexts, INIT_B8_TYPE, model);
+ ADD_XRATE2 (2, NUM_MV_RES_CTX, mc->mv_res_contexts, INIT_MV_RES, model);
+ ADD_XRATE2 (2, NUM_REF_NO_CTX, mc->ref_no_contexts, INIT_REF_NO, model);
+ ADD_XRATE1 ( NUM_DELTA_QP_CTX, mc->delta_qp_contexts, INIT_DELTA_QP, model);
+ ADD_XRATE1 ( NUM_MB_AFF_CTX, mc->mb_aff_contexts, INIT_MB_AFF, model);
+ ADD_XRATE1 ( NUM_TRANSFORM_SIZE_CTX, mc->transform_size_contexts, INIT_TRANSFORM_SIZE, model);
+
+ //--- texture coding contexts ---
+ ADD_XRATE1 ( NUM_IPR_CTX, tc->ipr_contexts, INIT_IPR, model);
+ ADD_XRATE1 ( NUM_CIPR_CTX, tc->cipr_contexts, INIT_CIPR, model);
+ ADD_XRATE2 (3, NUM_CBP_CTX, tc->cbp_contexts, INIT_CBP, model);
+ ADD_XRATE2 (NUM_BLOCK_TYPES, NUM_BCBP_CTX, tc->bcbp_contexts, INIT_BCBP, model);
+ ADD_XRATE2 (NUM_BLOCK_TYPES, NUM_MAP_CTX, tc->map_contexts, INIT_MAP, model);
+ ADD_XRATE2 (NUM_BLOCK_TYPES, NUM_LAST_CTX, tc->last_contexts, INIT_LAST, model);
+ ADD_XRATE2 (NUM_BLOCK_TYPES, NUM_ONE_CTX, tc->one_contexts, INIT_ONE, model);
+ ADD_XRATE2 (NUM_BLOCK_TYPES, NUM_ABS_CTX, tc->abs_contexts, INIT_ABS, model);
+ ADD_XRATE2 (NUM_BLOCK_TYPES, NUM_MAP_CTX, tc->fld_map_contexts, INIT_FLD_MAP, model);
+ ADD_XRATE2 (NUM_BLOCK_TYPES, NUM_LAST_CTX, tc->fld_last_contexts, INIT_FLD_LAST, model);
+
+ if (xr<min_xr)
+ {
+ min_xr = xr;
+ *mnumber = model;
+ }
+ }
+ }
+
+ #undef ADD_XRATE2
+ #undef ADD_XRATE1
+
+
+
+
+
+
+ void store_contexts ()
+ {
+ int frame_field = img->field_picture;
+ int img_type = img->type;
+ int ctx_number = img->currentSlice->start_mb_nr / num_mb_per_slice;
+
+ if( input->context_init_method )
+ {
+ initialized [frame_field][img_type][ctx_number] = 1;
+ GetCtxModelNumber (model_number[frame_field][img_type]+ctx_number, img->currentSlice->mot_ctx, img->currentSlice->tex_ctx);
+ }
+ else
+ {
+ // do nothing
+ }
+ }
+
+
+ void update_field_frame_contexts (int field)
+ {
+ int i, j;
+
+ if (field)
+ {
+ // set frame contexts
+ for (j=0; j<FRAME_TYPES; j++)
+ {
+ for (i=0; i<number_of_slices; i++)
+ {
+ initialized [0][j][i] = initialized [1][j][i>>1];
+ model_number[0][j][i] = model_number[1][j][i>>1];
+ }
+ }
+ }
+ else
+ {
+ // set field contexts
+ for (j=0; j<FRAME_TYPES; j++)
+ {
+ for (i=0; i<((number_of_slices+1)>>1); i++)
+ {
+ initialized [1][j][i] = initialized [0][j][i<<1];
+ model_number[1][j][i] = model_number[0][j][i<<1];
+ }
+ }
+ }
+ }
+
Index: llvm-test/MultiSource/Applications/JM/lencod/context_ini.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/context_ini.h:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/context_ini.h Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,32 ----
+
+ /*!
+ *************************************************************************************
+ * \file context_ini.h
+ *
+ * \brief
+ * CABAC context initializations
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Detlev Marpe <marpe at hhi.de>
+ * - Heiko Schwarz <hschwarz at hhi.de>
+ **************************************************************************************
+ */
+
+ #ifndef _CONTEXT_INI_
+ #define _CONTEXT_INI_
+
+
+ void create_context_memory ();
+ void free_context_memory ();
+
+ void init_contexts ();
+ void store_contexts ();
+
+ void update_field_frame_contexts (int);
+ void update_rd_picture_contexts (int);
+
+ void SetCtxModelNumber ();
+
+ #endif
+
Index: llvm-test/MultiSource/Applications/JM/lencod/contributors.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/contributors.h:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/contributors.h Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,212 ----
+
+ /*! \file
+ * contributors.h
+ * \brief
+ * List of contributors and copyright information.
+ *
+ * \par Copyright statements
+ \verbatim
+ H.264 JM coder/decoder
+
+ Copyright (C) 2000 by
+ Telenor Broadband Services, Norway
+ Ericsson Radio Systems, Sweden
+ TELES AG, Germany
+ Nokia Inc., USA
+ Nokia Corporation, Finland
+ Siemens AG, Germany
+ Heinrich-Hertz-Institute for Communication Technology GmbH, Germany
+ University of Hannover, Institut of Communication Theory and Signal Processing,Germany
+ Videolocus, Canada
+ LSI Logic, Canada
+ Motorola Inc., USA
+ Microsoft Corp., USA
+ Apple Computer, Inc.
+ RealNetworks, Inc., USA
+ Thomson, Inc., USA
+ \endverbatim
+ \par Full Contact Information
+ \verbatim
+
+ Lowell Winger <lwinger at videolocus.com><lwinger at uwaterloo.ca><lwinger at lsil.com>
+ Guy Côté <gcote at videolocus.com>
+ Michael Gallant <mgallant at videolocus.com>
+ VideoLocus Inc.
+ 97 Randall Dr.
+ Waterloo, ON, Canada N2V1C5
+
+ Inge Lille-Langøy <inge.lille-langoy at telenor.com>
+ Telenor Broadband Services
+ P.O.Box 6914 St.Olavs plass
+ N-0130 Oslo, Norway
+
+ Rickard Sjoberg <rickard.sjoberg at era.ericsson.se>
+ Ericsson Radio Systems
+ KI/ERA/T/VV
+ 164 80 Stockholm, Sweden
+
+ Stephan Wenger <stewe at cs.tu-berlin.de>
+ TU Berlin / TELES AG
+ Sekr. FR 6-3
+ Franklinstr. 28-29
+ D-10587 Berlin, Germany
+
+ Jani Lainema <jani.lainema at nokia.com>
+ Nokia Inc. / Nokia Research Center
+ 6000 Connection Drive
+ Irving, TX 75039, USA
+
+ Sebastian Purreiter <sebastian.purreiter at mch.siemens.de>
+ Siemens AG
+ ICM MD MP RD MCH 83
+ P.O.Box 80 17 07
+ D-81617 Munich, Germany
+
+ Thomas Wedi <wedi at tnt.uni-hannover.de>
+ University of Hannover
+ Institut of Communication Theory and Signal Processing
+ Appelstr. 9a
+ 30167 Hannover
+
+ Thomas Stockhammer <stockhammer at ei.tum.de>
+ Institute for Communications Engineering
+ Munich University of Technology
+ 80290 Munich
+ Germany
+
+ Detlev Marpe <marpe at hhi.de>
+ Heinrich-Hertz-Institute
+ Einsteinufer 37
+ 10587 Berlin
+ Germany
+
+ Guido Heising <heising at hhi.de>
+ Heinrich-Hertz-Institute
+ Einsteinufer 37
+ 10587 Berlin
+ Germany
+
+ Ragip Kurceren <ragip.kurceren at nokia.com>
+ Nokia Inc. / Nokia Research Center
+ 6000 Connection Drive
+ Irving, TX 75039, USA
+
+ Tobias Oelbaum (TO) <drehvial at gmx.net>
+ Institute for Communications Engineering
+ Munich University of Technology
+ 80290 Munich
+ Germany
+
+ Yann Le Maguet <yann.lemaguet at philips.com>
+ Philips Research France
+
+ Dong Tian <tian at cs.tut.fi>
+ Ye-Kui Wang <wyk at ieee.org>
+ Tampere University of Technology
+ Tampere International Center for Signal Processing
+ 33720 Tampere, Finland
+
+ Miska M. Hannuksela <miska.hannuksela at nokia.com>
+ Nokia Corporation / Nokia Mobile Phones
+ P.O. Box 88
+ 33721 Tampere, Finland
+
+ Karsten Suehring <suehring at hhi.de>
+ Heinrich-Hertz-Institute
+ Einsteinufer 37
+ 10587 Berlin
+ Germany
+
+ Heiko Schwarz <hschwarz at hhi.de>
+ Heinrich-Hertz-Institute
+ Einsteinufer 37
+ 10587 Berlin
+ Germany
+
+ Limin Wang <liwang at gi.com>
+ Krit Panusopone <kpanusopone at gi.com>
+ Rajeev Gandhi <rgandhi at gi.com>
+ Yue Yu <yyu at gi.com>
+ Motorola Inc.
+ 6450 Sequence Drive
+ San Diego, CA 92121 USA
+
+ Feng Wu <fengwu at microsoft.com>
+ Xiaoyan Sun <sunxiaoyan at msrchina.research.microsoft.com>
+ Microsoft Research Asia
+ 3/F, Beijing Sigma Center
+ No.49, Zhichun Road, Hai Dian District,
+ Beijing China 100080
+
+
+ Mathias Wien <wien at ient.rwth-aachen.de>
+ Institut und Lehrstuhl für Nachrichtentechnik
+ RWTH Aachen University
+ 52072 Aachen
+ Germany
+
+ Achim Dahlhoff <dahlhoff at ient.rwth-aachen.de>
+ Institut und Lehrstuhl für Nachrichtentechnik
+ RWTH Aachen University
+ 52072 Aachen
+ Germany
+
+ Yoshihiro Kikuchi <yoshihiro.kikuchi at toshiba.co.jp>
+ Takeshi Chujoh <takeshi.chujoh at toshiba.co.jp>
+ Toshiba Corporation
+ Research and Development Center
+ Kawasaki 212-8582, Japan
+
+ Shinya Kadono <kadono at drl.mei.co.jp>
+ Matsushita Electric Industrial Co., Ltd.
+ 1006 Kadoma, Kadoma
+ Osaka 663-8113, Japan
+
+ Dzung Hoang <dzung.hoang at conexant.com>
+ Eric Viscito <eric.viscito at conexant.com>
+ Conexant Systems. Inc.
+ MPEG Compression Group
+ 20450 Stevens Creek Blvd.
+ Cupertino, CA 95014
+
+ Barry Haskell
+ Apple Computer, Inc. <bhaskell at apple.com>
+ 2 Infinite Loop
+ Cupertino, California 95014
+
+ Greg Conklin
+ RealNetworks, Inc. <gregc at real.com>
+ 2601 Elliott Ave
+ Seattle, WA 98101
+
+ Jill Boyce <jill.boyce at thomson.net>
+ Cristina Gomila <cristina.gomila at thomson.net>
+ Thomson
+ 2 Independence Way
+ Princeton, NJ 08540
+
+ Siwei Ma <swma at jdl.ac.cn>
+ Institute of Computing Technology
+ Chinese Academy of Sciences
+ Kexueyuan South Road 6
+ Haidian District
+ Beijing, China
+
+ Zhibo Chen <chenzhibo at tsinghua.org.cn>
+ JianFeng Xu <fenax at video.mdc.tsinghua.edu.cn>
+ Wenfang Fu <fwf at video.mdc.tsinghua.edu.cn>
+ Dept.of E&E, Tsinghua Univ
+ Haidian District
+ Beijing China, 100084
+
+ Alexis Michael Tourapis <alexismt at ieee.org>
+
+ Xiaoquan Yi <xyi at engr.scu.edu>
+ Jun Zhang <jzhang2 at engr.scu.edu>
+ Dept. of C.E. Santa Clara Univ.
+ 500 El Camino Real
+ Santa Clara, CA 95053
+
+ \endverbatim
+ */
+
Index: llvm-test/MultiSource/Applications/JM/lencod/ctx_tables.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/ctx_tables.h:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/ctx_tables.h Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,729 ----
+
+ /*!
+ *************************************************************************************
+ * \file ctx_tables.h
+ *
+ * \brief
+ * CABAC context initialization tables
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Detlev Marpe <marpe at hhi.de>
+ * - Heiko Schwarz <hschwarz at hhi.de>
+ **************************************************************************************
+ */
+
+ #define CTX_UNUSED {0,64}
+ #define CTX_UNDEF {0,63}
+
+ #ifdef CONTEXT_INI_C
+
+
+ #define NUM_CTX_MODELS_I 1
+ #define NUM_CTX_MODELS_P 3
+
+
+ static const int INIT_MB_TYPE_I[1][3][11][2] =
+ {
+ //----- model 0 -----
+ {
+ { { 20, -15} , { 2, 54} , { 3, 74} , CTX_UNUSED , { -28, 127} , { -23, 104} , { -6, 53} , { -1, 54} , { 7, 51} , CTX_UNUSED , CTX_UNUSED },
+ { { 20, -15} , { 2, 54} , { 3, 74} , { 20, -15} , { 2, 54} , { 3, 74} , { -28, 127} , { -23, 104} , { -6, 53} , { -1, 54} , { 7, 51} }, // SI (unused at the moment)
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ }
+ };
+ static const int INIT_MB_TYPE_P[3][3][11][2] =
+ {
+ //----- model 0 -----
+ {
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { 23, 33} , { 23, 2} , { 21, 0} , CTX_UNUSED , { 1, 9} , { 0, 49} , { -37, 118} , { 5, 57} , { -13, 78} , { -11, 65} , { 1, 62} },
+ { { 26, 67} , { 16, 90} , { 9, 104} , CTX_UNUSED , { -46, 127} , { -20, 104} , { 1, 67} , { 18, 64} , { 9, 43} , { 29, 0} , CTX_UNUSED }
+ },
+ //----- model 1 -----
+ {
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { 22, 25} , { 34, 0} , { 16, 0} , CTX_UNUSED , { -2, 9} , { 4, 41} , { -29, 118} , { 2, 65} , { -6, 71} , { -13, 79} , { 5, 52} },
+ { { 57, 2} , { 41, 36} , { 26, 69} , CTX_UNUSED , { -45, 127} , { -15, 101} , { -4, 76} , { 26, 34} , { 19, 22} , { 40, 0} , CTX_UNUSED }
+ },
+ //----- model 2 -----
+ {
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { 29, 16} , { 25, 0} , { 14, 0} , CTX_UNUSED , { -10, 51} , { -3, 62} , { -27, 99} , { 26, 16} , { -4, 85} , { -24, 102} , { 5, 57} },
+ { { 54, 0} , { 37, 42} , { 12, 97} , CTX_UNUSED , { -32, 127} , { -22, 117} , { -2, 74} , { 20, 40} , { 20, 10} , { 29, 0} , CTX_UNUSED }
+ }
+ };
+
+
+
+
+
+ static const int INIT_B8_TYPE_I[1][2][9][2] =
+ {
+ //----- model 0 -----
+ {
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ }
+ };
+ static const int INIT_B8_TYPE_P[3][2][9][2] =
+ {
+ //----- model 0 -----
+ {
+ { CTX_UNUSED , { 12, 49} , CTX_UNUSED , { -4, 73} , { 17, 50} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { -6, 86} , { -17, 95} , { -6, 61} , { 9, 45} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ },
+ //----- model 1 -----
+ {
+ { CTX_UNUSED , { 9, 50} , CTX_UNUSED , { -3, 70} , { 10, 54} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { 6, 69} , { -13, 90} , { 0, 52} , { 8, 43} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ },
+ //----- model 2 -----
+ {
+ { CTX_UNUSED , { 6, 57} , CTX_UNUSED , { -17, 73} , { 14, 57} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { -6, 93} , { -14, 88} , { -6, 44} , { 4, 55} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ }
+ };
+
+
+
+
+
+ static const int INIT_MV_RES_I[1][2][10][2] =
+ {
+ //----- model 0 -----
+ {
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ }
+ };
+ static const int INIT_MV_RES_P[3][2][10][2] =
+ {
+ //----- model 0 -----
+ {
+ { { -3, 69} , CTX_UNUSED , { -6, 81} , { -11, 96} , CTX_UNUSED , { 0, 58} , CTX_UNUSED , { -3, 76} , { -10, 94} , CTX_UNUSED },
+ { { 6, 55} , { 7, 67} , { -5, 86} , { 2, 88} , CTX_UNUSED , { 5, 54} , { 4, 69} , { -3, 81} , { 0, 88} , CTX_UNUSED }
+ },
+ //----- model 1 -----
+ {
+ { { -2, 69} , CTX_UNUSED , { -5, 82} , { -10, 96} , CTX_UNUSED , { 1, 56} , CTX_UNUSED , { -3, 74} , { -6, 85} , CTX_UNUSED },
+ { { 2, 59} , { 2, 75} , { -3, 87} , { -3, 100} , CTX_UNUSED , { 0, 59} , { -3, 81} , { -7, 86} , { -5, 95} , CTX_UNUSED }
+ },
+ //----- model 2 -----
+ {
+ { { -11, 89} , CTX_UNUSED , { -15, 103} , { -21, 116} , CTX_UNUSED , { 1, 63} , CTX_UNUSED , { -5, 85} , { -13, 106} , CTX_UNUSED },
+ { { 19, 57} , { 20, 58} , { 4, 84} , { 6, 96} , CTX_UNUSED , { 5, 63} , { 6, 75} , { -3, 90} , { -1, 101} , CTX_UNUSED }
+ }
+ };
+
+
+
+
+
+ static const int INIT_REF_NO_I[1][2][6][2] =
+ {
+ //----- model 0 -----
+ {
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ }
+ };
+ static const int INIT_REF_NO_P[3][2][6][2] =
+ {
+ //----- model 0 -----
+ {
+ { { -7, 67} , { -5, 74} , { -4, 74} , { -5, 80} , { -7, 72} , { 1, 58} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ },
+ //----- model 1 -----
+ {
+ { { -1, 66} , { -1, 77} , { 1, 70} , { -2, 86} , { -5, 72} , { 0, 61} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ },
+ //----- model 2 -----
+ {
+ { { 3, 55} , { -4, 79} , { -2, 75} , { -12, 97} , { -7, 50} , { 1, 60} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ }
+ };
+
+
+ static const int INIT_TRANSFORM_SIZE_I[1][1][3][2]=
+ {
+ //----- model 0 -----
+ {
+ { { 31, 21} , { 31, 31} , { 25, 50} },
+ // { { 0, 41} , { 0, 63} , { 0, 63} },
+ }
+ };
+
+ static const int INIT_TRANSFORM_SIZE_P[3][1][3][2]=
+ {
+ //----- model 0 -----
+ {
+ { { 12, 40} , { 11, 51} , { 14, 59} },
+ // { { 0, 41} , { 0, 63} , { 0, 63} },
+ },
+ //----- model 1 -----
+ {
+ { { 25, 32} , { 21, 49} , { 21, 54} },
+ // { { 0, 41} , { 0, 63} , { 0, 63} },
+ },
+ //----- model 2 -----
+ {
+ { { 21, 33} , { 19, 50} , { 17, 61} },
+ // { { 0, 41} , { 0, 63} , { 0, 63} },
+ }
+ };
+
+ static const int INIT_DELTA_QP_I[1][1][4][2]=
+ {
+ //----- model 0 -----
+ {
+ { { 0, 41} , { 0, 63} , { 0, 63} , { 0, 63} },
+ }
+ };
+ static const int INIT_DELTA_QP_P[3][1][4][2]=
+ {
+ //----- model 0 -----
+ {
+ { { 0, 41} , { 0, 63} , { 0, 63} , { 0, 63} },
+ },
+ //----- model 1 -----
+ {
+ { { 0, 41} , { 0, 63} , { 0, 63} , { 0, 63} },
+ },
+ //----- model 2 -----
+ {
+ { { 0, 41} , { 0, 63} , { 0, 63} , { 0, 63} },
+ }
+ };
+
+
+
+
+
+ static const int INIT_MB_AFF_I[1][1][4][2] =
+ {
+ //----- model 0 -----
+ {
+ { { 0, 11} , { 1, 55} , { 0, 69} , CTX_UNUSED }
+ }
+ };
+ static const int INIT_MB_AFF_P[3][1][4][2] =
+ {
+ //----- model 0 -----
+ {
+ { { 0, 45} , { -4, 78} , { -3, 96} , CTX_UNUSED }
+ },
+ //----- model 1 -----
+ {
+ { { 13, 15} , { 7, 51} , { 2, 80} , CTX_UNUSED }
+ },
+ //----- model 2 -----
+ {
+ { { 7, 34} , { -9, 88} , { -20, 127} , CTX_UNUSED }
+ }
+ };
+
+
+
+
+
+ static const int INIT_IPR_I[1][1][2][2] =
+ {
+ //----- model 0 -----
+ {
+ { { 13, 41} , { 3, 62} }
+ }
+ };
+ static const int INIT_IPR_P[3][1][2][2] =
+ {
+ //----- model 0 -----
+ {
+ { { 13, 41} , { 3, 62} }
+ },
+ //----- model 1 -----
+ {
+ { { 13, 41} , { 3, 62} }
+ },
+ //----- model 2 -----
+ {
+ { { 13, 41} , { 3, 62} }
+ }
+ };
+
+
+
+
+
+ static const int INIT_CIPR_I[1][1][4][2] =
+ {
+ //----- model 0 -----
+ {
+ { { -9, 83} , { 4, 86} , { 0, 97} , { -7, 72} }
+ }
+ };
+ static const int INIT_CIPR_P[3][1][4][2] =
+ {
+ //----- model 0 -----
+ {
+ { { -9, 83} , { 4, 86} , { 0, 97} , { -7, 72} }
+ },
+ //----- model 1 -----
+ {
+ { { -9, 83} , { 4, 86} , { 0, 97} , { -7, 72} }
+ },
+ //----- model 2 -----
+ {
+ { { -9, 83} , { 4, 86} , { 0, 97} , { -7, 72} }
+ }
+ };
+
+
+
+
+
+
+ static const int INIT_CBP_I[1][3][4][2] =
+ {
+ //----- model 0 -----
+ {
+ { { -17, 127} , { -13, 102} , { 0, 82} , { -7, 74} },
+ { { -21, 107} , { -27, 127} , { -31, 127} , { -24, 127} },
+ { { -18, 95} , { -27, 127} , { -21, 114} , { -30, 127} }
+ }
+ };
+ static const int INIT_CBP_P[3][3][4][2] =
+ {
+ //----- model 0 -----
+ {
+ { { -27, 126} , { -28, 98} , { -25, 101} , { -23, 67} },
+ { { -28, 82} , { -20, 94} , { -16, 83} , { -22, 110} },
+ { { -21, 91} , { -18, 102} , { -13, 93} , { -29, 127} }
+ },
+ //----- model 1 -----
+ {
+ { { -39, 127} , { -18, 91} , { -17, 96} , { -26, 81} },
+ { { -35, 98} , { -24, 102} , { -23, 97} , { -27, 119} },
+ { { -24, 99} , { -21, 110} , { -18, 102} , { -36, 127} }
+ },
+ //----- model 2 -----
+ {
+ { { -36, 127} , { -17, 91} , { -14, 95} , { -25, 84} },
+ { { -25, 86} , { -12, 89} , { -17, 91} , { -31, 127} },
+ { { -14, 76} , { -18, 103} , { -13, 90} , { -37, 127} }
+ }
+ };
+
+
+
+
+
+ static const int INIT_BCBP_I[1][8][4][2] =
+ {
+ //----- model 0 -----
+ {
+ { { -17, 123} , { -12, 115} , { -16, 122} , { -11, 115} },
+ { { -12, 63} , { -2, 68} , { -15, 84} , { -13, 104} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { -3, 70} , { -8, 93} , { -10, 90} , { -30, 127} },
+ { { -1, 74} , { -6, 97} , { -7, 91} , { -20, 127} },
+ { { -4, 56} , { -5, 82} , { -7, 76} , { -22, 125} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ }
+ };
+ static const int INIT_BCBP_P[3][8][4][2] =
+ {
+ //----- model 0 -----
+ {
+ { { -7, 92} , { -5, 89} , { -7, 96} , { -13, 108} },
+ { { -3, 46} , { -1, 65} , { -1, 57} , { -9, 93} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { -3, 74} , { -9, 92} , { -8, 87} , { -23, 126} },
+ { { 5, 54} , { 6, 60} , { 6, 59} , { 6, 69} },
+ { { -1, 48} , { 0, 68} , { -4, 69} , { -8, 88} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ },
+ //----- model 1 -----
+ {
+ { { 0, 80} , { -5, 89} , { -7, 94} , { -4, 92} },
+ { { 0, 39} , { 0, 65} , { -15, 84} , { -35, 127} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { -2, 73} , { -12, 104} , { -9, 91} , { -31, 127} },
+ { { 3, 55} , { 7, 56} , { 7, 55} , { 8, 61} },
+ { { -3, 53} , { 0, 68} , { -7, 74} , { -9, 88} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ },
+ //----- model 2 -----
+ {
+ { { 11, 80} , { 5, 76} , { 2, 84} , { 5, 78} },
+ { { -6, 55} , { 4, 61} , { -14, 83} , { -37, 127} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { -5, 79} , { -11, 104} , { -11, 91} , { -30, 127} },
+ { { 0, 65} , { -2, 79} , { 0, 72} , { -4, 92} },
+ { { -6, 56} , { 3, 68} , { -8, 71} , { -13, 98} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ }
+ };
+
+
+
+
+
+ static const int INIT_MAP_I[1][8][15][2] =
+ {
+ //----- model 0 -----
+ {
+ { { -7, 93} , { -11, 87} , { -3, 77} , { -5, 71} , { -4, 63} , { -4, 68} , { -12, 84} , { -7, 62} , { -7, 65} , { 8, 61} , { 5, 56} , { -2, 66} , { 1, 64} , { 0, 61} , { -2, 78} },
+ { CTX_UNUSED , { 1, 50} , { 7, 52} , { 10, 35} , { 0, 44} , { 11, 38} , { 1, 45} , { 0, 46} , { 5, 44} , { 31, 17} , { 1, 51} , { 7, 50} , { 28, 19} , { 16, 33} , { 14, 62} },
+ { { -17, 120} , { -20, 112} , { -18, 114} , { -11, 85} , { -15, 92} , { -14, 89} , { -26, 71} , { -15, 81} , { -14, 80} , { 0, 68} , { -14, 70} , { -24, 56} , { -23, 68} , { -24, 50} , { -11, 74} },
+ // { { -1, 73} , { -7, 73} , { -6, 76} , { -7, 71} , { -9, 72} , { -5, 65} , { -14, 83} , { -8, 72} , { -10, 75} , { -5, 64} , { -4, 59} , { -13, 79} , { -9, 69} , { -8, 66} , { 3, 55} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { -13, 108} , { -15, 100} , { -13, 101} , { -13, 91} , { -12, 94} , { -10, 88} , { -16, 84} , { -10, 86} , { -7, 83} , { -13, 87} , { -19, 94} , { 1, 70} , { 0, 72} , { -5, 74} , { 18, 59} },
+ { { -8, 102} , { -15, 100} , { 0, 95} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , { -4, 75} , { 2, 72} , { -11, 75} , { -3, 71} , { 15, 46} , { -13, 69} , { 0, 62} , { 0, 65} , { 21, 37} , { -15, 72} , { 9, 57} , { 16, 54} , { 0, 62} , { 12, 72} }
+ }
+ };
+ static const int INIT_MAP_P[3][8][15][2] =
+ {
+ //----- model 0 -----
+ {
+ { { -2, 85} , { -6, 78} , { -1, 75} , { -7, 77} , { 2, 54} , { 5, 50} , { -3, 68} , { 1, 50} , { 6, 42} , { -4, 81} , { 1, 63} , { -4, 70} , { 0, 67} , { 2, 57} , { -2, 76} },
+ { CTX_UNUSED , { 11, 35} , { 4, 64} , { 1, 61} , { 11, 35} , { 18, 25} , { 12, 24} , { 13, 29} , { 13, 36} , { -10, 93} , { -7, 73} , { -2, 73} , { 13, 46} , { 9, 49} , { -7, 100} },
+ { { -4, 79} , { -7, 71} , { -5, 69} , { -9, 70} , { -8, 66} , { -10, 68} , { -19, 73} , { -12, 69} , { -16, 70} , { -15, 67} , { -20, 62} , { -19, 70} , { -16, 66} , { -22, 65} , { -20, 63} },
+ // { { -4, 60} , { -3, 49} , { -2, 50} , { -4, 49} , { -5, 48} , { -2, 46} , { -7, 54} , { -1, 45} , { -4, 49} , { 4, 39} , { 0, 42} , { 2, 43} , { 0, 44} , { 5, 32} , { 15, 30} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { 9, 53} , { 2, 53} , { 5, 53} , { -2, 61} , { 0, 56} , { 0, 56} , { -13, 63} , { -5, 60} , { -1, 62} , { 4, 57} , { -6, 69} , { 4, 57} , { 14, 39} , { 4, 51} , { 13, 68} },
+ { { 3, 64} , { 1, 61} , { 9, 63} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , { 7, 50} , { 16, 39} , { 5, 44} , { 4, 52} , { 11, 48} , { -5, 60} , { -1, 59} , { 0, 59} , { 22, 33} , { 5, 44} , { 14, 43} , { -1, 78} , { 0, 60} , { 9, 69} }
+ },
+ //----- model 1 -----
+ {
+ { { -13, 103} , { -13, 91} , { -9, 89} , { -14, 92} , { -8, 76} , { -12, 87} , { -23, 110} , { -24, 105} , { -10, 78} , { -20, 112} , { -17, 99} , { -78, 127} , { -70, 127} , { -50, 127} , { -46, 127} },
+ { CTX_UNUSED , { -4, 66} , { -5, 78} , { -4, 71} , { -8, 72} , { 2, 59} , { -1, 55} , { -7, 70} , { -6, 75} , { -8, 89} , { -34, 119} , { -3, 75} , { 32, 20} , { 30, 22} , { -44, 127} },
+ { { -5, 85} , { -6, 81} , { -10, 77} , { -7, 81} , { -17, 80} , { -18, 73} , { -4, 74} , { -10, 83} , { -9, 71} , { -9, 67} , { -1, 61} , { -8, 66} , { -14, 66} , { 0, 59} , { 2, 59} },
+ // { { -4, 60} , { -3, 49} , { -2, 50} , { -4, 49} , { -5, 48} , { -2, 46} , { -7, 54} , { -1, 45} , { -4, 49} , { 4, 39} , { 0, 42} , { 2, 43} , { 0, 44} , { 5, 32} , { 15, 30} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { 0, 54} , { -5, 61} , { 0, 58} , { -1, 60} , { -3, 61} , { -8, 67} , { -25, 84} , { -14, 74} , { -5, 65} , { 5, 52} , { 2, 57} , { 0, 61} , { -9, 69} , { -11, 70} , { 18, 55} },
+ { { -4, 71} , { 0, 58} , { 7, 61} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , { 9, 41} , { 18, 25} , { 9, 32} , { 5, 43} , { 9, 47} , { 0, 44} , { 0, 51} , { 2, 46} , { 19, 38} , { -4, 66} , { 15, 38} , { 12, 42} , { 9, 34} , { 0, 89} }
+ },
+ //----- model 2 -----
+ {
+ { { -4, 86} , { -12, 88} , { -5, 82} , { -3, 72} , { -4, 67} , { -8, 72} , { -16, 89} , { -9, 69} , { -1, 59} , { 5, 66} , { 4, 57} , { -4, 71} , { -2, 71} , { 2, 58} , { -1, 74} },
+ { CTX_UNUSED , { -4, 44} , { -1, 69} , { 0, 62} , { -7, 51} , { -4, 47} , { -6, 42} , { -3, 41} , { -6, 53} , { 8, 76} , { -9, 78} , { -11, 83} , { 9, 52} , { 0, 67} , { -5, 90} },
+ { { -3, 78} , { -8, 74} , { -9, 72} , { -10, 72} , { -18, 75} , { -12, 71} , { -11, 63} , { -5, 70} , { -17, 75} , { -14, 72} , { -16, 67} , { -8, 53} , { -14, 59} , { -9, 52} , { -11, 68} },
+ // { { -4, 60} , { -3, 49} , { -2, 50} , { -4, 49} , { -5, 48} , { -2, 46} , { -7, 54} , { -1, 45} , { -4, 49} , { 4, 39} , { 0, 42} , { 2, 43} , { 0, 44} , { 5, 32} , { 15, 30} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { 1, 67} , { -15, 72} , { -5, 75} , { -8, 80} , { -21, 83} , { -21, 64} , { -13, 31} , { -25, 64} , { -29, 94} , { 9, 75} , { 17, 63} , { -8, 74} , { -5, 35} , { -2, 27} , { 13, 91} },
+ { { 3, 65} , { -7, 69} , { 8, 77} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , { -10, 66} , { 3, 62} , { -3, 68} , { -20, 81} , { 0, 30} , { 1, 7} , { -3, 23} , { -21, 74} , { 16, 66} , { -23, 124} , { 17, 37} , { 44, -18} , { 50, -34} , { -22, 127} }
+ }
+ };
+
+
+
+
+ static const int INIT_LAST_I[1][8][15][2] =
+ {
+ //----- model 0 -----
+ {
+ { { 24, 0} , { 15, 9} , { 8, 25} , { 13, 18} , { 15, 9} , { 13, 19} , { 10, 37} , { 12, 18} , { 6, 29} , { 20, 33} , { 15, 30} , { 4, 45} , { 1, 58} , { 0, 62} , { 7, 61} },
+ { CTX_UNUSED , { 12, 38} , { 11, 45} , { 15, 39} , { 11, 42} , { 13, 44} , { 16, 45} , { 12, 41} , { 10, 49} , { 30, 34} , { 18, 42} , { 10, 55} , { 17, 51} , { 17, 46} , { 0, 89} },
+ { { 23, -13} , { 26, -13} , { 40, -15} , { 49, -14} , { 44, 3} , { 45, 6} , { 44, 34} , { 33, 54} , { 19, 82} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ // { { 12, 33} , { 5, 38} , { 9, 34} , { 18, 22} , { 19, 22} , { 23, 19} , { 26, 16} , { 14, 44} , { 40, 14} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { 26, -19} , { 22, -17} , { 26, -17} , { 30, -25} , { 28, -20} , { 33, -23} , { 37, -27} , { 33, -23} , { 40, -28} , { 38, -17} , { 33, -11} , { 40, -15} , { 41, -6} , { 38, 1} , { 41, 17} },
+ { { 30, -6} , { 27, 3} , { 26, 22} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , { 37, -16} , { 35, -4} , { 38, -8} , { 38, -3} , { 37, 3} , { 38, 5} , { 42, 0} , { 35, 16} , { 39, 22} , { 14, 48} , { 27, 37} , { 21, 60} , { 12, 68} , { 2, 97} }
+ }
+ };
+ static const int INIT_LAST_P[3][8][15][2] =
+ {
+ //----- model 0 -----
+ {
+ { { 11, 28} , { 2, 40} , { 3, 44} , { 0, 49} , { 0, 46} , { 2, 44} , { 2, 51} , { 0, 47} , { 4, 39} , { 2, 62} , { 6, 46} , { 0, 54} , { 3, 54} , { 2, 58} , { 4, 63} },
+ { CTX_UNUSED , { 6, 51} , { 6, 57} , { 7, 53} , { 6, 52} , { 6, 55} , { 11, 45} , { 14, 36} , { 8, 53} , { -1, 82} , { 7, 55} , { -3, 78} , { 15, 46} , { 22, 31} , { -1, 84} },
+ { { 9, -2} , { 26, -9} , { 33, -9} , { 39, -7} , { 41, -2} , { 45, 3} , { 49, 9} , { 45, 27} , { 36, 59} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ // { { 17, 27} , { 23, 13} , { 24, 16} , { 22, 25} , { 23, 27} , { 23, 32} , { 17, 43} , { 17, 49} , { 2, 70} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { 25, 7} , { 30, -7} , { 28, 3} , { 28, 4} , { 32, 0} , { 34, -1} , { 30, 6} , { 30, 6} , { 32, 9} , { 31, 19} , { 26, 27} , { 26, 30} , { 37, 20} , { 28, 34} , { 17, 70} },
+ { { 1, 67} , { 5, 59} , { 9, 67} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , { 16, 30} , { 18, 32} , { 18, 35} , { 22, 29} , { 24, 31} , { 23, 38} , { 18, 43} , { 20, 41} , { 11, 63} , { 9, 59} , { 9, 64} , { -1, 94} , { -2, 89} , { -9, 108} }
+ },
+ //----- model 1 -----
+ {
+ { { 4, 45} , { 10, 28} , { 10, 31} , { 33, -11} , { 52, -43} , { 18, 15} , { 28, 0} , { 35, -22} , { 38, -25} , { 34, 0} , { 39, -18} , { 32, -12} , { 102, -94} , { 0, 0} , { 56, -15} },
+ { CTX_UNUSED , { 33, -4} , { 29, 10} , { 37, -5} , { 51, -29} , { 39, -9} , { 52, -34} , { 69, -58} , { 67, -63} , { 44, -5} , { 32, 7} , { 55, -29} , { 32, 1} , { 0, 0} , { 27, 36} },
+ { { 17, -10} , { 32, -13} , { 42, -9} , { 49, -5} , { 53, 0} , { 64, 3} , { 68, 10} , { 66, 27} , { 47, 57} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ // { { 17, 27} , { 23, 13} , { 24, 16} , { 22, 25} , { 23, 27} , { 23, 32} , { 17, 43} , { 17, 49} , { 2, 70} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { 33, -25} , { 34, -30} , { 36, -28} , { 38, -28} , { 38, -27} , { 34, -18} , { 35, -16} , { 34, -14} , { 32, -8} , { 37, -6} , { 35, 0} , { 30, 10} , { 28, 18} , { 26, 25} , { 29, 41} },
+ { { 0, 75} , { 2, 72} , { 8, 77} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , { 14, 35} , { 18, 31} , { 17, 35} , { 21, 30} , { 17, 45} , { 20, 42} , { 18, 45} , { 27, 26} , { 16, 54} , { 7, 66} , { 16, 56} , { 11, 73} , { 10, 67} , { -10, 116} }
+ },
+ //----- model 2 -----
+ {
+ { { 4, 39} , { 0, 42} , { 7, 34} , { 11, 29} , { 8, 31} , { 6, 37} , { 7, 42} , { 3, 40} , { 8, 33} , { 13, 43} , { 13, 36} , { 4, 47} , { 3, 55} , { 2, 58} , { 6, 60} },
+ { CTX_UNUSED , { 8, 44} , { 11, 44} , { 14, 42} , { 7, 48} , { 4, 56} , { 4, 52} , { 13, 37} , { 9, 49} , { 19, 58} , { 10, 48} , { 12, 45} , { 0, 69} , { 20, 33} , { 8, 63} },
+ { { 9, -2} , { 30, -10} , { 31, -4} , { 33, -1} , { 33, 7} , { 31, 12} , { 37, 23} , { 31, 38} , { 20, 64} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ // { { 17, 27} , { 23, 13} , { 24, 16} , { 22, 25} , { 23, 27} , { 23, 32} , { 17, 43} , { 17, 49} , { 2, 70} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { 35, -18} , { 33, -25} , { 28, -3} , { 24, 10} , { 27, 0} , { 34, -14} , { 52, -44} , { 39, -24} , { 19, 17} , { 31, 25} , { 36, 29} , { 24, 33} , { 34, 15} , { 30, 20} , { 22, 73} },
+ { { 20, 34} , { 19, 31} , { 27, 44} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , { 19, 16} , { 15, 36} , { 15, 36} , { 21, 28} , { 25, 21} , { 30, 20} , { 31, 12} , { 27, 16} , { 24, 42} , { 0, 93} , { 14, 56} , { 15, 57} , { 26, 38} , { -24, 127} }
+ }
+ };
+
+
+
+
+
+ static const int INIT_ONE_I[1][8][5][2] =
+ {
+ //----- model 0 -----
+ {
+ { { -3, 71} , { -6, 42} , { -5, 50} , { -3, 54} , { -2, 62} },
+ { { -5, 67} , { -5, 27} , { -3, 39} , { -2, 44} , { 0, 46} },
+ { { -3, 75} , { -1, 23} , { 1, 34} , { 1, 43} , { 0, 54} },
+ // { { -9, 75} , { -1, 44} , { -2, 49} , { -2, 51} , { -1, 51} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { -12, 92} , { -15, 55} , { -10, 60} , { -6, 62} , { -4, 65} },
+ { { -11, 97} , { -20, 84} , { -11, 79} , { -6, 73} , { -4, 74} },
+ { { -8, 78} , { -5, 33} , { -4, 48} , { -2, 53} , { -3, 62} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ }
+ };
+ static const int INIT_ONE_P[3][8][5][2] =
+ {
+ //----- model 0 -----
+ {
+ { { -6, 76} , { -2, 44} , { 0, 45} , { 0, 52} , { -3, 64} },
+ { { -9, 77} , { 3, 24} , { 0, 42} , { 0, 48} , { 0, 55} },
+ { { -6, 66} , { -7, 35} , { -7, 42} , { -8, 45} , { -5, 48} },
+ // { { -3, 58} , { -1, 28} , { 0, 29} , { 2, 30} , { 1, 35} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { 1, 58} , { -3, 29} , { -1, 36} , { 1, 38} , { 2, 43} },
+ { { 0, 70} , { -4, 29} , { 5, 31} , { 7, 42} , { 1, 59} },
+ { { 0, 58} , { 8, 5} , { 10, 14} , { 14, 18} , { 13, 27} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ },
+ //----- model 1 -----
+ {
+ { { -23, 112} , { -15, 71} , { -7, 61} , { 0, 53} , { -5, 66} },
+ { { -21, 101} , { -3, 39} , { -5, 53} , { -7, 61} , { -11, 75} },
+ { { -5, 71} , { 0, 24} , { -1, 36} , { -2, 42} , { -2, 52} },
+ // { { -3, 58} , { -1, 28} , { 0, 29} , { 2, 30} , { 1, 35} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { -11, 76} , { -10, 44} , { -10, 52} , { -10, 57} , { -9, 58} },
+ { { 2, 66} , { -9, 34} , { 1, 32} , { 11, 31} , { 5, 52} },
+ { { 3, 52} , { 7, 4} , { 10, 8} , { 17, 8} , { 16, 19} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ },
+ //----- model 2 -----
+ {
+ { { -24, 115} , { -22, 82} , { -9, 62} , { 0, 53} , { 0, 59} },
+ { { -21, 100} , { -14, 57} , { -12, 67} , { -11, 71} , { -10, 77} },
+ { { -9, 71} , { -7, 37} , { -8, 44} , { -11, 49} , { -10, 56} },
+ // { { -3, 58} , { -1, 28} , { 0, 29} , { 2, 30} , { 1, 35} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { -10, 82} , { -8, 48} , { -8, 61} , { -8, 66} , { -7, 70} },
+ { { -4, 79} , { -22, 69} , { -16, 75} , { -2, 58} , { 1, 58} },
+ { { -13, 81} , { -6, 38} , { -13, 62} , { -6, 58} , { -2, 59} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ }
+ };
+
+
+
+
+
+ static const int INIT_ABS_I[1][8][5][2] =
+ {
+ //----- model 0 -----
+ {
+ { { 0, 58} , { 1, 63} , { -2, 72} , { -1, 74} , { -9, 91} },
+ { { -16, 64} , { -8, 68} , { -10, 78} , { -6, 77} , { -10, 86} },
+ { { -2, 55} , { 0, 61} , { 1, 64} , { 0, 68} , { -9, 92} },
+ // { { -4, 56} , { -1, 59} , { -6, 71} , { -8, 74} , { -11, 85} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { -12, 73} , { -8, 76} , { -7, 80} , { -9, 88} , { -17, 110} },
+ { { -13, 86} , { -13, 96} , { -11, 97} , { -19, 117} , CTX_UNUSED },
+ { { -13, 71} , { -10, 79} , { -12, 86} , { -13, 90} , { -14, 97} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ }
+ };
+ static const int INIT_ABS_P[3][8][5][2] =
+ {
+ //----- model 0 -----
+ {
+ { { -2, 59} , { -4, 70} , { -4, 75} , { -8, 82} , { -17, 102} },
+ { { -6, 59} , { -7, 71} , { -12, 83} , { -11, 87} , { -30, 119} },
+ { { -12, 56} , { -6, 60} , { -5, 62} , { -8, 66} , { -8, 76} },
+ // { { -7, 54} , { -2, 58} , { -4, 63} , { -5, 66} , { 1, 64} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { -6, 55} , { 0, 58} , { 0, 64} , { -3, 74} , { -10, 90} },
+ { { -2, 58} , { -3, 72} , { -3, 81} , { -11, 97} , CTX_UNUSED },
+ { { 2, 40} , { 0, 58} , { -3, 70} , { -6, 79} , { -8, 85} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ },
+ //----- model 1 -----
+ {
+ { { -11, 77} , { -9, 80} , { -9, 84} , { -10, 87} , { -34, 127} },
+ { { -15, 77} , { -17, 91} , { -25, 107} , { -25, 111} , { -28, 122} },
+ { { -9, 57} , { -6, 63} , { -4, 65} , { -4, 67} , { -7, 82} },
+ // { { -7, 54} , { -2, 58} , { -4, 63} , { -5, 66} , { 1, 64} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { -16, 72} , { -7, 69} , { -4, 69} , { -5, 74} , { -9, 86} },
+ { { -2, 55} , { -2, 67} , { 0, 73} , { -8, 89} , CTX_UNUSED },
+ { { 3, 37} , { -1, 61} , { -5, 73} , { -1, 70} , { -4, 78} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ },
+ //----- model 2 -----
+ {
+ { { -14, 85} , { -13, 89} , { -13, 94} , { -11, 92} , { -29, 127} },
+ { { -21, 85} , { -16, 88} , { -23, 104} , { -15, 98} , { -37, 127} },
+ { { -12, 59} , { -8, 63} , { -9, 67} , { -6, 68} , { -10, 79} },
+ // { { -7, 54} , { -2, 58} , { -4, 63} , { -5, 66} , { 1, 64} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { -14, 75} , { -10, 79} , { -9, 83} , { -12, 92} , { -18, 108} },
+ { { -13, 78} , { -9, 83} , { -4, 81} , { -13, 99} , CTX_UNUSED },
+ { { -16, 73} , { -10, 76} , { -13, 86} , { -9, 83} , { -10, 87} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }
+ }
+ };
+
+
+
+
+
+ static const int INIT_FLD_MAP_I[1][8][15][2] =
+ {
+ //----- model 0 -----
+ {
+ { { -6, 93} , { -6, 84} , { -8, 79} , { 0, 66} , { -1, 71} , { 0, 62} , { -2, 60} , { -2, 59} , { -5, 75} , { -3, 62} , { -4, 58} , { -9, 66} , { -1, 79} , { 0, 71} , { 3, 68} },
+ { CTX_UNUSED , { 10, 44} , { -7, 62} , { 15, 36} , { 14, 40} , { 16, 27} , { 12, 29} , { 1, 44} , { 20, 36} , { 18, 32} , { 5, 42} , { 1, 48} , { 10, 62} , { 17, 46} , { 9, 64} },
+ { { -14, 106} , { -13, 97} , { -15, 90} , { -12, 90} , { -18, 88} , { -10, 73} , { -9, 79} , { -14, 86} , { -10, 73} , { -10, 70} , { -10, 69} , { -5, 66} , { -9, 64} , { -5, 58} , { 2, 59} },
+ // { { -1, 73} , { -7, 73} , { -6, 76} , { -7, 71} , { -9, 72} , { -5, 65} , { -14, 83} , { -8, 72} , { -10, 75} , { -5, 64} , { -4, 59} , { -13, 79} , { -9, 69} , { -8, 66} , { 3, 55} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { -12, 104} , { -11, 97} , { -16, 96} , { -7, 88} , { -8, 85} , { -7, 85} , { -9, 85} , { -13, 88} , { 4, 66} , { -3, 77} , { -3, 76} , { -6, 76} , { 10, 58} , { -1, 76} , { -1, 83} },
+ { { -7, 99} , { -14, 95} , { 2, 95} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , { 0, 76} , { -5, 74} , { 0, 70} , { -11, 75} , { 1, 68} , { 0, 65} , { -14, 73} , { 3, 62} , { 4, 62} , { -1, 68} , { -13, 75} , { 11, 55} , { 5, 64} , { 12, 70} }
+ }
+ };
+ static const int INIT_FLD_MAP_P[3][8][15][2] =
+ {
+ //----- model 0 -----
+ {
+ { { -13, 106} , { -16, 106} , { -10, 87} , { -21, 114} , { -18, 110} , { -14, 98} , { -22, 110} , { -21, 106} , { -18, 103} , { -21, 107} , { -23, 108} , { -26, 112} , { -10, 96} , { -12, 95} , { -5, 91} },
+ { CTX_UNUSED , { -9, 93} , { -22, 94} , { -5, 86} , { 9, 67} , { -4, 80} , { -10, 85} , { -1, 70} , { 7, 60} , { 9, 58} , { 5, 61} , { 12, 50} , { 15, 50} , { 18, 49} , { 17, 54} },
+ { { -5, 85} , { -6, 81} , { -10, 77} , { -7, 81} , { -17, 80} , { -18, 73} , { -4, 74} , { -10, 83} , { -9, 71} , { -9, 67} , { -1, 61} , { -8, 66} , { -14, 66} , { 0, 59} , { 2, 59} },
+ // { { -4, 60} , { -3, 49} , { -2, 50} , { -4, 49} , { -5, 48} , { -2, 46} , { -7, 54} , { -1, 45} , { -4, 49} , { 4, 39} , { 0, 42} , { 2, 43} , { 0, 44} , { 5, 32} , { 15, 30} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { 10, 41} , { 7, 46} , { -1, 51} , { 7, 49} , { 8, 52} , { 9, 41} , { 6, 47} , { 2, 55} , { 13, 41} , { 10, 44} , { 6, 50} , { 5, 53} , { 13, 49} , { 4, 63} , { 6, 64} },
+ { { -2, 69} , { -2, 59} , { 6, 70} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , { 10, 44} , { 9, 31} , { 12, 43} , { 3, 53} , { 14, 34} , { 10, 38} , { -3, 52} , { 13, 40} , { 17, 32} , { 7, 44} , { 7, 38} , { 13, 50} , { 10, 57} , { 26, 43} }
+ },
+ //----- model 1 -----
+ {
+ { { -21, 126} , { -23, 124} , { -20, 110} , { -26, 126} , { -25, 124} , { -17, 105} , { -27, 121} , { -27, 117} , { -17, 102} , { -26, 117} , { -27, 116} , { -33, 122} , { -10, 95} , { -14, 100} , { -8, 95} },
+ { CTX_UNUSED , { -17, 111} , { -28, 114} , { -6, 89} , { -2, 80} , { -4, 82} , { -9, 85} , { -8, 81} , { -1, 72} , { 5, 64} , { 1, 67} , { 9, 56} , { 0, 69} , { 1, 69} , { 7, 69} },
+ { { -3, 81} , { -3, 76} , { -7, 72} , { -6, 78} , { -12, 72} , { -14, 68} , { -3, 70} , { -6, 76} , { -5, 66} , { -5, 62} , { 0, 57} , { -4, 61} , { -9, 60} , { 1, 54} , { 2, 58} },
+ // { { -4, 60} , { -3, 49} , { -2, 50} , { -4, 49} , { -5, 48} , { -2, 46} , { -7, 54} , { -1, 45} , { -4, 49} , { 4, 39} , { 0, 42} , { 2, 43} , { 0, 44} , { 5, 32} , { 15, 30} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { -7, 69} , { -6, 67} , { -16, 77} , { -2, 64} , { 2, 61} , { -6, 67} , { -3, 64} , { 2, 57} , { -3, 65} , { -3, 66} , { 0, 62} , { 9, 51} , { -1, 66} , { -2, 71} , { -2, 75} },
+ { { -1, 70} , { -9, 72} , { 14, 60} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , { 16, 37} , { 0, 47} , { 18, 35} , { 11, 37} , { 12, 41} , { 10, 41} , { 2, 48} , { 12, 41} , { 13, 41} , { 0, 59} , { 3, 50} , { 19, 40} , { 3, 66} , { 18, 50} }
+ },
+ //----- model 2 -----
+ {
+ { { -22, 127} , { -25, 127} , { -25, 120} , { -27, 127} , { -19, 114} , { -23, 117} , { -25, 118} , { -26, 117} , { -24, 113} , { -28, 118} , { -31, 120} , { -37, 124} , { -10, 94} , { -15, 102} , { -10, 99} },
+ { CTX_UNUSED , { -13, 106} , { -50, 127} , { -5, 92} , { 17, 57} , { -5, 86} , { -13, 94} , { -12, 91} , { -2, 77} , { 0, 71} , { -1, 73} , { 4, 64} , { -7, 81} , { 5, 64} , { 15, 57} },
+ { { -3, 78} , { -8, 74} , { -9, 72} , { -10, 72} , { -18, 75} , { -12, 71} , { -11, 63} , { -5, 70} , { -17, 75} , { -14, 72} , { -16, 67} , { -8, 53} , { -14, 59} , { -9, 52} , { -11, 68} },
+ // { { -4, 60} , { -3, 49} , { -2, 50} , { -4, 49} , { -5, 48} , { -2, 46} , { -7, 54} , { -1, 45} , { -4, 49} , { 4, 39} , { 0, 42} , { 2, 43} , { 0, 44} , { 5, 32} , { 15, 30} },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { 1, 67} , { 0, 68} , { -10, 67} , { 1, 68} , { 0, 77} , { 2, 64} , { 0, 68} , { -5, 78} , { 7, 55} , { 5, 59} , { 2, 65} , { 14, 54} , { 15, 44} , { 5, 60} , { 2, 70} },
+ { { -2, 76} , { -18, 86} , { 12, 70} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , { 5, 64} , { -12, 70} , { 11, 55} , { 5, 56} , { 0, 69} , { 2, 65} , { -6, 74} , { 5, 54} , { 7, 54} , { -6, 76} , { -11, 82} , { -2, 77} , { -2, 77} , { 25, 42} }
+ }
+ };
+
+
+
+
+
+ static const int INIT_FLD_LAST_I[1][8][15][2] =
+ {
+ //----- model 0 -----
+ {
+ { { 15, 6} , { 6, 19} , { 7, 16} , { 12, 14} , { 18, 13} , { 13, 11} , { 13, 15} , { 15, 16} , { 12, 23} , { 13, 23} , { 15, 20} , { 14, 26} , { 14, 44} , { 17, 40} , { 17, 47} },
+ { CTX_UNUSED , { 24, 17} , { 21, 21} , { 25, 22} , { 31, 27} , { 22, 29} , { 19, 35} , { 14, 50} , { 10, 57} , { 7, 63} , { -2, 77} , { -4, 82} , { -3, 94} , { 9, 69} , { -12, 109} },
+ { { 21, -10} , { 24, -11} , { 28, -8} , { 28, -1} , { 29, 3} , { 29, 9} , { 35, 20} , { 29, 36} , { 14, 67} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ // { { 12, 33} , { 5, 38} , { 9, 34} , { 18, 22} , { 19, 22} , { 23, 19} , { 26, 16} , { 14, 44} , { 40, 14} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { 36, -35} , { 36, -34} , { 32, -26} , { 37, -30} , { 44, -32} , { 34, -18} , { 34, -15} , { 40, -15} , { 33, -7} , { 35, -5} , { 33, 0} , { 38, 2} , { 33, 13} , { 23, 35} , { 13, 58} },
+ { { 29, -3} , { 26, 0} , { 22, 30} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , { 31, -7} , { 35, -15} , { 34, -3} , { 34, 3} , { 36, -1} , { 34, 5} , { 32, 11} , { 35, 5} , { 34, 12} , { 39, 11} , { 30, 29} , { 34, 26} , { 29, 39} , { 19, 66} }
+ }
+ };
+ static const int INIT_FLD_LAST_P[3][8][15][2] =
+ {
+ //----- model 0 -----
+ {
+ { { 14, 11} , { 11, 14} , { 9, 11} , { 18, 11} , { 21, 9} , { 23, -2} , { 32, -15} , { 32, -15} , { 34, -21} , { 39, -23} , { 42, -33} , { 41, -31} , { 46, -28} , { 38, -12} , { 21, 29} },
+ { CTX_UNUSED , { 45, -24} , { 53, -45} , { 48, -26} , { 65, -43} , { 43, -19} , { 39, -10} , { 30, 9} , { 18, 26} , { 20, 27} , { 0, 57} , { -14, 82} , { -5, 75} , { -19, 97} , { -35, 125} },
+ { { 21, -13} , { 33, -14} , { 39, -7} , { 46, -2} , { 51, 2} , { 60, 6} , { 61, 17} , { 55, 34} , { 42, 62} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ // { { 17, 27} , { 23, 13} , { 24, 16} , { 22, 25} , { 23, 27} , { 23, 32} , { 17, 43} , { 17, 49} , { 2, 70} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { 27, 0} , { 28, 0} , { 31, -4} , { 27, 6} , { 34, 8} , { 30, 10} , { 24, 22} , { 33, 19} , { 22, 32} , { 26, 31} , { 21, 41} , { 26, 44} , { 23, 47} , { 16, 65} , { 14, 71} },
+ { { 8, 60} , { 6, 63} , { 17, 65} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , { 21, 24} , { 23, 20} , { 26, 23} , { 27, 32} , { 28, 23} , { 28, 24} , { 23, 40} , { 24, 32} , { 28, 29} , { 23, 42} , { 19, 57} , { 22, 53} , { 22, 61} , { 11, 86} }
+ },
+ //----- model 1 -----
+ {
+ { { 19, -6} , { 18, -6} , { 14, 0} , { 26, -12} , { 31, -16} , { 33, -25} , { 33, -22} , { 37, -28} , { 39, -30} , { 42, -30} , { 47, -42} , { 45, -36} , { 49, -34} , { 41, -17} , { 32, 9} },
+ { CTX_UNUSED , { 69, -71} , { 63, -63} , { 66, -64} , { 77, -74} , { 54, -39} , { 52, -35} , { 41, -10} , { 36, 0} , { 40, -1} , { 30, 14} , { 28, 26} , { 23, 37} , { 12, 55} , { 11, 65} },
+ { { 17, -10} , { 32, -13} , { 42, -9} , { 49, -5} , { 53, 0} , { 64, 3} , { 68, 10} , { 66, 27} , { 47, 57} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ // { { 17, 27} , { 23, 13} , { 24, 16} , { 22, 25} , { 23, 27} , { 23, 32} , { 17, 43} , { 17, 49} , { 2, 70} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { 37, -33} , { 39, -36} , { 40, -37} , { 38, -30} , { 46, -33} , { 42, -30} , { 40, -24} , { 49, -29} , { 38, -12} , { 40, -10} , { 38, -3} , { 46, -5} , { 31, 20} , { 29, 30} , { 25, 44} },
+ { { 12, 48} , { 11, 49} , { 26, 45} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , { 22, 22} , { 23, 22} , { 27, 21} , { 33, 20} , { 26, 28} , { 30, 24} , { 27, 34} , { 18, 42} , { 25, 39} , { 18, 50} , { 12, 70} , { 21, 54} , { 14, 71} , { 11, 83} }
+ },
+ //----- model 2 -----
+ {
+ { { 17, -13} , { 16, -9} , { 17, -12} , { 27, -21} , { 37, -30} , { 41, -40} , { 42, -41} , { 48, -47} , { 39, -32} , { 46, -40} , { 52, -51} , { 46, -41} , { 52, -39} , { 43, -19} , { 32, 11} },
+ { CTX_UNUSED , { 61, -55} , { 56, -46} , { 62, -50} , { 81, -67} , { 45, -20} , { 35, -2} , { 28, 15} , { 34, 1} , { 39, 1} , { 30, 17} , { 20, 38} , { 18, 45} , { 15, 54} , { 0, 79} },
+ { { 9, -2} , { 30, -10} , { 31, -4} , { 33, -1} , { 33, 7} , { 31, 12} , { 37, 23} , { 31, 38} , { 20, 64} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ // { { 17, 27} , { 23, 13} , { 24, 16} , { 22, 25} , { 23, 27} , { 23, 32} , { 17, 43} , { 17, 49} , { 2, 70} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { { 36, -16} , { 37, -14} , { 37, -17} , { 32, 1} , { 34, 15} , { 29, 15} , { 24, 25} , { 34, 22} , { 31, 16} , { 35, 18} , { 31, 28} , { 33, 41} , { 36, 28} , { 27, 47} , { 21, 62} },
+ { { 18, 31} , { 19, 26} , { 36, 24} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED },
+ { CTX_UNUSED , { 24, 23} , { 27, 16} , { 24, 30} , { 31, 29} , { 22, 41} , { 22, 42} , { 16, 60} , { 15, 52} , { 14, 60} , { 3, 78} , { -16, 123} , { 21, 53} , { 22, 56} , { 25, 61} }
+ }
+ };
+
+
+ #endif
+
Index: llvm-test/MultiSource/Applications/JM/lencod/decoder.c
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/decoder.c:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/decoder.c Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,655 ----
+
+ /*!
+ *************************************************************************************
+ * \file decoder.c
+ *
+ * \brief
+ * Contains functions that implement the "decoders in the encoder" concept for the
+ * rate-distortion optimization with losses.
+ * \date
+ * October 22nd, 2001
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and
+ * affiliation details)
+ * - Dimitrios Kontopodis <dkonto at eikon.tum.de>
+ *************************************************************************************
+ */
+
+ #include <stdlib.h>
+ #include <memory.h>
+
+ #include "global.h"
+ #include "refbuf.h"
+ #include "image.h"
+
+ /*!
+ *************************************************************************************
+ * \brief
+ * decodes one 8x8 partition
+ *
+ * \note
+ * Gives the expected value in the decoder of one 8x8 block. This is done based on the
+ * stored reconstructed residue decs->resY[][], the reconstructed values imgY[][]
+ * and the motion vectors. The decoded 8x8 block is moved to decs->decY[][].
+ *************************************************************************************
+ */
+ void decode_one_b8block (int decoder, int mbmode, int b8block, int b8mode, int b8ref)
+ {
+ int i,j,block_y,block_x,bx,by;
+ int ref_inx = (IMG_NUMBER-1)%img->num_ref_frames;
+
+ int mv[2][BLOCK_MULTIPLE][BLOCK_MULTIPLE];
+ int resY_tmp[MB_BLOCK_SIZE][MB_BLOCK_SIZE];
+
+ int i0 = (b8block%2)<<3, i1 = i0+8, bx0 = i0>>2, bx1 = bx0+2;
+ int j0 = (b8block/2)<<3, j1 = j0+8, by0 = j0>>2, by1 = by0+2;
+
+ if (img->type==I_SLICE)
+ {
+ for(i=i0;i<i1;i++)
+ for(j=j0;j<j1;j++)
+ {
+ decs->decY[decoder][img->pix_y+j][img->pix_x+i]=enc_picture->imgY[img->pix_y+j][img->pix_x+i];
+ }
+ }
+ else
+ {
+ if (mbmode==0 && (img->type==P_SLICE || (img->type==B_SLICE && img->nal_reference_idc>0)))
+ {
+ for(i=i0;i<i1;i++)
+ for(j=j0;j<j1;j++)
+ {
+ resY_tmp[j][i]=0;
+ }
+ for (by=by0; by<by1; by++)
+ for (bx=bx0; bx<bx1; bx++)
+ {
+ mv[0][by][bx] = mv[1][by][bx] = 0;
+ }
+ }
+ else
+ {
+ if (b8mode>=1 && b8mode<=7)
+ {
+ for (by=by0; by<by1; by++)
+ for (bx=bx0; bx<bx1; bx++)
+ {
+ mv[0][by][bx] = img->all_mv[by][bx][LIST_0][b8ref][b8mode][0];
+ mv[1][by][bx] = img->all_mv[by][bx][LIST_0][b8ref][b8mode][1];
+ }
+ }
+ else
+ {
+ for (by=by0; by<by1; by++)
+ for (bx=bx0; bx<bx1; bx++)
+ {
+ mv[0][by][bx] = mv[1][by][bx] = 0;
+ }
+ }
+
+ for(i=i0;i<i1;i++)
+ for(j=j0;j<j1;j++)
+ {
+ resY_tmp[j][i]=decs->resY[j][i];
+ }
+ }
+
+ // Decode Luminance
+ if ((b8mode>=1 && b8mode<=7) || (mbmode==0 && (img->type==P_SLICE || (img->type==B_SLICE && img->nal_reference_idc>0))))
+ {
+ for (by=by0; by<by1; by++)
+ for (bx=bx0; bx<bx1; bx++)
+ {
+ block_x = img->block_x+bx;
+ block_y = img->block_y+by;
+ if (img->type == B_SLICE && enc_picture != enc_frame_picture)
+ ref_inx = (IMG_NUMBER-b8ref-2)%img->num_ref_frames;
+
+ Get_Reference_Block (decs->decref[decoder][ref_inx],
+ block_y, block_x,
+ mv[0][by][bx],
+ mv[1][by][bx],
+ decs->RefBlock);
+ for (j=0; j<4; j++)
+ for (i=0; i<4; i++)
+ {
+ /*
+ if (decs->RefBlock[j][i] != UMVPelY_14 (mref[ref_inx],
+ (block_y*4+j)*4+mv[1][by][bx],
+ (block_x*4+i)*4+mv[0][by][bx]))
+ ref_inx = (img->number-ref-1)%img->num_ref_frames;
+ */
+ decs->decY[decoder][block_y*4+j][block_x*4+i] = resY_tmp[by*4+j][bx*4+i] + decs->RefBlock[j][i];
+ }
+ }
+ }
+ else
+ {
+ // Intra Refresh - Assume no spatial prediction
+ for(i=i0;i<i1;i++)
+ for(j=j0;j<j1;j++)
+ {
+ decs->decY[decoder][img->pix_y+j][img->pix_x+i] = enc_picture->imgY[img->pix_y+j][img->pix_x+i];
+ }
+ }
+ }
+ }
+
+
+ /*!
+ *************************************************************************************
+ * \brief
+ * decodes one macroblock
+ *************************************************************************************
+ */
+ void decode_one_mb (int decoder, Macroblock* currMB)
+ {
+ /*
+ decode_one_b8block (decoder, currMB->mb_type, 0, currMB->b8mode[0], refFrArr[img->block_y+0][img->block_x+0]);
+ decode_one_b8block (decoder, currMB->mb_type, 1, currMB->b8mode[1], refFrArr[img->block_y+0][img->block_x+2]);
+ decode_one_b8block (decoder, currMB->mb_type, 2, currMB->b8mode[2], refFrArr[img->block_y+2][img->block_x+0]);
+ decode_one_b8block (decoder, currMB->mb_type, 3, currMB->b8mode[3], refFrArr[img->block_y+2][img->block_x+2]);
+ */
+ }
+
+ /*!
+ *************************************************************************************
+ * \brief
+ * Finds the reference MB given the decoded reference frame
+ * \note
+ * This is based on the function UnifiedOneForthPix, only it is modified to
+ * be used at the "many decoders in the encoder" RD optimization. In this case
+ * we dont want to keep full upsampled reference frames for all decoders, so
+ * we just upsample when it is necessary.
+ * \param imY
+ * The frame to be upsampled
+ * \param block_y
+ * The row of the block, whose prediction we want to find
+ * \param block_x
+ * The column of the block, whose prediction we want to track
+ * \param mvhor
+ * Motion vector, horizontal part
+ * \param mvver
+ * Motion vector, vertical part
+ * \param out
+ * Output: The prediction for the block (block_y, block_x)
+ *************************************************************************************
+ */
+ void Get_Reference_Block(imgpel **imY,
+ int block_y,
+ int block_x,
+ int mvhor,
+ int mvver,
+ imgpel **out)
+ {
+ int i,j,y,x;
+
+ y = block_y * BLOCK_SIZE * 4 + mvver;
+ x = block_x * BLOCK_SIZE * 4 + mvhor;
+
+ for (j=0; j<BLOCK_SIZE; j++)
+ for (i=0; i<BLOCK_SIZE; i++)
+ out[j][i] = Get_Reference_Pixel(imY, y+j*4, x+i*4);
+ }
+
+ /*!
+ *************************************************************************************
+ * \brief
+ * Finds a pixel (y,x) of the upsampled reference frame
+ * \note
+ * This is based on the function UnifiedOneForthPix, only it is modified to
+ * be used at the "many decoders in the encoder" RD optimization. In this case
+ * we dont want to keep full upsampled reference frames for all decoders, so
+ * we just upsample when it is necessary.
+ *************************************************************************************
+ */
+ byte Get_Reference_Pixel(imgpel **imY, int y_pos, int x_pos)
+ {
+
+ int dx, x;
+ int dy, y;
+ int maxold_x,maxold_y;
+
+ int result = 0, result1, result2;
+ int pres_x;
+ int pres_y;
+
+ int tmp_res[6];
+
+ static const int COEF[6] = {
+ 1, -5, 20, 20, -5, 1
+ };
+
+
+ dx = x_pos&3;
+ dy = y_pos&3;
+ x_pos = (x_pos-dx)/4;
+ y_pos = (y_pos-dy)/4;
+ maxold_x = img->width-1;
+ maxold_y = img->height-1;
+
+ if (dx == 0 && dy == 0) { /* fullpel position */
+ result = imY[max(0,min(maxold_y,y_pos))][max(0,min(maxold_x,x_pos))];
+ }
+ else { /* other positions */
+
+ if (dy == 0) {
+
+ pres_y = max(0,min(maxold_y,y_pos));
+ for(x=-2;x<4;x++) {
+ pres_x = max(0,min(maxold_x,x_pos+x));
+ result += imY[pres_y][pres_x]*COEF[x+2];
+ }
+
+ result = max(0, min(img->max_imgpel_value, (result+16)/32));
+
+ if (dx == 1) {
+ result = (result + imY[pres_y][max(0,min(maxold_x,x_pos))])/2;
+ }
+ else if (dx == 3) {
+ result = (result + imY[pres_y][max(0,min(maxold_x,x_pos+1))])/2;
+ }
+ }
+ else if (dx == 0) {
+
+ pres_x = max(0,min(maxold_x,x_pos));
+ for(y=-2;y<4;y++) {
+ pres_y = max(0,min(maxold_y,y_pos+y));
+ result += imY[pres_y][pres_x]*COEF[y+2];
+ }
+
+ result = max(0, min(img->max_imgpel_value, (result+16)/32));
+
+ if (dy == 1) {
+ result = (result + imY[max(0,min(maxold_y,y_pos))][pres_x])/2;
+ }
+ else if (dy == 3) {
+ result = (result + imY[max(0,min(maxold_y,y_pos+1))][pres_x])/2;
+ }
+ }
+ else if (dx == 2) {
+
+ for(y=-2;y<4;y++) {
+ result = 0;
+ pres_y = max(0,min(maxold_y,y_pos+y));
+ for(x=-2;x<4;x++) {
+ pres_x = max(0,min(maxold_x,x_pos+x));
+ result += imY[pres_y][pres_x]*COEF[x+2];
+ }
+ tmp_res[y+2] = result;
+ }
+
+ result = 0;
+ for(y=-2;y<4;y++) {
+ result += tmp_res[y+2]*COEF[y+2];
+ }
+
+ result = max(0, min(img->max_imgpel_value, (result+512)/1024));
+
+ if (dy == 1) {
+ result = (result + max(0, min(img->max_imgpel_value, (tmp_res[2]+16)/32)))/2;
+ }
+ else if (dy == 3) {
+ result = (result + max(0, min(img->max_imgpel_value, (tmp_res[3]+16)/32)))/2;
+ }
+ }
+ else if (dy == 2) {
+
+ for(x=-2;x<4;x++) {
+ result = 0;
+ pres_x = max(0,min(maxold_x,x_pos+x));
+ for(y=-2;y<4;y++) {
+ pres_y = max(0,min(maxold_y,y_pos+y));
+ result += imY[pres_y][pres_x]*COEF[y+2];
+ }
+ tmp_res[x+2] = result;
+ }
+
+ result = 0;
+ for(x=-2;x<4;x++) {
+ result += tmp_res[x+2]*COEF[x+2];
+ }
+
+ result = max(0, min(img->max_imgpel_value, (result+512)/1024));
+
+ if (dx == 1) {
+ result = (result + max(0, min(img->max_imgpel_value, (tmp_res[2]+16)/32)))/2;
+ }
+ else {
+ result = (result + max(0, min(img->max_imgpel_value, (tmp_res[3]+16)/32)))/2;
+ }
+ }
+ else {
+
+ result = 0;
+ pres_y = dy == 1 ? y_pos : y_pos+1;
+ pres_y = max(0,min(maxold_y,pres_y));
+
+ for(x=-2;x<4;x++) {
+ pres_x = max(0,min(maxold_x,x_pos+x));
+ result += imY[pres_y][pres_x]*COEF[x+2];
+ }
+
+ result1 = max(0, min(img->max_imgpel_value, (result+16)/32));
+
+ result = 0;
+ pres_x = dx == 1 ? x_pos : x_pos+1;
+ pres_x = max(0,min(maxold_x,pres_x));
+
+ for(y=-2;y<4;y++) {
+ pres_y = max(0,min(maxold_y,y_pos+y));
+ result += imY[pres_y][pres_x]*COEF[y+2];
+ }
+
+ result2 = max(0, min(img->max_imgpel_value, (result+16)/32));
+ result = (result1+result2)/2;
+ }
+ }
+
+ return result;
+ }
+
+ /*!
+ *************************************************************************************
+ * \brief
+ * Performs the simulation of the packet losses, calls the error concealment funcs
+ * and copies the decoded images to the reference frame buffers of the decoders
+ *
+ *************************************************************************************
+ */
+ void UpdateDecoders()
+ {
+ int k;
+ for (k=0; k<input->NoOfDecoders; k++)
+ {
+ Build_Status_Map(decs->status_map); // simulates the packet losses
+ Error_Concealment(decs->decY_best[k], decs->status_map, decs->decref[k]); // for the moment error concealment is just a "copy"
+ // Move decoded frames to reference buffers: (at the decoders this is done
+ // without interpolation (upsampling) - upsampling is done while decoding
+ DecOneForthPix(decs->decY_best[k], decs->decref[k]);
+ }
+ }
+ /*!
+ *************************************************************************************
+ * \brief
+ * Copies one (reconstructed) image to the respective reference frame buffer
+ *
+ * \note
+ * This is used at the "many decoders in the encoder"
+ * \param dY
+ * The reconstructed image
+ * \param dref
+ * The reference buffer
+ *************************************************************************************
+ */
+ void DecOneForthPix(imgpel **dY, imgpel ***dref)
+ {
+ int j, ref=IMG_NUMBER%img->buf_cycle;
+
+ for (j=0; j<img->height; j++)
+ memcpy(dref[ref][j], dY[j], img->width*sizeof(imgpel));
+ }
+
+ /*!
+ *************************************************************************************
+ * \brief
+ * Gives the prediction residue for a 8x8 block
+ *************************************************************************************
+ */
+ void compute_residue_b8block (int b8block, int i16mode) // if not INTRA16x16 it has to be -1
+ {
+ int i,j;
+ int i0 = (b8block%2)<<3, i1 = i0+8;
+ int j0 = (b8block/2)<<3, j1 = j0+8;
+
+ if (i16mode>=0)
+ {
+ for (i=i0; i<i1; i++)
+ for (j=j0; j<j1; j++)
+ {
+ decs->resY[j][i] = enc_picture->imgY[img->pix_y+j][img->pix_x+i] - img->mprr_2[i16mode][j][i];
+ }
+ }
+ else
+ {
+ for (i=i0; i<i1; i++)
+ for (j=j0; j<j1; j++)
+ {
+ decs->resY[j][i] = enc_picture->imgY[img->pix_y+j][img->pix_x+i] - img->mpr[j][i];
+ }
+ }
+ }
+
+ /*!
+ *************************************************************************************
+ * \brief
+ * Gives the prediction residue for a macroblock
+ *************************************************************************************
+ */
+ void compute_residue_mb (int i16mode)
+ {
+ compute_residue_b8block (0, i16mode);
+ compute_residue_b8block (1, i16mode);
+ compute_residue_b8block (2, i16mode);
+ compute_residue_b8block (3, i16mode);
+ }
+
+
+ /*!
+ *************************************************************************************
+ * \brief
+ * Builds a random status map showing whether each MB is received or lost, based
+ * on the packet loss rate and the slice structure.
+ *
+ * \param s_map
+ * The status map to be filled
+ *************************************************************************************
+ */
+ void Build_Status_Map(byte **s_map)
+ {
+ int i,j,slice=-1,mb=0,jj,ii,packet_lost=0;
+
+ jj = img->height/MB_BLOCK_SIZE;
+ ii = img->width/MB_BLOCK_SIZE;
+
+ for (j=0 ; j<jj; j++)
+ for (i=0 ; i<ii; i++)
+ {
+ if (!input->slice_mode || img->mb_data[mb].slice_nr != slice) /* new slice */
+ {
+ packet_lost=0;
+ if ((double)rand()/(double)RAND_MAX*100 < input->LossRateC) packet_lost += 3;
+ if ((double)rand()/(double)RAND_MAX*100 < input->LossRateB) packet_lost += 2;
+ if ((double)rand()/(double)RAND_MAX*100 < input->LossRateA) packet_lost = 1;
+ slice++;
+ }
+ if (!packet_lost)
+ {
+ s_map[j][i]=0; //! Packet OK
+ }
+ else
+ {
+ s_map[j][i]=packet_lost;
+ if(input->partition_mode == 0) s_map[j][i]=1;
+ }
+ mb++;
+ }
+ }
+
+ /*!
+ *************************************************************************************
+ * \brief
+ * Performs some sort of error concealment for the areas that are lost according
+ * to the status_map
+ *
+ * \param inY
+ * Error concealment is performed on this frame imY[][]
+ * \param s_map
+ * The status map shows which areas are lost.
+ * \param refY
+ * The set of reference frames - may be used for the error concealment.
+ *************************************************************************************
+ */
+ void Error_Concealment(imgpel **inY, byte **s_map, imgpel ***refY)
+ {
+ int mb_y, mb_x, mb_h, mb_w;
+ mb_h = img->height/MB_BLOCK_SIZE;
+ mb_w = img->width/MB_BLOCK_SIZE;
+
+ for (mb_y=0; mb_y < mb_h; mb_y++)
+ for (mb_x=0; mb_x < mb_w; mb_x++)
+ {
+ if (s_map[mb_y][mb_x]) Conceal_Error(inY, mb_y, mb_x, refY, s_map);
+ }
+ }
+
+ /*!
+ *************************************************************************************
+ * \brief
+ * Copies a certain MB (mb_y,mb_x) of the frame inY[][] from the previous frame.
+ * For the time there is no better EC...
+ *************************************************************************************
+ */
+ void Conceal_Error(imgpel **inY, int mb_y, int mb_x, imgpel ***refY, byte **s_map)
+ {
+ int i,j,block_x, block_y;
+ int ref_inx = (IMG_NUMBER-1)%img->num_ref_frames;
+ int pos_y = mb_y*MB_BLOCK_SIZE, pos_x = mb_x*MB_BLOCK_SIZE;
+ int mv[2][BLOCK_MULTIPLE][BLOCK_MULTIPLE];
+ int resY[MB_BLOCK_SIZE][MB_BLOCK_SIZE];
+ int copy = (decs->dec_mb_mode[mb_x][mb_y]==0 && (img->type==P_SLICE || (img->type==B_SLICE && img->nal_reference_idc>0)));
+ int inter = (((decs->dec_mb_mode[mb_x][mb_y]>=1 && decs->dec_mb_mode[mb_x][mb_y]<=3) || decs->dec_mb_mode[mb_x][mb_y]==P8x8) && (img->type==P_SLICE || (img->type==B_SLICE && img->nal_reference_idc>0)));
+ short ***tmp_mv = enc_picture->mv[LIST_0];
+
+ switch(s_map[mb_y][mb_x])
+ {
+ case 1: //! whole slice lost (at least partition A lost)
+ if (img->type!=I_SLICE)
+ {
+ for (j=0;j<MB_BLOCK_SIZE;j++)
+ for (i=0;i<MB_BLOCK_SIZE;i++)
+ inY[pos_y+j][pos_x+i] = refY[ref_inx][pos_y+j][pos_x+i];
+ }
+ else
+ {
+ for (j=0;j<MB_BLOCK_SIZE;j++)
+ for (i=0;i<MB_BLOCK_SIZE;i++)
+ inY[pos_y+j][pos_x+i] = 127;
+ }
+ break;
+ case 5: //! partition B and partition C lost
+
+ //! Copy motion vectors
+ for (block_y=0; block_y<BLOCK_MULTIPLE; block_y++)
+ for (block_x=0; block_x<BLOCK_MULTIPLE; block_x++)
+ for (i=0;i<2;i++)
+ mv[i][block_y][block_x]=tmp_mv[mb_y*BLOCK_SIZE+block_y][mb_x*BLOCK_SIZE+block_x+4][i];
+
+ //! Residuum ist set to zero
+ for(i=0;i<MB_BLOCK_SIZE;i++)
+ for(j=0;j<MB_BLOCK_SIZE;j++)
+ resY[j][i]=0;
+
+ //! not first frame
+ if (img->type!=I_SLICE)
+ {
+ //! if copy mb
+ if (copy)
+ {
+ for (j=0;j<MB_BLOCK_SIZE;j++)
+ for (i=0;i<MB_BLOCK_SIZE;i++)
+ inY[pos_y+j][pos_x+i] = refY[ref_inx][pos_y+j][pos_x+i];
+ }
+ //! if inter mb
+ else if (inter)
+ {
+ for (block_y = mb_y*BLOCK_SIZE ; block_y < (mb_y*BLOCK_SIZE + BLOCK_MULTIPLE) ; block_y++)
+ for (block_x = mb_x*BLOCK_SIZE ; block_x < (mb_x*BLOCK_SIZE + BLOCK_MULTIPLE) ; block_x++)
+ {
+ Get_Reference_Block(refY[ref_inx],
+ block_y, block_x,
+ mv[0][block_y - mb_y*BLOCK_SIZE][block_x - mb_x*BLOCK_SIZE],
+ mv[1][block_y - mb_y*BLOCK_SIZE][block_x - mb_x*BLOCK_SIZE],
+ decs->RefBlock);
+ for (j=0;j<BLOCK_SIZE;j++)
+ for (i=0;i<BLOCK_SIZE;i++)
+ {
+ inY[block_y*BLOCK_SIZE + j][block_x*BLOCK_SIZE + i] = decs->RefBlock[j][i];
+ }
+ }
+ }
+ else //intra; up to now only copy mb, may integrate nokia EC
+ {
+ for (j=0;j<MB_BLOCK_SIZE;j++)
+ for (i=0;i<MB_BLOCK_SIZE;i++)
+ inY[pos_y+j][pos_x+i] = refY[ref_inx][pos_y+j][pos_x+i];
+ }
+ }
+ else //! first frame; up to now set value to grey, may integrate nokia EC
+ {
+ for (j=0;j<MB_BLOCK_SIZE;j++)
+ for (i=0;i<MB_BLOCK_SIZE;i++)
+ inY[pos_y+j][pos_x+i] = 127;
+ }
+ break;
+ case 3: //! Partition C lost
+ if(img->type!=I_SLICE)
+ {
+ //! Copy motion vectors
+ for (block_y=0; block_y<BLOCK_MULTIPLE; block_y++)
+ for (block_x=0; block_x<BLOCK_MULTIPLE; block_x++)
+ for (i=0;i<2;i++)
+ mv[i][block_y][block_x]=tmp_mv[mb_y*BLOCK_SIZE+block_y][mb_x*BLOCK_SIZE+block_x+4][i];
+
+ //! Residuum ist set to zero
+ for(i=0;i<MB_BLOCK_SIZE;i++)
+ for(j=0;j<MB_BLOCK_SIZE;j++)
+ resY[j][i]=0;
+
+ //! if copy mb
+ if (copy)
+ {
+ for (j=0;j<MB_BLOCK_SIZE;j++)
+ for (i=0;i<MB_BLOCK_SIZE;i++)
+ inY[pos_y+j][pos_x+i] = refY[ref_inx][pos_y+j][pos_x+i];
+ }
+ //! if inter mb
+ else if (inter)
+ {
+ for (block_y = mb_y*BLOCK_SIZE ; block_y < (mb_y*BLOCK_SIZE + BLOCK_MULTIPLE) ; block_y++)
+ for (block_x = mb_x*BLOCK_SIZE ; block_x < (mb_x*BLOCK_SIZE + BLOCK_MULTIPLE) ; block_x++)
+ {
+ Get_Reference_Block(refY[ref_inx],
+ block_y, block_x,
+ mv[0][block_y - mb_y*BLOCK_SIZE][block_x - mb_x*BLOCK_SIZE],
+ mv[1][block_y - mb_y*BLOCK_SIZE][block_x - mb_x*BLOCK_SIZE],
+ decs->RefBlock);
+ for (j=0;j<BLOCK_SIZE;j++)
+ for (i=0;i<BLOCK_SIZE;i++)
+ {
+ inY[block_y*BLOCK_SIZE + j][block_x*BLOCK_SIZE + i] = decs->RefBlock[j][i];
+ }
+ }
+ }
+ }
+ break;
+ case 2: //! Partition B lost
+ if(img->type!=I_SLICE)
+ {
+ if(!inter)
+ {
+ for (j=0;j<MB_BLOCK_SIZE;j++)
+ for (i=0;i<MB_BLOCK_SIZE;i++)
+ inY[pos_y+j][pos_x+i] = refY[ref_inx][pos_y+j][pos_x+i];
+ }
+ }
+ else //! first frame; up to now set value to grey, may integrate nokia EC
+ {
+ for (j=0;j<MB_BLOCK_SIZE;j++)
+ for (i=0;i<MB_BLOCK_SIZE;i++)
+ inY[pos_y+j][pos_x+i] = 127;
+ }
+ break;
+ } //! End Switch
+ }
Index: llvm-test/MultiSource/Applications/JM/lencod/defines.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/defines.h:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/defines.h Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,207 ----
+
+ /*!
+ **************************************************************************
+ * \file defines.h
+ *
+ * \brief
+ * Header file containing some useful global definitions
+ *
+ * \author
+ * Detlev Marpe
+ * Copyright (C) 2000 HEINRICH HERTZ INSTITUTE All Rights Reserved.
+ *
+ * \date
+ * 21. March 2001
+ **************************************************************************
+ */
+
+
+ #ifndef _DEFINES_H_
+ #define _DEFINES_H_
+
+ #if defined _DEBUG
+ #define TRACE 0 //!< 0:Trace off 1:Trace on 2:detailed CABAC context information
+ #else
+ #define TRACE 0 //!< 0:Trace off 1:Trace on 2:detailed CABAC context information
+ #endif
+
+ typedef unsigned char byte; //!< byte type definition
+
+ //FREXT Profile IDC definitions
+ #define FREXT_HP 100 //!< YUV 4:2:0/8 "High"
+ #define FREXT_Hi10P 110 //!< YUV 4:2:0/10 "High 10"
+ #define FREXT_Hi422 122 //!< YUV 4:2:2/10 "High 4:2:2"
+ #define FREXT_Hi444 144 //!< YUV 4:4:4/12 "High 4:4:4"
+
+ #define YUV400 0
+ #define YUV420 1
+ #define YUV422 2
+ #define YUV444 3
+
+ enum {
+ LIST_0 = 0,
+ LIST_1 = 1,
+ BI_PRED = 2,
+ BI_PRED_L0 = 3,
+ BI_PRED_L1 = 4
+ };
+
+ #define ZEROSNR 1
+ // CAVLC
+ #define LUMA 0
+ #define LUMA_INTRA16x16DC 1
+ #define LUMA_INTRA16x16AC 2
+
+ #define LEVEL_NUM 6
+ #define TOTRUN_NUM 15
+ #define RUNBEFORE_NUM 7
+
+ #define CAVLC_LEVEL_LIMIT 2063
+
+
+ //--- block types for CABAC
+ #define LUMA_16DC 0
+ #define LUMA_16AC 1
+ #define LUMA_8x8 2
+ #define LUMA_8x4 3
+ #define LUMA_4x8 4
+ #define LUMA_4x4 5
+ #define CHROMA_DC 6
+ #define CHROMA_AC 7
+ #define CHROMA_DC_2x4 8
+ #define CHROMA_DC_4x4 9
+ #define NUM_BLOCK_TYPES 10
+
+
+ #define _FAST_FULL_ME_
+
+ #define _FULL_SEARCH_RANGE_
+ #define _ADAPT_LAST_GROUP_
+ #define _CHANGE_QP_
+ #define _LEAKYBUCKET_
+
+ // ---------------------------------------------------------------------------------
+ // FLAGS and DEFINES for new chroma intra prediction, Dzung Hoang
+ // Threshold values to zero out quantized transform coefficients.
+ // Recommend that _CHROMA_COEFF_COST_ be low to improve chroma quality
+ #define _LUMA_COEFF_COST_ 4 //!< threshold for luma coeffs
+ #define _CHROMA_COEFF_COST_ 4 //!< threshold for chroma coeffs, used to be 7
+ #define _LUMA_MB_COEFF_COST_ 5 //!< threshold for luma coeffs of inter Macroblocks
+ #define _LUMA_8x8_COEFF_COST_ 5 //!< threshold for luma coeffs of 8x8 Inter Partition
+
+ #define IMG_PAD_SIZE 4 //!< Number of pixels padded around the reference frame (>=4)
+ #define IMG_PAD_SIZE_TIMES4 16 //!< Number of pixels padded around the reference frame in subpel units(>=16)
+
+ #define absm(A) ((A)<(0) ? (-(A)):(A)) //!< abs macro, faster than procedure
+ #define MAX_VALUE 999999 //!< used for start value for some variables
+
+ #define INVALIDINDEX (-135792468)
+
+ #define Clip1(a) ((a)>img->max_imgpel_value?img->max_imgpel_value:((a)<0?0:(a)))
+ #define Clip1_Chr(a) ((a)>img->max_imgpel_value_uv?img->max_imgpel_value_uv:((a)<0?0:(a)))
+ #define Clip3(min,max,val) (((val)<(min))?(min):(((val)>(max))?(max):(val)))
+
+ #define P8x8 8
+ #define I4MB 9
+ #define I16MB 10
+ #define IBLOCK 11
+ #define SI4MB 12
+ #define I8MB 13
+ #define IPCM 14
+ #define MAXMODE 15
+
+
+ #define LAMBDA_ACCURACY_BITS 16
+ #define LAMBDA_FACTOR(lambda) ((int)((double)(1<<LAMBDA_ACCURACY_BITS)*lambda+0.5))
+ #define WEIGHTED_COST(factor,bits) (((factor)*(bits))>>LAMBDA_ACCURACY_BITS)
+ #define MV_COST(f,s,cx,cy,px,py) (WEIGHTED_COST(f,mvbits[((cx)<<(s))-px]+mvbits[((cy)<<(s))-py]))
+ #define REF_COST(f,ref,list_offset) (WEIGHTED_COST(f,((listXsize[list_offset]<=1)? 0:refbits[(ref)])))
+
+ #define IS_INTRA(MB) ((MB)->mb_type==I4MB || (MB)->mb_type==I16MB || (MB)->mb_type==I8MB || (MB)->mb_type==IPCM)
+ #define IS_NEWINTRA(MB) ((MB)->mb_type==I16MB)
+ #define IS_OLDINTRA(MB) ((MB)->mb_type==I4MB)
+ #define IS_IPCM(MB) ((MB)->mb_type==IPCM)
+
+ #define IS_INTER(MB) ((MB)->mb_type!=I4MB && (MB)->mb_type!=I16MB && (MB)->mb_type!=I8MB)
+ #define IS_INTERMV(MB) ((MB)->mb_type!=I4MB && (MB)->mb_type!=I16MB && (MB)->mb_type!=I8MB && (MB)->mb_type!=0)
+ #define IS_DIRECT(MB) ((MB)->mb_type==0 && (img->type==B_SLICE))
+ #define IS_COPY(MB) ((MB)->mb_type==0 && (img->type==P_SLICE||img ->type==SP_SLICE));
+ #define IS_P8x8(MB) ((MB)->mb_type==P8x8)
+
+ // Quantization parameter range
+
+ #define MIN_QP 0
+ #define MAX_QP 51
+ #define SHIFT_QP 12
+
+ // Direct Mode types
+ #define DIR_TEMPORAL 0 //!< Temporal Direct Mode
+ #define DIR_SPATIAL 1 //!< Spatial Direct Mode
+
+ #define MAX_REFERENCE_PICTURES 32
+
+ #define BLOCK_SHIFT 2
+ #define BLOCK_SIZE 4
+ #define MB_BLOCK_SIZE 16
+
+ // number of intra prediction modes
+ #define NO_INTRA_PMODE 9
+
+ // 4x4 intra prediction modes
+ #define VERT_PRED 0
+ #define HOR_PRED 1
+ #define DC_PRED 2
+ #define DIAG_DOWN_LEFT_PRED 3
+ #define DIAG_DOWN_RIGHT_PRED 4
+ #define VERT_RIGHT_PRED 5
+ #define HOR_DOWN_PRED 6
+ #define VERT_LEFT_PRED 7
+ #define HOR_UP_PRED 8
+
+ // 16x16 intra prediction modes
+ #define VERT_PRED_16 0
+ #define HOR_PRED_16 1
+ #define DC_PRED_16 2
+ #define PLANE_16 3
+
+ // 8x8 chroma intra prediction modes
+ #define DC_PRED_8 0
+ #define HOR_PRED_8 1
+ #define VERT_PRED_8 2
+ #define PLANE_8 3
+
+ #define INIT_FRAME_RATE 30
+ #define EOS 1 //!< End Of Sequence
+
+
+ #define MVPRED_MEDIAN 0
+ #define MVPRED_L 1
+ #define MVPRED_U 2
+ #define MVPRED_UR 3
+
+ #define BLOCK_MULTIPLE (MB_BLOCK_SIZE/BLOCK_SIZE)
+ #define MB_BLOCK_PARTITIONS (BLOCK_MULTIPLE * BLOCK_MULTIPLE)
+ #define MB_PIXELS (MB_BLOCK_SIZE * MB_BLOCK_SIZE)
+ #define BLOCK_CONTEXT (2 * 2 * MB_BLOCK_PARTITIONS)
+
+ #define MAX_SYMBOLS_PER_MB 1200 //!< Maximum number of different syntax elements for one MB
+ // CAVLC needs more symbols per MB
+
+
+ #define MAX_PART_NR 3 /*!< Maximum number of different data partitions.
+ Some reasonable number which should reflect
+ what is currently defined in the SE2Partition map (elements.h) */
+
+ //Start code and Emulation Prevention need this to be defined in identical manner at encoder and decoder
+ #define ZEROBYTES_SHORTSTARTCODE 2 //indicates the number of zero bytes in the short start-code prefix
+
+ #define Q_BITS 15
+ #define DQ_BITS 6
+ #define DQ_ROUND (1<<(DQ_BITS-1))
+
+ #define Q_BITS_8 16
+ #define DQ_BITS_8 6
+ #define DQ_ROUND_8 (1<<(DQ_BITS_8-1))
+
+ #endif
+
Index: llvm-test/MultiSource/Applications/JM/lencod/elements.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/elements.h:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/elements.h Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,109 ----
+
+ /*!
+ **************************************************************************
+ * \file elements.h
+ * \brief Header file for elements in H.264 streams
+ * \date 6.10.2000,
+ * \version
+ * 1.1
+ *
+ * \note
+ * Version 1.0 included three partition modes, no DP, 2 partitionsper slice
+ * and 4 partitions per slice. As per document VCEG-N72 this is changed
+ * in version 1.1 to only two partition modes, one without DP and one with
+ * 3 partition per slice
+ *
+ * \author Sebastian Purreiter <sebastian.purreiter at mch.siemens.de>
+ * \author Stephan Wenger <stewe at cs.tu-berlin.de>
+ *
+ **************************************************************************
+ */
+
+ #ifndef _ELEMENTS_H_
+ #define _ELEMENTS_H_
+
+ /*!
+ * definition of H.264 syntax elements
+ * order of elements follow dependencies for picture reconstruction
+ */
+ /*!
+ * \brief Assignment of old TYPE or partition elements to new
+ * elements
+ *
+ * old element | new elements
+ * ----------------+-------------------------------------------------------------------
+ * TYPE_HEADER | SE_HEADER, SE_PTYPE
+ * TYPE_MBHEADER | SE_MBTYPE, SE_REFFRAME, SE_INTRAPREDMODE
+ * TYPE_MVD | SE_MVD
+ * TYPE_CBP | SE_CBP_INTRA, SE_CBP_INTER
+ * TYPE_COEFF_Y | SE_LUM_DC_INTRA, SE_LUM_AC_INTRA, SE_LUM_DC_INTER, SE_LUM_AC_INTER
+ * TYPE_2x2DC | SE_CHR_DC_INTRA, SE_CHR_DC_INTER
+ * TYPE_COEFF_C | SE_CHR_AC_INTRA, SE_CHR_AC_INTER
+ * TYPE_EOS | SE_EOS
+ */
+
+
+
+
+ #define MAXPARTITIONMODES 2 //!< maximum possible partition modes as defined in assignSE2partition[][]
+
+ /*!
+ * \brief lookup-table to assign different elements to partition
+ *
+ * \note here we defined up to 6 different partitions similar to
+ * document Q15-k-18 described in the PROGFRAMEMODE.
+ * The Sliceheader contains the PSYNC information. \par
+ *
+ * Elements inside a partition are not ordered. They are
+ * ordered by occurence in the stream.
+ * Assumption: Only partitionlosses are considered. \par
+ *
+ * The texture elements luminance and chrominance are
+ * not ordered in the progressive form
+ * This may be changed in image.c \par
+ *
+ * -IMPORTANT:
+ * Picture- or Sliceheaders must be assigned to partition 0. \par
+ * Furthermore partitions must follow syntax dependencies as
+ * outlined in document Q15-J-23.
+ */
+
+
+ // A note on this table:
+ //
+ // While the assignment of values in enum data types is specified in C, it is not
+ // very ood style to have an "elementnumber", not even as a comment.
+ //
+ // Hence a copy of the relevant structure from global.h here
+ /*
+ typedef enum {
+ 0 SE_HEADER,
+ 1 SE_PTYPE,
+ 2 SE_MBTYPE,
+ 3 SE_REFFRAME,
+ 4 SE_INTRAPREDMODE,
+ 5 SE_MVD,
+ 6 SE_CBP_INTRA,
+ 7 SE_LUM_DC_INTRA,
+ 8 SE_CHR_DC_INTRA,
+ 9 SE_LUM_AC_INTRA,
+ 10 SE_CHR_AC_INTRA,
+ 11 SE_CBP_INTER,
+ 12 SE_LUM_DC_INTER,
+ 13 SE_CHR_DC_INTER,
+ 14 SE_LUM_AC_INTER,
+ 15 SE_CHR_AC_INTER,
+ 16 SE_DELTA_QUANT_INTER,
+ 17 SE_DELTA_QUANT_INTRA,
+ 18 SE_BFRAME,
+ 19 SE_EOS,
+ 20 SE_MAX_ELEMENTS */ // number of maximum syntax elements
+ //} SE_type;
+
+
+ extern int * assignSE2partition[2];
+ extern int assignSE2partition_NoDP[SE_MAX_ELEMENTS];
+ extern int assignSE2partition_DP[SE_MAX_ELEMENTS];
+
+ #endif
+
Index: llvm-test/MultiSource/Applications/JM/lencod/epzs.c
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/epzs.c:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/epzs.c Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,2321 ----
+
+ /*!
+ *************************************************************************************
+ * \file epzs.c
+ *
+ * \brief
+ * Motion Estimation using EPZS
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Alexis Michael Tourapis <alexismt at ieee.org>
+ *
+ *************************************************************************************
+ */
+
+ #include "contributors.h"
+
+ #include <stdlib.h>
+ #include <limits.h>
+ #include <string.h>
+
+ #include "global.h"
+ #include "image.h"
+ #include "memalloc.h"
+ #include "mb_access.h"
+
+ #include "epzs.h"
+
+ #define EPZSREF 1
+
+ extern int *mvbits;
+ extern unsigned int *byte_abs;
+
+ // Define Global Parameters
+ static const short blk_parent[8] = {1, 1, 1, 1, 2, 4, 4, 5}; //!< {skip, 16x16, 16x8, 8x16, 8x8, 8x4, 4x8, 4x4}
+ static const short blk_child[8] = {1, 2, 4, 4, 5, 7, 7, 7}; //!< {skip, 16x16, 16x8, 8x16, 8x8, 8x4, 4x8, 4x4}
+ static const int minthres_base[8] = {0, 64, 32, 32, 16, 8, 8, 4};
+ static const int medthres_base[8] = {0, 256, 128, 128, 64, 32, 32, 16};
+ static const int maxthres_base[8] = {0, 768, 384, 384, 192, 96, 96, 48};
+ static short img_width;
+ static short img_height;
+ static short weight1, weight2, offsetBi;
+
+ //! Define EPZS Refinement patterns
+ static int pattern_data[4][12][4] =
+ {
+ { // Small Diamond pattern
+ { 0, 1, 3, 3 }, { 1, 0, 0, 3 }, { 0, -1, 1, 3 }, { -1, 0, 2, 3 }
+ },
+ { // Square pattern
+ { 0, 1, 7, 3 }, { 1, 1, 7, 5 }, { 1, 0, 1, 3 }, { 1, -1, 1, 5 },
+ { 0, -1, 3, 3 }, { -1, -1, 3, 5 }, { -1, 0, 5, 3 }, { -1, 1, 5, 5 }
+ },
+ { // Enhanced Diamond pattern
+ { -1, 1, 10, 5 }, { 0, 2, 10, 8 }, { 0, 1, 10, 7 }, { 1, 1, 1, 5 },
+ { 2, 0, 1, 8 }, { 1, 0, 1, 7 }, { 1, -1, 4, 5 }, { 0, -2, 4, 8 },
+ { 0, -1, 4, 7 }, { -1, -1, 7, 5 }, { -2, 0, 7, 8 }, { -1, 0, 7, 7 }
+ },
+ { // Large Diamond pattern
+ { 0, 2, 6, 5 }, { 1, 1, 0, 3 }, { 2, 0, 0, 5 }, { 1, -1, 2, 3 },
+ { 0, -2, 2, 5 }, { -1, -1, 4, 3 }, { -2, 0, 4, 5 }, { -1, 1, 6, 3 }
+ }
+ };
+
+ // Other definitions
+ const char c_EPZSPattern[4][20] = { "Diamond", "Square", "Extended Diamond", "Large Diamond"};
+ const char c_EPZSDualPattern[5][20] = { "Disabled","Diamond", "Square", "Extended Diamond", "Large Diamond"};
+ const char c_EPZSFixed[3][20] = { "Disabled","All P", "All P + B"};
+ const char c_EPZSOther[2][20] = { "Disabled","Enabled"};
+
+ int medthres[8];
+ int maxthres[8];
+ int minthres[8];
+ int mv_scale[6][MAX_REFERENCE_PICTURES][MAX_REFERENCE_PICTURES];
+
+ static byte **EPZSMap; //!< Memory Map definition
+ int ***EPZSDistortion; //!< Array for storing SAD Values
+ #if EPZSREF
+ short ******EPZSMotion; //!< Array for storing Motion Vectors
+ #else
+ short *****EPZSMotion; //!< Array for storing Motion Vectors
+ #endif
+
+ //
+ EPZSStructure *searchPattern,*searchPatternD, *predictor;
+ EPZSStructure *window_predictor, *window_predictor_extended;
+ EPZSStructure *sdiamond,*square,*ediamond,*ldiamond;
+ EPZSColocParams *EPZSCo_located;
+
+ int (*computeBiPredSad)(pel_t **, int, int, int, int, int, int, int, int, int);
+
+ static pel_t *(*get_ref_line1)(int, pel_t *, int, int, int, int);
+ static pel_t *(*get_ref_line2)(int, pel_t *, int, int, int, int);
+ static pel_t *(*get_ref_line) (int, pel_t *, int, int, int, int);
+ static pel_t *ref_pic;
+ static pel_t *ref_pic1;
+ static pel_t *ref_pic2;
+ /*!
+ ************************************************************************
+ * \brief
+ * Allocate co-located memory
+ *
+ * \param size_x
+ * horizontal luma size
+ * \param size_y
+ * vertical luma size
+ * \param mb_adaptive_frame_field_flag
+ * flag that indicates macroblock adaptive frame/field coding
+ *
+ * \return
+ * the allocated EPZSColocParams structure
+ ************************************************************************
+ */
+ EPZSColocParams* allocEPZScolocated(int size_x, int size_y, int mb_adaptive_frame_field_flag)
+ {
+ EPZSColocParams *s;
+
+ s = calloc(1, sizeof(EPZSColocParams));
+ if (NULL == s)
+ no_mem_exit("alloc_EPZScolocated: s");
+
+ s->size_x = size_x;
+ s->size_y = size_y;
+ get_mem4Dshort (&(s->mv), 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE, 2);
+
+ if (mb_adaptive_frame_field_flag)
+ {
+ get_mem4Dshort (&(s->top_mv), 2, size_y / BLOCK_SIZE/2, size_x / BLOCK_SIZE, 2);
+ get_mem4Dshort (&(s->bottom_mv),2, size_y / BLOCK_SIZE/2, size_x / BLOCK_SIZE, 2);
+ }
+
+ s->mb_adaptive_frame_field_flag = mb_adaptive_frame_field_flag;
+
+ return s;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Free co-located memory.
+ *
+ * \param p
+ * structure to be freed
+ *
+ ************************************************************************
+ */
+ void freeEPZScolocated(EPZSColocParams* p)
+ {
+ if (p)
+ {
+ free_mem4Dshort (p->mv, 2, p->size_y / BLOCK_SIZE);
+
+ if (p->mb_adaptive_frame_field_flag)
+ {
+ free_mem4Dshort (p->top_mv, 2, p->size_y / BLOCK_SIZE / 2);
+ free_mem4Dshort (p->bottom_mv, 2, p->size_y / BLOCK_SIZE / 2);
+ }
+
+ free(p);
+
+ p=NULL;
+ }
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Allocate EPZS pattern memory
+ *
+ * \param searchpoints
+ * number of searchpoints to allocate
+ *
+ * \return
+ * the allocated EPZSStructure structure
+ ************************************************************************
+ */
+ EPZSStructure* allocEPZSpattern(int searchpoints)
+ {
+ EPZSStructure *s;
+
+ s = calloc(1, sizeof(EPZSStructure));
+ if (NULL == s)
+ no_mem_exit("alloc_EPZSpattern: s");
+
+ s->searchPoints = searchpoints;
+ s->point = (SPoint*) calloc(searchpoints, sizeof(SPoint));
+
+ return s;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Free EPZS pattern memory.
+ *
+ * \param p
+ * structure to be freed
+ *
+ ************************************************************************
+ */
+ void freeEPZSpattern(EPZSStructure* p)
+ {
+ if (p)
+ {
+ free ( (SPoint*) p->point);
+ free(p);
+ p=NULL;
+ }
+ }
+
+ void assignEPZSpattern(EPZSStructure *pattern,int type)
+ {
+ int i;
+
+ for (i = 0; i < pattern->searchPoints; i++)
+ {
+ pattern->point[i].x = pattern_data[type][i][0];
+ pattern->point[i].y = pattern_data[type][i][1];
+ pattern->point[i].start_nmbr = pattern_data[type][i][2];
+ pattern->point[i].next_points = pattern_data[type][i][3];
+ }
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * calculate RoundLog2(uiVal)
+ ************************************************************************
+ */
+ static int RoundLog2 (int iValue)
+ {
+ int iRet = 0;
+ int iValue_square = iValue * iValue;
+
+ while ((1 << (iRet + 1)) <= iValue_square)
+ iRet++;
+
+ iRet = (iRet + 1) >> 1;
+
+ return iRet;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * EPZS Search Window Predictor Initialization
+ ************************************************************************
+ */
+ void EPZSWindowPredictorInit (short search_range, EPZSStructure * predictor, short mode)
+ {
+ int pos;
+ short searchpos, fieldsearchpos;
+ short prednum = 0;
+ short i;
+ if (mode == 0)
+ {
+ for (pos = RoundLog2 (search_range) - 2; pos > -1; pos--)
+ {
+ searchpos = (search_range >> pos);
+
+ for (i=1; i>=-1; i-=2)
+ {
+ predictor->point[prednum ].x = i * searchpos;
+ predictor->point[prednum++].y = 0;
+ predictor->point[prednum ].x = i * searchpos;
+ predictor->point[prednum++].y = i * searchpos;
+ predictor->point[prednum ].x = 0;
+ predictor->point[prednum++].y = i * searchpos;
+ predictor->point[prednum ].x = -i * searchpos;
+ predictor->point[prednum++].y = i * searchpos;
+ }
+ }
+ }
+ else // if (mode == 0)
+ {
+ for (pos = RoundLog2 (search_range) - 2; pos > -1; pos--)
+ {
+ searchpos = (search_range >> pos);
+ fieldsearchpos = (3 * searchpos + 1) >> 1;
+
+ for (i=1; i>=-1; i-=2)
+ {
+ predictor->point[prednum ].x = i * searchpos;
+ predictor->point[prednum++].y = 0;
+ predictor->point[prednum ].x = i * searchpos;
+ predictor->point[prednum++].y = i * searchpos;
+ predictor->point[prednum ].x = 0;
+ predictor->point[prednum++].y = i * searchpos;
+ predictor->point[prednum ].x = -i * searchpos;
+ predictor->point[prednum++].y = i * searchpos;
+ }
+
+ for (i=1; i>=-1; i-=2)
+ {
+ predictor->point[prednum ].x = i * fieldsearchpos;
+ predictor->point[prednum++].y = -i * searchpos;
+ predictor->point[prednum ].x = i * fieldsearchpos;
+ predictor->point[prednum++].y = 0;
+ predictor->point[prednum ].x = i * fieldsearchpos;
+ predictor->point[prednum++].y = i * searchpos;
+ predictor->point[prednum ].x = i * searchpos;
+ predictor->point[prednum++].y = i * fieldsearchpos;
+ predictor->point[prednum ].x = 0;
+ predictor->point[prednum++].y = i * fieldsearchpos;
+ predictor->point[prednum ].x = -i * searchpos;
+ predictor->point[prednum++].y = i * fieldsearchpos;
+ }
+ }
+ }
+ predictor->searchPoints = prednum;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * EPZS Global Initialization
+ ************************************************************************
+ */
+ int
+ EPZSInit ()
+ {
+ int pel_error_me = 1 << (img->bitdepth_luma - 8);
+ int i, memory_size = 0;
+ int searcharray = input->BiPredMotionEstimation? 2 * max (input->search_range, input->BiPredMESearchRange) + 1 : 2 * input->search_range + 1;
+ int searchlevels = RoundLog2 (input->search_range) - 1;
+
+ //! In this implementation we keep threshold limits fixed.
+ //! However one could adapt these limits based on lagrangian
+ //! optimization considerations (i.e. qp), while also allow
+ //! adaptation of the limits themselves based on content or complexity.
+ for (i=0;i<8;i++)
+ {
+ medthres[i] = input->EPZSMedThresScale * medthres_base[i] * pel_error_me;
+ maxthres[i] = input->EPZSMaxThresScale * maxthres_base[i] * pel_error_me;
+ minthres[i] = input->EPZSMinThresScale * minthres_base[i] * pel_error_me;
+ }
+
+ //! Definition of pottential EPZS patterns.
+ //! It is possible to also define other patterns, or even use
+ //! resizing patterns (such as the PMVFAST scheme. These patterns
+ //! are only shown here as reference, while the same also holds
+ //! for this implementation (i.e. new conditions could be added
+ //! on adapting predictors, or thresholds etc. Note that search
+ //! could also be performed on subpel positions directly while
+ //! pattern needs not be restricted on integer positions only.
+
+ //! Allocate memory and assign search patterns
+ sdiamond = allocEPZSpattern(4);
+ assignEPZSpattern(sdiamond, SDIAMOND);
+ square = allocEPZSpattern(8);
+ assignEPZSpattern(square, SQUARE);
+ ediamond = allocEPZSpattern(12);
+ assignEPZSpattern(ediamond, EDIAMOND);
+ ldiamond = allocEPZSpattern(8);
+ assignEPZSpattern(ldiamond, LDIAMOND);
+
+ //! Allocate and assign window based predictors.
+ //! Other window types could also be used, while method could be
+ //! made a bit more adaptive (i.e. patterns could be assigned
+ //! based on neighborhood
+ window_predictor = allocEPZSpattern(searchlevels * 8);
+ window_predictor_extended = allocEPZSpattern(searchlevels * 20);
+ EPZSWindowPredictorInit ((short) input->search_range, window_predictor, 0);
+ EPZSWindowPredictorInit ((short) input->search_range, window_predictor_extended, 1);
+ //! Also assing search predictor memory
+ // maxwindow + spatial + blocktype + temporal + memspatial
+ predictor = allocEPZSpattern(searchlevels * 20 + 5 + 5 + 9 * (input->EPZSTemporal) + 3 * (input->EPZSSpatialMem));
+
+ //! Finally assign memory for all other elements
+ //! (distortion, EPZSMap, and temporal predictors)
+
+ memory_size += get_mem3Dint (&EPZSDistortion, 6, 7, img->width/BLOCK_SIZE);
+ memory_size += get_mem2D (&EPZSMap, searcharray, searcharray );
+ if (input->EPZSSpatialMem)
+ {
+ #if EPZSREF
+ memory_size += get_mem6Dshort (&EPZSMotion, 6, img->max_num_references, 7, 4, img->width/BLOCK_SIZE, 2);
+ #else
+ memory_size += get_mem5Dshort (&EPZSMotion, 6, 7, 4, img->width/BLOCK_SIZE, 2);
+ #endif
+ }
+
+ if (input->EPZSTemporal)
+ EPZSCo_located = allocEPZScolocated (img->width, img->height,
+ active_sps->mb_adaptive_frame_field_flag);
+
+ switch (input->EPZSPattern)
+ {
+ case 3:
+ searchPattern = ldiamond;
+ break;
+ case 2:
+ searchPattern = ediamond;
+ break;
+ case 1:
+ searchPattern = square;
+ break;
+ case 0:
+ default:
+ searchPattern = sdiamond;
+ break;
+ }
+
+ switch (input->EPZSDual)
+ {
+ case 4:
+ searchPatternD = ldiamond;
+ break;
+ case 3:
+ searchPatternD = ediamond;
+ break;
+ case 2:
+ searchPatternD = square;
+ break;
+ case 1:
+ default:
+ searchPatternD = sdiamond;
+ break;
+ }
+
+ return memory_size;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Delete EPZS Alocated memory
+ ************************************************************************
+ */
+ void EPZSDelete ()
+ {
+ if (input->EPZSTemporal)
+ freeEPZScolocated (EPZSCo_located);
+
+ free_mem2D (EPZSMap);
+ free_mem3Dint (EPZSDistortion, 6);
+ freeEPZSpattern(window_predictor_extended);
+ freeEPZSpattern(window_predictor);
+ freeEPZSpattern(predictor);
+ freeEPZSpattern(ldiamond);
+ freeEPZSpattern(ediamond);
+ freeEPZSpattern(sdiamond);
+ freeEPZSpattern(square);
+ if (input->EPZSSpatialMem)
+ {
+ #if EPZSREF
+ free_mem6Dshort (EPZSMotion, 6, img->max_num_references, 7, 4);
+ #else
+ free_mem5Dshort (EPZSMotion, 6, 7, 4);
+ #endif
+ }
+
+ }
+
+ //! For ME purposes restricting the co-located partition is not necessary.
+ /*!
+ ************************************************************************
+ * \brief
+ * EPZS Slice Level Initialization
+ ************************************************************************
+ */
+ void
+ EPZSSliceInit (EPZSColocParams * p,
+ StorablePicture ** listX[6])
+ {
+ StorablePicture *fs, *fs_top, *fs_bottom;
+ StorablePicture *fs1, *fs_top1, *fs_bottom1, *fsx;
+ int i, j, k, jj, jdiv, loffset;
+ int prescale, iTRb, iTRp;
+ int list = img->type == B_SLICE ? LIST_1 : LIST_0;
+ int tempmv_scale[2];
+ int epzs_scale[2][6][MAX_LIST_SIZE];
+ int iref;
+
+ // Lets compute scaling factoes between all references in lists.
+ // Needed to scale spatial predictors.
+ for (j = LIST_0; j < 2 + (img->MbaffFrameFlag * 4); j ++)
+ {
+ for (k = 0; k < listXsize[j]; k++)
+ {
+ for (i = 0; i < listXsize[j]; i++)
+ {
+ if (j/2 == 0)
+ {
+ iTRb = Clip3 (-128, 127, enc_picture->poc - listX[j][i]->poc);
+ iTRp = Clip3 (-128, 127, enc_picture->poc - listX[j][k]->poc);
+ }
+ else if (j/2 == 1)
+ {
+ iTRb = Clip3 (-128, 127, enc_picture->top_poc - listX[j][i]->poc);
+ iTRp = Clip3 (-128, 127, enc_picture->top_poc - listX[j][k]->poc);
+ }
+ else
+ {
+ iTRb = Clip3 (-128, 127, enc_picture->bottom_poc - listX[j][i]->poc);
+ iTRp = Clip3 (-128, 127, enc_picture->bottom_poc - listX[j][k]->poc);
+ }
+
+ if (iTRp != 0)
+ {
+ prescale = (16384 + abs (iTRp / 2)) / iTRp;
+ mv_scale[j][i][k] = Clip3 (-2048, 2047, (iTRb * prescale + 32) >> 6);
+ }
+ else
+ mv_scale[j][i][k] = 256;
+ }
+ }
+ }
+
+ if (input->EPZSTemporal)
+ {
+ fs_top = fs_bottom = fs = listX[list][0];
+ if (listXsize[0]> 1)
+ fs_top1 = fs_bottom1 = fs1 = listX[list][1];
+ else
+ fs_top1 = fs_bottom1 = fs1 = listX[list][0];
+
+ for (j = 0; j < 6; j++)
+ {
+ for (i = 0; i < 6; i++)
+ {
+ epzs_scale[0][j][i] = 256;
+ epzs_scale[1][j][i] = 256;
+ }
+ }
+
+ for (j = 0; j < 2 + (img->MbaffFrameFlag * 4); j += 2)
+ {
+ for (i = 0; i < listXsize[j]; i++)
+ {
+ if (j == 0)
+ iTRb = Clip3 (-128, 127, enc_picture->poc - listX[LIST_0 + j][i]->poc);
+ else if (j == 2)
+ iTRb = Clip3 (-128, 127, enc_picture->top_poc - listX[LIST_0 + j][i]->poc);
+ else
+ iTRb = Clip3 (-128, 127, enc_picture->bottom_poc - listX[LIST_0 + j][i]->poc);
+ iTRp = Clip3 (-128, 127, listX[list + j][0]->poc - listX[LIST_0 + j][i]->poc);
+ if (iTRp != 0)
+ {
+ prescale = (16384 + abs (iTRp / 2)) / iTRp;
+ prescale = Clip3 (-2048, 2047, (iTRb * prescale + 32) >> 6);
+ //prescale = (iTRb * prescale + 32) >> 6;
+ }
+ else // This could not happen but lets use it in case that reference is removed.
+ prescale = 256;
+ epzs_scale[0][j][i] = (mv_scale[j][0][i] * prescale + 128) >> 8;
+ epzs_scale[0][j + 1][i] = prescale - 256;
+ if (listXsize[j]>1)
+ {
+ iTRp = Clip3 (-128, 127, listX[list + j][1]->poc - listX[LIST_0 + j][i]->poc);
+ if (iTRp != 0)
+ {
+ prescale = (16384 + abs (iTRp / 2)) / iTRp;
+ prescale = Clip3 (-2048, 2047, (iTRb * prescale + 32) >> 6);
+ //prescale = (iTRb * prescale + 32) >> 6;
+ }
+ else // This could not happen but lets use it for case that reference is removed.
+ prescale = 256;
+ epzs_scale[1][j][i] = (mv_scale[j][1][i] * prescale + 128) >> 8;
+ epzs_scale[1][j + 1][i] = prescale - 256;
+ }
+ else
+ {
+ epzs_scale[1][j][i] = epzs_scale[0][j][i];
+ epzs_scale[1][j + 1][i] = epzs_scale[0][j + 1][i];
+ }
+ }
+ }
+ if (img->MbaffFrameFlag)
+ {
+ fs_top = listX[list + 2][0];
+ fs_bottom = listX[list + 4][0];
+ if (listXsize[0]> 1)
+ {
+ fs_top1 = listX[list + 2][1];
+ fs_bottom = listX[list + 4][1];
+ }
+ }
+ else
+ {
+ if (img->structure != FRAME)
+ {
+ if ((img->structure != fs->structure) && (fs->coded_frame))
+ {
+ if (img->structure == TOP_FIELD)
+ {
+ fs_top = fs_bottom = fs = listX[list][0]->top_field;
+ fs_top1 = fs_bottom1 = fs1 = listX[list][0]->bottom_field;
+ }
+ else
+ {
+ fs_top = fs_bottom = fs = listX[list][0]->bottom_field;
+ fs_top1 = fs_bottom1 = fs1 = listX[list][0]->top_field;
+ }
+ }
+ }
+ }
+
+ //if (!active_sps->frame_mbs_only_flag || active_sps->direct_8x8_inference_flag)
+ if (!active_sps->frame_mbs_only_flag)
+ {
+ for (j = 0; j < fs->size_y >> 2; j++)
+ {
+ jj = j / 2;
+ jdiv = j / 2 + 4 * (j / 8);
+ for (i = 0; i < fs->size_x >> 2; i++)
+ {
+ if (img->MbaffFrameFlag && fs->field_frame[j][i])
+ {
+ //! Assign frame buffers for field MBs
+ //! Check whether we should use top or bottom field mvs.
+ //! Depending on the assigned poc values.
+ if (abs (enc_picture->poc - fs_bottom->poc) > abs (enc_picture->poc - fs_top->poc))
+ {
+ tempmv_scale[LIST_0] = 256;
+ tempmv_scale[LIST_1] = 0;
+
+ if (fs->ref_id [LIST_0][jdiv][i] < 0 && listXsize[LIST_0] > 1)
+ {
+ fsx = fs_top1;
+ loffset = 1;
+ }
+ else
+ {
+ fsx = fs_top;
+ loffset = 0;
+ }
+
+ if (fs->ref_id [LIST_0][jdiv][i] != -1)
+ {
+ for (iref=0;iref<min(img->num_ref_idx_l0_active,listXsize[LIST_0]);iref++)
+ {
+ if (enc_picture->ref_pic_num[LIST_0][iref]==fs->ref_id [LIST_0][jdiv][i])
+ {
+ tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
+ tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
+ break;
+ }
+ }
+ p->mv[LIST_0][j][i][0] = (tempmv_scale[LIST_0] * fsx->mv[LIST_0][jj][i][0] + 32) >> 6;
+ p->mv[LIST_0][j][i][1] = (tempmv_scale[LIST_0] * fsx->mv[LIST_0][jj][i][1] + 32) >> 6;
+ p->mv[LIST_1][j][i][0] = (tempmv_scale[LIST_1] * fsx->mv[LIST_0][jj][i][0] + 32) >> 6;
+ p->mv[LIST_1][j][i][1] = (tempmv_scale[LIST_1] * fsx->mv[LIST_0][jj][i][1] + 32) >> 6;
+ }
+ else
+ {
+ p->mv[LIST_0][j][i][0] = 0;
+ p->mv[LIST_0][j][i][1] = 0;
+ p->mv[LIST_1][j][i][0] = 0;
+ p->mv[LIST_1][j][i][1] = 0;
+ }
+
+ }
+ else
+ {
+ tempmv_scale[LIST_0] = 256;
+ tempmv_scale[LIST_1] = 0;
+
+ if (fs->ref_id [LIST_0][jdiv + 4][i] < 0 && listXsize[LIST_0] > 1)
+ {
+ fsx = fs_bottom1;
+ loffset = 1;
+ }
+ else
+ {
+ fsx = fs_bottom;
+ loffset = 0;
+ }
+
+ if (fs->ref_id [LIST_0][jdiv + 4][i] != -1)
+ {
+ for (iref=0;iref<min(img->num_ref_idx_l0_active,listXsize[LIST_0]);iref++)
+ {
+ if (enc_picture->ref_pic_num[LIST_0][iref]==fs->ref_id [LIST_0][jdiv + 4][i])
+ {
+ tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
+ tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
+ break;
+ }
+ }
+ p->mv[LIST_0][j][i][0] = (tempmv_scale[LIST_0] * fsx->mv[LIST_0][jj][i][0] + 32) >> 6;
+ p->mv[LIST_0][j][i][1] = (tempmv_scale[LIST_0] * fsx->mv[LIST_0][jj][i][1] + 32) >> 6;
+ p->mv[LIST_1][j][i][0] = (tempmv_scale[LIST_1] * fsx->mv[LIST_0][jj][i][0] + 32) >> 6;
+ p->mv[LIST_1][j][i][1] = (tempmv_scale[LIST_1] * fsx->mv[LIST_0][jj][i][1] + 32) >> 6;
+ }
+ else
+ {
+ p->mv[LIST_0][j][i][0] = 0;
+ p->mv[LIST_0][j][i][1] = 0;
+ p->mv[LIST_1][j][i][0] = 0;
+ p->mv[LIST_1][j][i][1] = 0;
+ }
+ }
+ }
+ else
+ {
+ tempmv_scale[LIST_0] = 256;
+ tempmv_scale[LIST_1] = 0;
+ if (fs->ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1)
+ {
+ fsx = fs1;
+ loffset = 1;
+ }
+ else
+ {
+ fsx = fs;
+ loffset = 0;
+ }
+
+ if (fsx->ref_id [LIST_0][j][i] != -1)
+ {
+ for (iref=0;iref<min(img->num_ref_idx_l0_active,listXsize[LIST_0]);iref++)
+ {
+ if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->ref_id [LIST_0][j][i])
+ {
+ tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
+ tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
+ break;
+ }
+ }
+ p->mv[LIST_0][j][i][0] = (tempmv_scale[LIST_0] * fsx->mv[LIST_0][j][i][0] + 32) >> 6;
+ p->mv[LIST_0][j][i][1] = (tempmv_scale[LIST_0] * fsx->mv[LIST_0][j][i][1] + 32) >> 6;
+ p->mv[LIST_1][j][i][0] = (tempmv_scale[LIST_1] * fsx->mv[LIST_0][j][i][0] + 32) >> 6;
+ p->mv[LIST_1][j][i][1] = (tempmv_scale[LIST_1] * fsx->mv[LIST_0][j][i][1] + 32) >> 6;
+ }
+ else
+ {
+ p->mv[LIST_0][j][i][0] = 0;
+ p->mv[LIST_0][j][i][1] = 0;
+ p->mv[LIST_1][j][i][0] = 0;
+ p->mv[LIST_1][j][i][1] = 0;
+ }
+ }
+ }
+ }
+ }
+
+ //! Generate field MVs from Frame MVs
+ if (img->structure || img->MbaffFrameFlag)
+ {
+ for (j = 0; j < fs->size_y / 8; j++)
+ {
+ for (i = 0; i < fs->size_x / 4; i++)
+ {
+ if (!img->MbaffFrameFlag)
+ {
+ tempmv_scale[LIST_0] = 256;
+ tempmv_scale[LIST_1] = 0;
+
+ if (fs->ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1)
+ {
+ fsx = fs1;
+ loffset = 1;
+ }
+ else
+ {
+ fsx = fs;
+ loffset = 0;
+ }
+
+ if (fsx->ref_id [LIST_0][j][i] != -1)
+ {
+ for (iref=0;iref<min(img->num_ref_idx_l0_active,listXsize[LIST_0]);iref++)
+ {
+ if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->ref_id [LIST_0][j][i])
+ {
+ tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
+ tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
+ break;
+ }
+ }
+ p->mv[LIST_0][j][i][0] = (tempmv_scale[LIST_0] * fsx->mv[LIST_0][j][i][0] + 32) >> 6;
+ p->mv[LIST_0][j][i][1] = (tempmv_scale[LIST_0] * fsx->mv[LIST_0][j][i][1] + 32) >> 6;
+ p->mv[LIST_1][j][i][0] = (tempmv_scale[LIST_1] * fsx->mv[LIST_0][j][i][0] + 32) >> 6;
+ p->mv[LIST_1][j][i][1] = (tempmv_scale[LIST_1] * fsx->mv[LIST_0][j][i][1] + 32) >> 6;
+
+ }
+ else
+ {
+ p->mv[LIST_0][j][i][0] = 0;
+ p->mv[LIST_0][j][i][1] = 0;
+ p->mv[LIST_1][j][i][0] = 0;
+ p->mv[LIST_1][j][i][1] = 0;
+ }
+ }
+ else
+ {
+ tempmv_scale[LIST_0] = 256;
+ tempmv_scale[LIST_1] = 0;
+
+ if (fs_bottom->ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1)
+ {
+ fsx = fs_bottom1;
+ loffset = 1;
+ }
+ else
+ {
+ fsx = fs_bottom;
+ loffset = 0;
+ }
+
+ if (fsx->ref_id [LIST_0][j][i] != -1)
+ {
+ for (iref=0;iref<min(2*img->num_ref_idx_l0_active,listXsize[LIST_0 + 4]);iref++)
+ {
+ if (enc_picture->ref_pic_num[LIST_0 + 4][iref]==fsx->ref_id [LIST_0][j][i])
+ {
+ tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0 + 4][iref];
+ tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1 + 4][iref];
+ break;
+ }
+ }
+ p->bottom_mv[LIST_0][j][i][0] = (tempmv_scale[LIST_0] * fsx->mv[LIST_0][j][i][0] + 32) >> 6;
+ p->bottom_mv[LIST_0][j][i][1] = (tempmv_scale[LIST_0] * fsx->mv[LIST_0][j][i][1] + 32) >> 6;
+ p->bottom_mv[LIST_1][j][i][0] = (tempmv_scale[LIST_1] * fsx->mv[LIST_0][j][i][0] + 32) >> 6;
+ p->bottom_mv[LIST_1][j][i][1] = (tempmv_scale[LIST_1] * fsx->mv[LIST_0][j][i][1] + 32) >> 6;
+ }
+ else
+ {
+ p->bottom_mv[LIST_0][j][i][0] = 0;
+ p->bottom_mv[LIST_0][j][i][1] = 0;
+ p->bottom_mv[LIST_1][j][i][0] = 0;
+ p->bottom_mv[LIST_1][j][i][1] = 0;
+ }
+
+ if (!fs->field_frame[2 * j][i])
+ {
+ p->bottom_mv[LIST_0][j][i][1] = (p->bottom_mv[LIST_0][j][i][1] + 1) >> 1;
+ p->bottom_mv[LIST_1][j][i][1] = (p->bottom_mv[LIST_1][j][i][1] + 1) >> 1;
+ }
+
+ tempmv_scale[LIST_0] = 256;
+ tempmv_scale[LIST_1] = 0;
+
+ if (fs_top->ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1)
+ {
+ fsx = fs_top1;
+ loffset = 1;
+ }
+ else
+ {
+ fsx = fs_top;
+ loffset = 0;
+ }
+
+ if (fsx->ref_id [LIST_0][j][i] != -1)
+ {
+ for (iref=0;iref<min(2*img->num_ref_idx_l0_active,listXsize[LIST_0 + 2]);iref++)
+ {
+ if (enc_picture->ref_pic_num[LIST_0 + 2][iref]==fsx->ref_id [LIST_0][j][i])
+ {
+ tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0 + 2][iref];
+ tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1 + 2][iref];
+ break;
+ }
+ }
+ p->top_mv[LIST_0][j][i][0] = (tempmv_scale[LIST_0] * fsx->mv[LIST_0][j][i][0] + 32) >> 6;
+ p->top_mv[LIST_0][j][i][1] = (tempmv_scale[LIST_0] * fsx->mv[LIST_0][j][i][1] + 32) >> 6;
+ p->top_mv[LIST_1][j][i][0] = (tempmv_scale[LIST_1] * fsx->mv[LIST_0][j][i][0] + 32) >> 6;
+ p->top_mv[LIST_1][j][i][1] = (tempmv_scale[LIST_1] * fsx->mv[LIST_0][j][i][1] + 32) >> 6;
+ }
+ else
+ {
+ p->top_mv[LIST_0][j][i][0] = 0;
+ p->top_mv[LIST_0][j][i][1] = 0;
+ p->top_mv[LIST_1][j][i][0] = 0;
+ p->top_mv[LIST_1][j][i][1] = 0;
+ }
+
+ if (!fs->field_frame[2 * j][i])
+ {
+ p->top_mv[LIST_0][j][i][1] = (p->top_mv[LIST_0][j][i][1] + 1) >> 1;
+ p->top_mv[LIST_1][j][i][1] = (p->top_mv[LIST_1][j][i][1] + 1) >> 1;
+ }
+ }
+ }
+ }
+ }
+
+ //if (!active_sps->frame_mbs_only_flag || active_sps->direct_8x8_inference_flag)
+ if (!active_sps->frame_mbs_only_flag )
+ {
+ //! Use inference flag to remap mvs/references
+ //! Frame with field co-located
+ if (!img->structure)
+ {
+ for (j = 0; j < fs->size_y >> 2; j++)
+ {
+ jj = j>>1;
+ jdiv = (j>>1) + ((j>>3) << 2);
+ for (i = 0; i < fs->size_x >> 2; i++)
+ {
+ if (fs->field_frame[j][i])
+ {
+ tempmv_scale[LIST_0] = 256;
+ tempmv_scale[LIST_1] = 0;
+
+ if (fs->ref_id [LIST_0][jdiv][i] < 0 && listXsize[LIST_0] > 1)
+ {
+ fsx = fs1;
+ loffset = 1;
+ }
+ else
+ {
+ fsx = fs;
+ loffset = 0;
+ }
+ if (fsx->ref_id [LIST_0][jdiv][i] != -1)
+ {
+ for (iref=0;iref<min(img->num_ref_idx_l0_active,listXsize[LIST_0]);iref++)
+ {
+ if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->ref_id [LIST_0][jdiv][i])
+ {
+ tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
+ tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
+ break;
+ }
+ }
+
+ if (abs (enc_picture->poc - fsx->bottom_field->poc) > abs (enc_picture->poc - fsx->top_field->poc))
+ {
+ p->mv[LIST_0][j][i][0] = (tempmv_scale[LIST_0] * fsx->top_field->mv[LIST_0][jj][i][0] + 32) >> 6;
+ p->mv[LIST_0][j][i][1] = (tempmv_scale[LIST_0] * fsx->top_field->mv[LIST_0][jj][i][1] + 32) >> 6;
+ p->mv[LIST_1][j][i][0] = (tempmv_scale[LIST_1] * fsx->top_field->mv[LIST_0][jj][i][0] + 32) >> 6;
+ p->mv[LIST_1][j][i][1] = (tempmv_scale[LIST_1] * fsx->top_field->mv[LIST_0][jj][i][1] + 32) >> 6;
+ }
+ else
+ {
+ p->mv[LIST_0][j][i][0] = (tempmv_scale[LIST_0] * fsx->bottom_field->mv[LIST_0][jj][i][0] + 32) >> 6;
+ p->mv[LIST_0][j][i][1] = (tempmv_scale[LIST_0] * fsx->bottom_field->mv[LIST_0][jj][i][1] + 32) >> 6;
+ p->mv[LIST_1][j][i][0] = (tempmv_scale[LIST_1] * fsx->bottom_field->mv[LIST_0][jj][i][0] + 32) >> 6;
+ p->mv[LIST_1][j][i][1] = (tempmv_scale[LIST_1] * fsx->bottom_field->mv[LIST_0][jj][i][1] + 32) >> 6;
+ }
+ }
+ else
+ {
+ p->mv[LIST_0][j][i][0] = 0;
+ p->mv[LIST_0][j][i][1] = 0;
+ p->mv[LIST_1][j][i][0] = 0;
+ p->mv[LIST_1][j][i][1] = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (active_sps->frame_mbs_only_flag)
+ {
+ for (j = 0; j < fs->size_y >> 2; j++)
+ {
+ for (i = 0; i < fs->size_x >> 2; i++)
+ {
+ tempmv_scale[LIST_0] = 256;
+ tempmv_scale[LIST_1] = 0;
+ if (fs->ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1)
+ {
+ fsx = fs1;
+ loffset = 1;
+ }
+ else
+ {
+ fsx = fs;
+ loffset = 0;
+ }
+ if (fsx->ref_id [LIST_0][j][i] != -1)
+ {
+ for (iref=0;iref<min(img->num_ref_idx_l0_active,listXsize[LIST_0]);iref++)
+ {
+ if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->ref_id [LIST_0][j][i])
+ {
+ tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
+ tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
+ break;
+ }
+ }
+ p->mv[LIST_0][j][i][0] = (tempmv_scale[LIST_0] * fsx->mv[LIST_0][j][i][0] + 32) >> 6;
+ p->mv[LIST_0][j][i][1] = (tempmv_scale[LIST_0] * fsx->mv[LIST_0][j][i][1] + 32) >> 6;
+ p->mv[LIST_1][j][i][0] = (tempmv_scale[LIST_1] * fsx->mv[LIST_0][j][i][0] + 32) >> 6;
+ p->mv[LIST_1][j][i][1] = (tempmv_scale[LIST_1] * fsx->mv[LIST_0][j][i][1] + 32) >> 6;
+ }
+ else
+ {
+ p->mv[LIST_0][j][i][0] = 0;
+ p->mv[LIST_0][j][i][1] = 0;
+ p->mv[LIST_1][j][i][0] = 0;
+ p->mv[LIST_1][j][i][1] = 0;
+ }
+ }
+ }
+ }
+
+ if (!active_sps->frame_mbs_only_flag)
+ {
+ for (j = 0; j < fs->size_y >> 2; j++)
+ {
+ for (i = 0; i < fs->size_x >> 2; i++)
+ {
+ if ((!img->MbaffFrameFlag && !img->structure && fs->field_frame[j][i]) || (img->MbaffFrameFlag && fs->field_frame[j][i]))
+ {
+ p->mv[LIST_0][j][i][1] *= 2;
+ p->mv[LIST_1][j][i][1] *= 2;
+ }
+ else if (img->structure && !fs->field_frame[j][i])
+ {
+ p->mv[LIST_0][j][i][1] = (p->mv[LIST_0][j][i][1] + 1) >> 1;
+ p->mv[LIST_1][j][i][1] = (p->mv[LIST_1][j][i][1] + 1) >> 1;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * Spatial Predictors
+ * AMT/HYC
+ ***********************************************************************
+ */
+ static short EPZSSpatialPredictors (PixelPos block_a,
+ PixelPos block_b,
+ PixelPos block_c,
+ PixelPos block_d,
+ int list,
+ int list_offset,
+ short ref,
+ char **refPic,
+ short ***tmp_mv,
+ EPZSStructure * predictor)
+ {
+ int refA, refB, refC, refD;
+ int *mot_scale = mv_scale[list + list_offset][ref];
+
+ // zero predictor
+ predictor->point[0].x = 0;
+ predictor->point[0].y = 0;
+
+ // Non MB-AFF mode
+ if (!img->MbaffFrameFlag)
+ {
+ refA = block_a.available ? (int) refPic[block_a.pos_y][block_a.pos_x] : -1;
+ refB = block_b.available ? (int) refPic[block_b.pos_y][block_b.pos_x] : -1;
+ refC = block_c.available ? (int) refPic[block_c.pos_y][block_c.pos_x] : -1;
+ refD = block_d.available ? (int) refPic[block_d.pos_y][block_d.pos_x] : -1;
+
+ // Left Predictor
+ predictor->point[1].x = (block_a.available)
+ ? (mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][0] + 512) >> 10 : 3;
+ predictor->point[1].y = (block_a.available)
+ ? (mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][1] + 512) >> 10 : 0;
+
+ // Up predictor
+ predictor->point[2].x = (block_b.available)
+ ? (mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][0] + 512) >> 10 : 0;
+ predictor->point[2].y = (block_b.available)
+ ? (mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][1] + 512) >> 10 : 3;
+
+ // Up-Right predictor
+ predictor->point[3].x = (block_c.available)
+ ? (mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][0] + 512) >> 10 : -3;
+ predictor->point[3].y = (block_c.available)
+ ? (mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][1] + 512) >> 10 : 0;
+
+ //Up-Left predictor
+ predictor->point[4].x = (block_d.available)
+ ? (mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][0] + 512) >> 10 : 0;
+ predictor->point[4].y = (block_d.available)
+ ? (mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][1] + 512) >> 10 : -3;
+ }
+ else // MB-AFF mode
+ {
+ // Field Macroblock
+ if (list_offset)
+ {
+ refA = block_a.available
+ ? img->mb_data[block_a.mb_addr].mb_field
+ ? (int) refPic[block_a.pos_y][block_a.pos_x]
+ : (int) refPic[block_a.pos_y][block_a.pos_x] * 2 : -1;
+ refB =block_b.available
+ ? img->mb_data[block_b.mb_addr].mb_field
+ ? (int) refPic[block_b.pos_y][block_b.pos_x]
+ : (int) refPic[block_b.pos_y][block_b.pos_x] * 2 : -1;
+ refC = block_c.available
+ ? img->mb_data[block_c.mb_addr].mb_field
+ ? (int) refPic[block_c.pos_y][block_c.pos_x]
+ : (int) refPic[block_c.pos_y][block_c.pos_x] * 2 : -1;
+ refD = block_d.available
+ ? img->mb_data[block_d.mb_addr].mb_field
+ ? (int) refPic[block_d.pos_y][block_d.pos_x]
+ : (int) refPic[block_d.pos_y][block_d.pos_x] * 2 : -1;
+
+ // Left Predictor
+ predictor->point[1].x = (block_a.available)
+ ? (mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][0] + 512 ) >> 10 : 3;
+ predictor->point[1].y = (block_a.available)
+ ? img->mb_data[block_a.mb_addr].mb_field
+ ? (mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][1] + 512 ) >> 10
+ : (mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][1] + 1024) >> 11 : 0;
+
+ // Up predictor
+ predictor->point[2].x = (block_b.available)
+ ? (mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][0] + 512 ) >> 10 : 0;
+ predictor->point[2].y = (block_b.available)
+ ? img->mb_data[block_b.mb_addr].mb_field
+ ? (mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][1] + 512 ) >> 10
+ : (mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][1] + 1024) >> 11 : 3;
+
+ // Up-Right predictor
+ predictor->point[3].x = (block_c.available)
+ ? (mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][0] + 512 ) >> 10 : -3;
+ predictor->point[3].y = (block_c.available)
+ ? img->mb_data[block_c.mb_addr].mb_field
+ ? (mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][1] + 512 ) >> 10
+ : (mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][1] + 1024) >> 11 : 0;
+
+ //Up-Left predictor
+ predictor->point[4].x = (block_d.available)
+ ? (mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][0] + 512 ) >> 10 : 0;
+ predictor->point[4].y = (block_d.available)
+ ? img->mb_data[block_d.mb_addr].mb_field
+ ? (mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][1] + 512 ) >> 10
+ : (mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][1] + 1024) >> 11 : -3;
+ }
+ else // Frame macroblock
+ {
+ refA = block_a.available
+ ? img->mb_data[block_a.mb_addr].mb_field
+ ? (int) refPic[block_a.pos_y][block_a.pos_x] >> 1
+ : (int) refPic[block_a.pos_y][block_a.pos_x] : -1;
+ refB = block_b.available
+ ? img->mb_data[block_b.mb_addr].mb_field
+ ? (int) refPic[block_b.pos_y][block_b.pos_x] >> 1
+ : (int) refPic[block_b.pos_y][block_b.pos_x] : -1;
+ refC = block_c.available
+ ? img->mb_data[block_c.mb_addr].mb_field
+ ? (int) refPic[block_c.pos_y][block_c.pos_x] >> 1
+ : (int) refPic[block_c.pos_y][block_c.pos_x] : -1;
+ refD = block_d.available
+ ? img->mb_data[block_d.mb_addr].mb_field
+ ? (int) refPic[block_d.pos_y][block_d.pos_x] >> 1
+ : (int) refPic[block_d.pos_y][block_d.pos_x] : -1;
+
+ // Left Predictor
+ predictor->point[1].x = (block_a.available)
+ ? (mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][0] + 512) >> 10 : 3;
+ predictor->point[1].y = (block_a.available)
+ ? img->mb_data[block_a.mb_addr].mb_field
+ ? (mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][1] + 256) >> 9
+ : (mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][1] + 512) >> 10 : 0;
+
+ // Up predictor
+ predictor->point[2].x = (block_b.available)
+ ? (mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][0] + 512) >> 10 : 0;
+ predictor->point[2].y = (block_b.available)
+ ? img->mb_data[block_b.mb_addr].mb_field
+ ? (mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][1] + 256) >> 9
+ : (mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][1] + 512) >> 10 : 3;
+
+ // Up-Right predictor
+ predictor->point[3].x = (block_c.available)
+ ? (mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][0] + 512) >> 10 : -3;
+ predictor->point[3].y = (block_c.available)
+ ? img->mb_data[block_c.mb_addr].mb_field
+ ? (mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][1] + 256) >> 9
+ : (mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][1] + 512) >> 10 : 3;
+
+ //Up-Left predictor
+ predictor->point[4].x = (block_d.available)
+ ? (mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][0] + 512) >> 10 : 0;
+ predictor->point[4].y = (block_d.available)
+ ? img->mb_data[block_d.mb_addr].mb_field
+ ? (mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][1] + 256) >> 9
+ : (mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][1] + 512) >> 10 : -3;
+ }
+ }
+
+ return ((refA == -1) + (refB == -1) + (refC == -1 && refD == -1));
+ }
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * Spatial Predictors
+ * AMT/HYC
+ ***********************************************************************
+ */
+
+ static void EPZSSpatialMemPredictors (int list,
+ short ref,
+ int blocktype,
+ int pic_x,
+ int bs_x,
+ int bs_y,
+ int by,
+ int *prednum,
+ int img_width,
+ EPZSStructure * predictor)
+ {
+ #if EPZSREF
+ short ***mv = EPZSMotion[list][ref][blocktype];
+
+ // Left Predictor
+ predictor->point[*prednum].x = (pic_x > 0) ? mv[by][pic_x - bs_x][0] : 0;
+ predictor->point[*prednum].y = (pic_x > 0) ? mv[by][pic_x - bs_x][1] : 0;
+ *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
+
+ // Up predictor
+ predictor->point[*prednum].x = (by > 0) ? mv[by - bs_y][pic_x][0] : mv[4 - bs_y][pic_x][0] ;
+ predictor->point[*prednum].y = (by > 0) ? mv[by - bs_y][pic_x][1] : mv[4 - bs_y][pic_x][1];
+ *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
+
+ // Up-Right predictor
+ predictor->point[*prednum].x = (pic_x + bs_x < img_width) ? (by > 0)
+ ? mv[by - bs_y][pic_x + bs_x][0] : mv[4 - bs_y][pic_x + bs_x][0] : 0;
+ predictor->point[*prednum].y = (pic_x + bs_x < img_width) ? (by > 0)
+ ? mv[by - bs_y][pic_x + bs_x][1] : mv[4 - bs_y][pic_x + bs_x][1] : 0;
+ *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
+
+ #else
+ int mot_scale = mv_scale[list][ref][0];
+ short **mv = EPZSMotion[list][blocktype];
+
+ // Left Predictor
+ predictor->point[*prednum].x = (pic_x > 0)
+ ? (mot_scale * mv[by][pic_x - bs_x][0] + 128) >> 8
+ : 0;
+ predictor->point[*prednum].y = (pic_x > 0)
+ ? (mot_scale * mv[by][pic_x - bs_x][1] + 128) >> 8
+ : 0;
+ *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
+
+ // Up predictor
+ predictor->point[*prednum].x = (by > 0)
+ ? (mot_scale * mv[by - bs_y][pic_x][0] + 128) >> 8
+ : (mot_scale * mv[4 - bs_y][pic_x][0] + 128) >> 8;
+ predictor->point[*prednum].y = (by > 0)
+ ? (mot_scale * mv[by - bs_y][pic_x][1] + 128) >> 8
+ : (mot_scale * mv[4 - bs_y][pic_x][0] + 128) >> 8;
+ *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
+
+ // Up-Right predictor
+ predictor->point[*prednum].x = (pic_x + bs_x < img_width)
+ ? (by > 0)
+ ? (mot_scale * mv[by - bs_y][pic_x + bs_x][0] + 128) >> 8
+ : (mot_scale * mv[4 - bs_y][pic_x + bs_x][0] + 128) >> 8
+ : 0;
+ predictor->point[*prednum].y = (pic_x + bs_x < img_width)
+ ? (by > 0)
+ ? (mot_scale * mv[by - bs_y][pic_x + bs_x][1] + 128) >> 8
+ : (mot_scale * mv[4 - bs_y][pic_x + bs_x][1] + 128) >> 8
+ : 0;
+ *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
+ #endif
+ }
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * Temporal Predictors
+ * AMT/HYC
+ ***********************************************************************
+ */
+ static void
+ EPZSTemporalPredictors (int list, // <-- current list
+ int list_offset, // <-- list offset for MBAFF
+ short ref, // <-- current reference frame
+ int o_block_x, // <-- absolute x-coordinate of regarded AxB block
+ int o_block_y, // <-- absolute y-coordinate of regarded AxB block
+ EPZSStructure * predictor,
+ int *prednum,
+ int block_available_left,
+ int block_available_up,
+ int block_available_right,
+ int block_available_below,
+ int blockshape_x,
+ int blockshape_y,
+ int stopCriterion,
+ int min_mcost)
+ {
+ int mvScale = mv_scale[list + list_offset][ref][0];
+ short ***col_mv = (list_offset == 0) ? EPZSCo_located->mv[list]
+ : (list_offset == 2) ? EPZSCo_located->top_mv[list] : EPZSCo_located->bottom_mv[list];
+
+ predictor->point[*prednum].x = (mvScale * col_mv[o_block_y][o_block_x][0] + 2048) >> 12;
+ predictor->point[*prednum].y = (mvScale * col_mv[o_block_y][o_block_x][1] + 2048) >> 12;
+ *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
+
+ if (min_mcost > stopCriterion && ref < 2)
+ {
+ if (block_available_left)
+ {
+ predictor->point[*prednum].x = (mvScale * col_mv[o_block_y][o_block_x - 1][0] + 2048) >> 12;
+ predictor->point[*prednum].y = (mvScale * col_mv[o_block_y][o_block_x - 1][1] + 2048) >> 12;
+ *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
+
+ //Up_Left
+ if (block_available_up)
+ {
+ predictor->point[*prednum].x = (mvScale * col_mv[o_block_y - 1][o_block_x - 1][0] + 2048) >> 12;
+ predictor->point[*prednum].y = (mvScale * col_mv[o_block_y - 1][o_block_x - 1][1] + 2048) >> 12;
+ *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));;
+ }
+ //Down_Left
+ if (block_available_below)
+ {
+ predictor->point[*prednum].x = (mvScale * col_mv[o_block_y + blockshape_y][o_block_x - 1][0] + 2048) >> 12;
+ predictor->point[*prednum].y = (mvScale * col_mv[o_block_y + blockshape_y][o_block_x - 1][1] + 2048) >> 12;
+ *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
+ }
+ }
+ // Up
+ if (block_available_up)
+ {
+ predictor->point[*prednum].x = (mvScale * col_mv[o_block_y - 1][o_block_x][0] + 2048) >> 12;
+ predictor->point[*prednum].y = (mvScale * col_mv[o_block_y - 1][o_block_x][1] + 2048) >> 12;
+ *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
+ }
+
+ // Up - Right
+ if (block_available_right)
+ {
+ predictor->point[*prednum].x = (mvScale * col_mv[o_block_y][o_block_x + blockshape_x][0] + 2048) >> 12;
+ predictor->point[*prednum].y = (mvScale * col_mv[o_block_y][o_block_x + blockshape_x][1] + 2048) >> 12;
+ *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
+
+ if (block_available_up)
+ {
+ predictor->point[*prednum].x = (mvScale * col_mv[o_block_y - 1][o_block_x + blockshape_x][0] + 2048) >> 12;
+ predictor->point[*prednum].y = (mvScale * col_mv[o_block_y - 1][o_block_x + blockshape_x][1] + 2048) >> 12;
+ *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
+ }
+ if (block_available_below)
+ {
+ predictor->point[*prednum].x = (mvScale * col_mv[o_block_y + blockshape_y][o_block_x + blockshape_x][0] + 2048) >> 12;
+ predictor->point[*prednum].y = (mvScale * col_mv[o_block_y + blockshape_y][o_block_x + blockshape_x][1] + 2048) >> 12;
+ *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
+ }
+ }
+
+ if (block_available_below)
+ {
+ predictor->point[*prednum].x = (mvScale * col_mv[o_block_y + blockshape_y][o_block_x][0] + 2048) >> 12;
+ predictor->point[*prednum].y = (mvScale * col_mv[o_block_y + blockshape_y][o_block_x][1] + 2048) >> 12;
+ *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
+ }
+ }
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * EPZS Block Type Predictors
+ ************************************************************************
+ */
+ static void EPZSBlockTypePredictors (int block_x, int block_y, int blocktype, int ref, int list,
+ EPZSStructure * predictor, int *prednum)
+ {
+ short ***all_mv = img->all_mv[block_y][block_x][list];
+
+
+ if ((ref > 0) && (blocktype < 5 || img->structure != FRAME))
+ {
+ predictor->point[*prednum].x = (mv_scale[list][ref][ref-1] * all_mv[ref-1][blocktype][0] + 512) >> 10;
+ predictor->point[*prednum].y = (mv_scale[list][ref][ref-1] * all_mv[ref-1][blocktype][1] + 512) >> 10;
+ *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
+
+ predictor->point[*prednum].x = (mv_scale[list][ref][0] * all_mv[0][blocktype][0] + 512) >> 10;
+ predictor->point[*prednum].y = (mv_scale[list][ref][0] * all_mv[0][blocktype][1] + 512) >> 10;
+ *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
+ }
+
+ predictor->point[*prednum].x = (all_mv[ref][blk_parent[blocktype]][0] + 2) >> 2;
+ predictor->point[*prednum].y = (all_mv[ref][blk_parent[blocktype]][1] + 2) >> 2;
+ *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
+
+ if (blocktype != 1)
+ {
+ predictor->point[*prednum].x = (all_mv[ref][1][0] + 2) >> 2;
+ predictor->point[*prednum].y = (all_mv[ref][1][1] + 2) >> 2;
+ *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
+ }
+
+ if (blocktype != 4)
+ {
+ predictor->point[*prednum].x = (all_mv[ref][4][0] + 2) >> 2;
+ predictor->point[*prednum].y = (all_mv[ref][4][1] + 2) >> 2;
+ *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
+ }
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * EPZS Window Based Predictors
+ ************************************************************************
+ */
+ static void EPZSWindowPredictors (int mv_x, int mv_y, EPZSStructure *predictor, int *prednum, int extended)
+ {
+ int pos;
+ EPZSStructure *windowPred = (extended) ? window_predictor_extended : window_predictor;
+
+ for (pos = 0; pos < windowPred->searchPoints; pos++)
+ {
+ predictor->point[(*prednum) ].x = mv_x + windowPred->point[pos].x;
+ predictor->point[(*prednum)++].y = mv_y + windowPred->point[pos].y;
+ }
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * SAD computation
+ ************************************************************************
+ */
+ static int computeSad(pel_t** cur_pic,
+ int blocksize_y,
+ int blocksize_x,
+ int blockshape_x,
+ int mcost,
+ int min_mcost,
+ int cand_x,
+ int cand_y)
+ {
+ int y,x4;
+
+ pel_t *cur_line, *ref_line;
+ for (y=0; y<blocksize_y; y++)
+ {
+ ref_line = get_ref_line (blocksize_x, ref_pic, cand_y + y, cand_x, img_height, img_width);
+ cur_line = cur_pic [y];
+
+ for (x4 = 0; x4 < blockshape_x; x4++)
+ {
+ mcost += byte_abs[ *cur_line++ - *ref_line++ ];
+ mcost += byte_abs[ *cur_line++ - *ref_line++ ];
+ mcost += byte_abs[ *cur_line++ - *ref_line++ ];
+ mcost += byte_abs[ *cur_line++ - *ref_line++ ];
+ //mcost += abs( *cur_line++ - *ref_line++ );
+ //mcost += abs( *cur_line++ - *ref_line++ );
+ //mcost += abs( *cur_line++ - *ref_line++ );
+ //mcost += abs( *cur_line++ - *ref_line++ );
+ }
+ if (mcost >= min_mcost) break;
+ }
+ return mcost;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * BiPred SAD computation (no weights)
+ ************************************************************************
+ */
+ static int computeBiPredSad1(pel_t** cur_pic,
+ int blocksize_y,
+ int blocksize_x,
+ int blockshape_x,
+ int mcost,
+ int min_mcost,
+ int cand_x1, int cand_y1,
+ int cand_x2, int cand_y2)
+ {
+ pel_t *cur_line, *ref1_line, *ref2_line;
+ int bi_diff;
+ int y,x4;
+
+ for (y = 0; y < blocksize_y; y++)
+ {
+ ref2_line = get_ref_line2 (blocksize_x, ref_pic2, cand_y2 + y, cand_x2, img_height, img_width);
+ ref1_line = get_ref_line1 (blocksize_x, ref_pic1, cand_y1 + y, cand_x1, img_height, img_width);
+ cur_line = cur_pic [y];
+
+ for (x4 = 0; x4 < blockshape_x; x4++)
+ {
+ bi_diff = (*cur_line++) - ((*ref1_line++ + *ref2_line++)>>1);
+ mcost += byte_abs[bi_diff];
+ bi_diff = (*cur_line++) - ((*ref1_line++ + *ref2_line++)>>1);
+ mcost += byte_abs[bi_diff];
+ bi_diff = (*cur_line++) - ((*ref1_line++ + *ref2_line++)>>1);
+ mcost += byte_abs[bi_diff];
+ bi_diff = (*cur_line++) - ((*ref1_line++ + *ref2_line++)>>1);
+ mcost += byte_abs[bi_diff];
+ }
+
+ if (mcost >= min_mcost) break;
+ }
+ return mcost;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * BiPred SAD computation (with weights)
+ ************************************************************************
+ */
+ static int computeBiPredSad2(pel_t** cur_pic,
+ int blocksize_y,
+ int blocksize_x,
+ int blockshape_x,
+ int mcost,
+ int min_mcost,
+ int cand_x1, int cand_y1,
+ int cand_x2, int cand_y2)
+ {
+ pel_t *cur_line, *ref1_line, *ref2_line;
+ int bi_diff;
+ int denom = luma_log_weight_denom + 1;
+ int lround = 2 * wp_luma_round;
+ int y,x4;
+ int weightedpel, pixel1, pixel2;
+ for (y=0; y<blocksize_y; y++)
+ {
+ ref2_line = get_ref_line2 (blocksize_x, ref_pic2, cand_y2 + y, cand_x2, img_height, img_width);
+ ref1_line = get_ref_line1 (blocksize_x, ref_pic1, cand_y1 + y, cand_x1, img_height, img_width);
+ cur_line = cur_pic [y];
+
+ for (x4 = 0; x4 < blockshape_x; x4++)
+ {
+ pixel1 = weight1 * (*ref1_line++);
+ pixel2 = weight2 * (*ref2_line++);
+ weightedpel = Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + lround) >> denom) + offsetBi);
+ bi_diff = (*cur_line++) - weightedpel;
+ mcost += byte_abs[bi_diff];
+
+ pixel1 = weight1 * (*ref1_line++);
+ pixel2 = weight2 * (*ref2_line++);
+ weightedpel = Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + lround) >> denom) + offsetBi);
+ bi_diff = (*cur_line++) - weightedpel;
+ mcost += byte_abs[bi_diff];
+
+ pixel1 = weight1 * (*ref1_line++);
+ pixel2 = weight2 * (*ref2_line++);
+ weightedpel = Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + lround) >> denom) + offsetBi);
+ bi_diff = (*cur_line++) - weightedpel;
+ mcost += byte_abs[bi_diff];
+
+ pixel1 = weight1 * (*ref1_line++);
+ pixel2 = weight2 * (*ref2_line++);
+ weightedpel = Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + lround) >> denom) + offsetBi);
+ bi_diff = (*cur_line++) - weightedpel;
+ mcost += byte_abs[bi_diff];
+ if (mcost >= min_mcost) break;
+ }
+
+ if (mcost >= min_mcost) break;
+ }
+ return mcost;
+ }
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * FAST Motion Estimation using EPZS
+ * AMT/HYC
+ ***********************************************************************
+ */
+ int // ==> minimum motion cost after search
+ EPZSPelBlockMotionSearch (pel_t ** cur_pic, // <-- original pixel values for the AxB block
+ short ref, // <-- reference picture
+ int list, // <-- reference list
+ int list_offset, // <-- offset for Mbaff
+ char ***refPic, // <-- reference array
+ short ****tmp_mv, // <-- mv array
+ int pic_pix_x, // <-- absolute x-coordinate of regarded AxB block
+ int pic_pix_y, // <-- absolute y-coordinate of regarded AxB block
+ int blocktype, // <-- block type (1-16x16 ... 7-4x4)
+ short pred_mv_x, // <-- motion vector predictor (x) in sub-pel units
+ short pred_mv_y, // <-- motion vector predictor (y) in sub-pel units
+ short *mv_x, // <--> in: search center (x) / out: motion vector (x) - in pel units
+ short *mv_y, // <--> in: search center (y) / out: motion vector (y) - in pel units
+ int search_range, // <-- 1-d search range in pel units
+ int min_mcost, // <-- minimum motion cost (cost for center or huge value)
+ int lambda_factor) // <-- lagrangian parameter for determining motion cost
+ {
+ StorablePicture *ref_picture = listX[list+list_offset][ref];
+ short blocksize_y = input->blc_size[blocktype][1]; // vertical block size
+ short blocksize_x = input->blc_size[blocktype][0]; // horizontal block size
+ short blockshape_x = (blocksize_x >> 2); // horizontal block size in 4-pel units
+ short blockshape_y = (blocksize_y >> 2); // vertical block size in 4-pel units
+
+ short mb_x = pic_pix_x - img->opix_x;
+ short mb_y = pic_pix_y - img->opix_y;
+ short pic_pix_x2 = pic_pix_x >> 2;
+ short pic_pix_y2 = pic_pix_y >> 2;
+ short block_x = (mb_x >> 2);
+ short block_y = (mb_y >> 2);
+
+ int pred_x = (pic_pix_x << 2) + pred_mv_x; // predicted position x (in sub-pel units)
+ int pred_y = (pic_pix_y << 2) + pred_mv_y; // predicted position y (in sub-pel units)
+ int center_x = pic_pix_x + *mv_x; // center position x (in pel units)
+ int center_y = pic_pix_y + *mv_y; // center position y (in pel units)
+ int cand_x = center_x;
+ int cand_y = center_y;
+ int tempmv_x = *mv_x, tempmv_y = *mv_y;
+ int tempmv_x2 = 0, tempmv_y2 = 0;
+ int stopCriterion = medthres[blocktype];
+ int mapCenter_x = search_range - *mv_x;
+ int mapCenter_y = search_range - *mv_y;
+ int second_mcost = INT_MAX;
+ short apply_weights = (active_pps->weighted_pred_flag > 0 || active_pps->weighted_bipred_idc == 1);
+ int *prevSad = EPZSDistortion[list + list_offset][blocktype - 1];
+ short *motion=NULL;
+
+ short invalid_refs = 0;
+ byte checkMedian = FALSE;
+ EPZSStructure *searchPatternF = searchPattern;
+ ref_pic = (apply_weights && input->UseWeightedReferenceME) ? ref_picture->imgY_11_w : ref_picture->imgY_11;
+
+ if (input->EPZSSpatialMem)
+ {
+ #if EPZSREF
+ motion = EPZSMotion[list + list_offset][ref][blocktype - 1][block_y][pic_pix_x2];
+ #else
+ motion = EPZSMotion[list + list_offset][blocktype - 1][block_y][pic_pix_x2];
+ #endif
+ }
+ img_width = ref_picture->size_x;
+ img_height = ref_picture->size_y;
+
+
+ //===== set function for getting reference picture lines =====
+ get_ref_line = CHECK_RANGE ? FastLineX : UMVLineX;
+
+ // Clear EPZSMap
+ memset(EPZSMap[0],FALSE,(2*search_range+1)*(2*search_range+1));
+ // Check median candidate;
+ EPZSMap[search_range][search_range] = TRUE;
+
+ //--- initialize motion cost (cost for motion vector) and check ---
+ min_mcost = MV_COST (lambda_factor, 2, cand_x, cand_y, pred_x, pred_y);
+
+ //--- add residual cost to motion cost ---
+ min_mcost = computeSad(cur_pic, blocksize_y,blocksize_x,
+ blockshape_x,min_mcost, INT_MAX, cand_x,cand_y);
+ // Additional threshold for ref>0
+ if ((ref>0 && img->structure == FRAME)
+ && (prevSad[pic_pix_x2] < medthres[blocktype])
+ && (prevSad[pic_pix_x2] < min_mcost))
+ {
+ return min_mcost;
+ }
+
+ if ((center_x > search_range) && (center_x < img_width - search_range - blocksize_x) &&
+ (center_y > search_range) && (center_y < img_height - search_range - blocksize_y) )
+ get_ref_line = FastLineX;
+ else
+ get_ref_line = UMVLineX;
+
+ //! If medthres satisfied, then terminate, otherwise generate Predictors
+ //! Condition could be strengthened by consideration distortion of adjacent partitions.
+ if (min_mcost > stopCriterion)
+ {
+ int mb_available_right = (img->mb_x < (img_width >> 4) - 1);
+ int mb_available_below = (img->mb_y < (img_height >> 4) - 1);
+
+ int sadA, sadB, sadC;
+ int block_available_right;
+ int block_available_below;
+ int prednum = 5;
+ int patternStop = 0, pointNumber = 0, checkPts;
+ int totalCheckPts = 0, motionDirection = 0;
+ int conditionEPZS;
+ int mvx, mvy;
+ int pos, mcost;
+ PixelPos block_a, block_b, block_c, block_d;
+
+ getLuma4x4Neighbour (img->current_mb_nr, block_x, block_y, -1, 0, &block_a);
+ getLuma4x4Neighbour (img->current_mb_nr, block_x, block_y, 0, -1, &block_b);
+ getLuma4x4Neighbour (img->current_mb_nr, block_x, block_y, blocksize_x, -1, &block_c);
+ getLuma4x4Neighbour (img->current_mb_nr, block_x, block_y, -1, -1, &block_d);
+
+ if (mb_y > 0)
+ {
+ if (mb_x < 8) // first column of 8x8 blocks
+ {
+ if (mb_y == 8)
+ {
+ block_available_right = (blocksize_x != MB_BLOCK_SIZE) || mb_available_right;
+ if (blocksize_x == MB_BLOCK_SIZE)
+ block_c.available = 0;
+ }
+ else
+ {
+ block_available_right = (mb_x + blocksize_x != 8) || mb_available_right;
+ if (mb_x + blocksize_x == 8)
+ block_c.available = 0;
+ }
+ }
+ else
+ {
+ block_available_right = (mb_x + blocksize_x != MB_BLOCK_SIZE) || mb_available_right;
+ if (mb_x + blocksize_x == MB_BLOCK_SIZE)
+ block_c.available = 0;
+ }
+ }
+ else
+ {
+ block_available_right = (mb_x + blocksize_x != MB_BLOCK_SIZE) || mb_available_right;
+ }
+ block_available_below = (mb_y + blocksize_y != MB_BLOCK_SIZE) || (mb_available_below);
+
+ sadA = block_a.available ? prevSad[pic_pix_x2 - blockshape_x] : INT_MAX;
+ sadB = block_b.available ? prevSad[pic_pix_x2] : INT_MAX;
+ sadC = block_c.available ? prevSad[pic_pix_x2 + blockshape_x] : INT_MAX;
+
+ stopCriterion = min(sadA,min(sadB,sadC));
+ stopCriterion = max(stopCriterion,minthres[blocktype]);
+ stopCriterion = min(stopCriterion,maxthres[blocktype]);
+
+ stopCriterion = (9 * max (medthres[blocktype], stopCriterion) + 2 * medthres[blocktype]) >> 3;
+
+ //! Add Spatial Predictors in predictor list.
+ //! Scheme adds zero, left, top-left, top, top-right. Note that top-left adds very little
+ //! in terms of performance and could be removed with little penalty if any.
+ invalid_refs = EPZSSpatialPredictors (block_a, block_b, block_c, block_d,
+ list, list_offset, ref, refPic[list], tmp_mv[list], predictor);
+ if (input->EPZSSpatialMem)
+ EPZSSpatialMemPredictors (list + list_offset, ref, blocktype - 1, pic_pix_x2,
+ blockshape_x, blockshape_y, block_y, &prednum, img_width>>2, predictor);
+
+ // Temporal predictors
+ if (input->EPZSTemporal)
+ EPZSTemporalPredictors (list, list_offset, ref, pic_pix_x2, pic_pix_y2, predictor, &prednum,
+ block_a.available, block_b.available, block_available_right,
+ block_available_below, blockshape_x, blockshape_y, stopCriterion, min_mcost);
+
+ //! Window Size Based Predictors
+ //! Basically replaces a Hierarchical ME concept and helps escaping local minima, or
+ //! determining large motion variations.
+ //! Following predictors can be adjusted further (i.e. removed, conditioned etc)
+ //! based on distortion, correlation of adjacent MVs, complexity etc. These predictors
+ //! and their conditioning could also be moved after all other predictors have been
+ //! tested. Adaptation could also be based on type of material and coding mode (i.e.
+ //! field/frame coding,MBAFF etc considering the higher dependency with opposite parity field
+ //conditionEPZS = ((min_mcost > stopCriterion)
+ // && (input->EPZSFixed > 1 || (input->EPZSFixed && img->type == P_SLICE)));
+ //conditionEPZS = ((ref == 0) && (blocktype < 5) && (min_mcost > stopCriterion)
+ //&& (input->EPZSFixed > 1 || (input->EPZSFixed && img->type == P_SLICE)));
+ conditionEPZS = ((min_mcost > stopCriterion) && ((ref < 2 && blocktype < 5)
+ || ((img->structure!=FRAME || list_offset) && ref < 3))
+ && (input->EPZSFixed > 1 || (input->EPZSFixed && img->type == P_SLICE)));
+
+ if (conditionEPZS)
+ EPZSWindowPredictors ((int) *mv_x, (int) *mv_y, predictor, &prednum,
+ (blocktype < 5) && (invalid_refs > 2) && (ref < 1 + (img->structure!=FRAME || list_offset)));
+
+ //! Blocktype/Reference dependent predictors.
+ //! Since already mvs for other blocktypes/references have been computed, we can reuse
+ //! them in order to easier determine the optimal point. Use of predictors could depend
+ //! on cost,
+ //conditionEPZS = (ref == 0 || (ref > 0 && min_mcost > stopCriterion) || img->structure != FRAME || list_offset);
+ conditionEPZS = (ref == 0 || (ref > 0 && min_mcost > stopCriterion));
+
+ if (conditionEPZS)
+ EPZSBlockTypePredictors (block_x, block_y, blocktype, ref, list, predictor, &prednum);
+
+ //! Check all predictors
+ for (pos = 0; pos < prednum; pos++)
+ {
+ mvx = predictor->point[pos].x;
+ mvy = predictor->point[pos].y;
+ //if ((abs (mvx - *mv_x) > search_range || abs (mvy - *mv_y) > search_range) && (mvx || mvy))
+ if (abs (mvx - *mv_x) > search_range || abs (mvy - *mv_y) > search_range)
+ continue;
+
+ if ((abs (mvx - *mv_x) <= search_range) && (abs (mvy - *mv_y) <= search_range))
+ {
+ if (EPZSMap[mapCenter_y + mvy][mapCenter_x + mvx] == TRUE)
+ continue;
+ else
+ EPZSMap[mapCenter_y + mvy][mapCenter_x + mvx] = TRUE;
+ }
+
+ cand_x = pic_pix_x + mvx;
+ cand_y = pic_pix_y + mvy;
+
+ //--- set motion cost (cost for motion vector) and check ---
+ mcost = MV_COST (lambda_factor, 2, cand_x, cand_y, pred_x, pred_y);
+
+ if (mcost >= second_mcost) continue;
+ get_ref_line = CHECK_RANGE ? FastLineX : UMVLineX;
+
+ mcost = computeSad(cur_pic, blocksize_y,blocksize_x,
+ blockshape_x, mcost, second_mcost, cand_x, cand_y);
+
+ //--- check if motion cost is less than minimum cost ---
+ if (mcost < min_mcost)
+ {
+ tempmv_x2 = tempmv_x;
+ tempmv_y2 = tempmv_y;
+ second_mcost = min_mcost;
+ tempmv_x = mvx;
+ tempmv_y = mvy;
+ min_mcost = mcost;
+ checkMedian = TRUE;
+ }
+ //else if (mcost < second_mcost && (tempmv_x != mvx || tempmv_y != mvy))
+ else if (mcost < second_mcost)
+ {
+ tempmv_x2 = mvx;
+ tempmv_y2 = mvy;
+ second_mcost = mcost;
+ checkMedian = TRUE;
+ }
+ }
+
+ //! Refine using EPZS pattern if needed
+ //! Note that we are using a conservative threshold method. Threshold
+ //! could be tested after checking only a certain number of predictors
+ //! instead of the full set. Code could be easily modified for this task.
+ if (min_mcost > stopCriterion)
+ {
+ //! Adapt pattern based on different conditions.
+ if (input->EPZSPattern != 0)
+ {
+ if ((min_mcost < stopCriterion + ((3 * medthres[blocktype]) >> 1)))
+ {
+ if ((tempmv_x == 0 && tempmv_y == 0)
+ || (abs (tempmv_x - *mv_x) < 2 && abs (tempmv_y - *mv_y) < 2))
+ searchPatternF = sdiamond;
+ else
+ searchPatternF = square;
+ }
+ else if (blocktype > 5 || (ref > 0 && blocktype != 1))
+ searchPatternF = square;
+ else
+ searchPatternF = searchPattern;
+ }
+
+ totalCheckPts = searchPatternF->searchPoints;
+
+ //! center on best predictor
+ center_x = tempmv_x;
+ center_y = tempmv_y;
+ while(1)
+ {
+ do
+ {
+ checkPts = totalCheckPts;
+ do
+ {
+ mvx = center_x + searchPatternF->point[pointNumber].x;
+ mvy = center_y + searchPatternF->point[pointNumber].y;
+ cand_x = pic_pix_x + mvx;
+ cand_y = pic_pix_y + mvy;
+
+ if ((abs (mvx - *mv_x) <= search_range)
+ && (abs (mvy - *mv_y) <= search_range))
+ {
+ if (EPZSMap[mapCenter_y + mvy][mapCenter_x + mvx] != TRUE)
+ EPZSMap[mapCenter_y + mvy][mapCenter_x + mvx] = TRUE;
+ else
+ {
+ pointNumber += 1;
+ if (pointNumber >= searchPatternF->searchPoints)
+ pointNumber -= searchPatternF->searchPoints;
+ checkPts -= 1;
+ continue;
+ }
+ mcost = MV_COST (lambda_factor, 2, cand_x, cand_y, pred_x, pred_y);
+
+ if (mcost < min_mcost)
+ {
+ get_ref_line = CHECK_RANGE ? FastLineX : UMVLineX;
+ mcost = computeSad(cur_pic, blocksize_y,blocksize_x,
+ blockshape_x, mcost, min_mcost, cand_x, cand_y);
+ if (mcost < min_mcost)
+ {
+ min_mcost = mcost;
+ tempmv_x = mvx;
+ tempmv_y = mvy;
+ motionDirection = pointNumber;
+ }
+ }
+ }
+ pointNumber += 1;
+ if (pointNumber >= searchPatternF->searchPoints)
+ pointNumber -= searchPatternF->searchPoints;
+ checkPts -= 1;
+ }
+ while (checkPts > 0);
+
+ if ((tempmv_x == center_x) && (tempmv_y == center_y))
+ {
+ totalCheckPts = searchPatternF->searchPoints;
+ patternStop = 1;
+ motionDirection = 0;
+ pointNumber = 0;
+ }
+ else
+ {
+ totalCheckPts = searchPatternF->point[motionDirection].next_points;
+ pointNumber = searchPatternF->point[motionDirection].start_nmbr;
+ center_x = tempmv_x;
+ center_y = tempmv_y;
+ }
+ }
+ while (patternStop != 1);
+
+ if ((ref>0) && (img->structure == FRAME)
+ && (( 4 * prevSad[pic_pix_x2] < min_mcost) ||
+ ((3 * prevSad[pic_pix_x2] < min_mcost) && (prevSad[pic_pix_x2] <= stopCriterion))))
+ {
+ *mv_x = tempmv_x;
+ *mv_y = tempmv_y;
+ return min_mcost;
+ }
+
+ //! Check Second best predictor with EPZS pattern
+ conditionEPZS = (checkMedian == TRUE)
+ && ((img->type == P_SLICE) || (blocktype < 5))
+ && (min_mcost > stopCriterion) && (input->EPZSDual > 0);
+
+ if (!conditionEPZS) break;
+
+ pointNumber = 0;
+ patternStop = 0;
+ motionDirection = 0;
+
+ if ((tempmv_x == 0 && tempmv_y == 0)
+ || (tempmv_x == *mv_x && tempmv_y == *mv_y))
+ {
+ if (abs (tempmv_x - *mv_x) < 2 && abs (tempmv_y - *mv_y) < 2)
+ searchPatternF = sdiamond;
+ else
+ searchPatternF = square;
+ }
+ else
+ searchPatternF = searchPatternD;
+ totalCheckPts = searchPatternF->searchPoints;
+
+ //! Second best. Note that following code is identical as for best predictor.
+ center_x = tempmv_x2;
+ center_y = tempmv_y2;
+ checkMedian = FALSE;
+ }
+ }
+ }
+
+ if ((ref==0) || (prevSad[pic_pix_x2] > min_mcost))
+ prevSad[pic_pix_x2] = min_mcost;
+ #if EPZSREF
+ if (input->EPZSSpatialMem)
+ #else
+ if (input->EPZSSpatialMem && ref == 0)
+ #endif
+ {
+ motion[0] = tempmv_x;
+ motion[1] = tempmv_y;
+ }
+
+ *mv_x = tempmv_x;
+ *mv_y = tempmv_y;
+ return min_mcost;
+ }
+
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * FAST Motion Estimation using EPZS
+ * AMT/HYC
+ ***********************************************************************
+ */
+ int // ==> minimum motion cost after search
+ EPZSBiPredBlockMotionSearch (pel_t ** cur_pic, // <-- original pixel values for the AxB block
+ short ref, // <-- reference picture
+ int list, // <-- reference list
+ int list_offset, // <-- offset for Mbaff
+ char ***refPic, // <-- reference array
+ short ****tmp_mv, // <-- mv array
+ int pic_pix_x, // <-- absolute x-coordinate of regarded AxB block
+ int pic_pix_y, // <-- absolute y-coordinate of regarded AxB block
+ int blocktype, //<-- block type (1-16x16 ... 7-4x4)
+ short pred_mv_x1, // <-- motion vector predictor (x) in sub-pel units
+ short pred_mv_y1, // <-- motion vector predictor (y) in sub-pel units
+ short pred_mv_x2, // <-- motion vector predictor (x) in sub-pel units
+ short pred_mv_y2, // <-- motion vector predictor (y) in sub-pel units
+ short *mv_x, // <--> in: search center (x) / out: motion vector (x) - in pel units
+ short *mv_y, // <--> in: search center (y) / out: motion vector (y) - in pel units
+ short *s_mv_x, // <--> in: search center (x) / out: motion vector (x) - in pel units
+ short *s_mv_y, // <--> in: search center (y) / out: motion vector (y) - in pel units
+ int search_range, // <-- 1-d search range in pel units
+ int min_mcost, // <-- minimum motion cost (cost for center or huge value)
+ int lambda_factor) // <-- lagrangian parameter for determining motion cost
+ {
+ short blocksize_y = input->blc_size[blocktype][1]; // vertical block size
+ short blocksize_x = input->blc_size[blocktype][0]; // horizontal block size
+ short blockshape_x = (blocksize_x >> 2); // horizontal block size in 4-pel units
+ short mb_x = pic_pix_x - img->opix_x;
+ short mb_y = pic_pix_y - img->opix_y;
+ short block_x = (mb_x >> 2);
+ short block_y = (mb_y >> 2);
+ int pred_x1 = (pic_pix_x << 2) + pred_mv_x1; // predicted position x (in sub-pel units)
+ int pred_y1 = (pic_pix_y << 2) + pred_mv_y1; // predicted position y (in sub-pel units)
+ int pred_x2 = (pic_pix_x << 2) + pred_mv_x2; // predicted position x (in sub-pel units)
+ int pred_y2 = (pic_pix_y << 2) + pred_mv_y2; // predicted position y (in sub-pel units)
+ int center2_x = pic_pix_x + *mv_x; // center position x (in pel units)
+ int center2_y = pic_pix_y + *mv_y; // center position y (in pel units)
+ int center1_x = pic_pix_x + *s_mv_x; // mvx of second pred (in pel units)
+ int center1_y = pic_pix_y + *s_mv_y; // mvy of second pred (in pel units)
+ int tempmv_x = *mv_x, tempmv_y = *mv_y;
+ int tempmv_x2 = 0, tempmv_y2 = 0;
+ int stopCriterion = medthres[blocktype];
+ int mapCenter_x = search_range - *mv_x;
+ int mapCenter_y = search_range - *mv_y;
+ int second_mcost = INT_MAX;
+ short apply_weights = (active_pps->weighted_bipred_idc != 0);
+ short offset1 = apply_weights ? list == 0
+ ? wp_offset[list_offset ][ref] [0]
+ : wp_offset[list_offset + LIST_1][0 ] [0]
+ : 0;
+ short offset2 = apply_weights ? list == 0
+ ? wp_offset[list_offset + LIST_1][ref] [0]
+ : wp_offset[list_offset ][0 ] [0]
+ : 0;
+ short invalid_refs = 0;
+ byte checkMedian = FALSE;
+ EPZSStructure *searchPatternF = searchPattern;
+ ref_pic1 = listX[ list + list_offset][ref]->imgY_11;
+ ref_pic2 = listX[(list ^ 1) + list_offset][ 0 ]->imgY_11;
+
+ img_width = listX[ list + list_offset][ref]->size_x;
+ img_height = listX[ list + list_offset][ref]->size_y;
+
+ weight1 = apply_weights ? list == 0
+ ? wbp_weight[list_offset ][ref][0 ][0]
+ : wbp_weight[list_offset + LIST_1][0 ][ref][0]
+ : 1<<luma_log_weight_denom;
+ weight2 = apply_weights ? list == 0
+ ? wbp_weight[list_offset + LIST_1][ref][0 ][0]
+ : wbp_weight[list_offset ][0 ][ref][0]
+ : 1<<luma_log_weight_denom;
+ offsetBi=(offset1 + offset2 + 1)>>1;
+
+ computeBiPredSad = apply_weights? computeBiPredSad2 : computeBiPredSad1;
+
+ //===== set function for getting reference picture lines from reference 1=====
+ if ( (center2_x > search_range) && (center2_x < img_width - search_range-blocksize_x)
+ && (center2_y > search_range) && (center2_y < img_height - search_range-blocksize_y))
+ {
+ get_ref_line2 = FastLineX;
+ }
+ else
+ {
+ get_ref_line2 = UMVLineX;
+ }
+
+ //===== set function for getting reference picture lines from reference 2=====
+ if ( (center1_x > search_range) && (center1_x < img_width - search_range-blocksize_x)
+ && (center1_y > search_range) && (center1_y < img_height - search_range-blocksize_y))
+ {
+ get_ref_line1 = FastLineX;
+ }
+ else
+ {
+ get_ref_line1 = UMVLineX;
+ }
+ // Clear EPZSMap
+ memset(EPZSMap[0],FALSE,(2*search_range+1)*(2*search_range+1));
+ // Check median candidate;
+ EPZSMap[search_range][search_range] = TRUE;
+
+ //--- initialize motion cost (cost for motion vector) and check ---
+ min_mcost = MV_COST (lambda_factor, 2, center1_x, center1_y, pred_x1, pred_y1);
+ min_mcost += MV_COST (lambda_factor, 2, center2_x, center2_y, pred_x2, pred_y2);
+
+ //--- add residual cost to motion cost ---
+ min_mcost = computeBiPredSad(cur_pic, blocksize_y, blocksize_x, blockshape_x,
+ min_mcost, INT_MAX, center1_x, center1_y, center2_x, center2_y);
+
+ //! If medthres satisfied, then terminate, otherwise generate Predictors
+ if (min_mcost > stopCriterion)
+ {
+ int prednum = 5;
+ int patternStop = 0, pointNumber = 0, checkPts;
+ int totalCheckPts = 0, motionDirection = 0;
+ int conditionEPZS;
+ int mvx, mvy, cand_x, cand_y;
+ int pos, mcost;
+ PixelPos block_a, block_b, block_c, block_d;
+
+ getLuma4x4Neighbour (img->current_mb_nr, block_x, block_y, -1, 0, &block_a);
+ getLuma4x4Neighbour (img->current_mb_nr, block_x, block_y, 0, -1, &block_b);
+ getLuma4x4Neighbour (img->current_mb_nr, block_x, block_y, blocksize_x, -1, &block_c);
+ getLuma4x4Neighbour (img->current_mb_nr, block_x, block_y, -1, -1, &block_d);
+
+ if (mb_y > 0)
+ {
+ if (mb_x < 8) // first column of 8x8 blocks
+ {
+ if (mb_y==8)
+ {
+ if (blocksize_x == MB_BLOCK_SIZE)
+ block_c.available = 0;
+ }
+ else if (mb_x+blocksize_x == 8)
+ block_c.available = 0;
+ }
+ else if (mb_x+blocksize_x == MB_BLOCK_SIZE)
+ block_c.available = 0;
+ }
+
+ stopCriterion = (11 * medthres[blocktype]) >> 3;
+
+ //! Add Spatial Predictors in predictor list.
+ //! Scheme adds zero, left, top-left, top, top-right. Note that top-left adds very little
+ //! in terms of performance and could be removed with little penalty if any.
+ invalid_refs = EPZSSpatialPredictors (block_a, block_b, block_c, block_d,
+ list, list_offset, ref, refPic[list], tmp_mv[list], predictor);
+
+ //! Check all predictors
+ for (pos = 0; pos < prednum; pos++)
+ {
+ mvx = predictor->point[pos].x;
+ mvy = predictor->point[pos].y;
+ if ((abs (mvx - *mv_x) > search_range || abs (mvy - *mv_y) > search_range) && (mvx || mvy))
+ continue;
+
+ if ((abs (mvx - *mv_x) <= search_range) && (abs (mvy - *mv_y) <= search_range))
+ {
+ if (EPZSMap[mapCenter_y + mvy][mapCenter_x + mvx] == TRUE)
+ continue;
+ else
+ EPZSMap[mapCenter_y + mvy][mapCenter_x + mvx] = TRUE;
+ }
+
+ cand_x = pic_pix_x + mvx;
+ cand_y = pic_pix_y + mvy;
+
+ //--- set motion cost (cost for motion vector) and check ---
+ mcost = MV_COST (lambda_factor, 2, center1_x, center1_y, pred_x1, pred_y1);
+ mcost += MV_COST (lambda_factor, 2, cand_x , cand_y, pred_x2, pred_y2);
+
+ if (mcost >= second_mcost) continue;
+
+ mcost = computeBiPredSad(cur_pic, blocksize_y, blocksize_x, blockshape_x,
+ mcost, second_mcost, center1_x, center1_y, cand_x, cand_y);
+
+ //--- check if motion cost is less than minimum cost ---
+ if (mcost < min_mcost)
+ {
+ tempmv_x2 = tempmv_x;
+ tempmv_y2 = tempmv_y;
+ second_mcost = min_mcost;
+ tempmv_x = mvx;
+ tempmv_y = mvy;
+ min_mcost = mcost;
+ checkMedian = TRUE;
+ }
+ //else if (mcost < second_mcost && (tempmv_x != mvx || tempmv_y != mvy))
+ else if (mcost < second_mcost)
+ {
+ tempmv_x2 = mvx;
+ tempmv_y2 = mvy;
+ second_mcost = mcost;
+ checkMedian = TRUE;
+ }
+ }
+
+ //! Refine using EPZS pattern if needed.
+ //! Note that we are using a simplistic threshold computation.
+ if (min_mcost > stopCriterion)
+ {
+ //! Adapt pattern based on different conditions.
+ if (input->EPZSPattern != 0)
+ {
+ if ((min_mcost < stopCriterion + ((3 * medthres[blocktype]) >> 1)))
+ {
+ if ((tempmv_x == 0 && tempmv_y == 0)
+ || (abs (tempmv_x - *mv_x) < 2 && abs (tempmv_y - *mv_y) < 2))
+ searchPatternF = sdiamond;
+ else
+ searchPatternF = square;
+ }
+ else if (blocktype > 5 || (ref > 0 && blocktype != 1))
+ searchPatternF = square;
+ else
+ searchPatternF = searchPattern;
+ }
+
+ totalCheckPts = searchPatternF->searchPoints;
+
+ //! center on best predictor
+ center2_x = tempmv_x;
+ center2_y = tempmv_y;
+ while (1)
+ {
+ do
+ {
+ checkPts = totalCheckPts;
+ do
+ {
+ mvx = center2_x + searchPatternF->point[pointNumber].x;
+ mvy = center2_y + searchPatternF->point[pointNumber].y;
+ cand_x = pic_pix_x + mvx;
+ cand_y = pic_pix_y + mvy;
+
+ if ((abs (mvx - *mv_x) <= search_range)
+ && (abs (mvy - *mv_y) <= search_range))
+ {
+ if (EPZSMap[mapCenter_y + mvy][mapCenter_x + mvx] != TRUE)
+ EPZSMap[mapCenter_y + mvy][mapCenter_x + mvx] = TRUE;
+ else
+ {
+ pointNumber += 1;
+ if (pointNumber >= searchPatternF->searchPoints)
+ pointNumber -= searchPatternF->searchPoints;
+ checkPts -= 1;
+ continue;
+ }
+
+ mcost = MV_COST (lambda_factor, 2, center1_x, center1_y, pred_x1, pred_y1);
+ mcost += MV_COST (lambda_factor, 2, cand_x , cand_y, pred_x2, pred_y2);
+
+ if (mcost < min_mcost)
+ {
+ mcost = computeBiPredSad(cur_pic, blocksize_y, blocksize_x, blockshape_x,
+ mcost, min_mcost, center1_x, center1_y, cand_x, cand_y);
+
+ if (mcost < min_mcost)
+ {
+ min_mcost = mcost;
+ tempmv_x = mvx;
+ tempmv_y = mvy;
+ motionDirection = pointNumber;
+ }
+ }
+ }
+ pointNumber += 1;
+ if (pointNumber >= searchPatternF->searchPoints)
+ pointNumber -= searchPatternF->searchPoints;
+ checkPts -= 1;
+ }
+ while (checkPts > 0);
+
+ if ((tempmv_x == center2_x) && (tempmv_y == center2_y))
+ {
+ totalCheckPts = searchPatternF->searchPoints;
+ patternStop = 1;
+ motionDirection = 0;
+ pointNumber = 0;
+ }
+ else
+ {
+ totalCheckPts = searchPatternF->point[motionDirection].next_points;
+ pointNumber = searchPatternF->point[motionDirection].start_nmbr;
+ center2_x = tempmv_x;
+ center2_y = tempmv_y;
+ }
+ }
+ while (patternStop != 1);
+
+ //! Check Second best predictor with EPZS pattern
+
+ conditionEPZS = (checkMedian == TRUE) && (blocktype < 5) && (min_mcost > stopCriterion) && (input->EPZSDual > 0);
+
+ if (!conditionEPZS) break;
+
+ pointNumber = 0;
+ patternStop = 0;
+ motionDirection = 0;
+
+ if ((tempmv_x == 0 && tempmv_y == 0)
+ || (tempmv_x == *mv_x && tempmv_y == *mv_y))
+ {
+ if (abs (tempmv_x - *mv_x) < 2 && abs (tempmv_y - *mv_y) < 2)
+ searchPatternF = sdiamond;
+ else
+ searchPatternF = square;
+ }
+ else
+ searchPatternF = searchPatternD;
+ totalCheckPts = searchPatternF->searchPoints;
+
+ //! Second best. Note that following code is identical as for best predictor.
+ center2_x = tempmv_x2;
+ center2_y = tempmv_y2;
+
+ checkMedian = FALSE;
+ }
+ }
+ }
+ *mv_x = tempmv_x;
+ *mv_y = tempmv_y;
+ return min_mcost;
+ }
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * Report function for EPZS Fast ME
+ * AMT/HYC
+ ***********************************************************************
+ */
+ void
+ EPZSOutputStats (FILE * stat, short stats_file)
+ {
+ if (stats_file == 1)
+ {
+ fprintf (stat, " EPZS Pattern : %s\n",c_EPZSPattern[input->EPZSPattern]);
+ fprintf (stat, " EPZS Dual Pattern : %s\n",c_EPZSDualPattern[input->EPZSDual]);
+ fprintf (stat, " EPZS Fixed Predictors : %s\n",c_EPZSFixed[input->EPZSFixed]);
+ fprintf (stat, " EPZS Temporal Predictors : %s\n",c_EPZSOther[input->EPZSTemporal]);
+ fprintf (stat, " EPZS Spatial Predictors : %s\n",c_EPZSOther[input->EPZSSpatialMem]);
+ fprintf (stat, " EPZS Thresholds (16x16) : (%d %d %d)\n",medthres[1], minthres[1], maxthres[1]);
+ }
+ else
+ {
+ fprintf (stat, " EPZS Pattern : %s\n",c_EPZSPattern[input->EPZSPattern]);
+ fprintf (stat, " EPZS Dual Pattern : %s\n",c_EPZSDualPattern[input->EPZSDual]);
+ fprintf (stat, " EPZS Fixed Predictors : %s\n",c_EPZSFixed[input->EPZSFixed]);
+ fprintf (stat, " EPZS Temporal Predictors : %s\n",c_EPZSOther[input->EPZSTemporal]);
+ fprintf (stat, " EPZS Spatial Predictors : %s\n",c_EPZSOther[input->EPZSSpatialMem]);
+ fprintf (stat, " EPZS Thresholds (16x16) : (%d %d %d)\n",medthres[1], minthres[1], maxthres[1]);
+ }
+ }
Index: llvm-test/MultiSource/Applications/JM/lencod/epzs.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/epzs.h:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/epzs.h Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,71 ----
+
+ /*!
+ ************************************************************************
+ * \file epzs.h
+ *
+ * \author
+ * Alexis Michael Tourapis <alexismt at ieee.org>
+ *
+ ************************************************************************
+ */
+
+ #ifndef _EPZS_H_
+ #define _EPZS_H_
+
+
+ #define CHECK_RANGE ((cand_x >= 0) && (cand_x < img_width - blocksize_x) &&(cand_y >= 0) && (cand_y < img_height - blocksize_y))
+
+
+ typedef struct
+ {
+ int mb_adaptive_frame_field_flag;
+ int size_x, size_y;
+
+ // Frame
+ short **** mv; //!< motion vector [list][subblock_x][subblock_y][component]
+ // Top field
+ short **** top_mv; //!< motion vector [list][subblock_x][subblock_y][component]
+ // Bottom field params
+ short **** bottom_mv; //!< motion vector [list][subblock_x][subblock_y][component]
+
+ } EPZSColocParams;
+
+ typedef struct
+ {
+ int x;
+ int y;
+ int start_nmbr;
+ int next_points;
+ }
+ SPoint;
+
+ typedef struct
+ {
+ int searchPoints;
+ SPoint *point;
+ }
+ EPZSStructure;
+
+ typedef enum
+ {
+ SDIAMOND = 0,
+ SQUARE = 1,
+ EDIAMOND = 2,
+ LDIAMOND = 3
+ } EPZSPatterns;
+
+ extern EPZSColocParams *EPZSCo_located;
+ extern int ***EPZSDistortion; //!< Array for storing SAD Values
+
+ extern int EPZSInit();
+ extern void EPZSDelete ();
+ extern void EPZSOutputStats(FILE *stat,short stats_file);
+ extern void EPZSSliceInit(EPZSColocParams* p, StorablePicture **listX[6]);
+ extern int EPZSPelBlockMotionSearch (pel_t **, short, int, int, char ***, short ****,
+ int, int, int, short, short, short*, short*, int, int, int);
+
+ extern int EPZSBiPredBlockMotionSearch (pel_t **, short, int, int, char ***, short ****,
+ int, int, int, short, short, short, short,
+ short *, short *, short *, short *, int, int, int);
+
+ #endif
Index: llvm-test/MultiSource/Applications/JM/lencod/explicit_gop.c
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/explicit_gop.c:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/explicit_gop.c Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,472 ----
+
+ /*!
+ *************************************************************************************
+ * \file explicit_gop.c
+ *
+ * \brief
+ * Code for explicit gop support and pyramidal coding.
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Alexis Michael Tourapis <alexismt at ieee.org>
+ *************************************************************************************
+ */
+
+ #include <stdlib.h>
+ #include <ctype.h>
+ #include <limits.h>
+ #include "global.h"
+ #include "contributors.h"
+ #include "explicit_gop.h"
+ #include "image.h"
+ #include "nalucommon.h"
+ #include "string.h"
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Generation of Pyramid GOP
+ ************************************************************************
+ */
+ void create_pyramid()
+ {
+ int i, j;
+ int centerB=input->successive_Bframe/2;
+ GOP_DATA tmp;
+
+ if (input->PyramidCoding == 1)
+ {
+ for (i=0;i<input->successive_Bframe;i++)
+ {
+ if (i < centerB)
+ {
+ gop_structure[i].slice_type = B_SLICE;
+ gop_structure[i].display_no = i * 2 + 1;
+ gop_structure[i].pyramid_layer = 0;
+ gop_structure[i].reference_idc = NALU_PRIORITY_HIGH;
+ gop_structure[i].slice_qp = max(0, (input->qpB + (input->PyramidLevelQPEnable ? -1: input->qpBRSOffset)));
+
+ }
+ else
+ {
+ gop_structure[i].slice_type = B_SLICE;
+ gop_structure[i].display_no = (i - centerB) * 2;
+ gop_structure[i].pyramid_layer = 1;
+ gop_structure[i].reference_idc = NALU_PRIORITY_DISPOSABLE;
+ gop_structure[i].slice_qp = input->qpB;
+ }
+ }
+ }
+ else
+ {
+ int GOPlevels = 1;
+ int Bframes = input->successive_Bframe;
+ int *curGOPLevelfrm,*curGOPLeveldist ;
+ int curlevel = GOPlevels ;
+ int prvlevelrefs = input->successive_Bframe;
+ int levelrefs = input->successive_Bframe;
+ int i;
+
+ while (((Bframes + 1 ) >> GOPlevels) > 1)
+ {
+ GOPlevels ++;
+ }
+
+ curlevel = GOPlevels ;
+
+ if (NULL == (curGOPLevelfrm = (int*)malloc(GOPlevels * sizeof(int)))) no_mem_exit("create_pyramid:curGOPLevelfrm");
+ if (NULL == (curGOPLeveldist= (int*)malloc(GOPlevels * sizeof(int)))) no_mem_exit("create_pyramid:curGOPLeveldist");
+
+ for (i=0; i <input->successive_Bframe; i++)
+ {
+ gop_structure[i].display_no = i;
+ gop_structure[i].slice_type = B_SLICE;
+ gop_structure[i].pyramid_layer = 0;
+ gop_structure[i].reference_idc = NALU_PRIORITY_DISPOSABLE;
+ gop_structure[i].slice_qp = input->qpB;
+ }
+
+ for (j = 1; j < GOPlevels; j++)
+ {
+ for (i = (1 << j) - 1; i < Bframes + 1 - (1 << j); i += (1 << j)) {
+ gop_structure[i].pyramid_layer = j;
+ gop_structure[i].reference_idc = NALU_PRIORITY_HIGH;
+ gop_structure[i].slice_qp = max(0, input->qpB + (input->PyramidLevelQPEnable ? -j: input->qpBRSOffset));
+ }
+ }
+
+ for (i = 1; i < Bframes; i++)
+ {
+ j = i;
+
+ while (j > 0 && gop_structure[j].pyramid_layer > gop_structure[j-1].pyramid_layer)
+ {
+ tmp = gop_structure[j-1];
+ gop_structure[j-1] = gop_structure[j];
+ gop_structure[j] = tmp;
+ j--;
+ }
+ }
+ }
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Initialization of GOP structure.
+ *
+ ************************************************************************
+ */
+ void init_gop_structure()
+ {
+ int max_gopsize = input->PyramidCoding != 3 ? input->successive_Bframe : input->jumpd;
+
+ gop_structure = calloc(max(10,max_gopsize), sizeof (GOP_DATA)); // +1 for reordering
+ if (NULL==gop_structure)
+ no_mem_exit("init_gop_structure: gop_structure");
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Clear GOP structure
+ ************************************************************************
+ */
+ void clear_gop_structure()
+ {
+ if (gop_structure)
+ free(gop_structure);
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Interpret GOP struct from input parameters
+ ************************************************************************
+ */
+ void interpret_gop_structure()
+ {
+
+ int nLength = strlen(input->ExplicitPyramidFormat);
+ int i =0, k, dqp, display_no;
+ int slice_read =0, order_read = 0, stored_read = 0, qp_read =0;
+ int coded_frame = 0;
+
+ if (nLength > 0)
+ {
+
+ for (i = 0; i < nLength ; i++)
+ {
+ //! First lets read slice type
+ if (slice_read == 0)
+ {
+ switch (input->ExplicitPyramidFormat[i])
+ {
+ case 'P':
+ case 'p':
+ gop_structure[coded_frame].slice_type=P_SLICE;
+ break;
+ case 'B':
+ case 'b':
+ gop_structure[coded_frame].slice_type=B_SLICE;
+ break;
+ case 'I':
+ case 'i':
+ gop_structure[coded_frame].slice_type=I_SLICE;
+ break;
+ default:
+ snprintf(errortext, ET_SIZE, "Slice Type invalid in ExplicitPyramidFormat param. Please check configuration file.");
+ error (errortext, 400);
+ break;
+ }
+ slice_read = 1;
+ }
+ else
+ {
+ //! Next is Display Order
+ if (order_read == 0)
+ {
+ if (isdigit((int)(*(input->ExplicitPyramidFormat+i))))
+ {
+ sscanf(input->ExplicitPyramidFormat+i,"%d",&display_no);
+ gop_structure[coded_frame].display_no = display_no;
+ order_read = 1;
+ if (display_no<0 || display_no>=input->jumpd)
+ {
+ snprintf(errortext, ET_SIZE, "Invalid Frame Order value. Frame position needs to be in [0,%d] range.",input->jumpd-1);
+ error (errortext, 400);
+ }
+ for (k=0;k<coded_frame;k++)
+ {
+ if (gop_structure[k].display_no == display_no)
+ {
+ snprintf(errortext, ET_SIZE, "Frame Order value %d in frame %d already used for enhancement frame %d.",display_no,coded_frame,k);
+ error (errortext, 400);
+ }
+ }
+ }
+ else
+ {
+ snprintf(errortext, ET_SIZE, "Slice Type needs to be followed by Display Order. Please check configuration file.");
+ error (errortext, 400);
+ }
+ }
+ else if (order_read == 1)
+ {
+ if (stored_read == 0 && !(isdigit((int)(*(input->ExplicitPyramidFormat+i)))))
+ {
+ switch (input->ExplicitPyramidFormat[i])
+ {
+ case 'E':
+ case 'e':
+ gop_structure[coded_frame].reference_idc = NALU_PRIORITY_DISPOSABLE;
+ break;
+ case 'R':
+ case 'r':
+ gop_structure[coded_frame].reference_idc= NALU_PRIORITY_HIGH;
+ break;
+ default:
+ snprintf(errortext, ET_SIZE, "Reference_IDC invalid in ExplicitPyramidFormat param. Please check configuration file.");
+ error (errortext, 400);
+ break;
+ }
+ stored_read = 1;
+ }
+ else if (stored_read == 1 && qp_read == 0)
+ {
+ if (isdigit((int)(*(input->ExplicitPyramidFormat+i))))
+ {
+ sscanf(input->ExplicitPyramidFormat+i,"%d",&dqp);
+
+ if (gop_structure[coded_frame].slice_type == I_SLICE)
+ gop_structure[coded_frame].slice_qp = input->qp0;
+ else if (gop_structure[coded_frame].slice_type == P_SLICE)
+ gop_structure[coded_frame].slice_qp = input->qpN;
+ else
+ gop_structure[coded_frame].slice_qp = input->qpB;
+
+ gop_structure[coded_frame].slice_qp = Clip3(-img->bitdepth_luma_qp_scale, 51,gop_structure[coded_frame].slice_qp + dqp);
+ qp_read = 1;
+ }
+ else
+ {
+ snprintf(errortext, ET_SIZE, "Reference_IDC needs to be followed by QP. Please check configuration file.");
+ error (errortext, 400);
+ }
+ }
+ else if (stored_read == 1 && qp_read == 1 && !(isdigit((int)(*(input->ExplicitPyramidFormat+i)))) && (i < nLength - 2))
+ {
+ stored_read =0;
+ qp_read=0;
+ order_read=0;
+ slice_read=0;
+ i--;
+ coded_frame ++;
+ if (coded_frame >= input->jumpd )
+ {
+ snprintf(errortext, ET_SIZE, "Total number of frames in Enhancement GOP need to be fewer or equal to FrameSkip parameter.");
+ error (errortext, 400);
+ }
+
+ }
+ }
+
+ }
+ }
+ }
+ else
+ {
+ snprintf(errortext, ET_SIZE, "ExplicitPyramidFormat is empty. Please check configuration file.");
+ error (errortext, 400);
+ }
+
+ input->successive_Bframe = coded_frame + 1;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Encode Enhancement Layer.
+ ************************************************************************
+ */
+ void encode_enhancement_layer()
+ {
+ int previous_ref_idc = 1;
+
+ if ((input->successive_Bframe != 0) && (IMG_NUMBER > 0)) // B-frame(s) to encode
+ {
+ img->type = B_SLICE; // set image type to B-frame
+
+ if (input->NumFramesInELSubSeq == 0)
+ img->layer = 0;
+ else
+ img->layer = 1;
+
+ if (input->BRefPictures != 1 && input->PyramidCoding==0)
+ {
+ img->frame_num++; //increment frame_num once for B-frames
+ img->frame_num %= (1 << (log2_max_frame_num_minus4 + 4));
+ }
+ img->nal_reference_idc = 0;
+
+ //if (input->PyramidCoding == 3 || input->PyramidCoding == 1)
+ if (input->PyramidCoding)
+ {
+ for(img->b_frame_to_code=1; img->b_frame_to_code<=input->successive_Bframe; img->b_frame_to_code++)
+ {
+
+ img->nal_reference_idc = 0;
+
+ img->type = gop_structure[img->b_frame_to_code - 1].slice_type;
+
+ if (previous_ref_idc == 1)
+ {
+ img->frame_num++; //increment frame_num for each stored B slice
+ img->frame_num %= (1 << (log2_max_frame_num_minus4 + 4));
+ }
+
+ if (gop_structure[img->b_frame_to_code - 1].reference_idc== NALU_PRIORITY_HIGH )
+ {
+ img->nal_reference_idc = 1;
+ previous_ref_idc = 1;
+ }
+ else
+ previous_ref_idc = 0;
+
+ img->b_interval =
+ ((double) (input->jumpd + 1) / (input->successive_Bframe + 1.0) );
+
+ if (input->PyramidCoding == 3)
+ img->b_interval = 1.0;
+
+ if(input->intra_period && input->idr_enable)
+ img->toppoc = 2*(((IMG_NUMBER%input->intra_period)-1)*(input->jumpd+1) + (int)(img->b_interval * (double)(1 + gop_structure[img->b_frame_to_code - 1].display_no)));
+ else
+ img->toppoc = 2*((IMG_NUMBER-1)*(input->jumpd + 1) + (int)(img->b_interval * (double)(1 + gop_structure[img->b_frame_to_code -1].display_no)));
+
+ if (img->b_frame_to_code == 1)
+ img->delta_pic_order_cnt[0] = img->toppoc - 2*(start_tr_in_this_IGOP + (IMG_NUMBER)*((input->jumpd+1)));
+ else
+ img->delta_pic_order_cnt[0] = img->toppoc - 2*(start_tr_in_this_IGOP + (IMG_NUMBER-1)*((input->jumpd+1)) + (int) (2.0 *img->b_interval * (double) (1+ gop_structure[img->b_frame_to_code - 2].display_no)));
+
+ if ((input->PicInterlace==FRAME_CODING)&&(input->MbInterlace==FRAME_CODING))
+ img->bottompoc = img->toppoc; //progressive
+ else
+ img->bottompoc = img->toppoc+1;
+
+ img->framepoc = min (img->toppoc, img->bottompoc);
+
+ img->delta_pic_order_cnt[1]= 0; // POC200301
+
+ encode_one_frame(); // encode one B-frame
+ if (input->ReportFrameStats)
+ report_frame_statistic();
+
+ if (gop_structure[img->b_frame_to_code - 1].reference_idc== NALU_PRIORITY_HIGH && img->b_frame_to_code==input->successive_Bframe)
+ {
+ img->frame_num++; //increment frame_num for each stored B slice
+ img->frame_num %= (1 << (log2_max_frame_num_minus4 + 4));
+ }
+ }
+ img->b_frame_to_code = 0;
+ }
+ else
+ {
+ for(img->b_frame_to_code=1; img->b_frame_to_code<=input->successive_Bframe; img->b_frame_to_code++)
+ {
+
+ img->nal_reference_idc = 0;
+ if (input->BRefPictures == 1 )
+ {
+ img->nal_reference_idc = 1;
+ img->frame_num++; //increment frame_num once for B-frames
+ img->frame_num %= (1 << (log2_max_frame_num_minus4 + 4));
+ }
+
+ img->b_interval =
+ ((double) (input->jumpd + 1) / (input->successive_Bframe + 1.0) );
+
+ if (input->PyramidCoding == 3)
+ img->b_interval = 1.0;
+
+ if(input->intra_period && input->idr_enable)
+ img->toppoc = 2*(((IMG_NUMBER% input->intra_period)-1)*(input->jumpd+1) + (int) (img->b_interval * (double)img->b_frame_to_code));
+ else
+ img->toppoc = 2*((IMG_NUMBER-1)*(input->jumpd+1) + (int) (img->b_interval * (double)img->b_frame_to_code));
+
+ if ((input->PicInterlace==FRAME_CODING)&&(input->MbInterlace==FRAME_CODING))
+ img->bottompoc = img->toppoc; //progressive
+ else
+ img->bottompoc = img->toppoc+1;
+
+ img->framepoc = min (img->toppoc, img->bottompoc);
+
+ //the following is sent in the slice header
+ if (input->BRefPictures != 1)
+ {
+ img->delta_pic_order_cnt[0]= 2*(img->b_frame_to_code-1);
+ }
+ else
+ {
+ img->delta_pic_order_cnt[0]= -2;
+ }
+
+ img->delta_pic_order_cnt[1]= 0; // POC200301
+
+ encode_one_frame(); // encode one B-frame
+
+ if (input->BRefPictures == 1 && img->b_frame_to_code==input->successive_Bframe)
+ {
+ img->frame_num++; //increment frame_num for each stored B slice
+ img->frame_num %= (1 << (log2_max_frame_num_minus4 + 4));
+ }
+
+ if (input->ReportFrameStats)
+ report_frame_statistic();
+ }
+ }
+ }
+ img->b_frame_to_code = 0;
+ }
+
+
+ void poc_based_ref_management(int current_pic_num)
+ {
+ unsigned i, pic_num = 0;
+
+ int min_poc=INT_MAX;
+ DecRefPicMarking_t *tmp_drpm,*tmp_drpm2;
+
+ if (img->dec_ref_pic_marking_buffer!=NULL)
+ return;
+
+ if ((dpb.ref_frames_in_buffer+dpb.ltref_frames_in_buffer)==0)
+ return;
+
+ for (i=0; i<dpb.used_size;i++)
+ {
+ if (dpb.fs[i]->is_reference && (!(dpb.fs[i]->is_long_term)) && dpb.fs[i]->poc < min_poc)
+ {
+ min_poc = dpb.fs[i]->frame->poc ;
+ pic_num = dpb.fs[i]->frame->pic_num;
+ }
+ }
+
+ if (NULL==(tmp_drpm=(DecRefPicMarking_t*)calloc (1,sizeof (DecRefPicMarking_t)))) no_mem_exit("poc_based_ref_management: tmp_drpm");
+ tmp_drpm->Next=NULL;
+
+ tmp_drpm->memory_management_control_operation = 0;
+
+ if (NULL==(tmp_drpm2=(DecRefPicMarking_t*)calloc (1,sizeof (DecRefPicMarking_t)))) no_mem_exit("poc_based_ref_management: tmp_drpm2");
+ tmp_drpm2->Next=tmp_drpm;
+
+ tmp_drpm2->memory_management_control_operation = 1;
+ tmp_drpm2->difference_of_pic_nums_minus1 = current_pic_num - pic_num - 1;
+ img->dec_ref_pic_marking_buffer = tmp_drpm2;
+
+ }
Index: llvm-test/MultiSource/Applications/JM/lencod/explicit_gop.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/explicit_gop.h:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/explicit_gop.h Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,25 ----
+
+ /*!
+ *************************************************************************************
+ * \file explicit_gop.h
+ *
+ * \brief
+ * Functions for explicit gop and pyramid support
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Alexis Michael Tourapis <alexismt at ieee.org>
+ *************************************************************************************
+ */
+
+ #ifndef _EXPLICIT_GOP_H_
+ #define _EXPLICIT_GOP_H_
+
+ // GOP Pyramid
+ void init_gop_structure();
+ void interpret_gop_structure();
+ void create_pyramid();
+ void clear_gop_structure();
+ void encode_enhancement_layer();
+
+ #endif
Index: llvm-test/MultiSource/Applications/JM/lencod/fast_me.c
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/fast_me.c:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/fast_me.c Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,914 ----
+
+ /*!
+ ************************************************************************
+ *
+ * \file fast_me.c
+ *
+ * \brief
+ * Fast integer pel motion estimation and fractional pel motion estimation
+ * algorithms are described in this file.
+ * 1. get_mem_FME() and free_mem_FME() are functions for allocation and release
+ * of memories about motion estimation
+ * 2. FME_BlockMotionSearch() is the function for fast integer pel motion
+ * estimation and fractional pel motion estimation
+ * 3. DefineThreshold() defined thresholds for early termination
+ * \author
+ * Main contributors: (see contributors.h for copyright, address and affiliation details)
+ * - Zhibo Chen <chenzhibo at tsinghua.org.cn>
+ * - JianFeng Xu <fenax at video.mdc.tsinghua.edu.cn>
+ * - Wenfang Fu <fwf at video.mdc.tsinghua.edu.cn>
+ * \date
+ * 2003.8
+ ************************************************************************
+ */
+
+ #include <stdlib.h>
+ #include <string.h>
+
+ #include "global.h"
+
+ #include "memalloc.h"
+ #include "fast_me.h"
+ #include "refbuf.h"
+
+ #define Q_BITS 15
+
+ extern unsigned int* byte_abs;
+ extern int* mvbits;
+ extern short* spiral_search_x;
+ extern short* spiral_search_y;
+
+
+ static pel_t *(*get_line) (pel_t**, int, int, int, int);
+
+ static const int quant_coef[6][4][4] = {
+ {{13107, 8066,13107, 8066},{ 8066, 5243, 8066, 5243},{13107, 8066,13107, 8066},{ 8066, 5243, 8066, 5243}},
+ {{11916, 7490,11916, 7490},{ 7490, 4660, 7490, 4660},{11916, 7490,11916, 7490},{ 7490, 4660, 7490, 4660}},
+ {{10082, 6554,10082, 6554},{ 6554, 4194, 6554, 4194},{10082, 6554,10082, 6554},{ 6554, 4194, 6554, 4194}},
+ {{ 9362, 5825, 9362, 5825},{ 5825, 3647, 5825, 3647},{ 9362, 5825, 9362, 5825},{ 5825, 3647, 5825, 3647}},
+ {{ 8192, 5243, 8192, 5243},{ 5243, 3355, 5243, 3355},{ 8192, 5243, 8192, 5243},{ 5243, 3355, 5243, 3355}},
+ {{ 7282, 4559, 7282, 4559},{ 4559, 2893, 4559, 2893},{ 7282, 4559, 7282, 4559},{ 4559, 2893, 4559, 2893}}
+ };
+
+
+ void DefineThreshold()
+ {
+ AlphaSec[1] = 0.01f;
+ AlphaSec[2] = 0.01f;
+ AlphaSec[3] = 0.01f;
+ AlphaSec[4] = 0.02f;
+ AlphaSec[5] = 0.03f;
+ AlphaSec[6] = 0.03f;
+ AlphaSec[7] = 0.04f;
+
+ AlphaThird[1] = 0.06f;
+ AlphaThird[2] = 0.07f;
+ AlphaThird[3] = 0.07f;
+ AlphaThird[4] = 0.08f;
+ AlphaThird[5] = 0.12f;
+ AlphaThird[6] = 0.11f;
+ AlphaThird[7] = 0.15f;
+
+ DefineThresholdMB();
+ return;
+ }
+
+ void DefineThresholdMB()
+ {
+ int gb_qp_per = (input->qpN-MIN_QP)/6;
+ int gb_qp_rem = (input->qpN-MIN_QP)%6;
+
+ int gb_q_bits = Q_BITS+gb_qp_per;
+ int gb_qp_const,Thresh4x4;
+
+ float Quantize_step;
+
+ gb_qp_const=(1<<gb_q_bits)/6;
+
+ Thresh4x4 = ((1<<gb_q_bits) - gb_qp_const)/quant_coef[gb_qp_rem][0][0];
+ Quantize_step = Thresh4x4/(4*5.61f);
+ Bsize[7]=(16*16)*Quantize_step;
+
+ Bsize[6]=Bsize[7]*4;
+ Bsize[5]=Bsize[7]*4;
+ Bsize[4]=Bsize[5]*4;
+ Bsize[3]=Bsize[4]*4;
+ Bsize[2]=Bsize[4]*4;
+ Bsize[1]=Bsize[2]*4;
+ }
+
+
+ int get_mem_FME()
+ {
+ int memory_size = 0;
+ if (NULL==(flag_intra = calloc ((img->width>>4)+1,sizeof(byte)))) no_mem_exit("get_mem_FME: flag_intra"); //fwf 20050330
+
+ memory_size += get_mem2D(&McostState, 2*input->search_range+1, 2*input->search_range+1);
+ memory_size += get_mem4Dint(&(fastme_ref_cost), img->max_num_references, 9, 4, 4);
+ memory_size += get_mem3Dint(&(fastme_l0_cost), 9, img->height/4, img->width/4);
+ memory_size += get_mem3Dint(&(fastme_l1_cost), 9, img->height/4, img->width/4);
+ memory_size += get_mem2D(&SearchState,7,7);
+
+ return memory_size;
+ }
+
+
+ void free_mem_FME()
+ {
+ free_mem2D(McostState);
+ free_mem4Dint(fastme_ref_cost, img->max_num_references, 9);
+ free_mem3Dint(fastme_l0_cost, 9);
+ free_mem3Dint(fastme_l1_cost, 9);
+ free_mem2D(SearchState);
+
+ free (flag_intra);
+ }
+
+
+ int PartCalMad(pel_t *ref_pic,pel_t** orig_pic,pel_t *(*get_ref_line)(int, pel_t*, int, int, int, int), int blocksize_y,int blocksize_x, int blocksize_x4,int mcost,int min_mcost,int cand_x,int cand_y)
+ {
+ int y,x4;
+ int height=((img->MbaffFrameFlag)&&(img->mb_data[img->current_mb_nr].mb_field))?img->height/2:img->height;
+ pel_t *orig_line, *ref_line;
+ for (y=0; y<blocksize_y; y++)
+ {
+ ref_line = get_ref_line (blocksize_x, ref_pic, cand_y+y, cand_x, height, img->width);//2004.3.3
+ orig_line = orig_pic [y];
+
+ for (x4=0; x4<blocksize_x4; x4++)
+ {
+ mcost += byte_abs[ *orig_line++ - *ref_line++ ];
+ mcost += byte_abs[ *orig_line++ - *ref_line++ ];
+ mcost += byte_abs[ *orig_line++ - *ref_line++ ];
+ mcost += byte_abs[ *orig_line++ - *ref_line++ ];
+ }
+ if (mcost >= min_mcost)
+ {
+ break;
+ }
+ }
+ return mcost;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * FastIntegerPelBlockMotionSearch: fast pixel block motion search
+ * this algrithm is called UMHexagonS(see JVT-D016),which includes
+ * four steps with different kinds of search patterns
+ * \par Input:
+ * pel_t** orig_pic, // <-- original picture
+ * int ref, // <-- reference frame (0... or -1 (backward))
+ * int pic_pix_x, // <-- absolute x-coordinate of regarded AxB block
+ * int pic_pix_y, // <-- absolute y-coordinate of regarded AxB block
+ * int blocktype, // <-- block type (1-16x16 ... 7-4x4)
+ * int pred_mv_x, // <-- motion vector predictor (x) in sub-pel units
+ * int pred_mv_y, // <-- motion vector predictor (y) in sub-pel units
+ * int* mv_x, // --> motion vector (x) - in pel units
+ * int* mv_y, // --> motion vector (y) - in pel units
+ * int search_range, // <-- 1-d search range in pel units
+ * int min_mcost, // <-- minimum motion cost (cost for center or huge value)
+ * int lambda_factor // <-- lagrangian parameter for determining motion cost
+ * \par
+ * Three macro definitions defined in this program:
+ * 1. EARLY_TERMINATION: early termination algrithm, refer to JVT-D016.doc
+ * 2. SEARCH_ONE_PIXEL: search one pixel in search range
+ * 3. SEARCH_ONE_PIXEL1(value_iAbort): search one pixel in search range,
+ * but give a parameter to show if mincost refeshed
+ * \author
+ * Main contributors: (see contributors.h for copyright, address and affiliation details)
+ * - Zhibo Chen <chenzhibo at tsinghua.org.cn>
+ * - JianFeng Xu <fenax at video.mdc.tsinghua.edu.cn>
+ * \date :
+ * 2003.8
+ ************************************************************************
+ */
+ int // ==> minimum motion cost after search
+ FastIntegerPelBlockMotionSearch (pel_t** orig_pic, // <-- not used
+ short ref, // <-- reference frame (0... or -1 (backward))
+ int list,
+ int pic_pix_x, // <-- absolute x-coordinate of regarded AxB block
+ int pic_pix_y, // <-- absolute y-coordinate of regarded AxB block
+ int blocktype, // <-- block type (1-16x16 ... 7-4x4)
+ short pred_mv_x, // <-- motion vector predictor (x) in sub-pel units
+ short pred_mv_y, // <-- motion vector predictor (y) in sub-pel units
+ short* mv_x, // --> motion vector (x) - in pel units
+ short* mv_y, // --> motion vector (y) - in pel units
+ int search_range, // <-- 1-d search range in pel units
+ int min_mcost, // <-- minimum motion cost (cost for center or huge value)
+ int lambda_factor) // <-- lagrangian parameter for determining motion cost
+ {
+ static int Diamond_x[4] = {-1, 0, 1, 0};
+ static int Diamond_y[4] = {0, 1, 0, -1};
+ static int Hexagon_x[6] = {2, 1, -1, -2, -1, 1};
+ static int Hexagon_y[6] = {0, -2, -2, 0, 2, 2};
+ static int Big_Hexagon_x[16] = {0,-2, -4,-4,-4, -4, -4, -2, 0, 2, 4, 4, 4, 4, 4, 2};
+ static int Big_Hexagon_y[16] = {4, 3, 2, 1, 0, -1, -2, -3, -4, -3, -2, -1, 0, 1, 2, 3};
+
+ int pos, cand_x, cand_y, mcost;
+ pel_t *(*get_ref_line)(int, pel_t*, int, int, int, int);
+ int list_offset = ((img->MbaffFrameFlag)&&(img->mb_data[img->current_mb_nr].mb_field))? img->current_mb_nr%2 ? 4 : 2 : 0;
+
+ int mvshift = 2; // motion vector shift for getting sub-pel units
+ int blocksize_y = input->blc_size[blocktype][1]; // vertical block size
+ int blocksize_x = input->blc_size[blocktype][0]; // horizontal block size
+ int blocksize_x4 = blocksize_x >> 2; // horizontal block size in 4-pel units
+ int pred_x = (pic_pix_x << mvshift) + pred_mv_x; // predicted position x (in sub-pel units)
+ int pred_y = (pic_pix_y << mvshift) + pred_mv_y; // predicted position y (in sub-pel units)
+ int center_x = pic_pix_x + *mv_x; // center position x (in pel units)
+ int center_y = pic_pix_y + *mv_y; // center position y (in pel units)
+ int best_x = 0, best_y = 0;
+ int search_step,iYMinNow, iXMinNow;
+ int i,m;
+ int iAbort;
+ float betaSec,betaThird;
+ int height=((img->MbaffFrameFlag)&&(img->mb_data[img->current_mb_nr].mb_field))?img->height/2:img->height;
+
+ //===== Use weighted Reference for ME ====
+ pel_t* ref_pic;
+ int apply_weights = ( (active_pps->weighted_pred_flag && (img->type == P_SLICE || img->type == SP_SLICE)) ||
+ (active_pps->weighted_bipred_idc && (img->type == B_SLICE)));
+
+ if (apply_weights && input->UseWeightedReferenceME)
+ ref_pic = listX[list+list_offset][ref]->imgY_11_w;
+ else
+ ref_pic = listX[list+list_offset][ref]->imgY_11;
+
+
+ //===== set function for getting reference picture lines =====
+ if ((center_x > search_range) && (center_x < img->width -1-search_range-blocksize_x) &&
+ (center_y > search_range) && (center_y < height-1-search_range-blocksize_y) )
+ {
+ get_ref_line = FastLineX;
+ }
+ else
+ {
+ get_ref_line = UMVLineX;
+ }
+
+ //////allocate memory for search state//////////////////////////
+ memset(McostState[0],0,(2*input->search_range+1)*(2*input->search_range+1));
+
+ ///////Threshold defined for early termination///////////////////
+ if(list==0 && ref>0)
+ {
+ if(pred_SAD_ref!=0)
+ {
+ betaSec = Bsize[blocktype]/(pred_SAD_ref*pred_SAD_ref)-AlphaSec[blocktype];
+ betaThird = Bsize[blocktype]/(pred_SAD_ref*pred_SAD_ref)-AlphaThird[blocktype];
+ }
+ else
+ {
+ betaSec = 0;
+ betaThird = 0;
+ }
+ }
+ else
+ {
+ if(blocktype==1)
+ {
+ if(pred_SAD_space !=0)
+ {
+ betaSec = Bsize[blocktype]/(pred_SAD_space*pred_SAD_space)-AlphaSec[blocktype];
+ betaThird = Bsize[blocktype]/(pred_SAD_space*pred_SAD_space)-AlphaThird[blocktype];
+ }
+ else
+ {
+ betaSec = 0;
+ betaThird = 0;
+ }
+ }
+ else
+ {
+ if(pred_SAD_uplayer !=0)
+ {
+ betaSec = Bsize[blocktype]/(pred_SAD_uplayer*pred_SAD_uplayer)-AlphaSec[blocktype];
+ betaThird = Bsize[blocktype]/(pred_SAD_uplayer*pred_SAD_uplayer)-AlphaThird[blocktype];
+ }
+ else
+ {
+ betaSec = 0;
+ betaThird = 0;
+ }
+ }
+ }
+ /*****************************/
+
+ //check the center median predictor
+ cand_x = center_x ;
+ cand_y = center_y ;
+ mcost = MV_COST (lambda_factor, mvshift, cand_x, cand_y, pred_x, pred_y);
+ mcost = PartCalMad(ref_pic, orig_pic, get_ref_line,blocksize_y,blocksize_x,blocksize_x4,mcost,min_mcost,cand_x,cand_y);
+ McostState[search_range][search_range] = 1;
+ if (mcost < min_mcost)
+ {
+ min_mcost = mcost;
+ best_x = cand_x;
+ best_y = cand_y;
+ }
+
+ iXMinNow = best_x;
+ iYMinNow = best_y;
+ for (m = 0; m < 4; m++)
+ {
+ cand_x = iXMinNow + Diamond_x[m];
+ cand_y = iYMinNow + Diamond_y[m];
+ SEARCH_ONE_PIXEL
+ }
+
+ if(center_x != pic_pix_x || center_y != pic_pix_y)
+ {
+ cand_x = pic_pix_x ;
+ cand_y = pic_pix_y ;
+ SEARCH_ONE_PIXEL
+
+ iXMinNow = best_x;
+ iYMinNow = best_y;
+ for (m = 0; m < 4; m++)
+ {
+ cand_x = iXMinNow + Diamond_x[m];
+ cand_y = iYMinNow + Diamond_y[m];
+ SEARCH_ONE_PIXEL
+ }
+ }
+
+ if(blocktype>1)
+ {
+ cand_x = pic_pix_x + (pred_MV_uplayer[0]/4);
+ cand_y = pic_pix_y + (pred_MV_uplayer[1]/4);
+ SEARCH_ONE_PIXEL
+ if ((min_mcost-pred_SAD_uplayer)<pred_SAD_uplayer*betaThird)
+ goto third_step;
+ else if((min_mcost-pred_SAD_uplayer)<pred_SAD_uplayer*betaSec)
+ goto sec_step;
+ }
+
+
+ //prediciton using mV of last ref moiton vector
+ if (img->field_picture)
+ {
+ if ((list==0 && ref>1) || (img->type == B_SLICE && list == 0 && (ref==0 ||ref==1 ) ))
+ //Notes: for interlace case, ref==1 should be added
+ {
+ cand_x = pic_pix_x + pred_MV_ref[0]/4;
+ cand_y = pic_pix_y + pred_MV_ref[1]/4;
+ SEARCH_ONE_PIXEL
+ }
+ }
+ else
+ {
+ if ((list==0 && ref > 0) || (img->type == B_SLICE && list == 0 && ref==0 ))
+ //Notes: for interlace case, ref==1 should be added
+ {
+ cand_x = pic_pix_x + pred_MV_ref[0]/4;
+ cand_y = pic_pix_y + pred_MV_ref[1]/4;
+ SEARCH_ONE_PIXEL
+ }
+ }
+ //small local search
+ iXMinNow = best_x;
+ iYMinNow = best_y;
+ for (m = 0; m < 4; m++)
+ {
+ cand_x = iXMinNow + Diamond_x[m];
+ cand_y = iYMinNow + Diamond_y[m];
+ SEARCH_ONE_PIXEL
+ }
+
+ //early termination alogrithm, refer to JVT-G016
+ EARLY_TERMINATION
+
+ if(blocktype>6)
+ goto sec_step;
+ else
+ goto first_step;
+
+ first_step: //Unsymmetrical-cross search
+ iXMinNow = best_x;
+ iYMinNow = best_y;
+
+ for(i=1;i<=search_range/2;i++)
+ {
+ search_step = 2*i - 1;
+ cand_x = iXMinNow + search_step;
+ cand_y = iYMinNow ;
+ SEARCH_ONE_PIXEL
+ cand_x = iXMinNow - search_step;
+ cand_y = iYMinNow ;
+ SEARCH_ONE_PIXEL
+ }
+
+ for(i=1;i<=search_range/4;i++)
+ {
+ search_step = 2*i - 1;
+ cand_x = iXMinNow ;
+ cand_y = iYMinNow + search_step;
+ SEARCH_ONE_PIXEL
+ cand_x = iXMinNow ;
+ cand_y = iYMinNow - search_step;
+ SEARCH_ONE_PIXEL
+ }
+ //early termination alogrithm, refer to JVT-G016
+ EARLY_TERMINATION
+
+ iXMinNow = best_x;
+ iYMinNow = best_y;
+ // Uneven Multi-Hexagon-grid Search
+ for(pos=1;pos<25;pos++)
+ {
+ cand_x = iXMinNow + spiral_search_x[pos];
+ cand_y = iYMinNow + spiral_search_y[pos];
+ SEARCH_ONE_PIXEL
+ }
+
+ //early termination alogrithm, refer to JVT-G016
+
+ for(i=1;i<=search_range/4; i++)
+ {
+ for (m = 0; m < 16; m++)
+ {
+ cand_x = iXMinNow + Big_Hexagon_x[m]*i;
+ cand_y = iYMinNow + Big_Hexagon_y[m]*i;
+ SEARCH_ONE_PIXEL1(1)
+ }
+ }
+ sec_step: //Extended Hexagon-based Search
+ iXMinNow = best_x;
+ iYMinNow = best_y;
+ for(i=0;i<search_range;i++)
+ {
+ iAbort = 1;
+ for (m = 0; m < 6; m++)
+ {
+ cand_x = iXMinNow + Hexagon_x[m];
+ cand_y = iYMinNow + Hexagon_y[m];
+ SEARCH_ONE_PIXEL1(0)
+ }
+ if(iAbort)
+ break;
+ iXMinNow = best_x;
+ iYMinNow = best_y;
+ }
+ third_step: // the third step with a small search pattern
+ iXMinNow = best_x;
+ iYMinNow = best_y;
+ for(i=0;i<search_range;i++)
+ {
+ iAbort = 1;
+ for (m = 0; m < 4; m++)
+ {
+ cand_x = iXMinNow + Diamond_x[m];
+ cand_y = iYMinNow + Diamond_y[m];
+ SEARCH_ONE_PIXEL1(0)
+ }
+ if(iAbort)
+ break;
+ iXMinNow = best_x;
+ iYMinNow = best_y;
+ }
+
+ *mv_x = best_x - pic_pix_x;
+ *mv_y = best_y - pic_pix_y;
+ return min_mcost;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Functions for fast fractional pel motion estimation.
+ * 1. int AddUpSADQuarter() returns SADT of a fractiona pel MV
+ * 2. int FastSubPelBlockMotionSearch () proceed the fast fractional pel ME
+ * \authors
+ * Zhibo Chen
+ * Dept.of EE, Tsinghua Univ.
+ * \date
+ * 2003.4
+ ************************************************************************
+ */
+ int AddUpSADQuarter(int pic_pix_x,int pic_pix_y,int blocksize_x,int blocksize_y,
+ int cand_mv_x,int cand_mv_y, StorablePicture *ref_picture, pel_t** orig_pic,
+ int Mvmcost, int min_mcost,int useABT, int blocktype)
+ {
+
+ int j, i, k;
+ int diff[16], *d;
+ int mcost = Mvmcost;
+ int c_diff[MB_PIXELS];
+ int y_offset, ypels =(128 - 64 * (blocktype == 3));
+ int ry0, ry4, ry8, ry12;
+ int y0, y1, y2, y3;
+ int x0, x1, x2, x3;
+ int abort_search, rx0;
+ int img_width = ((ref_picture->size_x + 2*IMG_PAD_SIZE - 1)<<2);
+ int img_height = ((ref_picture->size_y + 2*IMG_PAD_SIZE - 1)<<2);
+
+ //===== Use weighted Reference for ME ====
+ pel_t **ref_pic;
+ pel_t *ref_line;
+ pel_t *orig_line;
+ int apply_weights = ( (active_pps->weighted_pred_flag && (img->type == P_SLICE || img->type == SP_SLICE)) ||
+ (active_pps->weighted_bipred_idc && (img->type == B_SLICE)));
+
+ if (apply_weights && input->UseWeightedReferenceME)
+ {
+ ref_pic = ref_picture->imgY_ups_w;
+ }
+ else
+ ref_pic = ref_picture->imgY_ups;
+ ///////////////////////////////////////////
+
+
+ for (y0=0, abort_search=0; y0<blocksize_y && !abort_search; y0+=4)
+ {
+ y_offset = (y0>7)*ypels;
+ ry0 = (y0<<2) + cand_mv_y;
+ ry4 = ry0 + 4;
+ ry8 = ry4 + 4;
+ ry12 = ry8 + 4;
+ y1 = y0 + 1;
+ y2 = y1 + 1;
+ y3 = y2 + 1;
+
+
+ for (x0=0; x0<blocksize_x; x0+=4)
+ {
+ rx0 = (x0<<2) + cand_mv_x;
+ x1 = x0 + 1;
+ x2 = x1 + 1;
+ x3 = x2 + 1;
+ d = diff;
+
+ orig_line = orig_pic [y0];
+ ref_line = get_line (ref_pic, ry0, rx0, img_height, img_width);
+ *d++ = orig_line[x0] - *(ref_line );
+ *d++ = orig_line[x1] - *(ref_line + 4 );
+ *d++ = orig_line[x2] - *(ref_line + 8 );
+ *d++ = orig_line[x3] - *(ref_line + 12);
+
+ orig_line = orig_pic [y1];
+ ref_line = get_line (ref_pic, ry4, rx0, img_height, img_width);
+ *d++ = orig_line[x0] - *(ref_line );
+ *d++ = orig_line[x1] - *(ref_line + 4 );
+ *d++ = orig_line[x2] - *(ref_line + 8 );
+ *d++ = orig_line[x3] - *(ref_line + 12);
+
+ orig_line = orig_pic [y2];
+ ref_line = get_line (ref_pic, ry8, rx0, img_height, img_width);
+ *d++ = orig_line[x0] - *(ref_line );
+ *d++ = orig_line[x1] - *(ref_line += 4 );
+ *d++ = orig_line[x2] - *(ref_line += 4 );
+ *d++ = orig_line[x3] - *(ref_line += 4);
+
+ orig_line = orig_pic [y3];
+ ref_line = get_line (ref_pic, ry12, rx0, img_height, img_width);
+ *d++ = orig_line[x0] - *(ref_line );
+ *d++ = orig_line[x1] - *(ref_line += 4);
+ *d++ = orig_line[x2] - *(ref_line += 4);
+ *d = orig_line[x3] - *(ref_line += 4);
+
+ if (!useABT)
+ {
+ if ((mcost += SATD (diff, input->hadamard)) > min_mcost)
+ {
+ abort_search = 1;
+ break;
+ }
+ }
+ else // copy diff to curr_diff for ABT SATD calculation
+ {
+ i = (x0&0x7) + (x0>7) * 64 + y_offset;
+ for(k=0, j=y0; j<BLOCK_SIZE + y0; j++, k+=BLOCK_SIZE)
+ memcpy(&(c_diff[i + ((j&0x7)<<3)]), &diff[k], BLOCK_SIZE*sizeof(int));
+ }
+ }
+ }
+
+ if(useABT)
+ {
+ mcost += find_SATD (c_diff, blocktype);
+ }
+
+ return mcost;
+ }
+
+
+ int // ==> minimum motion cost after search
+ FastSubPelBlockMotionSearch (pel_t** orig_pic, // <-- original pixel values for the AxB block
+ short ref, // <-- reference frame (0... or -1 (backward))
+ int list,
+ int pic_pix_x, // <-- absolute x-coordinate of regarded AxB block
+ int pic_pix_y, // <-- absolute y-coordinate of regarded AxB block
+ int blocktype, // <-- block type (1-16x16 ... 7-4x4)
+ short pred_mv_x, // <-- motion vector predictor (x) in sub-pel units
+ short pred_mv_y, // <-- motion vector predictor (y) in sub-pel units
+ short* mv_x, // <--> in: search center (x) / out: motion vector (x) - in pel units
+ short* mv_y, // <--> in: search center (y) / out: motion vector (y) - in pel units
+ int search_pos2, // <-- search positions for half-pel search (default: 9)
+ int search_pos4, // <-- search positions for quarter-pel search (default: 9)
+ int min_mcost, // <-- minimum motion cost (cost for center or huge value)
+ int lambda_factor,
+ int useABT) // <-- lagrangian parameter for determining motion cost
+ {
+ static int Diamond_x[4] = {-1, 0, 1, 0};
+ static int Diamond_y[4] = {0, 1, 0, -1};
+ int mcost;
+ int cand_mv_x, cand_mv_y;
+
+ int list_offset = ((img->MbaffFrameFlag)&&(img->mb_data[img->current_mb_nr].mb_field))? img->current_mb_nr%2 ? 4 : 2 : 0;
+ StorablePicture *ref_picture = listX[list+list_offset][ref];
+
+ int mv_shift = 0;
+ int blocksize_x = input->blc_size[blocktype][0];
+ int blocksize_y = input->blc_size[blocktype][1];
+ int pic4_pix_x = ((pic_pix_x + IMG_PAD_SIZE)<< 2);
+ int pic4_pix_y = ((pic_pix_y + IMG_PAD_SIZE)<< 2);
+ short max_pos_x4 = ((ref_picture->size_x - blocksize_x + 2*IMG_PAD_SIZE)<<2);
+ short max_pos_y4 = ((ref_picture->size_y - blocksize_y + 2*IMG_PAD_SIZE)<<2);
+
+ int search_range_dynamic,iXMinNow,iYMinNow,i;
+ int m,currmv_x = 0,currmv_y = 0;
+ int pred_frac_mv_x,pred_frac_mv_y,abort_search;
+ int mv_cost;
+
+ int pred_frac_up_mv_x, pred_frac_up_mv_y;
+
+ if ((pic4_pix_x + *mv_x > 1) && (pic4_pix_x + *mv_x < max_pos_x4 - 1) &&
+ (pic4_pix_y + *mv_y > 1) && (pic4_pix_y + *mv_y < max_pos_y4 - 1) )
+ {
+ get_line = FastLine4X;
+ }
+ else
+ {
+ get_line = UMVLine4X;
+ }
+
+ search_range_dynamic = 3;
+ pred_frac_mv_x = (pred_mv_x - *mv_x)%4;
+ pred_frac_mv_y = (pred_mv_y - *mv_y)%4;
+
+ pred_frac_up_mv_x = (pred_MV_uplayer[0] - *mv_x)%4;
+ pred_frac_up_mv_y = (pred_MV_uplayer[1] - *mv_y)%4;
+
+
+ memset(SearchState[0],0,(2*search_range_dynamic+1)*(2*search_range_dynamic+1));
+
+ if(input->hadamard)
+ {
+ cand_mv_x = *mv_x;
+ cand_mv_y = *mv_y;
+ mv_cost = MV_COST (lambda_factor, mv_shift, cand_mv_x, cand_mv_y, pred_mv_x, pred_mv_y);
+ mcost = AddUpSADQuarter(pic_pix_x,pic_pix_y,blocksize_x,blocksize_y,cand_mv_x + pic4_pix_x,cand_mv_y + pic4_pix_y,ref_picture,orig_pic,mv_cost,min_mcost,useABT, blocktype);
+ SearchState[search_range_dynamic][search_range_dynamic] = 1;
+ if (mcost < min_mcost)
+ {
+ min_mcost = mcost;
+ currmv_x = cand_mv_x;
+ currmv_y = cand_mv_y;
+ }
+ }
+ else
+ {
+ SearchState[search_range_dynamic][search_range_dynamic] = 1;
+ currmv_x = *mv_x;
+ currmv_y = *mv_y;
+ }
+
+ if(pred_frac_mv_x!=0 || pred_frac_mv_y!=0)
+ {
+ cand_mv_x = *mv_x + pred_frac_mv_x;
+ cand_mv_y = *mv_y + pred_frac_mv_y;
+ mv_cost = MV_COST (lambda_factor, mv_shift, cand_mv_x, cand_mv_y, pred_mv_x, pred_mv_y);
+ mcost = AddUpSADQuarter(pic_pix_x,pic_pix_y,blocksize_x,blocksize_y,cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y,ref_picture,orig_pic,mv_cost,min_mcost,useABT, blocktype);
+ SearchState[cand_mv_y -*mv_y + search_range_dynamic][cand_mv_x - *mv_x + search_range_dynamic] = 1;
+ if (mcost < min_mcost)
+ {
+ min_mcost = mcost;
+ currmv_x = cand_mv_x;
+ currmv_y = cand_mv_y;
+ }
+ }
+
+
+ iXMinNow = currmv_x;
+ iYMinNow = currmv_y;
+ for(i=0;i<search_range_dynamic;i++)
+ {
+ abort_search=1;
+ for (m = 0; m < 4; m++)
+ {
+ cand_mv_x = iXMinNow + Diamond_x[m];
+ cand_mv_y = iYMinNow + Diamond_y[m];
+
+ if(abs(cand_mv_x - *mv_x) <=search_range_dynamic && abs(cand_mv_y - *mv_y)<= search_range_dynamic)
+ {
+ if(!SearchState[cand_mv_y -*mv_y+ search_range_dynamic][cand_mv_x -*mv_x+ search_range_dynamic])
+ {
+ mv_cost = MV_COST (lambda_factor, mv_shift, cand_mv_x, cand_mv_y, pred_mv_x, pred_mv_y);
+ mcost = AddUpSADQuarter(pic_pix_x,pic_pix_y,blocksize_x,blocksize_y,cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y,ref_picture,orig_pic,mv_cost,min_mcost,useABT, blocktype);
+ SearchState[cand_mv_y - *mv_y + search_range_dynamic][cand_mv_x - *mv_x + search_range_dynamic] = 1;
+ if (mcost < min_mcost)
+ {
+ min_mcost = mcost;
+ currmv_x = cand_mv_x;
+ currmv_y = cand_mv_y;
+ abort_search = 0;
+
+ }
+ }
+ }
+ }
+ iXMinNow = currmv_x;
+ iYMinNow = currmv_y;
+ if(abort_search)
+ break;
+ }
+
+ *mv_x = currmv_x;
+ *mv_y = currmv_y;
+
+ //===== return minimum motion cost =====
+ return min_mcost;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Functions for SAD prediction of intra block cases.
+ * 1. void decide_intrabk_SAD() judges the block coding type(intra/inter)
+ * of neibouring blocks
+ * 2. void skip_intrabk_SAD() set the SAD to zero if neigouring block coding
+ * type is intra
+ * \date
+ * 2003.4
+ ************************************************************************
+ */
+ void decide_intrabk_SAD()
+ {
+ if (img->type != I_SLICE)
+ {
+ if (img->pix_x == 0 && img->pix_y == 0)
+ {
+ flag_intra_SAD = 0;
+ }
+ else if (img->pix_x == 0)
+ {
+ flag_intra_SAD = flag_intra[(img->pix_x)>>4];
+ }
+ else if (img->pix_y == 0)
+ {
+ flag_intra_SAD = flag_intra[((img->pix_x)>>4)-1];
+ }
+ else
+ {
+ flag_intra_SAD = ((flag_intra[(img->pix_x)>>4])||(flag_intra[((img->pix_x)>>4)-1])||(flag_intra[((img->pix_x)>>4)+1])) ;
+ }
+ }
+ return;
+ }
+
+ void skip_intrabk_SAD(int best_mode, int ref_max)
+ {
+ int i,j,k, ref;
+ if (img->number > 0)
+ flag_intra[(img->pix_x)>>4] = (best_mode == 9 || best_mode == 10) ? 1:0;
+ if (img->type != I_SLICE && (best_mode == 9 || best_mode == 10))
+ {
+ for (i=0; i < 4; i++)
+ {
+ for (j=0; j < 4; j++)
+ {
+ for (k=0; k < 9;k++)
+ {
+ fastme_l0_cost[k][j][i] = 0;
+ fastme_l1_cost[k][j][i] = 0;
+ for (ref=0; ref<ref_max;ref++)
+ {
+ fastme_ref_cost[ref][k][j][i] = 0;
+ }
+ }
+ }
+ }
+
+ }
+ return;
+ }
+
+ void setup_FME(short ref, int list, int block_y, int block_x, int blocktype, short ******all_mv)
+ {
+ int N_Bframe=0, n_Bframe=0;
+
+ N_Bframe = input->successive_Bframe;
+ n_Bframe =(N_Bframe) ? (frame_ctr[B_SLICE]%(N_Bframe+1)): 0;
+
+ /**************************** MV prediction **********************/
+ //MV uplayer prediction
+
+ if(blocktype>6)
+ {
+ pred_MV_uplayer[0] = all_mv[block_y][block_x][list][ref][5][0];
+ pred_MV_uplayer[1] = all_mv[block_y][block_x][list][ref][5][1];
+
+ }
+ else if(blocktype>4)
+ {
+ pred_MV_uplayer[0] = all_mv[block_y][block_x][list][ref][4][0];
+ pred_MV_uplayer[1] = all_mv[block_y][block_x][list][ref][4][1];
+
+ }
+ else if(blocktype == 4)
+ {
+ pred_MV_uplayer[0] = all_mv[block_y][block_x][list][ref][2][0];
+ pred_MV_uplayer[1] = all_mv[block_y][block_x][list][ref][2][1];
+ }
+ else if(blocktype > 1)
+ {
+ pred_MV_uplayer[0] = all_mv[block_y][block_x][list][ref][1][0];
+ pred_MV_uplayer[1] = all_mv[block_y][block_x][list][ref][1][1];
+ }
+
+ //MV ref-frame prediction
+ if (img->field_picture)
+ {
+ if (list==0 && ref > 1)
+ {
+ pred_MV_ref[0] = all_mv[block_y][block_x][0][ref-2][blocktype][0];
+ pred_MV_ref[0] = (int)(pred_MV_ref[0]*((ref>>1)+1)/(float)((ref>>1)));
+ pred_MV_ref[1] = all_mv[block_y][block_x][0][ref-2][blocktype][1];
+ pred_MV_ref[1] = (int)(pred_MV_ref[1]*((ref>>1)+1)/(float)((ref>>1)));
+ }
+ if (img->type == B_SLICE && list==0 && (ref==0 || ref==1) )
+ {
+ pred_MV_ref[0] =(int) (all_mv[block_y][block_x][1][0][blocktype][0]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
+ pred_MV_ref[1] =(int) (all_mv[block_y][block_x][1][0][blocktype][1]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
+ }
+ }
+ else //frame case
+ {
+ if (list==0 && ref > 0)
+ {
+ pred_MV_ref[0] = all_mv[block_y][block_x][0][ref-1][blocktype][0];
+ pred_MV_ref[0] = (int)(pred_MV_ref[0]*(ref+1)/(float)(ref));
+ pred_MV_ref[1] = all_mv[block_y][block_x][0][ref-1][blocktype][1];
+ pred_MV_ref[1] = (int)(pred_MV_ref[1]*(ref+1)/(float)(ref));
+ }
+ if (img->type == B_SLICE && (list==0 && ref==0)) //B frame forward prediction, first ref
+ {
+ pred_MV_ref[0] =(int) (all_mv[block_y][block_x][1][0][blocktype][0]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
+ pred_MV_ref[1] =(int) (all_mv[block_y][block_x][1][0][blocktype][1]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
+ }
+ }
+
+ /******************************SAD prediction**********************************/
+ if (list==0 && ref>0)
+ {
+ if (img->field_picture)
+ {
+ if (ref > 1)
+ {
+ pred_SAD_ref = fastme_ref_cost[ref-2][blocktype][block_y][block_x];
+ pred_SAD_ref = flag_intra_SAD ? 0 : pred_SAD_ref;//add this for irregular motion
+ }
+ else
+ {
+ pred_SAD_ref = fastme_ref_cost[0][blocktype][block_y][block_x];
+ pred_SAD_ref = flag_intra_SAD ? 0 : pred_SAD_ref;//add this for irregular motion
+ }
+ }
+ else
+ {
+ pred_SAD_ref = fastme_ref_cost[ref-1][blocktype][block_y][block_x];
+ pred_SAD_ref = flag_intra_SAD ? 0 : pred_SAD_ref;//add this for irregular motion
+ }
+ }
+ else if (blocktype>1)
+ {
+ if(blocktype>6)
+ {
+ pred_SAD_uplayer = (list==1) ? (fastme_l1_cost[5][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]) : (fastme_l0_cost[5][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]);
+ pred_SAD_uplayer /= 2;
+ }
+ else if(blocktype>4)
+ {
+ pred_SAD_uplayer = (list==1) ? (fastme_l1_cost[4][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]) : (fastme_l0_cost[4][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]);
+ pred_SAD_uplayer /= 2;
+ }
+ else if(blocktype == 4)
+ {
+ pred_SAD_uplayer = (list==1) ? (fastme_l1_cost[2][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]) : (fastme_l0_cost[2][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]);
+ pred_SAD_uplayer /= 2;
+ }
+ else
+ {
+ pred_SAD_uplayer = (list==1) ? (fastme_l1_cost[1][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]) : (fastme_l0_cost[1][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]);
+ pred_SAD_uplayer /= 2;
+ }
+
+ pred_SAD_uplayer = flag_intra_SAD ? 0 : pred_SAD_uplayer;// for irregular motion
+ }
+
+
+ FME_blocktype=blocktype;
+
+ }
+
Index: llvm-test/MultiSource/Applications/JM/lencod/fast_me.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/fast_me.h:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/fast_me.h Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,168 ----
+
+ /*!
+ ************************************************************************
+ *
+ * \file fast_me.h
+ *
+ * \brief
+ * Macro definitions and global variables for fast integer pel motion
+ * estimation and fractional pel motion estimation
+ *
+ * \author
+ * Main contributors: (see contributors.h for copyright, address and affiliation details)
+ * - Zhibo Chen <chenzhibo at tsinghua.org.cn>
+ * - JianFeng Xu <fenax at video.mdc.tsinghua.edu.cn>
+ * - Wenfang Fu <fwf at video.mdc.tsinghua.edu.cn>
+ *
+ * \date
+ * Apr. 2003
+ ************************************************************************
+ */
+
+ #ifndef _FAST_ME_H_
+ #define _FAST_ME_H_
+
+ #include "mbuffer.h"
+
+ #define EARLY_TERMINATION if(list==0 && ref>0) \
+ { \
+ if ((min_mcost-pred_SAD_ref)<pred_SAD_ref*betaThird) \
+ goto third_step; \
+ else if((min_mcost-pred_SAD_ref)<pred_SAD_ref*betaSec) \
+ goto sec_step; \
+ } \
+ else if(blocktype>1) \
+ { \
+ if ((min_mcost-pred_SAD_uplayer)<pred_SAD_uplayer*betaThird) \
+ { \
+ goto third_step; \
+ } \
+ else if((min_mcost-pred_SAD_uplayer)<pred_SAD_uplayer*betaSec) \
+ goto sec_step; \
+ } \
+ else \
+ { \
+ if ((min_mcost-pred_SAD_space)<pred_SAD_space*betaThird) \
+ { \
+ goto third_step; \
+ } \
+ else if((min_mcost-pred_SAD_space)<pred_SAD_space*betaSec) \
+ goto sec_step; \
+ }
+
+
+ #define SEARCH_ONE_PIXEL if(abs(cand_x - center_x) <=search_range && abs(cand_y - center_y)<= search_range) \
+ { \
+ if(!McostState[cand_y-center_y+search_range][cand_x-center_x+search_range]) \
+ { \
+ mcost = MV_COST (lambda_factor, mvshift, cand_x, cand_y, pred_x, pred_y); \
+ mcost = PartCalMad(ref_pic, orig_pic, get_ref_line,blocksize_y,blocksize_x,blocksize_x4,mcost,min_mcost,cand_x,cand_y); \
+ McostState[cand_y-center_y+search_range][cand_x-center_x+search_range] = 1; \
+ if (mcost < min_mcost) \
+ { \
+ best_x = cand_x; \
+ best_y = cand_y; \
+ min_mcost = mcost; \
+ } \
+ } \
+ }
+ #define SEARCH_ONE_PIXEL1(value_iAbort) if(abs(cand_x - center_x) <=search_range && abs(cand_y - center_y)<= search_range) \
+ { \
+ if(!McostState[cand_y-center_y+search_range][cand_x-center_x+search_range]) \
+ { \
+ mcost = MV_COST (lambda_factor, mvshift, cand_x, cand_y, pred_x, pred_y); \
+ mcost = PartCalMad(ref_pic, orig_pic, get_ref_line,blocksize_y,blocksize_x,blocksize_x4,mcost,min_mcost,cand_x,cand_y); \
+ McostState[cand_y-center_y+search_range][cand_x-center_x+search_range] = 1; \
+ if (mcost < min_mcost) \
+ { \
+ best_x = cand_x; \
+ best_y = cand_y; \
+ min_mcost = mcost; \
+ iAbort = value_iAbort; \
+ } \
+ } \
+ }
+
+ byte **McostState; //state for integer pel search
+ byte **SearchState; //state for fractional pel search
+
+ int ****fastme_ref_cost; //store SAD information needed for forward ref-frame prediction
+ int ***fastme_l0_cost; //store SAD information needed for forward median and uplayer prediction
+ int ***fastme_l1_cost; //store SAD information needed for backward median and uplayer prediction
+
+ int pred_SAD_space, pred_SAD_ref,pred_SAD_uplayer; //SAD prediction
+ int pred_MV_ref[2], pred_MV_uplayer[2]; //pred motion vector by space or temporal correlation,Median is provided
+
+ int FME_blocktype; //blocktype for FME SetMotionVectorPredictor
+
+ //for early termination
+ float Bsize[8];
+ float AlphaSec[8];
+ float AlphaThird[8];
+ byte *flag_intra;
+ int flag_intra_SAD;
+
+ void DefineThreshold();
+ void DefineThresholdMB();
+ int get_mem_FME();
+ void free_mem_FME();
+
+ void decide_intrabk_SAD();
+ void skip_intrabk_SAD(int best_mode, int ref_max);
+ void setup_FME(short ref, int list, int block_y, int block_x, int blocktype, short ******all_mv);
+
+ int // ==> minimum motion cost after search
+ FastIntegerPelBlockMotionSearch (pel_t** orig_pic, // <-- not used
+ short ref, // <-- reference frame (0... or -1 (backward))
+ int list,
+ int pic_pix_x, // <-- absolute x-coordinate of regarded AxB block
+ int pic_pix_y, // <-- absolute y-coordinate of regarded AxB block
+ int blocktype, // <-- block type (1-16x16 ... 7-4x4)
+ short pred_mv_x, // <-- motion vector predictor (x) in sub-pel units
+ short pred_mv_y, // <-- motion vector predictor (y) in sub-pel units
+ short* mv_x, // --> motion vector (x) - in pel units
+ short* mv_y, // --> motion vector (y) - in pel units
+ int search_range, // <-- 1-d search range in pel units
+ int min_mcost, // <-- minimum motion cost (cost for center or huge value)
+ int lambda_factor);// <-- lagrangian parameter for determining motion cost
+
+ int AddUpSADQuarter(int pic_pix_x,int pic_pix_y,int blocksize_x,int blocksize_y,
+ int cand_mv_x,int cand_mv_y, StorablePicture *ref_picture, pel_t** orig_pic,
+ int Mvmcost, int min_mcost,int useABT,int blocktype);
+
+ int // ==> minimum motion cost after search
+ FastSubPelBlockMotionSearch (pel_t** orig_pic, // <-- original pixel values for the AxB block
+ short ref, // <-- reference frame (0... or -1 (backward))
+ int list,
+ int pic_pix_x, // <-- absolute x-coordinate of regarded AxB block
+ int pic_pix_y, // <-- absolute y-coordinate of regarded AxB block
+ int blocktype, // <-- block type (1-16x16 ... 7-4x4)
+ short pred_mv_x, // <-- motion vector predictor (x) in sub-pel units
+ short pred_mv_y, // <-- motion vector predictor (y) in sub-pel units
+ short* mv_x, // <--> in: search center (x) / out: motion vector (x) - in pel units
+ short* mv_y, // <--> in: search center (y) / out: motion vector (y) - in pel units
+ int search_pos2, // <-- search positions for half-pel search (default: 9)
+ int search_pos4, // <-- search positions for quarter-pel search (default: 9)
+ int min_mcost, // <-- minimum motion cost (cost for center or huge value)
+ int lambda_factor, // <-- lagrangian parameter for determining motion cost
+ int useABT);
+
+ int // ==> minimum motion cost after search
+ SubPelBlockMotionSearch (pel_t** orig_pic, // <-- original pixel values for the AxB block
+ short ref, // <-- reference frame (0... or -1 (backward))
+ int list,
+ int pic_pix_x, // <-- absolute x-coordinate of regarded AxB block
+ int pic_pix_y, // <-- absolute y-coordinate of regarded AxB block
+ int blocktype, // <-- block type (1-16x16 ... 7-4x4)
+ int pred_mv_x, // <-- motion vector predictor (x) in sub-pel units
+ int pred_mv_y, // <-- motion vector predictor (y) in sub-pel units
+ short* mv_x, // <--> in: search center (x) / out: motion vector (x) - in pel units
+ short* mv_y, // <--> in: search center (y) / out: motion vector (y) - in pel units
+ int search_pos2, // <-- search positions for half-pel search (default: 9)
+ int search_pos4, // <-- search positions for quarter-pel search (default: 9)
+ int min_mcost, // <-- minimum motion cost (cost for center or huge value)
+ int lambda_factor // <-- lagrangian parameter for determining motion cost
+ );
+
+
+ #endif
Index: llvm-test/MultiSource/Applications/JM/lencod/filehandle.c
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/filehandle.c:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/filehandle.c Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,140 ----
+
+ /*!
+ **************************************************************************************
+ * \file
+ * filehandle.c
+ * \brief
+ * Start and terminate sequences
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Thomas Stockhammer <stockhammer at ei.tum.de>
+ * - Detlev Marpe <marpe at hhi.de>
+ ***************************************************************************************
+ */
+
+ #include "contributors.h"
+
+ #include <stdlib.h>
+
+ #include "global.h"
+
+ #include "rtp.h"
+ #include "annexb.h"
+ #include "parset.h"
+ #include "mbuffer.h"
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Error handling procedure. Print error message to stderr and exit
+ * with supplied code.
+ * \param text
+ * Error message
+ * \param code
+ * Exit code
+ ************************************************************************
+ */
+ void error(char *text, int code)
+ {
+ fprintf(stderr, "%s\n", text);
+ flush_dpb();
+ exit(code);
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * This function generates and writes the PPS
+ *
+ ************************************************************************
+ */
+ int write_PPS(int len, int PPS_id)
+ {
+ NALU_t *nalu;
+ nalu = NULL;
+ nalu = GeneratePic_parameter_set_NALU (PPS_id);
+ len += WriteNALU (nalu);
+ FreeNALU (nalu);
+
+ return len;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * This function opens the output files and generates the
+ * appropriate sequence header
+ ************************************************************************
+ */
+ int start_sequence()
+ {
+ int i,len=0, total_pps = (input->GenerateMultiplePPS) ? 3 : 1;
+ NALU_t *nalu;
+
+
+ switch(input->of_mode)
+ {
+ case PAR_OF_ANNEXB:
+ OpenAnnexbFile (input->outfile);
+ WriteNALU = WriteAnnexbNALU;
+ break;
+ case PAR_OF_RTP:
+ OpenRTPFile (input->outfile);
+ WriteNALU = WriteRTPNALU;
+ break;
+ default:
+ snprintf(errortext, ET_SIZE, "Output File Mode %d not supported", input->of_mode);
+ error(errortext,1);
+ return 1;
+ }
+
+ //! As a sequence header, here we write the both sequence and picture
+ //! parameter sets. As soon as IDR is implemented, this should go to the
+ //! IDR part, as both parsets have to be transmitted as part of an IDR.
+ //! An alternative may be to consider this function the IDR start function.
+
+ nalu = NULL;
+ nalu = GenerateSeq_parameter_set_NALU ();
+ len += WriteNALU (nalu);
+ FreeNALU (nalu);
+
+ //! Lets write now the Picture Parameter sets. Output will be equal to the total number of bits spend here.
+ for (i=0;i<total_pps;i++)
+ {
+ len = write_PPS(len, i);
+ }
+ stats->bit_ctr_parametersets_n = len;
+ return 0;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * This function terminates the sequence and closes the
+ * output files
+ ************************************************************************
+ */
+ int terminate_sequence()
+ {
+ // Bitstream *currStream;
+
+ // Mainly flushing of everything
+ // Add termination symbol, etc.
+
+ switch(input->of_mode)
+ {
+ case PAR_OF_ANNEXB:
+ CloseAnnexbFile();
+ break;
+ case PAR_OF_RTP:
+ CloseRTPFile();
+ return 0;
+ default:
+ snprintf(errortext, ET_SIZE, "Output File Mode %d not supported", input->of_mode);
+ error(errortext,1);
+ return 1;
+ }
+ return 1; // make lint happy
+ }
+
Index: llvm-test/MultiSource/Applications/JM/lencod/fmo.c
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/fmo.c:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/fmo.c Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,730 ----
+ /*!
+ *****************************************************************************
+ *
+ * \file fmo.c
+ *
+ * \brief
+ * Support for Flexible Macroblock Ordering for different Slice Group Modes: MBAmap handling
+ *
+ * \date
+ * 16 June, 2002 Modified April 25, 2004
+ *
+ * \author
+ * Stephan Wenger stewe at cs.tu-berlin.de
+ * Dong Wang (modify) Dong.Wang at bristol.ac.uk
+ *
+ *****************************************************************************/
+
+ /*!
+ ****************************************************************************
+ * Notes by Dong Wang (April 25 2004)
+ *
+ * Source codes are modified to support 7 slice group types (fmo modes).
+ * The functions for generating map are very similar to that in decoder, but have
+ * a little difference.
+ *
+ * The MB map is calculated at the beginning of coding of each picture (frame or field).
+ *
+ * 'slice_group_change_cycle' in structure 'ImageParameters' is the syntax in the slice
+ * header. It's set to be 1 before the initialization of FMO in function code_a_picture().
+ * It can be changed every time if needed.
+ *
+ ****************************************************************************
+ */
+
+ /*!
+ *****************************************************************************
+ * How does a MBAmap look like?
+ *
+ * An MBAmap is a one-diemnsional array of ints. Each int
+ * represents an MB in scan order. A zero or positive value represents
+ * a slice group ID. Negative values are reserved for future extensions.
+ * The numbering range for the SliceGroupIDs is 0..7 as per JVT-C167.
+ *
+ * This module contains a static variable MBAmap. This is the MBAmap of the
+ * picture currently coded. It can be accessed only through the access
+ * functions.
+ *****************************************************************************
+ */
+
+ //#define PRINT_FMO_MAPS 1
+
+
+ #include <stdlib.h>
+ #include <string.h>
+ #include <assert.h>
+ #include <memory.h>
+
+ #include "global.h"
+
+ #include "fmo.h"
+
+
+ static int FirstMBInSlice[MAXSLICEGROUPIDS];
+
+ byte *MBAmap = NULL;
+ byte *MapUnitToSliceGroupMap = NULL;
+ unsigned PicSizeInMapUnits;
+
+
+ static void FmoGenerateType0MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
+ static void FmoGenerateType1MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
+ static void FmoGenerateType2MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
+ static void FmoGenerateType3MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
+ static void FmoGenerateType4MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
+ static void FmoGenerateType5MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
+ static void FmoGenerateType6MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
+
+
+ static int FmoGenerateMapUnitToSliceGroupMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps);
+ static int FmoGenerateMBAmap (ImageParameters * img, seq_parameter_set_rbsp_t* sps);
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Generates MapUnitToSliceGroupMap
+ *
+ * \param img
+ * Image Parameter to be used for map generation
+ * \param pps
+ * Picture Parameter set to be used for map generation
+ *
+ ************************************************************************
+ */
+ static int FmoGenerateMapUnitToSliceGroupMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps)
+ {
+ PicSizeInMapUnits = img->PicHeightInMapUnits * img->PicWidthInMbs;
+
+
+ if (pps->slice_group_map_type == 6)
+ {
+ if ((pps->pic_size_in_map_units_minus1+1) != PicSizeInMapUnits)
+ {
+ error ("wrong pps->pic_size_in_map_units_minus1 for used SPS and FMO type 6", 500);
+ }
+ }
+
+ // allocate memory for MapUnitToSliceGroupMap
+ if (MapUnitToSliceGroupMap)
+ free (MapUnitToSliceGroupMap);
+
+ if ((MapUnitToSliceGroupMap = malloc ((PicSizeInMapUnits) * sizeof (byte))) == NULL)
+ {
+ printf ("cannot allocated %d bytes for MapUnitToSliceGroupMap, exit\n", PicSizeInMapUnits * sizeof (byte));
+ exit (-1);
+ }
+
+ if (pps->num_slice_groups_minus1 == 0) // only one slice group
+ {
+ memset (MapUnitToSliceGroupMap, 0, PicSizeInMapUnits * sizeof (byte));
+ return 0;
+ }
+
+ switch (pps->slice_group_map_type)
+ {
+ case 0:
+ FmoGenerateType0MapUnitMap (img, pps);
+ break;
+ case 1:
+ FmoGenerateType1MapUnitMap (img, pps);
+ break;
+ case 2:
+ FmoGenerateType2MapUnitMap (img, pps);
+ break;
+ case 3:
+ FmoGenerateType3MapUnitMap (img, pps);
+ break;
+ case 4:
+ FmoGenerateType4MapUnitMap (img, pps);
+ break;
+ case 5:
+ FmoGenerateType5MapUnitMap (img, pps);
+ break;
+ case 6:
+ FmoGenerateType6MapUnitMap (img, pps);
+ break;
+ default:
+ printf ("Illegal slice_group_map_type %d , exit \n", pps->slice_group_map_type);
+ exit (-1);
+ }
+ return 0;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Generates MBAmap from MapUnitToSliceGroupMap
+ *
+ * \param img
+ * Image Parameter to be used for map generation
+ * \param sps
+ * Sequence Parameter set to be used for map generation
+ *
+ ************************************************************************
+ */
+ static int FmoGenerateMBAmap (ImageParameters * img, seq_parameter_set_rbsp_t* sps)
+ {
+ unsigned i;
+
+ // allocate memory for MBAmap
+ if (MBAmap)
+ free (MBAmap);
+
+
+ if ((MBAmap = malloc ((img->PicSizeInMbs) * sizeof (byte))) == NULL)
+ {
+ printf ("cannot allocated %d bytes for MBAmap, exit\n", (img->PicSizeInMbs) * sizeof (byte));
+ exit (-1);
+ }
+
+ if ((sps->frame_mbs_only_flag) || img->field_picture)
+ {
+ for (i=0; i<img->PicSizeInMbs; i++)
+ {
+ MBAmap[i] = MapUnitToSliceGroupMap[i];
+ }
+ }
+ else
+ if (sps->mb_adaptive_frame_field_flag && (! img->field_picture))
+ {
+ for (i=0; i<img->PicSizeInMbs; i++)
+ {
+ MBAmap[i] = MapUnitToSliceGroupMap[i/2];
+ }
+ }
+ else
+ {
+ for (i=0; i<img->PicSizeInMbs; i++)
+ {
+ MBAmap[i] = MapUnitToSliceGroupMap[(i/(2*img->PicWidthInMbs))*img->PicWidthInMbs+(i%img->PicWidthInMbs)];
+ }
+ }
+ return 0;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * FMO initialization: Generates MapUnitToSliceGroupMap and MBAmap.
+ *
+ * \param img
+ * Image Parameter to be used for map generation
+ * \param pps
+ * Picture Parameter set to be used for map generation
+ * \param sps
+ * Sequence Parameter set to be used for map generation
+ ************************************************************************
+ */
+ int FmoInit(ImageParameters * img, pic_parameter_set_rbsp_t * pps, seq_parameter_set_rbsp_t * sps)
+ {
+
+ #ifdef PRINT_FMO_MAPS
+ unsigned i,j;
+ int bottom;
+ #endif
+
+ int k;
+ for (k=0;k<MAXSLICEGROUPIDS;k++)
+ FirstMBInSlice[k] = -1;
+
+
+
+ FmoGenerateMapUnitToSliceGroupMap(img, pps);
+ FmoGenerateMBAmap(img, sps);
+
+ #ifdef PRINT_FMO_MAPS
+ printf("\n");
+ printf("FMO Map (Units):\n");
+
+ for (j=0; j<img->PicHeightInMapUnits; j++)
+ {
+ for (i=0; i<img->PicWidthInMbs; i++)
+ {
+ printf("%d ",MapUnitToSliceGroupMap[i+j*img->PicWidthInMbs]);
+ }
+ printf("\n");
+ }
+ printf("\n");
+
+ if(sps->mb_adaptive_frame_field_flag==0)
+ {
+ printf("FMO Map (Mb):\n");
+ for (j=0; j<(img->PicSizeInMbs/img->PicWidthInMbs); j++)
+ {
+ for (i=0; i<img->PicWidthInMbs; i++)
+ {
+ printf("%d ",MBAmap[i+j*img->PicWidthInMbs]);
+ }
+ printf("\n");
+ }
+ printf("\n");
+ }
+ else
+ {
+ printf("FMO Map (Mb in scan order for MBAFF):\n");
+ for (j=0; j<(img->PicSizeInMbs/img->PicWidthInMbs); j++)
+ {
+ for (i=0; i<img->PicWidthInMbs; i++)
+ {
+ bottom=(j%2);
+ printf("%d ",MBAmap[(j-bottom)*img->PicWidthInMbs+i*2+bottom]);
+ }
+ printf("\n");
+
+ }
+ printf("\n");
+
+ }
+
+ #endif
+
+ return 0;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Free memory if allocated by FMO functions
+ ************************************************************************
+ */
+ void FmoUninit()
+ {
+ if (MBAmap)
+ {
+ free (MBAmap);
+ MBAmap = NULL;
+ }
+ if (MapUnitToSliceGroupMap)
+ {
+ free (MapUnitToSliceGroupMap);
+ MapUnitToSliceGroupMap = NULL;
+ }
+
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Generate interleaved slice group map type MapUnit map (type 0)
+ *
+ * \param img
+ * Image Parameter to be used for map generation
+ * \param pps
+ * Picture Parameter set to be used for map generation
+ ************************************************************************
+ */
+ static void FmoGenerateType0MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
+ {
+ unsigned iGroup, j;
+ unsigned i = 0;
+ do
+ {
+ for( iGroup = 0;
+ (iGroup <= pps->num_slice_groups_minus1) && (i < PicSizeInMapUnits);
+ i += pps->run_length_minus1[iGroup++] + 1)
+ {
+ for( j = 0; j <= pps->run_length_minus1[ iGroup ] && i + j < PicSizeInMapUnits; j++ )
+ MapUnitToSliceGroupMap[i+j] = iGroup;
+ }
+ }
+ while( i < PicSizeInMapUnits );
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Generate dispersed slice group map type MapUnit map (type 1)
+ *
+ * \param img
+ * Image Parameter to be used for map generation
+ * \param pps
+ * Picture Parameter set to be used for map generation
+ ************************************************************************
+ */
+ static void FmoGenerateType1MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
+ {
+ unsigned i;
+ for( i = 0; i < PicSizeInMapUnits; i++ )
+ {
+ MapUnitToSliceGroupMap[i] = ((i%img->PicWidthInMbs)+(((i/img->PicWidthInMbs)*(pps->num_slice_groups_minus1+1))/2))
+ %(pps->num_slice_groups_minus1+1);
+ }
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Generate foreground with left-over slice group map type MapUnit map (type 2)
+ *
+ * \param img
+ * Image Parameter to be used for map generation
+ * \param pps
+ * Picture Parameter set to be used for map generation
+ ************************************************************************
+ */
+ static void FmoGenerateType2MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
+ {
+ int iGroup;
+ unsigned i, x, y;
+ unsigned yTopLeft, xTopLeft, yBottomRight, xBottomRight;
+
+ for( i = 0; i < PicSizeInMapUnits; i++ )
+ MapUnitToSliceGroupMap[ i ] = pps->num_slice_groups_minus1;
+
+ for( iGroup = pps->num_slice_groups_minus1 - 1 ; iGroup >= 0; iGroup-- )
+ {
+ yTopLeft = pps->top_left[ iGroup ] / img->PicWidthInMbs;
+ xTopLeft = pps->top_left[ iGroup ] % img->PicWidthInMbs;
+ yBottomRight = pps->bottom_right[ iGroup ] / img->PicWidthInMbs;
+ xBottomRight = pps->bottom_right[ iGroup ] % img->PicWidthInMbs;
+ for( y = yTopLeft; y <= yBottomRight; y++ )
+ for( x = xTopLeft; x <= xBottomRight; x++ )
+ MapUnitToSliceGroupMap[ y * img->PicWidthInMbs + x ] = iGroup;
+ }
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Generate box-out slice group map type MapUnit map (type 3)
+ *
+ * \param img
+ * Image Parameter to be used for map generation
+ * \param pps
+ * Picture Parameter set to be used for map generation
+ ************************************************************************
+ */
+ static void FmoGenerateType3MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
+ {
+ unsigned i, k;
+ int leftBound, topBound, rightBound, bottomBound;
+ int x, y, xDir, yDir;
+ int mapUnitVacant;
+
+ unsigned mapUnitsInSliceGroup0 = min((pps->slice_group_change_rate_minus1 + 1) * img->slice_group_change_cycle, PicSizeInMapUnits);
+
+ for( i = 0; i < PicSizeInMapUnits; i++ )
+ MapUnitToSliceGroupMap[ i ] = 2;
+
+ x = ( img->PicWidthInMbs - pps->slice_group_change_direction_flag ) / 2;
+ y = ( img->PicHeightInMapUnits - pps->slice_group_change_direction_flag ) / 2;
+
+ leftBound = x;
+ topBound = y;
+ rightBound = x;
+ bottomBound = y;
+
+ xDir = pps->slice_group_change_direction_flag - 1;
+ yDir = pps->slice_group_change_direction_flag;
+
+ for( k = 0; k < PicSizeInMapUnits; k += mapUnitVacant )
+ {
+ mapUnitVacant = ( MapUnitToSliceGroupMap[ y * img->PicWidthInMbs + x ] == 2 );
+ if( mapUnitVacant )
+ MapUnitToSliceGroupMap[ y * img->PicWidthInMbs + x ] = ( k >= mapUnitsInSliceGroup0 );
+
+ if( xDir == -1 && x == leftBound )
+ {
+ leftBound = max( leftBound - 1, 0 );
+ x = leftBound;
+ xDir = 0;
+ yDir = 2 * pps->slice_group_change_direction_flag - 1;
+ }
+ else
+ if( xDir == 1 && x == rightBound )
+ {
+ rightBound = min( rightBound + 1, (int)img->PicWidthInMbs - 1 );
+ x = rightBound;
+ xDir = 0;
+ yDir = 1 - 2 * pps->slice_group_change_direction_flag;
+ }
+ else
+ if( yDir == -1 && y == topBound )
+ {
+ topBound = max( topBound - 1, 0 );
+ y = topBound;
+ xDir = 1 - 2 * pps->slice_group_change_direction_flag;
+ yDir = 0;
+ }
+ else
+ if( yDir == 1 && y == bottomBound )
+ {
+ bottomBound = min( bottomBound + 1, (int)img->PicHeightInMapUnits - 1 );
+ y = bottomBound;
+ xDir = 2 * pps->slice_group_change_direction_flag - 1;
+ yDir = 0;
+ }
+ else
+ {
+ x = x + xDir;
+ y = y + yDir;
+ }
+ }
+
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Generate raster scan slice group map type MapUnit map (type 4)
+ *
+ * \param img
+ * Image Parameter to be used for map generation
+ * \param pps
+ * Picture Parameter set to be used for map generation
+ ************************************************************************
+ */
+ static void FmoGenerateType4MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
+ {
+
+ unsigned mapUnitsInSliceGroup0 = min((pps->slice_group_change_rate_minus1 + 1) * img->slice_group_change_cycle, PicSizeInMapUnits);
+ unsigned sizeOfUpperLeftGroup = pps->slice_group_change_direction_flag ? ( PicSizeInMapUnits - mapUnitsInSliceGroup0 ) : mapUnitsInSliceGroup0;
+
+ unsigned i;
+
+ for( i = 0; i < PicSizeInMapUnits; i++ )
+ if( i < sizeOfUpperLeftGroup )
+ MapUnitToSliceGroupMap[ i ] = pps->slice_group_change_direction_flag;
+ else
+ MapUnitToSliceGroupMap[ i ] = 1 - pps->slice_group_change_direction_flag;
+
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Generate wipe slice group map type MapUnit map (type 5)
+ *
+ * \param img
+ * Image Parameter to be used for map generation
+ * \param pps
+ * Picture Parameter set to be used for map generation
+ ************************************************************************
+ */
+ static void FmoGenerateType5MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
+ {
+
+ unsigned mapUnitsInSliceGroup0 = min((pps->slice_group_change_rate_minus1 + 1) * img->slice_group_change_cycle, PicSizeInMapUnits);
+ unsigned sizeOfUpperLeftGroup = pps->slice_group_change_direction_flag ? ( PicSizeInMapUnits - mapUnitsInSliceGroup0 ) : mapUnitsInSliceGroup0;
+
+ unsigned i,j, k = 0;
+
+ for( j = 0; j < img->PicWidthInMbs; j++ )
+ for( i = 0; i < img->PicHeightInMapUnits; i++ )
+ if( k++ < sizeOfUpperLeftGroup )
+ MapUnitToSliceGroupMap[ i * img->PicWidthInMbs + j ] = 1 - pps->slice_group_change_direction_flag;
+ else
+ MapUnitToSliceGroupMap[ i * img->PicWidthInMbs + j ] = pps->slice_group_change_direction_flag;
+
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Generate explicit slice group map type MapUnit map (type 6)
+ *
+ * \param img
+ * Image Parameter to be used for map generation
+ * \param pps
+ * Picture Parameter set to be used for map generation
+ ************************************************************************
+ */
+ static void FmoGenerateType6MapUnitMap (ImageParameters * img, pic_parameter_set_rbsp_t * pps )
+ {
+ unsigned i;
+ for (i=0; i<PicSizeInMapUnits; i++)
+ {
+ MapUnitToSliceGroupMap[i] = pps->slice_group_id[i];
+ }
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * FmoStartPicture: initializes FMO at the begin of each new picture
+ *
+ * \par Input:
+ * None
+ ************************************************************************
+ */
+ int FmoStartPicture ()
+ {
+ int i;
+
+ assert (MBAmap != NULL);
+
+ for (i=0; i<MAXSLICEGROUPIDS; i++)
+ FirstMBInSlice[i] = FmoGetFirstMBOfSliceGroup (i);
+ return 0;
+ }
+
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * FmoEndPicture: Ends the Scattered Slices Module (called once
+ * per picture).
+ *
+ * \par Input:
+ * None
+ ************************************************************************
+ */
+ int FmoEndPicture ()
+ {
+ // Do nothing
+ return 0;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * FmoMB2Slice: Returns SliceID for a given MB
+ *
+ * \par Input:
+ * Macroblock Nr (in scan order)
+ ************************************************************************
+ */
+ int FmoMB2SliceGroup ( int mb)
+ {
+ assert (mb < (int)img->PicSizeInMbs);
+ assert (MBAmap != NULL);
+ return MBAmap[mb];
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * FmoGetNextMBBr: Returns the MB-Nr (in scan order) of the next
+ * MB in the (FMO) Slice, -1 if the SliceGroup is finished
+ *
+ * \par Input:
+ * CurrentMbNr
+ ************************************************************************
+ */
+ int FmoGetNextMBNr (int CurrentMbNr)
+ {
+
+ int SliceGroupID = FmoMB2SliceGroup (CurrentMbNr);
+
+ while (++CurrentMbNr<(int)img->PicSizeInMbs && MBAmap[CurrentMbNr] != SliceGroupID)
+ ;
+
+ if (CurrentMbNr >= (int)img->PicSizeInMbs)
+ return -1; // No further MB in this slice (could be end of picture)
+ else
+ return CurrentMbNr;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * FmoGetNextMBBr: Returns the MB-Nr (in scan order) of the next
+ * MB in the (FMO) Slice, -1 if the SliceGroup is finished
+ *
+ * \par Input:
+ * CurrentMbNr
+ ************************************************************************
+ */
+ int FmoGetPreviousMBNr (int CurrentMbNr)
+ {
+
+ int SliceGroupID = FmoMB2SliceGroup (CurrentMbNr);
+ CurrentMbNr--;
+ while (CurrentMbNr>=0 && MBAmap[CurrentMbNr] != SliceGroupID)
+ CurrentMbNr--;
+
+ if (CurrentMbNr < 0)
+ return -1; // No previous MB in this slice
+ else
+ return CurrentMbNr;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * FmoGetFirstMBOfSliceGroup: Returns the MB-Nr (in scan order) of the
+ * next first MB of the Slice group, -1 if no such MB exists
+ *
+ * \par Input:
+ * SliceGroupID: Id of SliceGroup
+ ************************************************************************
+ */
+ int FmoGetFirstMBOfSliceGroup (int SliceGroupID)
+ {
+ int i = 0;
+ while ((i<(int)img->PicSizeInMbs) && (FmoMB2SliceGroup (i) != SliceGroupID))
+ i++;
+
+ if (i < (int)img->PicSizeInMbs)
+ return i;
+ else
+ return -1;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * FmoGetLastCodedMBOfSlice: Returns the MB-Nr (in scan order) of
+ * the last MB of the slice group
+ *
+ * \par Input:
+ * SliceGroupID
+ * \par Return
+ * MB Nr in case of success (is always >= 0)
+ * -1 if the SliceGroup doesn't exist
+ ************************************************************************
+ */
+ int FmoGetLastCodedMBOfSliceGroup (int SliceGroupID)
+ {
+ int i;
+ int LastMB = -1;
+
+ for (i=0; i<(int)img->PicSizeInMbs; i++)
+ if (FmoMB2SliceGroup (i) == SliceGroupID)
+ LastMB = i;
+ return LastMB;
+ }
+
+
+ void FmoSetLastMacroblockInSlice ( int mb)
+ {
+ // called by terminate_slice(), writes the last processed MB into the
+ // FirstMBInSlice[MAXSLICEGROUPIDS] array. FmoGetFirstMacroblockInSlice()
+ // uses this info to identify the first uncoded MB in each slice group
+
+ int currSliceGroup = FmoMB2SliceGroup (mb);
+ assert (mb >= 0);
+ mb = FmoGetNextMBNr (mb); // The next (still uncoded) MB, or -1 if SG is finished
+ FirstMBInSlice[currSliceGroup] = mb;
+ }
+
+ int FmoGetFirstMacroblockInSlice ( int SliceGroup)
+ {
+ return FirstMBInSlice[SliceGroup];
+ // returns the first uncoded MB in each slice group, -1 if there is no
+ // more to do in this slice group
+ }
+
+
+ int FmoSliceGroupCompletelyCoded( int SliceGroupID)
+ {
+ if (FmoGetFirstMacroblockInSlice (SliceGroupID) < 0) // slice group completelty coded or not present
+ return TRUE;
+ else
+ return FALSE;
+ }
+
+
+
Index: llvm-test/MultiSource/Applications/JM/lencod/fmo.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/fmo.h:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/fmo.h Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,39 ----
+
+ /*!
+ ***************************************************************************
+ *
+ * \file fmo.h
+ *
+ * \brief
+ * Support for Flexible Macroblock Ordering
+ *
+ * \date
+ * 16 June 2002
+ *
+ * \author
+ * Stephan Wenger stewe at cs.tu-berlin.de
+ **************************************************************************/
+
+ #ifndef _FMO_H_
+ #define _FMO_H_
+
+ #define MAXSLICEGROUPIDS 8
+
+ int FmoInit(ImageParameters * img, pic_parameter_set_rbsp_t * pps, seq_parameter_set_rbsp_t * sps);
+ void FmoUninit ();
+ int FmoFinit (seq_parameter_set_rbsp_t * sps);
+ int FmoMB2SliceGroup (int mb);
+ int FmoGetFirstMBOfSliceGroup (int SliceGroupID);
+ int FmoGetFirstMacroblockInSlice (int SliceGroup);
+ int FmoGetNextMBNr (int CurrentMbNr);
+ int FmoGetLastCodedMBOfSliceGroup (int SliceGroupID);
+ int FmoStartPicture ();
+ int FmoEndPicture();
+ int FmoSliceGroupCompletelyCoded(int SliceGroupID);
+ void FmoSetLastMacroblockInSlice (int mb);
+
+ int FmoGetPreviousMBNr (int CurrentMbNr);
+
+ extern byte *MBAmap;
+
+ #endif
Index: llvm-test/MultiSource/Applications/JM/lencod/global.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/global.h:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/global.h Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,1430 ----
+
+ /*!
+ ************************************************************************
+ * \file
+ * global.h
+ *
+ * \brief
+ * global definitions for for H.264 encoder.
+ *
+ * \author
+ * Copyright (C) 1999 Telenor Satellite Services,Norway
+ * Ericsson Radio Systems, Sweden
+ *
+ * Inge Lille-Langoy <inge.lille-langoy at telenor.com>
+ *
+ * Telenor Satellite Services
+ * Keysers gt.13 tel.: +47 23 13 86 98
+ * N-0130 Oslo,Norway fax.: +47 22 77 79 80
+ *
+ * Rickard Sjoberg <rickard.sjoberg at era.ericsson.se>
+ *
+ * Ericsson Radio Systems
+ * KI/ERA/T/VV
+ * 164 80 Stockholm, Sweden
+ *
+ ************************************************************************
+ */
+ #ifndef _GLOBAL_H_
+ #define _GLOBAL_H_
+
+ #include <stdio.h>
+
+ #include "defines.h"
+ #include "parsetcommon.h"
+ #include "q_matrix.h"
+ #include "q_offsets.h"
+ #include "minmax.h"
+
+ #ifdef WIN32
+ #define snprintf _snprintf
+ #endif
+
+ #if defined(WIN32) && !defined(__GNUC__)
+ typedef __int64 int64;
+ #ifndef INT64_MIN
+ # define INT64_MIN (-9223372036854775807i64 - 1i64)
+ #endif
+ #else
+ typedef long long int64;
+ #ifndef INT64_MIN
+ # define INT64_MIN (-9223372036854775807LL - 1LL)
+ #endif
+ #endif
+
+ #ifdef WIN32
+ #define snprintf _snprintf
+ #define open _open
+ #define close _close
+ #define read _read
+ #define write _write
+ #define lseek _lseeki64
+ #define fsync _commit
+ #define OPENFLAGS_WRITE _O_WRONLY|_O_CREAT|_O_BINARY|_O_TRUNC
+ #define OPEN_PERMISSIONS _S_IREAD | _S_IWRITE
+ #define OPENFLAGS_READ _O_RDONLY|_O_BINARY
+ #else
+ #define OPENFLAGS_WRITE O_WRONLY|O_CREAT|O_TRUNC
+ #define OPENFLAGS_READ O_RDONLY
+ #define OPEN_PERMISSIONS S_IRUSR | S_IWUSR
+ #endif
+
+
+ /***********************************************************************
+ * T y p e d e f i n i t i o n s f o r T M L
+ ***********************************************************************
+ */
+
+ //#define pel_t byte
+
+ #define imgpel unsigned short
+ #define distpel int
+ //#define imgpel byte
+ //#define distpel unsigned short
+
+ #define pel_t imgpel
+
+ //! Data Partitioning Modes
+ typedef enum
+ {
+ PAR_DP_1, //!< no data partitioning is supported
+ PAR_DP_3 //!< data partitioning with 3 partitions
+ } PAR_DP_TYPE;
+
+
+ //! Output File Types
+ typedef enum
+ {
+ PAR_OF_ANNEXB, //!< Annex B byte stream format
+ PAR_OF_RTP //!< RTP packets in outfile
+ } PAR_OF_TYPE;
+
+ //! Field Coding Types
+ typedef enum
+ {
+ FRAME_CODING,
+ FIELD_CODING,
+ ADAPTIVE_CODING
+ } CodingType;
+
+ //! definition of H.264 syntax elements
+ typedef enum
+ {
+ SE_HEADER,
+ SE_PTYPE,
+ SE_MBTYPE,
+ SE_REFFRAME,
+ SE_INTRAPREDMODE,
+ SE_MVD,
+ SE_CBP_INTRA,
+ SE_LUM_DC_INTRA,
+ SE_CHR_DC_INTRA,
+ SE_LUM_AC_INTRA,
+ SE_CHR_AC_INTRA,
+ SE_CBP_INTER,
+ SE_LUM_DC_INTER,
+ SE_CHR_DC_INTER,
+ SE_LUM_AC_INTER,
+ SE_CHR_AC_INTER,
+ SE_DELTA_QUANT_INTER,
+ SE_DELTA_QUANT_INTRA,
+ SE_BFRAME,
+ SE_EOS,
+ SE_MAX_ELEMENTS //!< number of maximum syntax elements
+ } SE_type; // substituting the definitions in elements.h
+
+
+ typedef enum
+ {
+ INTER_MB,
+ INTRA_MB_4x4,
+ INTRA_MB_16x16
+ } IntraInterDecision;
+
+
+ typedef enum
+ {
+ BITS_HEADER,
+ BITS_TOTAL_MB,
+ BITS_MB_MODE,
+ BITS_INTER_MB,
+ BITS_CBP_MB,
+ BITS_COEFF_Y_MB,
+ BITS_COEFF_UV_MB,
+ BITS_DELTA_QUANT_MB,
+ MAX_BITCOUNTER_MB
+ } BitCountType;
+
+
+ typedef enum
+ {
+ NO_SLICES,
+ FIXED_MB,
+ FIXED_RATE,
+ CALLBACK,
+ FMO
+ } SliceMode;
+
+
+ typedef enum
+ {
+ UVLC,
+ CABAC
+ } SymbolMode;
+
+
+ typedef enum
+ {
+ FRAME,
+ TOP_FIELD,
+ BOTTOM_FIELD
+ } PictureStructure; //!< New enum for field processing
+
+ typedef enum
+ {
+ P_SLICE = 0,
+ B_SLICE,
+ I_SLICE,
+ SP_SLICE,
+ SI_SLICE
+ } SliceType;
+
+ /***********************************************************************
+ * D a t a t y p e s f o r C A B A C
+ ***********************************************************************
+ */
+
+ //! struct to characterize the state of the arithmetic coding engine
+ typedef struct
+ {
+ unsigned int Elow, Erange;
+ unsigned int Ebuffer;
+ unsigned int Ebits_to_go;
+ unsigned int Ebits_to_follow;
+ byte *Ecodestrm;
+ int *Ecodestrm_len;
+ int C;
+ int E;
+
+ // storage in case of recode MB
+ unsigned int ElowS, ErangeS;
+ unsigned int EbufferS;
+ unsigned int Ebits_to_goS;
+ unsigned int Ebits_to_followS;
+ byte *EcodestrmS;
+ int *Ecodestrm_lenS;
+ int CS;
+ int ES;
+ } EncodingEnvironment;
+
+ typedef EncodingEnvironment *EncodingEnvironmentPtr;
+
+ //! struct for context management
+ typedef struct
+ {
+ unsigned short state; // index into state-table CP
+ unsigned char MPS; // Least Probable Symbol 0/1 CP
+
+ unsigned long count;
+
+ } BiContextType;
+
+ typedef BiContextType *BiContextTypePtr;
+
+
+ /**********************************************************************
+ * C O N T E X T S F O R T M L S Y N T A X E L E M E N T S
+ **********************************************************************
+ */
+
+
+ #define NUM_MB_TYPE_CTX 11
+ #define NUM_B8_TYPE_CTX 9
+ #define NUM_MV_RES_CTX 10
+ #define NUM_REF_NO_CTX 6
+ #define NUM_DELTA_QP_CTX 4
+ #define NUM_MB_AFF_CTX 4
+
+ #define NUM_TRANSFORM_SIZE_CTX 3
+
+ typedef struct
+ {
+ BiContextType mb_type_contexts [3][NUM_MB_TYPE_CTX];
+ BiContextType b8_type_contexts [2][NUM_B8_TYPE_CTX];
+ BiContextType mv_res_contexts [2][NUM_MV_RES_CTX];
+ BiContextType ref_no_contexts [2][NUM_REF_NO_CTX];
+ BiContextType delta_qp_contexts [NUM_DELTA_QP_CTX];
+ BiContextType mb_aff_contexts [NUM_MB_AFF_CTX];
+ BiContextType transform_size_contexts [NUM_TRANSFORM_SIZE_CTX];
+ } MotionInfoContexts;
+
+
+ #define NUM_IPR_CTX 2
+ #define NUM_CIPR_CTX 4
+ #define NUM_CBP_CTX 4
+ #define NUM_BCBP_CTX 4
+ #define NUM_MAP_CTX 15
+ #define NUM_LAST_CTX 15
+ #define NUM_ONE_CTX 5
+ #define NUM_ABS_CTX 5
+
+
+ typedef struct
+ {
+ BiContextType ipr_contexts [NUM_IPR_CTX];
+ BiContextType cipr_contexts[NUM_CIPR_CTX];
+ BiContextType cbp_contexts [3][NUM_CBP_CTX];
+ BiContextType bcbp_contexts[NUM_BLOCK_TYPES][NUM_BCBP_CTX];
+ BiContextType map_contexts [NUM_BLOCK_TYPES][NUM_MAP_CTX];
+ BiContextType last_contexts[NUM_BLOCK_TYPES][NUM_LAST_CTX];
+ BiContextType one_contexts [NUM_BLOCK_TYPES][NUM_ONE_CTX];
+ BiContextType abs_contexts [NUM_BLOCK_TYPES][NUM_ABS_CTX];
+ BiContextType fld_map_contexts [NUM_BLOCK_TYPES][NUM_MAP_CTX];
+ BiContextType fld_last_contexts[NUM_BLOCK_TYPES][NUM_LAST_CTX];
+ } TextureInfoContexts;
+
+ //*********************** end of data type definition for CABAC *******************
+
+ typedef struct pix_pos
+ {
+ int available;
+ int mb_addr;
+ int x;
+ int y;
+ int pos_x;
+ int pos_y;
+ } PixelPos;
+
+ /*! Buffer structure for RMPNI commands */
+ typedef struct RMPNIbuffer_s
+ {
+ int RMPNI;
+ int Data;
+ struct RMPNIbuffer_s *Next;
+ } RMPNIbuffer_t;
+
+ /*! Buffer structure for decoded referenc picture marking commands */
+ typedef struct DecRefPicMarking_s
+ {
+ int memory_management_control_operation;
+ int difference_of_pic_nums_minus1;
+ int long_term_pic_num;
+ int long_term_frame_idx;
+ int max_long_term_frame_idx_plus1;
+ struct DecRefPicMarking_s *Next;
+ } DecRefPicMarking_t;
+
+ //! Syntaxelement
+ typedef struct syntaxelement
+ {
+ int type; //!< type of syntax element for data part.
+ int value1; //!< numerical value of syntax element
+ int value2; //!< for blocked symbols, e.g. run/level
+ int len; //!< length of code
+ int inf; //!< info part of UVLC code
+ unsigned int bitpattern; //!< UVLC bitpattern
+ int context; //!< CABAC context
+ int k; //!< CABAC context for coeff_count,uv
+
+ #if TRACE
+ #define TRACESTRING_SIZE 100 //!< size of trace string
+ char tracestring[TRACESTRING_SIZE]; //!< trace string
+ #endif
+
+ //!< for mapping of syntaxElement to UVLC
+ void (*mapping)(int value1, int value2, int* len_ptr, int* info_ptr);
+ //!< used for CABAC: refers to actual coding method of each individual syntax element type
+ void (*writing)(struct syntaxelement *, EncodingEnvironmentPtr);
+
+ } SyntaxElement;
+
+ //! Macroblock
+ typedef struct macroblock
+ {
+ int currSEnr; //!< number of current syntax element
+ int slice_nr;
+ int delta_qp;
+ int qp ;
+ int qpsp ;
+ int bitcounter[MAX_BITCOUNTER_MB];
+
+ struct macroblock *mb_available_up; //!< pointer to neighboring MB (CABAC)
+ struct macroblock *mb_available_left; //!< pointer to neighboring MB (CABAC)
+
+ int mb_type;
+ int mvd[2][BLOCK_MULTIPLE][BLOCK_MULTIPLE][2]; //!< indices correspond to [forw,backw][block_y][block_x][x,y]
+ char intra_pred_modes[MB_BLOCK_PARTITIONS];
+ char intra_pred_modes8x8[MB_BLOCK_PARTITIONS]; //!< four 8x8 blocks in a macroblock
+ int cbp ;
+ int64 cbp_blk ; //!< 1 bit set for every 4x4 block with coefs (not implemented for INTRA)
+ int b8mode[4];
+ int b8pdir[4];
+ int64 cbp_bits;
+
+ int c_ipred_mode; //!< chroma intra prediction mode
+ int IntraChromaPredModeFlag;
+
+ int mb_field;
+ int list_offset;
+
+ int mbAddrA, mbAddrB, mbAddrC, mbAddrD;
+ int mbAvailA, mbAvailB, mbAvailC, mbAvailD;
+
+ int all_blk_8x8;
+ int luma_transform_size_8x8_flag;
+ int NoMbPartLessThan8x8Flag;
+
+ short bi_pred_me;
+
+ // rate control
+ double actj; // macroblock activity measure for macroblock j
+ int prev_qp;
+ int prev_delta_qp;
+ int prev_cbp;
+ int predict_qp;
+ int predict_error;
+
+ int LFDisableIdc;
+ int LFAlphaC0Offset;
+ int LFBetaOffset;
+
+ int skip_flag;
+ } Macroblock;
+
+
+
+ //! Bitstream
+ typedef struct
+ {
+ int byte_pos; //!< current position in bitstream;
+ int bits_to_go; //!< current bitcounter
+ byte byte_buf; //!< current buffer for last written byte
+ int stored_byte_pos; //!< storage for position in bitstream;
+ int stored_bits_to_go; //!< storage for bitcounter
+ byte stored_byte_buf; //!< storage for buffer of last written byte
+
+ byte byte_buf_skip; //!< current buffer for last written byte
+ int byte_pos_skip; //!< storage for position in bitstream;
+ int bits_to_go_skip; //!< storage for bitcounter
+
+ byte *streamBuffer; //!< actual buffer for written bytes
+ int write_flag; //!< Bitstream contains data and needs to be written
+
+ } Bitstream;
+
+ //! DataPartition
+ typedef struct datapartition
+ {
+
+ Bitstream *bitstream;
+ EncodingEnvironment ee_cabac;
+
+ int (*writeSyntaxElement)(SyntaxElement *, struct datapartition *);
+ /*!< virtual function;
+ actual method depends on chosen data partition and
+ entropy coding method */
+ } DataPartition;
+
+ //! Slice
+ typedef struct
+ {
+ int picture_id;
+ int qp;
+ int picture_type; //!< picture type
+ int start_mb_nr;
+ int max_part_nr; //!< number of different partitions
+ int num_mb; //!< number of MBs in the slice
+ DataPartition *partArr; //!< array of partitions
+ MotionInfoContexts *mot_ctx; //!< pointer to struct of context models for use in CABAC
+ TextureInfoContexts *tex_ctx; //!< pointer to struct of context models for use in CABAC
+
+ // !KS: RMPNI buffer should be retired. just do some sore simple stuff
+ RMPNIbuffer_t *rmpni_buffer; //!< stores the slice temporary buffer remapping commands
+
+ int ref_pic_list_reordering_flag_l0;
+ int *reordering_of_pic_nums_idc_l0;
+ int *abs_diff_pic_num_minus1_l0;
+ int *long_term_pic_idx_l0;
+ int ref_pic_list_reordering_flag_l1;
+ int *reordering_of_pic_nums_idc_l1;
+ int *abs_diff_pic_num_minus1_l1;
+ int *long_term_pic_idx_l1;
+
+ Boolean (*slice_too_big)(int bits_slice); //!< for use of callback functions
+
+ int field_ctx[3][2]; //GB
+
+ } Slice;
+
+
+ #define MAXSLICEPERPICTURE 100
+ typedef struct
+ {
+ int no_slices;
+ int idr_flag;
+ Slice *slices[MAXSLICEPERPICTURE];
+ int bits_per_picture;
+ float distortion_y;
+ float distortion_u;
+ float distortion_v;
+ } Picture;
+
+ Picture *top_pic;
+ Picture *bottom_pic;
+ Picture *frame_pic;
+ Picture *frame_pic_1;
+ Picture *frame_pic_2;
+ Picture *frame_pic_3;
+
+ // global picture format dependend buffers, mem allocation in image.c
+ imgpel **imgY_org; //!< Reference luma image
+ imgpel ***imgUV_org; //!< Reference chroma image
+ int **img4Y_tmp; //!< for quarter pel interpolation
+
+ unsigned int log2_max_frame_num_minus4;
+ unsigned int log2_max_pic_order_cnt_lsb_minus4;
+
+ int me_tot_time,me_time;
+ pic_parameter_set_rbsp_t *active_pps;
+ seq_parameter_set_rbsp_t *active_sps;
+
+ // B pictures
+ // motion vector : forward, backward, direct
+ int mb_adaptive; //!< For MB level field/frame coding tools
+ int MBPairIsField; //!< For MB level field/frame coding tools
+
+
+ //Weighted prediction
+ int ***wp_weight; // weight in [list][index][component] order
+ int ***wp_offset; // offset in [list][index][component] order
+ int ****wbp_weight; // weight in [list][fwd_index][bwd_idx][component] order
+ int luma_log_weight_denom;
+ int chroma_log_weight_denom;
+ int wp_luma_round;
+ int wp_chroma_round;
+
+ // global picture format dependend buffers, mem allocation in image.c (field picture)
+ imgpel **imgY_org_top;
+ imgpel **imgY_org_bot;
+
+ imgpel ***imgUV_org_top;
+ imgpel ***imgUV_org_bot;
+
+ imgpel **imgY_org_frm;
+ imgpel ***imgUV_org_frm;
+
+ imgpel **imgY_com; //!< Encoded luma images
+ imgpel ***imgUV_com; //!< Encoded croma images
+
+ char ***direct_ref_idx; //!< direct mode reference index buffer
+ short **direct_pdir; //!< direct mode reference index buffer
+
+ // Buffers for rd optimization with packet losses, Dim. Kontopodis
+ byte **pixel_map; //!< Shows the latest reference frame that is reliable for each pixel
+ byte **refresh_map; //!< Stores the new values for pixel_map
+ int intras; //!< Counts the intra updates in each frame.
+
+ int frame_ctr[5];
+ int frame_no, nextP_tr_fld, nextP_tr_frm;
+ int tot_time;
+
+ #define ET_SIZE 300 //!< size of error text buffer
+ char errortext[ET_SIZE]; //!< buffer for error message for exit with error()
+
+ // Residue Color Transform
+ int resTrans_R[16][16], resTrans_G[16][16], resTrans_B[16][16];
+ int rec_resR[16][16], rec_resG[16][16], rec_resB[16][16];
+ int mprRGB[3][16][16];
+ int dc_level[2][4][4], dc_level_temp[2][4][4];
+ int cbp_chroma_block[2][4][4], cbp_chroma_block_temp[2][4][4];
+ char b8_ipredmode8x8[4][4], b8_intra_pred_modes8x8[16];
+
+ //! Info for the "decoders-in-the-encoder" used for rdoptimization with packet losses
+ typedef struct
+ {
+ int **resY; //!< Residue of Luminance
+ imgpel ***decY; //!< Decoded values at the simulated decoders
+ imgpel ****decref; //!< Reference frames of the simulated decoders
+ imgpel ***decY_best; //!< Decoded frames for the best mode for all decoders
+ imgpel **RefBlock;
+ byte **status_map;
+ byte **dec_mb_mode;
+ } Decoders;
+ extern Decoders *decs;
+
+ //! SNRParameters
+ typedef struct
+ {
+ float snr_y; //!< current Y SNR
+ float snr_u; //!< current U SNR
+ float snr_v; //!< current V SNR
+ float snr_y1; //!< SNR Y(dB) first frame
+ float snr_u1; //!< SNR U(dB) first frame
+ float snr_v1; //!< SNR V(dB) first frame
+ float snr_yt[5]; //!< SNR Y(dB) based on frame type
+ float snr_ut[5]; //!< SNR U(dB) based on frame type
+ float snr_vt[5]; //!< SNR V(dB) based on frame type
+ float snr_ya; //!< Average SNR Y(dB) remaining frames
+ float snr_ua; //!< Average SNR U(dB) remaining frames
+ float snr_va; //!< Average SNR V(dB) remaining frames
+ float sse_y; //!< SSE Y
+ float sse_u; //!< SSE U
+ float sse_v; //!< SSE V
+ float msse_y; //!< Average SSE Y
+ float msse_u; //!< Average SSE U
+ float msse_v; //!< Average SSE V
+ int frame_ctr; //!< number of coded frames
+ } SNRParameters;
+
+ #define FILE_NAME_SIZE 200
+ //! all input parameters
+ typedef struct
+ {
+ int ProfileIDC; //!< profile idc
+ int LevelIDC; //!< level idc
+
+ int no_frames; //!< number of frames to be encoded
+ int qp0; //!< QP of first frame
+ int qpN; //!< QP of remaining frames
+ int jumpd; //!< number of frames to skip in input sequence (e.g 2 takes frame 0,3,6,9...)
+ int hadamard; /*!< 0: 'normal' SAD in sub pixel search. 1: use 4x4 Hadamard transform and '
+ Sum of absolute transform difference' in sub pixel search */
+ int DisableSubpelME; //!< Disable Subpixel Motion Estimation
+ int search_range; /*!< search range - integer pel search and 16x16 blocks. The search window is
+ generally around the predicted vector. Max vector is 2xmcrange. For 8x8
+ and 4x4 block sizes the search range is 1/2 of that for 16x16 blocks. */
+ int num_ref_frames; //!< number of reference frames to be used
+ int P_List0_refs;
+ int B_List0_refs;
+ int B_List1_refs;
+ int Log2MaxFNumMinus4;
+ int Log2MaxPOCLsbMinus4;
+ int ResendPPS;
+ int GenerateMultiplePPS;
+
+ int img_width; //!< image width (must be a multiple of 16 pels)
+ int img_height; //!< image height (must be a multiple of 16 pels)
+ int yuv_format; //!< YUV format (0=4:0:0, 1=4:2:0, 2=4:2:2, 3=4:4:4)
+ int intra_upd; /*!< For error robustness. 0: no special action. 1: One GOB/frame is intra coded
+ as regular 'update'. 2: One GOB every 2 frames is intra coded etc.
+ In connection with this intra update, restrictions is put on motion vectors
+ to prevent errors to propagate from the past */
+ int blc_size[8][2]; //!< array for different block sizes
+ int part_size[8][2]; //!< array for different partition sizes
+ int slice_mode; //!< Indicate what algorithm to use for setting slices
+ int slice_argument; //!< Argument to the specified slice algorithm
+ int UseConstrainedIntraPred; //!< 0: Inter MB pixels are allowed for intra prediction 1: Not allowed
+ int infile_header; //!< If input file has a header set this to the length of the header
+ char infile[FILE_NAME_SIZE]; //!< YUV 4:2:0 input format
+ char outfile[FILE_NAME_SIZE]; //!< H.264 compressed output bitstream
+ char ReconFile[FILE_NAME_SIZE]; //!< Reconstructed Pictures
+ char TraceFile[FILE_NAME_SIZE]; //!< Trace Outputs
+ char QmatrixFile[FILE_NAME_SIZE]; //!< Q matrix cfg file
+ int intra_period; //!< Random Access period though intra
+ int EnableOpenGOP; //!< support for open gops.
+
+ int idr_enable; //!< Encode intra slices as IDR
+ int start_frame; //!< Encode sequence starting from Frame start_frame
+
+ // B pictures
+ int successive_Bframe; //!< number of B frames that will be used
+ int qpB; //!< QP for non-reference B slice coded pictures
+ int qpBRSOffset; //!< QP for reference B slice coded pictures
+ int direct_spatial_mv_pred_flag; //!< Direct Mode type to be used (0: Temporal, 1: Spatial)
+ int directInferenceFlag; //!< Direct Inference Flag
+
+ int BiPredMotionEstimation;
+ int BiPredMERefinements;
+ int BiPredMESearchRange;
+ int BiPredMESubPel;
+
+
+ // SP Pictures
+ int sp_periodicity; //!< The periodicity of SP-pictures
+ int qpsp; //!< SP Picture QP for prediction error
+ int qpsp_pred; //!< SP Picture QP for predicted block
+
+ int WeightedPrediction; //!< Weighted prediciton for P frames (0: not used, 1: explicit)
+ int WeightedBiprediction; //!< Weighted prediciton for B frames (0: not used, 1: explicit, 2: implicit)
+ int UseWeightedReferenceME; //!< Use Weighted Reference for ME.
+ int RDPictureDecision; //!< Perform RD optimal decision between various coded versions of same picture
+ int RDPictureIntra; //!< Enabled RD pic decision for intra as well.
+ int RDPSliceWeightOnly; //!< If enabled, does not check QP variations for P slices.
+ int RDPSliceBTest; //!< Tests B slice replacement for P.
+ int RDBSliceWeightOnly; //!< If enabled, does not check QP variations for B slices.
+ int SkipIntraInInterSlices; //!< Skip intra type checking in inter slices if best_mode is skip/direct
+ int BRefPictures; //!< B coded reference pictures replace P pictures (0: not used, 1: used)
+ int PyramidCoding;
+ int PyramidLevelQPEnable;
+ char ExplicitPyramidFormat[1024]; //!< Explicit GOP format (PyramidCoding==3).
+ int PyramidRefReorder; //!< Reordering based on Poc distances for PyramidCoding
+ int PocMemoryManagement; //!< Memory management based on Poc distances for PyramidCoding
+
+ int symbol_mode; //!< Specifies the mode the symbols are mapped on bits
+ int of_mode; //!< Specifies the mode of the output file
+ int partition_mode; //!< Specifies the mode of data partitioning
+
+ int InterSearch16x16;
+ int InterSearch16x8;
+ int InterSearch8x16;
+ int InterSearch8x8;
+ int InterSearch8x4;
+ int InterSearch4x8;
+ int InterSearch4x4;
+
+ int IntraDisableInterOnly;
+ int Intra4x4ParDisable;
+ int Intra4x4DiagDisable;
+ int Intra4x4DirDisable;
+ int Intra16x16ParDisable;
+ int Intra16x16PlaneDisable;
+ int ChromaIntraDisable;
+
+ int EnableIPCM;
+
+ double FrameRate;
+
+ int EPZSPattern;
+ int EPZSDual;
+ int EPZSFixed;
+ int EPZSTemporal;
+ int EPZSSpatialMem;
+ int EPZSMinThresScale;
+ int EPZSMaxThresScale;
+ int EPZSMedThresScale;
+
+ int chroma_qp_index_offset;
+ #ifdef _FULL_SEARCH_RANGE_
+ int full_search;
+ #endif
+ #ifdef _ADAPT_LAST_GROUP_
+ int last_frame;
+ #endif
+ #ifdef _CHANGE_QP_
+ int qpN2, qpB2, qp2start;
+ int qp02, qpBRS2Offset;
+ #endif
+ int rdopt;
+ int disthres;
+ int nobskip;
+
+ #ifdef _LEAKYBUCKET_
+ int NumberLeakyBuckets;
+ char LeakyBucketRateFile[FILE_NAME_SIZE];
+ char LeakyBucketParamFile[FILE_NAME_SIZE];
+ #endif
+
+ int PicInterlace; //!< picture adaptive frame/field
+ int MbInterlace; //!< macroblock adaptive frame/field
+
+ int IntraBottom; //!< Force Intra Bottom at GOP periods.
+
+ int LossRateA; //!< assumed loss probablility of partition A (or full slice), in per cent, used for loss-aware R/D optimization
+ int LossRateB; //!< assumed loss probablility of partition B, in per cent, used for loss-aware R/D
+ int LossRateC; //!< assumed loss probablility of partition C, in per cent, used for loss-aware R/D
+ int NoOfDecoders;
+ int RestrictRef;
+ int NumFramesInELSubSeq;
+ int NumFrameIn2ndIGOP;
+
+ int RandomIntraMBRefresh; //!< Number of pseudo-random intra-MBs per picture
+
+ int LFSendParameters;
+ int LFDisableIdc;
+ int LFAlphaC0Offset;
+ int LFBetaOffset;
+
+ int SparePictureOption;
+ int SPDetectionThreshold;
+ int SPPercentageThreshold;
+
+ // FMO
+ char SliceGroupConfigFileName[FILE_NAME_SIZE]; //!< Filename for config info fot type 0, 2, 6
+ int num_slice_groups_minus1; //!< "FmoNumSliceGroups" in encoder.cfg, same as FmoNumSliceGroups, which should be erased later
+ int slice_group_map_type;
+
+ int *top_left; //!< top_left and bottom_right store values indicating foregrounds
+ int *bottom_right;
+ byte *slice_group_id; //!< slice_group_id is for slice group type being 6
+ int *run_length_minus1; //!< run_length_minus1 is for slice group type being 0
+
+ int slice_group_change_direction_flag;
+ int slice_group_change_rate_minus1;
+ int slice_group_change_cycle;
+
+ int redundant_slice_flag; //! whether redundant slices exist, JVT-D101
+ int pic_order_cnt_type; // POC200301
+
+ int context_init_method;
+ int model_number;
+ int Transform8x8Mode;
+ int ReportFrameStats;
+ int DisplayEncParams;
+ int Verbose;
+
+ //! Rate Control on JVT standard
+ int RCEnable;
+ int bit_rate;
+ int SeinitialQP;
+ int basicunit;
+ int channel_type;
+
+ int ScalingMatrixPresentFlag;
+ int ScalingListPresentFlag[8];
+
+ // FastME enable
+ int FMEnable;
+
+ // Fidelity Range Extensions
+ int BitDepthLuma;
+ int BitDepthChroma;
+ int img_height_cr;
+ int img_width_cr;
+ int rgb_input_flag;
+ int cb_qp_index_offset;
+ int cr_qp_index_offset;
+
+ // Lossless Coding
+ int lossless_qpprime_y_zero_flag;
+
+ //Residue Color Transform
+ int residue_transform_flag;
+
+ // Lambda Params
+ int UseExplicitLambdaParams;
+ double LambdaWeight[6];
+
+ char QOffsetMatrixFile[FILE_NAME_SIZE]; //!< Quantization Offset matrix cfg file
+ int OffsetMatrixPresentFlag; //!< Enable Explicit Quantization Offset Matrices
+
+ int AdaptiveRounding; //!< Adaptive Rounding parameter based on JVT-N011
+ int AdaptRndPeriod; //!< Set period for adaptive rounding of JVT-N011 in MBs
+ int AdaptRndChroma;
+ int AdaptRndWFactor[2][5]; //!< Weighting factors based on reference indicator and slice type
+ // Fast Mode Decision
+ int EarlySkipEnable;
+ int SelectiveIntraEnable;
+ int DisposableP;
+ int DispPQPOffset;
+ } InputParameters;
+
+ //! ImageParameters
+ typedef struct
+ {
+ int number; //!< current image number to be encoded
+ int pn; //!< picture number
+ int LevelIndex; //!< mapped level idc
+ int current_mb_nr;
+ int total_number_mb;
+ int current_slice_nr;
+ int type;
+ int structure; //!< picture structure
+ int num_ref_frames; //!< number of reference frames to be used
+ int max_num_references; //!< maximum number of reference pictures that may occur
+ int qp; //!< quant for the current frame
+ int qpsp; //!< quant for the prediction frame of SP-frame
+ float framerate;
+ int width; //!< Number of pels
+ int width_cr; //!< Number of pels chroma
+ int height; //!< Number of lines
+ int height_cr; //!< Number of lines chroma
+ int height_cr_frame; //!< Number of lines chroma frame
+ int subblock_x; //!< current subblock horizontal
+ int subblock_y; //!< current subblock vertical
+ int is_intra_block;
+ int is_v_block;
+ int mb_y_upd;
+ int mb_y_intra; //!< which GOB to intra code
+ int block_c_x; //!< current block chroma vertical
+ char **ipredmode; //!< intra prediction mode
+ char **ipredmode8x8; //!< help storage for 8x8 modes, inserted by YV
+
+ int cod_counter; //!< Current count of number of skipped macroblocks in a row
+ int ***nz_coeff; //!< number of coefficients per block (CAVLC)
+
+ int mb_x; //!< current MB horizontal
+ int mb_y; //!< current MB vertical
+ int block_x; //!< current block horizontal
+ int block_y; //!< current block vertical
+ int pix_x; //!< current pixel horizontal
+ int pix_y; //!< current pixel vertical
+ int pix_c_x; //!< current pixel chroma horizontal
+ int pix_c_y; //!< current pixel chroma vertical
+
+ int opix_x; //!< current original picture pixel horizontal
+ int opix_y; //!< current original picture pixel vertical
+ int opix_c_x; //!< current original picture pixel chroma horizontal
+ int opix_c_y; //!< current original picture pixel chroma vertical
+
+
+ // some temporal buffers
+ imgpel mprr[9][16][16]; //!< all 9 prediction modes? // enlarged from 4 to 16 for ABT (is that neccessary?)
+
+ imgpel mprr_2[5][16][16]; //!< all 4 new intra prediction modes
+ imgpel mprr_3[9][8][8]; //!< all 9 prediction modes for 8x8 transformation
+ imgpel mprr_c[2][4][16][16]; //!< chroma intra prediction modes
+ imgpel mpr[16][16]; //!< current best prediction mode
+ int m7[16][16]; //!< the diff pixel values between orginal image and prediction
+
+ int ****cofAC; //!< AC coefficients [8x8block][4x4block][level/run][scan_pos]
+ int ***cofDC; //!< DC coefficients [yuv][level/run][scan_pos]
+
+ int fadjust4x4[4][16][16]; //!< Transform coefficients for 4x4 luma. Excludes DC for I16x16
+ int fadjust8x8[3][16][16]; //!< Transform coefficients for 8x8 luma
+ int fadjust4x4Cr[4][2][16][16]; //!< Transform coefficients for 4x4 chroma. Excludes DC chroma.
+ int fadjust8x8Cr[1][2][16][16]; //!< Transform coefficients for 4x4 chroma within 8x8 inter blocks.
+
+ Picture *currentPicture; //!< The coded picture currently in the works (typically frame_pic, top_pic, or bottom_pic)
+ Slice *currentSlice; //!< pointer to current Slice data struct
+ Macroblock *mb_data; //!< array containing all MBs of a whole frame
+ SyntaxElement MB_SyntaxElements[MAX_SYMBOLS_PER_MB]; //!< temporal storage for all chosen syntax elements of one MB
+
+ int *quad; //!< Array containing square values,used for snr computation */ /* Values are limited to 5000 for pixel differences over 70 (sqr(5000)).
+ int *intra_block;
+
+ int tr;
+ int fld_type; //!< top or bottom field
+ unsigned int fld_flag;
+ unsigned int rd_pass;
+ int direct_intraP_ref[4][4];
+ int pstruct_next_P;
+ int imgtr_next_P_frm;
+ int imgtr_last_P_frm;
+ int imgtr_next_P_fld;
+ int imgtr_last_P_fld;
+
+ // B pictures
+ double b_interval;
+ int p_interval;
+ int b_frame_to_code;
+ int fw_mb_mode;
+ int bw_mb_mode;
+
+ short****** pred_mv; //!< motion vector predictors for all block types and all reference frames
+ short****** all_mv; //!< replaces local all_mv
+
+ short****** bipred_mv1; //!< Biprediction MVs
+ short****** bipred_mv2; //!< Biprediction MVs
+ short bi_pred_me[MAXMODE];
+
+ int LFDisableIdc;
+ int LFAlphaC0Offset;
+ int LFBetaOffset;
+
+ int direct_spatial_mv_pred_flag; //!< Direct Mode type to be used (0: Temporal, 1: Spatial)
+
+ int num_ref_idx_l0_active;
+ int num_ref_idx_l1_active;
+
+ int field_mode; //!< For MB level field/frame -- field mode on flag
+ int top_field; //!< For MB level field/frame -- top field flag
+ int mvscale[6][MAX_REFERENCE_PICTURES];
+ int buf_cycle;
+ int i16offset;
+
+ int layer; //!< which layer this picture belonged to
+ int old_layer; //!< old layer number
+ int NoResidueDirect;
+ int AdaptiveRounding; //!< Adaptive Rounding parameter based on JVT-N011
+
+ int redundant_pic_cnt; // JVT-D101
+
+ int MbaffFrameFlag; //!< indicates frame with mb aff coding
+
+ //the following should probably go in sequence parameters
+ // unsigned int log2_max_frame_num_minus4;
+ unsigned int pic_order_cnt_type;
+ // for poc mode 0, POC200301
+ // unsigned int log2_max_pic_order_cnt_lsb_minus4;
+ // for poc mode 1, POC200301
+ unsigned int delta_pic_order_always_zero_flag;
+ int offset_for_non_ref_pic;
+ int offset_for_top_to_bottom_field;
+ unsigned int num_ref_frames_in_pic_order_cnt_cycle;
+ int offset_for_ref_frame[1]; // MAX_LENGTH_POC_CYCLE in decoder
+
+ // POC200301
+ //the following is for slice header syntax elements of poc
+ // for poc mode 0.
+ unsigned int pic_order_cnt_lsb;
+ int delta_pic_order_cnt_bottom;
+ // for poc mode 1.
+ int delta_pic_order_cnt[2];
+
+
+ // POC200301
+ unsigned int field_picture;
+ signed int toppoc; //!< poc for this frame or field
+ signed int bottompoc; //!< for completeness - poc of bottom field of a frame (always = poc+1)
+ signed int framepoc; //!< min (toppoc, bottompoc)
+ signed int ThisPOC; //!< current picture POC
+ unsigned int frame_num; //!< frame_num for this frame
+
+ unsigned PicWidthInMbs;
+ unsigned PicHeightInMapUnits;
+ unsigned FrameHeightInMbs;
+ unsigned PicHeightInMbs;
+ unsigned PicSizeInMbs;
+ unsigned FrameSizeInMbs;
+
+ //the following should probably go in picture parameters
+ unsigned int pic_order_present_flag; // ????????
+
+ //the following are sent in the slice header
+ // int delta_pic_order_cnt[2];
+ int nal_reference_idc;
+
+ int adaptive_ref_pic_buffering_flag;
+ int no_output_of_prior_pics_flag;
+ int long_term_reference_flag;
+
+ DecRefPicMarking_t *dec_ref_pic_marking_buffer;
+
+ int model_number;
+
+
+ /*rate control*/
+ int NumberofHeaderBits;
+ int NumberofTextureBits;
+ int NumberofBasicUnitHeaderBits;
+ int NumberofBasicUnitTextureBits;
+ double TotalMADBasicUnit;
+ int NumberofMBTextureBits;
+ int NumberofMBHeaderBits;
+ int NumberofCodedBFrame;
+ int NumberofCodedPFrame;
+ int NumberofGOP;
+ int TotalQpforPPicture;
+ int NumberofPPicture;
+ double *MADofMB;
+ int BasicUnitQP;
+ int TopFieldFlag;
+ int FieldControl;
+ int FieldFrame;
+ int Frame_Total_Number_MB;
+ int IFLAG;
+ int NumberofCodedMacroBlocks;
+ int BasicUnit;
+ int write_macroblock;
+ int bot_MB;
+ int write_macroblock_frame;
+
+ int DeblockCall;
+
+ int last_pic_bottom_field;
+ int last_has_mmco_5;
+ int pre_frame_num;
+
+ int slice_group_change_cycle;
+
+ int pic_unit_size_on_disk;
+ int bitdepth_luma;
+ int bitdepth_chroma;
+ int bitdepth_luma_qp_scale;
+ int bitdepth_chroma_qp_scale;
+ int bitdepth_lambda_scale;
+ // Lagrangian Parameters
+ double lambda_md[10][52]; //!< Mode decision Lambda
+ double lambda_me[10][52]; //!< Motion Estimation Lambda
+ int lambda_mf[10][52]; //!< Integer formatted Motion Estimation Lambda
+
+ unsigned int dc_pred_value; //!< value for DC prediction (depends on pel bit depth)
+ int max_imgpel_value; //!< max value that one picture element (pixel) can take (depends on pic_unit_bitdepth)
+ int max_imgpel_value_uv;
+
+ int num_blk8x8_uv;
+ int num_cdc_coeff;
+ int yuv_format;
+ int lossless_qpprime_flag;
+ int mb_cr_size_x;
+ int mb_cr_size_y;
+
+ int chroma_qp_offset[2]; //!< offset for qp for chroma [0-Cb, 1-Cr]
+
+ // Residue Color Transform
+ int residue_transform_flag;
+
+ int auto_crop_right;
+ int auto_crop_bottom;
+
+ short checkref;
+ int last_valid_reference;
+
+
+ int bytes_in_picture;
+ } ImageParameters;
+
+ #define NUM_PIC_TYPE 5
+ //!< statistics
+ typedef struct
+ {
+ int quant0; //!< quant for the first frame
+ int quant1; //!< average quant for the remaining frames
+ float bitr; //!< bit rate for current frame, used only for output til terminal
+ float bitrate; //!< average bit rate for the sequence except first frame
+ int bit_ctr; //!< counter for bit usage
+ int bit_ctr_n; //!< bit usage for the current frame
+ int bit_slice; //!< number of bits in current slice
+ int bit_ctr_emulationprevention; //!< stored bits needed to prevent start code emulation
+ int b8_mode_0_use[NUM_PIC_TYPE][2];
+ int mode_use_transform_8x8[NUM_PIC_TYPE][MAXMODE];
+ int mode_use_transform_4x4[NUM_PIC_TYPE][MAXMODE];
+ int intra_chroma_mode[4];
+
+ // B pictures
+ int successive_Bframe;
+ int *mode_use_Bframe;
+ int *bit_use_mode_Bframe;
+ int bit_ctr_I;
+ int bit_ctr_P;
+ int bit_ctr_B;
+ float bitrate_I;
+ float bitrate_P;
+ float bitrate_B;
+
+ int mode_use [NUM_PIC_TYPE][MAXMODE]; //!< Macroblock mode usage for Intra frames
+ int bit_use_mode [NUM_PIC_TYPE][MAXMODE]; //!< statistics of bit usage
+ int bit_use_stuffingBits[NUM_PIC_TYPE];
+ int bit_use_mb_type [NUM_PIC_TYPE];
+ int bit_use_header [NUM_PIC_TYPE];
+ int tmp_bit_use_cbp [NUM_PIC_TYPE];
+ int bit_use_coeffY [NUM_PIC_TYPE];
+ int bit_use_coeffC [NUM_PIC_TYPE];
+ int bit_use_delta_quant [NUM_PIC_TYPE];
+
+ int em_prev_bits_frm;
+ int em_prev_bits_fld;
+ int *em_prev_bits;
+ int bit_ctr_parametersets;
+ int bit_ctr_parametersets_n;
+ } StatParameters;
+
+ //!< For MB level field/frame coding tools
+ //!< temporary structure to store MB data for field/frame coding
+ typedef struct
+ {
+ double min_rdcost;
+
+ imgpel rec_mbY[16][16]; // hold the Y component of reconstructed MB
+ imgpel rec_mbU[16][16], rec_mbV[16][16];
+ int ****cofAC;
+ int ***cofDC;
+ int mb_type;
+ short bi_pred_me;
+
+ int b8mode[4], b8pdir[4];
+ char **ipredmode;
+ char intra_pred_modes[16];
+ int cbp;
+ int64 cbp_blk;
+ int mode;
+ short ******pred_mv; //!< predicted motion vectors
+ short ******all_mv; //!< all modes motion vectors
+ char refar[2][4][4]; //!< reference frame array [list][y][x]
+ int i16offset;
+ int c_ipred_mode;
+
+ int luma_transform_size_8x8_flag;
+ int NoMbPartLessThan8x8Flag;
+
+ int qp;
+ int prev_qp;
+ int prev_delta_qp;
+ int delta_qp;
+ int prev_cbp;
+ } RD_DATA;
+
+
+ //!< Set Explicit GOP Parameters.
+ //!< Currently only supports Enhancement GOP but could be easily extended
+ typedef struct
+ {
+ int slice_type; //! Slice type
+ int display_no; //! GOP Display order
+ int reference_idc; //! Is reference?
+ int slice_qp; //! Assigned QP
+ int pyramid_layer; //! Pyramid layer (used with GOP Pyramid option 2
+ int pyramidPocDelta; //! Currently unused
+ } GOP_DATA;
+
+
+ typedef struct
+ {
+ int cost8x8;
+ int rec_resG_8x8[16][16];
+ int resTrans_R_8x8[16][16];
+ int resTrans_B_8x8[16][16];
+ int mprRGB_8x8[3][16][16];
+ short part8x8mode[4];
+ short part8x8pdir[4];
+ char part8x8fwref[4];
+ char part8x8bwref[4];
+ imgpel rec_mbY8x8[16][16];
+ imgpel mpr8x8[16][16];
+ } RD_8x8DATA;
+
+ typedef struct
+ {
+ double lambda_md; //!< Mode decision Lambda
+ double lambda_me; //!< Motion Estimation Lambda
+ int lambda_mf; //!< Integer formatted Motion Estimation Lambda
+
+ short valid[MAXMODE];
+ short list_offset[2];
+ short curr_mb_field;
+ short best_ref[2];
+ int best_mcost[2];
+ } RD_PARAMS;
+
+ GOP_DATA *gop_structure;
+ RD_DATA *rdopt;
+ RD_DATA rddata_top_frame_mb, rddata_bot_frame_mb; //!< For MB level field/frame coding tools
+ RD_DATA rddata_top_field_mb, rddata_bot_field_mb; //!< For MB level field/frame coding tools
+
+ extern InputParameters *input;
+ extern ImageParameters *img;
+ extern StatParameters *stats;
+
+ extern SNRParameters *snr;
+
+ // files
+ FILE *p_stat; //!< status file for the last encoding session
+ FILE *p_log; //!< SNR file
+ FILE *p_trace; //!< Trace file
+ int p_in; //!< original YUV file handle
+ int p_dec; //!< decoded image file handle
+
+
+ /***********************************************************************
+ * P r o t o t y p e s f o r T M L
+ ***********************************************************************
+ */
+
+ void intrapred_luma(int CurrPixX,int CurrPixY, int *left_available, int *up_available, int *all_available);
+ void init();
+ int dct_luma(int pos_mb1,int pos_mb2,int *cnt_nonz, int intra);
+ int dct_luma_sp(int pos_mb1,int pos_mb2,int *cnt_nonz);
+ void copyblock_sp(int pos_mb1,int pos_mb2);
+ int dct_chroma(int uv,int i11);
+ int dct_chroma_sp(int uv,int i11);
+ // Residue Color Transform
+ int dct_chroma4x4(int uv, int b8, int b4);
+ int dct_chroma_DC(int uv, int cr_cbp);
+
+ int motion_search(int isi);
+ int sign(int a,int b);
+ void intrapred_chroma(int,int,int uv);
+ void intrapred_luma_16x16();
+ int find_sad_16x16(int *intra_mode);
+
+ int dct_luma_16x16(int);
+
+ void init_poc();
+
+ void init_img();
+ void report();
+ void information_init();
+ int get_picture_type();
+ int clip1a(int a);
+ void DeblockFrame(ImageParameters *img, imgpel **, imgpel ***) ;
+ void MarkAllMacroblockModes(ImageParameters *img, imgpel **, imgpel ***);
+
+ int TransformDecision(int, int*);
+ int SATD8X8(int*, int);
+
+ void LumaPrediction4x4 (int, int, int, int, int, short, short);
+ int SATD (int*, int);
+ int find_SATD (int c_diff[MB_PIXELS], int blocktype);
+
+ pel_t* FastLineX (int, pel_t*, int, int, int, int);
+ pel_t* UMVLineX (int, pel_t*, int, int, int, int);
+
+ void LumaResidualCoding ();
+ void ChromaResidualCoding (int*);
+ void IntraChromaPrediction (int*, int*, int*);
+ void ChromaPrediction4x4 (int, int, int, int, int, int, short, short);
+
+ int writeMBLayer (int rdopt, int *coeff_rate);
+
+ extern int* refbits;
+ extern int**** motion_cost;
+
+ void Get_Direct_Motion_Vectors ();
+ void PartitionMotionSearch (int, int, int);
+ int BIDPartitionCost (int, int, short, short, int);
+ int LumaResidualCoding8x8 (int*, int64*, int, short, int, int, short, short);
+ int writeLumaCoeff8x8 (int, int, int);
+ int writeMotionVector8x8 (int i0, int j0, int i1, int j1, int refframe, int list_idx, int mv_mode);
+ int writeReferenceFrame (int, int, int, int, int);
+ int writeAbpCoeffIndex (int, int, int, int);
+ int writeIntra4x4Modes (int);
+ int writeChromaIntraPredMode ();
+
+ void estimate_weighting_factor_B_slice();
+ void estimate_weighting_factor_P_slice(int offset);
+ int test_wp_P_slice(int offset);
+ int test_wp_B_slice(int method);
+ void poc_based_ref_management(int current_pic_num);
+ int picture_coding_decision (Picture *picture1, Picture *picture2, int qp);
+
+ unsigned CeilLog2( unsigned uiVal);
+
+ int Get_Direct_Cost8x8 (int, int*);
+
+ int BPredPartitionCost (int, int, short, short, int, int);
+ void LumaPrediction4x4Bi (int, int, int, int, int, short, short, int);
+ int SATDBI (int* , int );
+
+ int Get_Direct_CostMB (int);
+ int B8Mode2Value (int b8mode, int b8pdir);
+
+ int GetSkipCostMB (int lambda_factor);
+ void FindSkipModeMotionVector ();
+
+
+ // dynamic mem allocation
+ int init_global_buffers();
+ void free_global_buffers();
+ void no_mem_exit (char *where);
+
+ int get_mem_mv (short*******);
+ void free_mem_mv (short******);
+ void free_img ();
+
+ int get_mem_ACcoeff (int*****);
+ int get_mem_DCcoeff (int****);
+ void free_mem_ACcoeff (int****);
+ void free_mem_DCcoeff (int***);
+
+ int decide_fld_frame(float snr_frame_Y, float snr_field_Y, int bit_field, int bit_frame, double lambda_picture);
+ void combine_field();
+
+ Picture *malloc_picture();
+ void free_picture (Picture *pic);
+
+ int encode_one_slice(int SLiceGroupId, Picture *pic, int TotalCodedMBs); //! returns the number of MBs in the slice
+
+ void start_macroblock(int mb_addr, int mb_field);
+ void set_MB_parameters (int mb_addr); //! sets up img-> according to input-> and currSlice->
+
+ int writeMotionInfo2NAL ();
+
+ void terminate_macroblock(Boolean *end_of_slice, Boolean *recode_macroblock);
+ int slice_too_big(int rlc_bits);
+ void write_one_macroblock(int eos_bit);
+ void proceed2nextMacroblock();
+
+ void free_slice_list(Picture *currPic);
+
+ void report_stats_on_error();
+
+ #if TRACE
+ void trace2out(SyntaxElement *se);
+ #endif
+
+
+ void error(char *text, int code);
+ int start_sequence();
+ int terminate_sequence();
+ int start_slice();
+ int terminate_slice();
+ int write_PPS(int, int);
+
+ // B pictures
+ int get_fwMV(int *min_fw_sad, int tot_intra_sad);
+ void get_bwMV(int *min_bw_sad);
+ void get_bid(int *bid_sad, int fw_predframe_no);
+ void get_dir(int *dir_sad);
+ void compare_sad(int tot_intra_sad, int fw_sad, int bw_sad, int bid_sad, int dir_sad, int);
+ int BlkSize2CodeNumber(int blc_size_h, int blc_size_v);
+
+ void InitMotionVectorSearchModule();
+
+ int field_flag_inference();
+
+ void set_mbaff_parameters(); // For MB AFF
+ void writeVlcByteAlign(Bitstream* currStream);
+
+
+ int writeLumaCoeff4x4_CABAC (int, int, int);
+ int writeLumaCoeff8x8_CABAC (int, int);
+ int writeCBPandLumaCoeff ();
+ int writeChromaCoeff ();
+ int writeMB_bits_for_4x4_luma (int, int, int);
+ int writeMB_bits_for_16x16_luma ();
+ int writeMB_bits_for_luma (int);
+ int writeMB_bits_for_DC_chroma (int);
+ int writeMB_bits_for_AC_chroma (int);
+ int writeMB_bits_for_CBP ();
+
+ int SingleUnifiedMotionSearch (int, int, int**, int***, int*****, int, int*****, double);
+
+ //============= rate-distortion optimization ===================
+ void clear_rdopt ();
+ void init_rdopt ();
+ void RD_Mode_Decision ();
+ //============= rate-distortion opt with packet losses ===========
+ void decode_one_macroblock();
+ void decode_one_mb (int, Macroblock*);
+ void decode_one_b8block (int, int, int, int, int);
+ void Get_Reference_Block(imgpel **imY, int block_y, int block_x, int mvhor, int mvver, imgpel **out);
+ byte Get_Reference_Pixel(imgpel **imY, int y, int x);
+ int Half_Upsample(imgpel **imY, int j, int i);
+ void DecOneForthPix(imgpel **dY, imgpel ***dref);
+ void compute_residue(int mode);
+ void compute_residue_b8block (int, int);
+ void compute_residue_mb (int);
+ void UpdateDecoders();
+ void Build_Status_Map(byte **s_map);
+ void Error_Concealment(imgpel **inY, byte **s_map, imgpel ***refY);
+ void Conceal_Error(imgpel **inY, int mb_y, int mb_x, imgpel ***refY, byte **s_map);
+ //============= restriction of reference frames based on the latest intra-refreshes==========
+ void UpdatePixelMap();
+
+ //============= fast full integer search =======================
+ #ifdef _FAST_FULL_ME_
+ void ClearFastFullIntegerSearch ();
+ void ResetFastFullIntegerSearch ();
+ #endif
+
+ void process_2nd_IGOP();
+ void SetImgType();
+
+ // Tian Dong: for IGOPs
+ extern Boolean In2ndIGOP;
+ extern int start_frame_no_in_this_IGOP;
+ extern int start_tr_in_this_IGOP;
+ extern int FirstFrameIn2ndIGOP;
+ #define IMG_NUMBER (img->number-start_frame_no_in_this_IGOP)
+
+ void AllocNalPayloadBuffer();
+ void FreeNalPayloadBuffer();
+ void SODBtoRBSP(Bitstream *currStream);
+ int RBSPtoEBSP(byte *streamBuffer, int begin_bytepos, int end_bytepos, int min_num_bytes);
+ int Bytes_After_Header;
+
+ // JVT-D101: the bit for redundant_pic_cnt in slice header may be changed,
+ // therefore the bit position in the bitstream must be stored.
+ int rpc_bytes_to_go;
+ int rpc_bits_to_go;
+ void modify_redundant_pic_cnt(unsigned char *streamBuffer);
+ // End JVT-D101
+
+ // Fast ME enable
+ int BlockMotionSearch (short,int,int,int,int,int, int);
+ void low_complexity_encode_md (void);
+ void encode_one_macroblock (void);
+ void fasthigh_complexity_encode_md (void);
+
+ int RDCost_for_4x4Blocks_Chroma (int b8, int b4, int chroma);
+
+ #endif
+
+ #include "context_ini.h"
+
+ void store_coding_state_cs_cm();
+ void reset_coding_state_cs_cm();
+
+ int writeIPCMBytes(Bitstream *currStream);
+ int writePCMByteAlign(Bitstream *currStream);
+
Index: llvm-test/MultiSource/Applications/JM/lencod/header.c
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/header.c:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/header.c Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,564 ----
+
+ /*!
+ *************************************************************************************
+ * \file header.c
+ *
+ * \brief
+ * H.264 Slice and Sequence headers
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Stephan Wenger <stewe at cs.tu-berlin.de>
+ * - Karsten Suehring <suehring at hhi.de>
+ *************************************************************************************
+ */
+
+ #include <math.h>
+ #include <assert.h>
+ #include <string.h>
+ #include <stdlib.h>
+
+ #include "global.h"
+
+ #include "elements.h"
+ #include "header.h"
+ #include "rtp.h"
+ #include "mbuffer.h"
+ #include "defines.h"
+ #include "vlc.h"
+ #include "parset.h"
+
+ // A little trick to avoid those horrible #if TRACE all over the source code
+ #if TRACE
+ #define SYMTRACESTRING(s) strncpy(sym->tracestring,s,TRACESTRING_SIZE)
+ #else
+ #define SYMTRACESTRING(s) // do nothing
+ #endif
+
+ int * assignSE2partition[2] ;
+ int assignSE2partition_NoDP[SE_MAX_ELEMENTS] =
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ int assignSE2partition_DP[SE_MAX_ELEMENTS] =
+ { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 2, 2, 2, 2, 0, 0, 0, 0 } ;
+
+ static int ref_pic_list_reordering();
+ static int dec_ref_pic_marking();
+ static int pred_weight_table();
+
+ /*!
+ ********************************************************************************************
+ * \brief
+ * Write a slice header
+ *
+ * \return
+ * number of bits used
+ ********************************************************************************************
+ */
+ int SliceHeader()
+ {
+ int dP_nr = assignSE2partition[input->partition_mode][SE_HEADER];
+ Bitstream *bitstream = img->currentSlice->partArr[dP_nr].bitstream;
+ Slice* currSlice = img->currentSlice;
+ int len = 0;
+ unsigned int field_pic_flag = 0, bottom_field_flag = 0;
+
+ int num_bits_slice_group_change_cycle;
+ float numtmp;
+
+ if (img->MbaffFrameFlag)
+ len = ue_v("SH: first_mb_in_slice", img->current_mb_nr >> 1, bitstream);
+ else
+ len = ue_v("SH: first_mb_in_slice", img->current_mb_nr, bitstream);
+
+ len += ue_v("SH: slice_type", get_picture_type (), bitstream);
+
+ len += ue_v("SH: pic_parameter_set_id" , active_pps->pic_parameter_set_id ,bitstream);
+
+ len += u_v (log2_max_frame_num_minus4 + 4,"SH: frame_num", img->frame_num, bitstream);
+
+ if (!active_sps->frame_mbs_only_flag)
+ {
+ // field_pic_flag u(1)
+ field_pic_flag = (img->structure ==TOP_FIELD || img->structure ==BOTTOM_FIELD)?1:0;
+ assert( field_pic_flag == img->fld_flag );
+ len += u_1("SH: field_pic_flag", field_pic_flag, bitstream);
+
+ if (field_pic_flag)
+ {
+ //bottom_field_flag u(1)
+ bottom_field_flag = (img->structure == BOTTOM_FIELD)?1:0;
+ len += u_1("SH: bottom_field_flag" , bottom_field_flag ,bitstream);
+ }
+ }
+
+ if (img->currentPicture->idr_flag)
+ {
+ // idr_pic_id
+ len += ue_v ("SH: idr_pic_id", (img->number % 2), bitstream);
+ }
+
+ if (img->pic_order_cnt_type == 0)
+ {
+ if (active_sps->frame_mbs_only_flag)
+ {
+ img->pic_order_cnt_lsb = (img->toppoc & ~((((unsigned int)(-1)) << (log2_max_pic_order_cnt_lsb_minus4+4))) );
+ }
+ else
+ {
+ if (!field_pic_flag || img->structure == TOP_FIELD)
+ img->pic_order_cnt_lsb = (img->toppoc & ~((((unsigned int)(-1)) << (log2_max_pic_order_cnt_lsb_minus4+4))) );
+ else if ( img->structure == BOTTOM_FIELD )
+ img->pic_order_cnt_lsb = (img->bottompoc & ~((((unsigned int)(-1)) << (log2_max_pic_order_cnt_lsb_minus4+4))) );
+ }
+
+ len += u_v (log2_max_pic_order_cnt_lsb_minus4+4, "SH: pic_order_cnt_lsb", img->pic_order_cnt_lsb, bitstream);
+
+ if (img->pic_order_present_flag && !field_pic_flag)
+ {
+ len += se_v ("SH: delta_pic_order_cnt_bottom", img->delta_pic_order_cnt_bottom, bitstream);
+ }
+ }
+ if (img->pic_order_cnt_type == 1 && !img->delta_pic_order_always_zero_flag)
+ {
+ len += se_v ("SH: delta_pic_order_cnt[0]", img->delta_pic_order_cnt[0], bitstream);
+
+ if (img->pic_order_present_flag && !field_pic_flag)
+ {
+ len += se_v ("SH: delta_pic_order_cnt[1]", img->delta_pic_order_cnt[1], bitstream);
+ }
+ }
+
+ if (input->redundant_slice_flag)
+ {
+ len += ue_v ("SH: redundant_pic_cnt", img->redundant_pic_cnt, bitstream);
+ }
+
+ // Direct Mode Type selection for B pictures
+ if (img->type==B_SLICE)
+ {
+ len += u_1 ("SH: direct_spatial_mv_pred_flag", img->direct_spatial_mv_pred_flag, bitstream);
+ }
+
+ if ((img->type == P_SLICE) || (img->type == B_SLICE) || (img->type==SP_SLICE))
+ {
+ int override_flag;
+ if ((img->type == P_SLICE) || (img->type==SP_SLICE))
+ {
+ override_flag = (img->num_ref_idx_l0_active != (active_pps->num_ref_idx_l0_active_minus1 +1)) ? 1 : 0;
+ }
+ else
+ {
+ override_flag = ((img->num_ref_idx_l0_active != (active_pps->num_ref_idx_l0_active_minus1 +1))
+ || (img->num_ref_idx_l1_active != (active_pps->num_ref_idx_l1_active_minus1 +1))) ? 1 : 0;
+ }
+
+ len += u_1 ("SH: num_ref_idx_active_override_flag", override_flag, bitstream);
+
+ if (override_flag)
+ {
+ len += ue_v ("SH: num_ref_idx_l0_active_minus1", img->num_ref_idx_l0_active-1, bitstream);
+ if (img->type==B_SLICE)
+ {
+ len += ue_v ("SH: num_ref_idx_l1_active_minus1", img->num_ref_idx_l1_active-1, bitstream);
+ }
+ }
+
+ }
+ len += ref_pic_list_reordering();
+
+ if (((img->type == P_SLICE || img->type == SP_SLICE) && active_pps->weighted_pred_flag) ||
+ ((img->type == B_SLICE) && active_pps->weighted_bipred_idc == 1))
+ {
+ len += pred_weight_table();
+ }
+
+ if (img->nal_reference_idc)
+ len += dec_ref_pic_marking();
+
+ if(input->symbol_mode==CABAC && img->type!=I_SLICE /*&& img->type!=SI_IMG*/)
+ {
+ len += ue_v("SH: cabac_init_idc", img->model_number, bitstream);
+ }
+
+ len += se_v("SH: slice_qp_delta", (currSlice->qp - 26 - active_pps->pic_init_qp_minus26), bitstream);
+
+ if (img->type==SP_SLICE /*|| img->type==SI_SLICE*/)
+ {
+ if (img->type==SP_SLICE) // Switch Flag only for SP pictures
+ {
+ len += u_1 ("SH: sp_for_switch_flag", 0, bitstream); // 1 for switching SP, 0 for normal SP
+ }
+ len += se_v ("SH: slice_qs_delta", (img->qpsp - 26), bitstream );
+ }
+
+ if (active_pps->deblocking_filter_control_present_flag)
+ {
+ len += ue_v("SH: disable_deblocking_filter_idc",img->LFDisableIdc, bitstream); // Turn loop filter on/off on slice basis
+
+ if (img->LFDisableIdc!=1)
+ {
+ len += se_v ("SH: slice_alpha_c0_offset_div2", img->LFAlphaC0Offset / 2, bitstream);
+
+ len += se_v ("SH: slice_beta_offset_div2", img->LFBetaOffset / 2, bitstream);
+ }
+ }
+
+
+ if ( active_pps->num_slice_groups_minus1>0 &&
+ active_pps->slice_group_map_type>=3 && active_pps->slice_group_map_type<=5)
+ {
+ numtmp=img->PicHeightInMapUnits*img->PicWidthInMbs/(float)(active_pps->slice_group_change_rate_minus1+1)+1;
+ num_bits_slice_group_change_cycle = (int)ceil(log(numtmp)/log(2));
+
+ //! img->slice_group_change_cycle can be changed before calling FmoInit()
+ len += u_v (num_bits_slice_group_change_cycle, "SH: slice_group_change_cycle", img->slice_group_change_cycle, bitstream);
+ }
+
+ // NOTE: The following syntax element is actually part
+ // Slice data bitstream A RBSP syntax
+
+ if(input->partition_mode&&!img->currentPicture->idr_flag)
+ {
+ len += ue_v("DPA: slice_id", img->current_slice_nr, bitstream);
+ }
+
+ return len;
+ }
+
+ /*!
+ ********************************************************************************************
+ * \brief
+ * writes the ref_pic_list_reordering syntax
+ * based on content of according fields in img structure
+ *
+ * \return
+ * number of bits used
+ ********************************************************************************************
+ */
+ static int ref_pic_list_reordering()
+ {
+ int dP_nr = assignSE2partition[input->partition_mode][SE_HEADER];
+ Bitstream *bitstream = img->currentSlice->partArr[dP_nr].bitstream;
+ Slice *currSlice = img->currentSlice;
+
+ int i, len=0;
+
+ if ((img->type!=I_SLICE) /*&&(img->type!=SI_IMG)*/ )
+ {
+ len += u_1 ("SH: ref_pic_list_reordering_flag_l0", currSlice->ref_pic_list_reordering_flag_l0, bitstream);
+ if (currSlice->ref_pic_list_reordering_flag_l0)
+ {
+ i=-1;
+ do
+ {
+ i++;
+ len += ue_v ("SH: reordering_of_pic_num_idc", currSlice->reordering_of_pic_nums_idc_l0[i], bitstream);
+ if (currSlice->reordering_of_pic_nums_idc_l0[i]==0 ||
+ currSlice->reordering_of_pic_nums_idc_l0[i]==1)
+ {
+ len += ue_v ("SH: abs_diff_pic_num_minus1_l0", currSlice->abs_diff_pic_num_minus1_l0[i], bitstream);
+ }
+ else
+ {
+ if (currSlice->reordering_of_pic_nums_idc_l0[i]==2)
+ {
+ len += ue_v ("SH: long_term_pic_idx_l0", currSlice->long_term_pic_idx_l0[i], bitstream);
+ }
+ }
+
+ } while (currSlice->reordering_of_pic_nums_idc_l0[i] != 3);
+ }
+ }
+
+ if (img->type==B_SLICE)
+ {
+ len += u_1 ("SH: ref_pic_list_reordering_flag_l1", currSlice->ref_pic_list_reordering_flag_l1, bitstream);
+ if (currSlice->ref_pic_list_reordering_flag_l1)
+ {
+ i=-1;
+ do
+ {
+ i++;
+ len += ue_v ("SH: remapping_of_pic_num_idc", currSlice->reordering_of_pic_nums_idc_l1[i], bitstream);
+ if (currSlice->reordering_of_pic_nums_idc_l1[i]==0 ||
+ currSlice->reordering_of_pic_nums_idc_l1[i]==1)
+ {
+ len += ue_v ("SH: abs_diff_pic_num_minus1_l1", currSlice->abs_diff_pic_num_minus1_l1[i], bitstream);
+ }
+ else
+ {
+ if (currSlice->reordering_of_pic_nums_idc_l1[i]==2)
+ {
+ len += ue_v ("SH: long_term_pic_idx_l1", currSlice->long_term_pic_idx_l1[i], bitstream);
+ }
+ }
+ } while (currSlice->reordering_of_pic_nums_idc_l1[i] != 3);
+ }
+ }
+
+ return len;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * write the memory management control operations
+ *
+ * \return
+ * number of bits used
+ ************************************************************************
+ */
+ static int dec_ref_pic_marking()
+ {
+ int dP_nr = assignSE2partition[input->partition_mode][SE_HEADER];
+ Bitstream *bitstream = img->currentSlice->partArr[dP_nr].bitstream;
+
+ DecRefPicMarking_t *tmp_drpm;
+
+ int val, len=0;
+
+ if (img->currentPicture->idr_flag)
+ {
+ len += u_1("SH: no_output_of_prior_pics_flag", img->no_output_of_prior_pics_flag, bitstream);
+ len += u_1("SH: long_term_reference_flag", img->long_term_reference_flag, bitstream);
+ }
+ else
+ {
+ img->adaptive_ref_pic_buffering_flag = (img->dec_ref_pic_marking_buffer!=NULL);
+
+ len += u_1("SH: adaptive_ref_pic_buffering_flag", img->adaptive_ref_pic_buffering_flag, bitstream);
+
+ if (img->adaptive_ref_pic_buffering_flag)
+ {
+ tmp_drpm = img->dec_ref_pic_marking_buffer;
+ // write Memory Management Control Operation
+ do
+ {
+ if (tmp_drpm==NULL) error ("Error encoding MMCO commands", 500);
+
+ val = tmp_drpm->memory_management_control_operation;
+ len += ue_v("SH: memory_management_control_operation", val, bitstream);
+
+ if ((val==1)||(val==3))
+ {
+ len += 1 + ue_v("SH: difference_of_pic_nums_minus1", tmp_drpm->difference_of_pic_nums_minus1, bitstream);
+ }
+ if (val==2)
+ {
+ len+= ue_v("SH: long_term_pic_num", tmp_drpm->long_term_pic_num, bitstream);
+ }
+ if ((val==3)||(val==6))
+ {
+ len+= ue_v("SH: long_term_frame_idx", tmp_drpm->long_term_frame_idx, bitstream);
+ }
+ if (val==4)
+ {
+ len += ue_v("SH: max_long_term_pic_idx_plus1", tmp_drpm->max_long_term_frame_idx_plus1, bitstream);
+ }
+
+ tmp_drpm=tmp_drpm->Next;
+
+ } while (val != 0);
+
+ }
+ }
+ return len;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * write prediction weight table
+ *
+ * \return
+ * number of bits used
+ ************************************************************************
+ */
+ static int pred_weight_table()
+ {
+ int dP_nr = assignSE2partition[input->partition_mode][SE_HEADER];
+ Bitstream *bitstream = img->currentSlice->partArr[dP_nr].bitstream;
+
+ int len = 0;
+ int i,j;
+
+ len += ue_v("SH: luma_log_weight_denom", luma_log_weight_denom, bitstream);
+
+ if ( 0 != active_sps->chroma_format_idc)
+ {
+ len += ue_v("SH: chroma_log_weight_denom", chroma_log_weight_denom, bitstream);
+ }
+
+ for (i=0; i< img->num_ref_idx_l0_active; i++)
+ {
+ if ( (wp_weight[0][i][0] != 1<<luma_log_weight_denom) || (wp_offset[0][i][0] != 0) )
+ {
+ len += u_1 ("SH: luma_weight_flag_l0", 1, bitstream);
+
+ len += se_v ("SH: luma_weight_l0", wp_weight[0][i][0], bitstream);
+
+ len += se_v ("SH: luma_offset_l0", wp_offset[0][i][0], bitstream);
+ }
+ else
+ {
+ len += u_1 ("SH: luma_weight_flag_l0", 0, bitstream);
+ }
+
+ if (active_sps->chroma_format_idc!=0)
+ {
+ if ( (wp_weight[0][i][1] != 1<<chroma_log_weight_denom) || (wp_offset[0][i][1] != 0) ||
+ (wp_weight[0][i][2] != 1<<chroma_log_weight_denom) || (wp_offset[0][i][2] != 0) )
+ {
+ len += u_1 ("chroma_weight_flag_l0", 1, bitstream);
+ for (j=1; j<3; j++)
+ {
+ len += se_v ("chroma_weight_l0", wp_weight[0][i][j] ,bitstream);
+
+ len += se_v ("chroma_offset_l0", wp_offset[0][i][j] ,bitstream);
+ }
+ }
+ else
+ {
+ len += u_1 ("chroma_weight_flag_l0", 0, bitstream);
+ }
+ }
+ }
+
+ if (img->type == B_SLICE)
+ {
+ for (i=0; i< img->num_ref_idx_l1_active; i++)
+ {
+ if ( (wp_weight[1][i][0] != 1<<luma_log_weight_denom) || (wp_offset[1][i][0] != 0) )
+ {
+ len += u_1 ("SH: luma_weight_flag_l1", 1, bitstream);
+
+ len += se_v ("SH: luma_weight_l1", wp_weight[1][i][0], bitstream);
+
+ len += se_v ("SH: luma_offset_l1", wp_offset[1][i][0], bitstream);
+ }
+ else
+ {
+ len += u_1 ("SH: luma_weight_flag_l1", 0, bitstream);
+ }
+
+ if (active_sps->chroma_format_idc!=0)
+ {
+ if ( (wp_weight[1][i][1] != 1<<chroma_log_weight_denom) || (wp_offset[1][i][1] != 0) ||
+ (wp_weight[1][i][2] != 1<<chroma_log_weight_denom) || (wp_offset[1][i][2] != 0) )
+ {
+ len += u_1 ("chroma_weight_flag_l1", 1, bitstream);
+ for (j=1; j<3; j++)
+ {
+ len += se_v ("chroma_weight_l1", wp_weight[1][i][j] ,bitstream);
+
+ len += se_v ("chroma_offset_l1", wp_offset[1][i][j] ,bitstream);
+ }
+ }
+ else
+ {
+ len += u_1 ("chroma_weight_flag_l1", 0, bitstream);
+ }
+ }
+ }
+ }
+ return len;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Selects picture type and codes it to symbol
+ *
+ * \return
+ * symbol value for picture type
+ ************************************************************************
+ */
+ int get_picture_type()
+ {
+ // set this value to zero for transmission without signaling
+ // that the whole picture has the same slice type
+ int same_slicetype_for_whole_frame = 5;
+
+ switch (img->type)
+ {
+ case I_SLICE:
+ return 2 + same_slicetype_for_whole_frame;
+ break;
+ case P_SLICE:
+ return 0 + same_slicetype_for_whole_frame;
+ break;
+ case B_SLICE:
+ return 1 + same_slicetype_for_whole_frame;
+ break;
+ case SP_SLICE:
+ return 3 + same_slicetype_for_whole_frame;
+ break;
+ default:
+ error("Picture Type not supported!",1);
+ break;
+ }
+
+ return 0;
+ }
+
+
+
+ /*!
+ *****************************************************************************
+ *
+ * \brief
+ * int Partition_BC_Header () write the Partition type B, C header
+ *
+ * \return
+ * Number of bits used by the partition header
+ *
+ * \par Parameters
+ * PartNo: Partition Number to which the header should be written
+ *
+ * \par Side effects
+ * Partition header as per VCEG-N72r2 is written into the appropriate
+ * partition bit buffer
+ *
+ * \par Limitations/Shortcomings/Tweaks
+ * The current code does not support the change of picture parameters within
+ * one coded sequence, hence there is only one parameter set necessary. This
+ * is hard coded to zero.
+ *
+ * \date
+ * October 24, 2001
+ *
+ * \author
+ * Stephan Wenger stewe at cs.tu-berlin.de
+ *****************************************************************************/
+ int Partition_BC_Header(int PartNo)
+ {
+ DataPartition *partition = &((img->currentSlice)->partArr[PartNo]);
+ SyntaxElement symbol, *sym = &symbol;
+
+ int len = 0;
+
+ assert (PartNo > 0 && PartNo < img->currentSlice->max_part_nr);
+
+ sym->type = SE_HEADER; // This will be true for all symbols generated here
+ sym->mapping = ue_linfo; // Mapping rule: Simple code number to len/info
+ sym->value2 = 0;
+
+ //ZL
+ //changed according to the g050r1
+ SYMTRACESTRING("RTP-PH: Slice ID");
+ sym->value1 = img->current_slice_nr;
+ len += writeSyntaxElement_UVLC (sym, partition);
+
+ if(active_pps->redundant_pic_cnt_present_flag)
+ {
+ SYMTRACESTRING("RTP-PH: Picture ID");
+ sym->value1 = img->currentSlice->picture_id;
+ len += writeSyntaxElement_UVLC (sym, partition);
+ }
+
+
+ return len;
+ }
Index: llvm-test/MultiSource/Applications/JM/lencod/header.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/header.h:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/header.h Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,22 ----
+
+ /*!
+ *************************************************************************************
+ * \file header.h
+ *
+ * \brief
+ * Prototypes for header.c
+ *************************************************************************************
+ */
+
+ #ifndef _HEADER_H_
+ #define _HEADER_H_
+
+ int SliceHeader();
+ int Partition_BC_Header();
+
+ int writeERPS(SyntaxElement *sym, DataPartition *partition);
+ // int SequenceHeader(FILE *outf);
+ void write_terminating_bit (short);
+
+ #endif
+
Index: llvm-test/MultiSource/Applications/JM/lencod/image.c
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/image.c:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/image.c Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,2640 ----
+
+ /*!
+ *************************************************************************************
+ * \file image.c
+ *
+ * \brief
+ * Code one image/slice
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Inge Lille-Langoy <inge.lille-langoy at telenor.com>
+ * - Rickard Sjoberg <rickard.sjoberg at era.ericsson.se>
+ * - Jani Lainema <jani.lainema at nokia.com>
+ * - Sebastian Purreiter <sebastian.purreiter at mch.siemens.de>
+ * - Byeong-Moon Jeon <jeonbm at lge.com>
+ * - Yoon-Seong Soh <yunsung at lge.com>
+ * - Thomas Stockhammer <stockhammer at ei.tum.de>
+ * - Detlev Marpe <marpe at hhi.de>
+ * - Guido Heising <heising at hhi.de>
+ * - Thomas Wedi <wedi at tnt.uni-hannover.de>
+ * - Ragip Kurceren <ragip.kurceren at nokia.com>
+ * - Antti Hallapuro <antti.hallapuro at nokia.com>
+ * - Alexis Michael Tourapis <alexismt at ieee.org>
+ *************************************************************************************
+ */
+ #include "contributors.h"
+
+ #include <stdlib.h>
+ #include <math.h>
+ #include <time.h>
+ #include <sys/timeb.h>
+ #include <string.h>
+ #include <memory.h>
+ #include <assert.h>
+
+ #ifdef WIN32
+ #include <io.h>
+ #else
+ #include <unistd.h>
+ #endif
+
+ #include "global.h"
+
+ #include "refbuf.h"
+ #include "mbuffer.h"
+ #include "intrarefresh.h"
+ #include "fmo.h"
+ #include "sei.h"
+ #include "memalloc.h"
+ #include "nalu.h"
+ #include "ratectl.h"
+ #include "mb_access.h"
+ #include "output.h"
+ #include "cabac.h"
+
+ extern pic_parameter_set_rbsp_t *PicParSet[MAXPPS];
+
+ void code_a_picture(Picture *pic);
+ void frame_picture (Picture *frame, int method);
+ void field_picture(Picture *top, Picture *bottom);
+
+ static int writeout_picture(Picture *pic);
+
+ static int picture_structure_decision(Picture *frame, Picture *top, Picture *bot);
+ static void distortion_fld (float *dis_fld_y, float *dis_fld_u, float *dis_fld_v);
+ static void find_snr();
+ static void find_distortion();
+
+ static void field_mode_buffer(int bit_field, float snr_field_y, float snr_field_u, float snr_field_v);
+ static void frame_mode_buffer (int bit_frame, float snr_frame_y, float snr_frame_u, float snr_frame_v);
+
+ static void init_frame();
+ static void init_field();
+
+ static void put_buffer_frame();
+ static void put_buffer_top();
+ static void put_buffer_bot();
+
+ static void copy_motion_vectors_MB();
+
+ static void PaddAutoCropBorders (int org_size_x, int org_size_y, int img_size_x, int img_size_y,
+ int org_size_x_cr, int org_size_y_cr, int img_size_x_cr, int img_size_y_cr);
+
+ static void ReadOneFrame (int FrameNoInFile, int HeaderSize, int xs, int ys, int xs_cr, int ys_cr);
+
+ static void writeUnit(Bitstream* currStream ,int partition);
+ static void rdPictureCoding();
+
+ #ifdef _ADAPT_LAST_GROUP_
+ int *last_P_no;
+ int *last_P_no_frm;
+ int *last_P_no_fld;
+ #endif
+
+ static void ReportFirstframe(int tmp_time, int me_time);
+ static void ReportIntra(int tmp_time, int me_time);
+ static void ReportSP(int tmp_time, int me_time);
+ static void ReportP(int tmp_time, int me_time);
+ static void ReportB(int tmp_time, int me_time);
+ static void ReportNALNonVLCBits(int tmp_time, int me_time);
+
+ static int CalculateFrameNumber(); // Calculates the next frame number
+
+ StorablePicture *enc_picture;
+ StorablePicture *enc_frame_picture;
+ StorablePicture *enc_frame_picture2;
+ StorablePicture *enc_frame_picture3;
+ StorablePicture *enc_top_picture;
+ StorablePicture *enc_bottom_picture;
+ //Rate control
+ int QP;
+
+ const int ONE_FOURTH_TAP[3][2] =
+ {
+ {20,20},
+ {-5,-4},
+ { 1, 0},
+ };
+
+
+ void MbAffPostProc()
+ {
+ imgpel temp[32][16];
+
+ imgpel ** imgY = enc_picture->imgY;
+ imgpel ***imgUV = enc_picture->imgUV;
+ int i, y, x0, y0, uv;
+
+ if (img->yuv_format != YUV400)
+ {
+ for (i=0; i<(int)img->PicSizeInMbs; i+=2)
+ {
+ if (enc_picture->mb_field[i])
+ {
+ get_mb_pos(i, &x0, &y0);
+ for (y=0; y<(2*MB_BLOCK_SIZE);y++)
+ memcpy(&temp[y],&imgY[y0+y][x0], MB_BLOCK_SIZE * sizeof(imgpel));
+
+ for (y=0; y<MB_BLOCK_SIZE;y++)
+ {
+ memcpy(&imgY[y0+(2*y)][x0],temp[y], MB_BLOCK_SIZE * sizeof(imgpel));
+ memcpy(&imgY[y0+(2*y + 1)][x0],temp[y+ MB_BLOCK_SIZE], MB_BLOCK_SIZE * sizeof(imgpel));
+ }
+
+ x0 = x0 / (16/img->mb_cr_size_x);
+ y0 = y0 / (16/img->mb_cr_size_y);
+
+ for (uv=0; uv<2; uv++)
+ {
+ for (y=0; y<(2*img->mb_cr_size_y);y++)
+ memcpy(&temp[y],&imgUV[uv][y0+y][x0], img->mb_cr_size_x * sizeof(imgpel));
+
+ for (y=0; y<img->mb_cr_size_y;y++)
+ {
+ memcpy(&imgUV[uv][y0+(2*y)][x0],temp[y], img->mb_cr_size_x * sizeof(imgpel));
+ memcpy(&imgUV[uv][y0+(2*y + 1)][x0],temp[y+ img->mb_cr_size_y], img->mb_cr_size_x * sizeof(imgpel));
+
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ for (i=0; i<(int)img->PicSizeInMbs; i+=2)
+ {
+ if (enc_picture->mb_field[i])
+ {
+ get_mb_pos(i, &x0, &y0);
+ for (y=0; y<(2*MB_BLOCK_SIZE);y++)
+ memcpy(&temp[y],&imgY[y0+y][x0], MB_BLOCK_SIZE * sizeof(imgpel));
+
+ for (y=0; y<MB_BLOCK_SIZE;y++)
+ {
+ memcpy(&imgY[y0+(2*y)][x0],temp[y], MB_BLOCK_SIZE * sizeof(imgpel));
+ memcpy(&imgY[y0+(2*y + 1)][x0],temp[y+ MB_BLOCK_SIZE], MB_BLOCK_SIZE * sizeof(imgpel));
+ }
+ }
+ }
+ }
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Encodes a picture
+ *
+ * This is the main picture coding loop.. It is called by all this
+ * frame and field coding stuff after the img-> elements have been
+ * set up. Not sure whether it is useful for MB-adaptive frame/field
+ * coding
+ ************************************************************************
+ */
+ void code_a_picture(Picture *pic)
+ {
+ unsigned int NumberOfCodedMBs = 0;
+ int SliceGroup = 0;
+ int j;
+
+ img->currentPicture = pic;
+
+ img->currentPicture->idr_flag = ((!IMG_NUMBER) && (!(img->structure==BOTTOM_FIELD))) || (input->idr_enable && (img->type == I_SLICE || img->type==SP_SLICE || img->type==SI_SLICE)&& (!(img->structure==BOTTOM_FIELD)));
+
+ pic->no_slices = 0;
+ pic->distortion_u = pic->distortion_v = pic->distortion_y = 0.0;
+
+ RandomIntraNewPicture (); //! Allocates forced INTRA MBs (even for fields!)
+
+ // The slice_group_change_cycle can be changed here.
+ // FmoInit() is called before coding each picture, frame or field
+ img->slice_group_change_cycle=1;
+ FmoInit(img, active_pps, active_sps);
+ FmoStartPicture (); //! picture level initialization of FMO
+
+ CalculateQuantParam();
+ CalculateOffsetParam();
+
+ if(input->Transform8x8Mode)
+ {
+ CalculateQuant8Param();
+ CalculateOffset8Param();
+ }
+
+ reset_pic_bin_count();
+ img->bytes_in_picture = 0;
+
+ while (NumberOfCodedMBs < img->PicSizeInMbs) // loop over slices
+ {
+ // Encode one SLice Group
+ while (!FmoSliceGroupCompletelyCoded (SliceGroup))
+ {
+ // Encode the current slice
+ NumberOfCodedMBs += encode_one_slice (SliceGroup, pic, NumberOfCodedMBs);
+ FmoSetLastMacroblockInSlice (img->current_mb_nr);
+ // Proceed to next slice
+ img->current_slice_nr++;
+ stats->bit_slice = 0;
+ }
+ // Proceed to next SliceGroup
+ SliceGroup++;
+ }
+ FmoEndPicture ();
+
+ // Modified for Fast Mode Decision. Inchoon Choi, SungKyunKwan Univ.
+ if (input->rdopt == 3 && (img->type != B_SLICE))
+ for (j = 0; j < input->NoOfDecoders; j++)
+ DeblockFrame (img, decs->decY_best[j], NULL);
+
+ DeblockFrame (img, enc_picture->imgY, enc_picture->imgUV); //comment out to disable loop filter
+
+ if (img->MbaffFrameFlag)
+ MbAffPostProc();
+ }
+
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Encodes one frame
+ ************************************************************************
+ */
+ int encode_one_frame ()
+ {
+ static int prev_frame_no = 0; // POC200301
+ static int consecutive_non_reference_pictures = 0; // POC200301
+ int FrameNumberInFile;
+
+ #ifdef _LEAKYBUCKET_
+ extern long Bit_Buffer[10000];
+ extern unsigned long total_frame_buffer;
+ #endif
+
+ time_t ltime1;
+ time_t ltime2;
+
+ #ifdef WIN32
+ struct _timeb tstruct1;
+ struct _timeb tstruct2;
+ #else
+ struct timeb tstruct1;
+ struct timeb tstruct2;
+ #endif
+
+ int tmp_time;
+ int bits_frm = 0, bits_fld = 0;
+ float dis_frm = 0.0, dis_frm_y = 0.0, dis_frm_u = 0.0, dis_frm_v = 0.0;
+ float dis_fld = 0.0, dis_fld_y = 0.0, dis_fld_u = 0.0, dis_fld_v = 0.0;
+
+ //Rate control
+ int pic_type, bits = 0;
+
+ me_time=0;
+ img->rd_pass = 0;
+ enc_frame_picture = NULL;
+ enc_frame_picture2 = NULL;
+ enc_frame_picture3 = NULL;
+
+ #ifdef WIN32
+ _ftime (&tstruct1); // start time ms
+ #else
+ ftime (&tstruct1);
+ #endif
+ time (<ime1); // start time s
+
+ //Rate control
+ img->write_macroblock = 0;
+ /*
+ //Shankar Regunathan (Oct 2002)
+ //Prepare Panscanrect SEI payload
+ UpdatePanScanRectInfo ();
+ //Prepare Arbitrarydata SEI Payload
+ UpdateUser_data_unregistered ();
+ //Prepare Registered data SEI Payload
+ UpdateUser_data_registered_itu_t_t35 ();
+ //Prepare RandomAccess SEI Payload
+ UpdateRandomAccess ();
+ */
+
+ if (input->ResendPPS && img->number !=0)
+ {
+ stats->bit_ctr_parametersets_n=write_PPS(0, 0);
+ //stats->bit_slice += stats->bit_ctr_parametersets_n;
+ stats->bit_ctr_parametersets += stats->bit_ctr_parametersets_n;
+ }
+
+ put_buffer_frame (); // sets the pointers to the frame structures
+ // (and not to one of the field structures)
+ init_frame ();
+ FrameNumberInFile = CalculateFrameNumber();
+
+ ReadOneFrame (FrameNumberInFile, input->infile_header,
+ input->img_width, input->img_height, input->img_width_cr, input->img_height_cr);
+
+ PaddAutoCropBorders (input->img_width, input->img_height, img->width, img->height,
+ input->img_width_cr, input->img_height_cr, img->width_cr, img->height_cr);
+
+ // set parameters for direct mode and deblocking filter
+ img->direct_spatial_mv_pred_flag = input->direct_spatial_mv_pred_flag;
+ img->LFDisableIdc = input->LFDisableIdc;
+ img->LFAlphaC0Offset = input->LFAlphaC0Offset;
+ img->LFBetaOffset = input->LFBetaOffset;
+ img->AdaptiveRounding = input->AdaptiveRounding;
+ // Following code should consider optimal coding mode. Currently also does not support
+ // multiple slices per frame.
+ frame_ctr[img->type]++;
+ snr->frame_ctr++;
+
+ if (input->PicInterlace == FIELD_CODING)
+ {
+ //Rate control
+ img->FieldControl=1;
+
+ img->field_picture = 1; // we encode fields
+ field_picture (top_pic, bottom_pic);
+ img->fld_flag = 1;
+ }
+ else
+ {
+ //Rate control
+ img->FieldControl=0;
+
+ // For frame coding, turn MB level field/frame coding flag on
+ if (input->MbInterlace)
+ mb_adaptive = 1;
+
+ img->field_picture = 0; // we encode a frame
+
+ //Rate control
+ if(input->RCEnable)
+ {
+ /*update the number of MBs in the basic unit for MB adaptive
+ f/f coding*/
+ if((input->MbInterlace)&&(input->basicunit<img->Frame_Total_Number_MB)\
+ &&(img->type==P_SLICE)&&(img->IFLAG==0))
+ img->BasicUnit=input->basicunit*2;
+ else
+ img->BasicUnit=input->basicunit;
+
+ rc_init_pict(1,0,1);
+ img->qp = updateQuantizationParameter(0);
+
+
+ pic_type = img->type;
+ QP =0;
+ }
+
+ if( active_sps->frame_mbs_only_flag)
+ img->TopFieldFlag=0;
+
+ if (input->GenerateMultiplePPS)
+ active_pps = PicParSet[0];
+
+ frame_picture (frame_pic_1, 0);
+
+ if ((input->RDPictureIntra || img->type!=I_SLICE) && input->RDPictureDecision)
+ {
+ rdPictureCoding();
+ }
+
+ // For field coding, turn MB level field/frame coding flag off
+ if (input->MbInterlace)
+ mb_adaptive = 0;
+
+ if (input->PicInterlace == ADAPTIVE_CODING)
+ {
+ //Rate control
+ img->FieldControl=1;
+ img->write_macroblock = 0;
+ img->bot_MB = 0;
+
+ img->field_picture = 1; // we encode fields
+ field_picture (top_pic, bottom_pic);
+
+ //! Note: the distortion for a field coded picture is stored in the top field
+ //! the distortion values in the bottom field are dummies
+ dis_fld = top_pic->distortion_y + top_pic->distortion_u + top_pic->distortion_v;
+ dis_frm = frame_pic_1->distortion_y + frame_pic_1->distortion_u + frame_pic_1->distortion_v;
+
+ img->fld_flag = picture_structure_decision (frame_pic_1, top_pic, bottom_pic);
+ update_field_frame_contexts (img->fld_flag);
+
+ //Rate control
+ if(img->fld_flag==0)
+ img->FieldFrame=1;
+ /*the current choice is field coding*/
+ else
+ img->FieldFrame=0;
+ }
+ else
+
+ img->fld_flag = 0;
+ }
+
+ if (img->fld_flag)
+ stats->bit_ctr_emulationprevention += stats->em_prev_bits_fld;
+ else
+ stats->bit_ctr_emulationprevention += stats->em_prev_bits_frm;
+
+ if (img->type != B_SLICE)
+ {
+ img->pstruct_next_P = img->fld_flag;
+ }
+
+ // Here, img->structure may be either FRAME or BOTTOM FIELD depending on whether AFF coding is used
+ // The picture structure decision changes really only the fld_flag
+
+ if (img->fld_flag) // field mode (use field when fld_flag=1 only)
+ {
+ field_mode_buffer (bits_fld, dis_fld_y, dis_fld_u, dis_fld_v);
+ writeout_picture (top_pic);
+ writeout_picture (bottom_pic);
+ }
+ else //frame mode
+ {
+ frame_mode_buffer (bits_frm, dis_frm_y, dis_frm_u, dis_frm_v);
+
+ if (input->RDPictureDecision && img->rd_pass == 2)
+ writeout_picture (frame_pic_3);
+ else if (input->RDPictureDecision && img->rd_pass == 1)
+ writeout_picture (frame_pic_2);
+ else
+ writeout_picture (frame_pic_1);
+ }
+
+ if (frame_pic_3)
+ free_slice_list(frame_pic_3);
+ if (frame_pic_2)
+ free_slice_list(frame_pic_2);
+ if (frame_pic_1)
+ free_slice_list(frame_pic_1);
+ if (top_pic)
+ free_slice_list(top_pic);
+ if (bottom_pic)
+ free_slice_list(bottom_pic);
+
+ /*
+ // Tian Dong (Sept 2002)
+ // in frame mode, the newly reconstructed frame has been inserted to the mem buffer
+ // and it is time to prepare the spare picture SEI payload.
+ if (input->InterlaceCodingOption == FRAME_CODING
+ && input->SparePictureOption && img->type != B_SLICE)
+ CalculateSparePicture ();
+ */
+
+ //Rate control
+ if(input->RCEnable)
+ {
+ bits = stats->bit_ctr-stats->bit_ctr_n;
+ rc_update_pict_frame(bits);
+ }
+
+ /*
+
+ if (input->InterlaceCodingOption == FRAME_CODING)
+ {
+ if (input->rdopt == 3 && img->type != B_SLICE)
+ UpdateDecoders (); // simulate packet losses and move decoded image to reference buffers
+
+ if (input->RestrictRef)
+ UpdatePixelMap ();
+ }
+ */
+
+ if (input->Verbose != 0)
+ find_snr ();
+ else
+ {
+ snr->snr_y = 0.0;
+ snr->snr_u = 0.0;
+ snr->snr_v = 0.0;
+ snr->sse_y = 0.0;
+ snr->sse_u = 0.0;
+ snr->sse_v = 0.0;
+ }
+
+ time (<ime2); // end time sec
+ #ifdef WIN32
+ _ftime (&tstruct2); // end time ms
+ #else
+ ftime (&tstruct2); // end time ms
+ #endif
+
+ tmp_time = (ltime2 * 1000 + tstruct2.millitm) - (ltime1 * 1000 + tstruct1.millitm);
+ tot_time = tot_time + tmp_time;
+
+ if (input->PicInterlace == ADAPTIVE_CODING)
+ {
+ if (img->fld_flag)
+ {
+ // store bottom field
+ store_picture_in_dpb(enc_bottom_picture);
+ free_storable_picture(enc_frame_picture);
+ }
+ else
+ {
+ // replace top with frame
+ replace_top_pic_with_frame(enc_frame_picture);
+ free_storable_picture(enc_bottom_picture);
+ }
+ }
+ else
+ {
+ if (img->fld_flag)
+ {
+ store_picture_in_dpb(enc_bottom_picture);
+ }
+ else
+ {
+ if (img->rd_pass==2)
+ {
+ store_picture_in_dpb(enc_frame_picture3);
+ free_storable_picture(enc_frame_picture);
+ free_storable_picture(enc_frame_picture2);
+ }
+ else if (img->rd_pass==1)
+ {
+ store_picture_in_dpb(enc_frame_picture2);
+ free_storable_picture(enc_frame_picture);
+ free_storable_picture(enc_frame_picture3);
+ }
+ else
+ {
+ store_picture_in_dpb(enc_frame_picture);
+ free_storable_picture(enc_frame_picture2);
+ free_storable_picture(enc_frame_picture3);
+ }
+ }
+ }
+
+
+ #ifdef _LEAKYBUCKET_
+ // Store bits used for this frame and increment counter of no. of coded frames
+ Bit_Buffer[total_frame_buffer] = stats->bit_ctr - stats->bit_ctr_n;
+ total_frame_buffer++;
+ #endif
+
+ // POC200301: Verify that POC coding type 2 is not used if more than one consecutive
+ // non-reference frame is requested or if decoding order is different from output order
+ if (img->pic_order_cnt_type == 2)
+ {
+ if (!img->nal_reference_idc) consecutive_non_reference_pictures++;
+ else consecutive_non_reference_pictures = 0;
+
+ if (frame_no < prev_frame_no || consecutive_non_reference_pictures>1)
+ error("POC type 2 cannot be applied for the coding pattern where the encoding /decoding order of pictures are different from the output order.\n", -1);
+ prev_frame_no = frame_no;
+ }
+
+ if (stats->bit_ctr_parametersets_n!=0)
+ ReportNALNonVLCBits(tmp_time, me_time);
+
+ if (IMG_NUMBER == 0)
+ ReportFirstframe(tmp_time,me_time);
+ else
+ {
+ //Rate control
+ if(input->RCEnable)
+ {
+ if((!input->PicInterlace)&&(!input->MbInterlace))
+ bits=stats->bit_ctr-stats->bit_ctr_n;
+ else
+ {
+ bits = stats->bit_ctr -Pprev_bits; // used for rate control update */
+ Pprev_bits = stats->bit_ctr;
+ }
+ }
+
+ switch (img->type)
+ {
+ case I_SLICE:
+ stats->bit_ctr_I += stats->bit_ctr - stats->bit_ctr_n;
+ ReportIntra(tmp_time,me_time);
+ break;
+ case SP_SLICE:
+ stats->bit_ctr_P += stats->bit_ctr - stats->bit_ctr_n;
+ ReportSP(tmp_time,me_time);
+ break;
+ case B_SLICE:
+ stats->bit_ctr_B += stats->bit_ctr - stats->bit_ctr_n;
+ ReportB(tmp_time,me_time);
+ break;
+ default: // P
+ stats->bit_ctr_P += stats->bit_ctr - stats->bit_ctr_n;
+ ReportP(tmp_time,me_time);
+ }
+ }
+
+ if (input->Verbose == 0)
+ {
+ //for (i = 0; i <= (img->number & 0x0F); i++)
+ //printf(".");
+ //printf(" \r");
+ printf("Completed Encoding Frame %05d.\r",frame_no);
+ }
+ // Flush output statistics
+ fflush(stdout);
+
+ stats->bit_ctr_n = stats->bit_ctr;
+
+ //Rate control
+ if(input->RCEnable)
+ {
+ rc_update_pict(bits);
+
+ // update the parameters of quadratic R-D model
+ if((img->type==P_SLICE)&&(active_sps->frame_mbs_only_flag))
+ updateRCModel();
+ else if((img->type==P_SLICE) && (!active_sps->frame_mbs_only_flag) && (img->IFLAG==0))
+ updateRCModel();
+ }
+
+ stats->bit_ctr_parametersets_n=0;
+
+ if (IMG_NUMBER == 0)
+ return 0;
+ else
+ return 1;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * This function write out a picture
+ * \return
+ * 0 if OK, \n
+ * 1 in case of error
+ *
+ ************************************************************************
+ */
+ static int writeout_picture(Picture *pic)
+ {
+ Bitstream *currStream;
+ int partition, slice;
+ Slice *currSlice;
+
+ img->currentPicture=pic;
+
+ for (slice=0; slice<pic->no_slices; slice++)
+ {
+ currSlice = pic->slices[slice];
+ for (partition=0; partition<currSlice->max_part_nr; partition++)
+ {
+ currStream = (currSlice->partArr[partition]).bitstream;
+ assert (currStream->bits_to_go == 8); //! should always be the case, the
+ //! byte alignment is done in terminate_slice
+ writeUnit (currSlice->partArr[partition].bitstream,partition);
+
+ } // partition loop
+ } // slice loop
+ return 0;
+ }
+
+
+ void copy_params()
+ {
+ enc_picture->frame_mbs_only_flag = active_sps->frame_mbs_only_flag;
+ enc_picture->frame_cropping_flag = active_sps->frame_cropping_flag;
+ enc_picture->chroma_format_idc = active_sps->chroma_format_idc;
+
+ if (active_sps->frame_cropping_flag)
+ {
+ enc_picture->frame_cropping_rect_left_offset=active_sps->frame_cropping_rect_left_offset;
+ enc_picture->frame_cropping_rect_right_offset=active_sps->frame_cropping_rect_right_offset;
+ enc_picture->frame_cropping_rect_top_offset=active_sps->frame_cropping_rect_top_offset;
+ enc_picture->frame_cropping_rect_bottom_offset=active_sps->frame_cropping_rect_bottom_offset;
+ }
+ else
+ {
+ enc_picture->frame_cropping_rect_left_offset=0;
+ enc_picture->frame_cropping_rect_right_offset=0;
+ enc_picture->frame_cropping_rect_top_offset=0;
+ enc_picture->frame_cropping_rect_bottom_offset=0;
+ }
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Encodes a frame picture
+ ************************************************************************
+ */
+ void frame_picture (Picture *frame, int rd_pass)
+ {
+ img->structure = FRAME;
+ img->PicSizeInMbs = img->FrameSizeInMbs;
+
+ if (rd_pass == 2)
+ {
+ enc_frame_picture3 = alloc_storable_picture (img->structure, img->width, img->height, img->width_cr, img->height_cr);
+ img->ThisPOC=enc_frame_picture3->poc=img->framepoc;
+ enc_frame_picture3->top_poc = img->toppoc;
+ enc_frame_picture3->bottom_poc = img->bottompoc;
+
+ enc_frame_picture3->frame_poc = img->framepoc;
+
+ enc_frame_picture3->pic_num = img->frame_num;
+ enc_frame_picture3->frame_num = img->frame_num;
+ enc_frame_picture3->coded_frame = 1;
+
+ enc_frame_picture3->MbaffFrameFlag = img->MbaffFrameFlag = (input->MbInterlace != FRAME_CODING);
+
+ enc_picture=enc_frame_picture3;
+ copy_params();
+ }
+ else if (rd_pass == 1)
+ {
+ enc_frame_picture2 = alloc_storable_picture (img->structure, img->width, img->height, img->width_cr, img->height_cr);
+ img->ThisPOC=enc_frame_picture2->poc=img->framepoc;
+ enc_frame_picture2->top_poc = img->toppoc;
+ enc_frame_picture2->bottom_poc = img->bottompoc;
+
+ enc_frame_picture2->frame_poc = img->framepoc;
+
+ enc_frame_picture2->pic_num = img->frame_num;
+ enc_frame_picture2->frame_num = img->frame_num;
+ enc_frame_picture2->coded_frame = 1;
+
+ enc_frame_picture2->MbaffFrameFlag = img->MbaffFrameFlag = (input->MbInterlace != FRAME_CODING);
+
+ enc_picture=enc_frame_picture2;
+ copy_params();
+ }
+ else
+ {
+ enc_frame_picture = alloc_storable_picture (img->structure, img->width, img->height, img->width_cr, img->height_cr);
+ img->ThisPOC=enc_frame_picture->poc=img->framepoc;
+ enc_frame_picture->top_poc = img->toppoc;
+ enc_frame_picture->bottom_poc = img->bottompoc;
+
+ enc_frame_picture->frame_poc = img->framepoc;
+
+ enc_frame_picture->pic_num = img->frame_num;
+ enc_frame_picture->frame_num = img->frame_num;
+ enc_frame_picture->coded_frame = 1;
+
+ enc_frame_picture->MbaffFrameFlag = img->MbaffFrameFlag = (input->MbInterlace != FRAME_CODING);
+
+ enc_picture=enc_frame_picture;
+ copy_params();
+ }
+
+
+ stats->em_prev_bits_frm = 0;
+ stats->em_prev_bits = &stats->em_prev_bits_frm;
+
+ img->fld_flag = 0;
+ code_a_picture(frame);
+
+ frame->bits_per_picture = 8 * ((((img->currentSlice)->partArr[0]).bitstream)->byte_pos);
+
+ if (img->structure==FRAME)
+ {
+ find_distortion (snr, img);
+ frame->distortion_y = snr->snr_y;
+ frame->distortion_u = snr->snr_u;
+ frame->distortion_v = snr->snr_v;
+ }
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Encodes a field picture, consisting of top and bottom field
+ ************************************************************************
+ */
+ void field_picture (Picture *top, Picture *bottom)
+ {
+ //Rate control
+ int old_pic_type; // picture type of top field used for rate control
+ int TopFieldBits;
+
+ //Rate control
+ old_pic_type = img->type;
+
+ stats->em_prev_bits_fld = 0;
+ stats->em_prev_bits = &stats->em_prev_bits_fld;
+ img->number *= 2;
+ img->buf_cycle *= 2;
+ img->height = (input->img_height+img->auto_crop_bottom) / 2;
+ img->height_cr = img->height_cr_frame / 2;
+ img->fld_flag = 1;
+ img->PicSizeInMbs = img->FrameSizeInMbs/2;
+ // Top field
+
+ enc_top_picture = alloc_storable_picture (img->structure, img->width, img->height, img->width_cr, img->height_cr);
+ enc_top_picture->poc=img->toppoc;
+ enc_top_picture->frame_poc = img->toppoc;
+ enc_top_picture->pic_num = img->frame_num;
+ enc_top_picture->frame_num = img->frame_num;
+ enc_top_picture->coded_frame = 0;
+ enc_top_picture->MbaffFrameFlag = img->MbaffFrameFlag = FALSE;
+ img->ThisPOC = img->toppoc;
+
+ img->structure = TOP_FIELD;
+ enc_picture = enc_top_picture;
+ copy_params();
+
+ put_buffer_top ();
+ init_field ();
+ if (img->type == B_SLICE) //all I- and P-frames
+ nextP_tr_fld--;
+
+
+ img->fld_flag = 1;
+
+ //Rate control
+ if(input->RCEnable)
+ {
+ img->BasicUnit=input->basicunit;
+
+ if(input->PicInterlace==FIELD_CODING)
+ rc_init_pict(0,1,1);
+ else
+ rc_init_pict(0,1,0);
+
+ img->qp = updateQuantizationParameter(1);
+ }
+ img->TopFieldFlag=1;
+
+ code_a_picture(top_pic);
+ enc_picture->structure = 1;
+
+ store_picture_in_dpb(enc_top_picture);
+
+ top->bits_per_picture = 8 * ((((img->currentSlice)->partArr[0]).bitstream)->byte_pos);
+
+ //Rate control
+ TopFieldBits=top->bits_per_picture;
+
+ // Bottom field
+ enc_bottom_picture = alloc_storable_picture (img->structure, img->width, img->height, img->width_cr, img->height_cr);
+ enc_bottom_picture->poc=img->bottompoc;
+ enc_bottom_picture->frame_poc = img->bottompoc;
+ enc_bottom_picture->pic_num = img->frame_num;
+ enc_bottom_picture->frame_num = img->frame_num;
+ enc_bottom_picture->coded_frame = 0;
+ enc_bottom_picture->MbaffFrameFlag = img->MbaffFrameFlag = FALSE;
+ img->ThisPOC = img->bottompoc;
+ img->structure = BOTTOM_FIELD;
+ enc_picture = enc_bottom_picture;
+ copy_params();
+ put_buffer_bot ();
+ img->number++;
+
+ init_field ();
+
+ if (img->type == B_SLICE) //all I- and P-frames
+ nextP_tr_fld++; //check once coding B field
+
+ if (img->type == I_SLICE && input->IntraBottom!=1)
+ img->type = (input->BRefPictures == 2) ? B_SLICE : P_SLICE;
+
+ img->fld_flag = 1;
+
+ //Rate control
+ if(input->RCEnable)
+ {
+ setbitscount(TopFieldBits);
+ rc_init_pict(0,0,0);
+ img->qp = updateQuantizationParameter(0);
+ }
+ img->TopFieldFlag=0;
+
+ enc_picture->structure = 2;
+ code_a_picture(bottom_pic);
+
+ bottom->bits_per_picture = 8 * ((((img->currentSlice)->partArr[0]).bitstream)->byte_pos);
+
+ // the distortion for a field coded frame (consisting of top and bottom field)
+ // lives in the top->distortion variables, the bottom-> are dummies
+ distortion_fld (&top->distortion_y, &top->distortion_u, &top->distortion_v);
+
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Distortion Field
+ ************************************************************************
+ */
+ static void distortion_fld (float *dis_fld_y, float *dis_fld_u, float *dis_fld_v)
+ {
+
+ img->number /= 2;
+ img->buf_cycle /= 2;
+ img->height = (input->img_height+img->auto_crop_bottom);
+ img->height_cr = img->height_cr_frame;
+
+ combine_field ();
+
+ imgY_org = imgY_org_frm;
+ imgUV_org = imgUV_org_frm;
+
+ find_distortion (snr, img); // find snr from original frame picture
+
+ *dis_fld_y = snr->snr_y;
+ *dis_fld_u = snr->snr_u;
+ *dis_fld_v = snr->snr_v;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Picture Structure Decision
+ ************************************************************************
+ */
+ static int picture_structure_decision (Picture *frame, Picture *top, Picture *bot)
+ {
+ double lambda_picture;
+ int bframe = (img->type == B_SLICE);
+ float snr_frame, snr_field;
+ int bit_frame, bit_field;
+
+ lambda_picture = 0.68 * pow (2, img->bitdepth_lambda_scale + ((img->qp - SHIFT_QP) / 3.0)) * (bframe ? 1 : 1);
+
+ snr_frame = frame->distortion_y + frame->distortion_u + frame->distortion_v;
+ //! all distrortions of a field picture are accumulated in the top field
+ snr_field = top->distortion_y + top->distortion_u + top->distortion_v;
+ bit_field = top->bits_per_picture + bot->bits_per_picture;
+ bit_frame = frame->bits_per_picture;
+
+ return decide_fld_frame (snr_frame, snr_field, bit_field, bit_frame, lambda_picture);
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Field Mode Buffer
+ ************************************************************************
+ */
+ static void field_mode_buffer (int bit_field, float snr_field_y, float snr_field_u, float snr_field_v)
+ {
+ put_buffer_frame ();
+
+ snr->snr_y = snr_field_y;
+ snr->snr_u = snr_field_u;
+ snr->snr_v = snr_field_v;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Frame Mode Buffer
+ ************************************************************************
+ */
+ static void frame_mode_buffer (int bit_frame, float snr_frame_y, float snr_frame_u, float snr_frame_v)
+ {
+ put_buffer_frame ();
+
+ if ((input->PicInterlace != FRAME_CODING)||(input->MbInterlace != FRAME_CODING))
+ {
+ img->height = img->height / 2;
+ img->height_cr = img->height_cr / 2;
+ img->number *= 2;
+
+ put_buffer_top ();
+
+ img->number++;
+ put_buffer_bot ();
+
+ img->number /= 2; // reset the img->number to field
+ img->height = (input->img_height+img->auto_crop_bottom);
+ img->height_cr = img->height_cr_frame;
+
+ snr->snr_y = snr_frame_y;
+ snr->snr_u = snr_frame_u;
+ snr->snr_v = snr_frame_v;
+ put_buffer_frame ();
+
+ }
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * mmco initializations should go here
+ ************************************************************************
+ */
+ static void init_dec_ref_pic_marking_buffer()
+ {
+ img->dec_ref_pic_marking_buffer=NULL;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Initializes the parameters for a new frame
+ ************************************************************************
+ */
+ static void init_frame ()
+ {
+ int i;
+ int prevP_no, nextP_no;
+
+ last_P_no = last_P_no_frm;
+
+ img->current_mb_nr = 0;
+ img->current_slice_nr = 0;
+ stats->bit_slice = 0;
+
+ img->mb_y = img->mb_x = 0;
+ img->block_y = img->pix_y = img->pix_c_y = 0;
+ img->block_x = img->pix_x = img->block_c_x = img->pix_c_x = 0;
+
+ // The 'slice_nr' of each macroblock is set to -1 here, to guarantee the correct encoding
+ // with FMO (if no FMO, encoding is correct without following assignment),
+ // for which MBs may not be encoded with scan order
+ for(i=0;i< ((img->width/MB_BLOCK_SIZE)*(img->height/MB_BLOCK_SIZE));i++)
+ img->mb_data[i].slice_nr=-1;
+
+ if (img->b_frame_to_code == 0)
+ {
+ img->tr = start_tr_in_this_IGOP + IMG_NUMBER * (input->jumpd + 1);
+
+ img->imgtr_last_P_frm = img->imgtr_next_P_frm;
+ img->imgtr_next_P_frm = img->tr;
+
+ #ifdef _ADAPT_LAST_GROUP_
+ if (input->last_frame && img->number + 1 == input->no_frames)
+ img->tr = input->last_frame;
+ #endif
+
+ if (IMG_NUMBER != 0 && input->successive_Bframe != 0) // B pictures to encode
+ nextP_tr_frm = img->tr;
+
+ //Rate control
+ if(!input->RCEnable) // without using rate control
+ {
+ if (img->type == I_SLICE)
+ #ifdef _CHANGE_QP_
+ if (input->qp2start > 0 && img->tr >= input->qp2start)
+ img->qp = input->qp02;
+ else
+ #endif
+ img->qp = input->qp0; // set quant. parameter for I-frame
+ else
+ {
+ #ifdef _CHANGE_QP_
+ if (input->qp2start > 0 && img->tr >= input->qp2start)
+ img->qp = input->qpN2 + (img->nal_reference_idc ? 0 : input->DispPQPOffset);
+ else
+ #endif
+ img->qp = input->qpN + (img->nal_reference_idc ? 0 : input->DispPQPOffset);
+
+ if (img->type == SP_SLICE)
+ {
+ img->qp = input->qpsp;
+ img->qpsp = input->qpsp_pred;
+ }
+ }
+ }
+
+ img->mb_y_intra = img->mb_y_upd; // img->mb_y_intra indicates which GOB to intra code for this frame
+
+ if (input->intra_upd > 0) // if error robustness, find next GOB to update
+ {
+ img->mb_y_upd = (IMG_NUMBER / input->intra_upd) % (img->height / MB_BLOCK_SIZE);
+ }
+ }
+ else
+ {
+ img->p_interval = input->jumpd + 1;
+ prevP_no = start_tr_in_this_IGOP + (IMG_NUMBER - 1) * img->p_interval;
+ nextP_no = start_tr_in_this_IGOP + (IMG_NUMBER) * img->p_interval;
+
+ #ifdef _ADAPT_LAST_GROUP_
+ last_P_no[0] = prevP_no;
+ for (i = 1; i < img->buf_cycle; i++)
+ last_P_no[i] = last_P_no[i - 1] - img->p_interval;
+
+ if (input->last_frame && img->number + 1 == input->no_frames)
+ {
+ nextP_no = input->last_frame;
+ img->p_interval = nextP_no - prevP_no;
+ }
+ #endif
+
+ img->b_interval =
+ ((double) (input->jumpd + 1) / (input->successive_Bframe + 1.0) );
+
+ if (input->PyramidCoding == 3)
+ img->b_interval = 1.0;
+
+ if (input->PyramidCoding)
+ img->tr = prevP_no + (int) (img->b_interval * (double) (1 + gop_structure[img->b_frame_to_code - 1].display_no)); // from prev_P
+ else
+ img->tr = prevP_no + (int) (img->b_interval * (double) img->b_frame_to_code); // from prev_P
+
+
+ if (img->tr >= nextP_no)
+ img->tr = nextP_no - 1;
+ //Rate control
+ if(!input->RCEnable && input->PyramidCoding == 0) // without using rate control
+ {
+ #ifdef _CHANGE_QP_
+ if (input->qp2start > 0 && img->tr >= input->qp2start)
+ {
+ img->qp = input->qpB2;
+ }
+ else
+ #endif
+ {
+ img->qp = input->qpB;
+ }
+
+ if (img->nal_reference_idc)
+ {
+ #ifdef _CHANGE_QP_
+ if (input->qp2start > 0 && img->tr >= input->qp2start)
+ {
+ img->qp = Clip3(-img->bitdepth_luma_qp_scale,51,input->qpB2 + input->qpBRS2Offset);
+ }
+ else
+ #endif
+ {
+ img->qp = Clip3(-img->bitdepth_luma_qp_scale,51,input->qpB + input->qpBRSOffset);
+ }
+ }
+ }
+ else if (input->PyramidCoding !=0)
+ {
+ // Note that _CHANGE_QP_ does not anymore work for gop_structure. Needs to be fixed
+ img->qp = gop_structure[img->b_frame_to_code - 1].slice_qp;
+ }
+ }
+
+ UpdateSubseqInfo (img->layer); // Tian Dong (Sept 2002)
+ UpdateSceneInformation (0, 0, 0, -1); // JVT-D099, scene information SEI, nothing included by default
+
+ //! Commented out by StW, needs fixing in SEI.h to keep the trace file clean
+ // PrepareAggregationSEIMessage ();
+
+ img->no_output_of_prior_pics_flag = 0;
+ img->long_term_reference_flag = 0;
+
+ init_dec_ref_pic_marking_buffer();
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Initializes the parameters for a new field
+ ************************************************************************
+ */
+ static void init_field ()
+ {
+ int i;
+ int prevP_no, nextP_no;
+
+ last_P_no = last_P_no_fld;
+
+ img->current_mb_nr = 0;
+ img->current_slice_nr = 0;
+ stats->bit_slice = 0;
+
+ input->jumpd *= 2;
+ input->successive_Bframe *= 2;
+ img->number /= 2;
+ img->buf_cycle /= 2;
+
+ img->mb_y = img->mb_x = 0;
+ img->block_y = img->pix_y = img->pix_c_y = 0; // define vertical positions
+ img->block_x = img->pix_x = img->block_c_x = img->pix_c_x = 0; // define horizontal positions
+
+ if (!img->b_frame_to_code)
+ {
+ img->tr = img->number * (input->jumpd + 2) + img->fld_type;
+
+ if (!img->fld_type)
+ {
+ img->imgtr_last_P_fld = img->imgtr_next_P_fld;
+ img->imgtr_next_P_fld = img->tr;
+ }
+
+ #ifdef _ADAPT_LAST_GROUP_
+ if (input->last_frame && img->number + 1 == input->no_frames)
+ img->tr = input->last_frame;
+ #endif
+ if (img->number != 0 && input->successive_Bframe != 0) // B pictures to encode
+ nextP_tr_fld = img->tr;
+
+ //Rate control
+ if(!input->RCEnable) // without using rate control
+ {
+ if (img->type == I_SLICE)
+ {
+ #ifdef _CHANGE_QP_
+ if (input->qp2start > 0 && img->tr >= input->qp2start)
+ img->qp = input->qp02;
+ else
+ #endif
+ img->qp = input->qp0; // set quant. parameter for I-frame
+ }
+ else
+ {
+ #ifdef _CHANGE_QP_
+ if (input->qp2start > 0 && img->tr >= input->qp2start)
+ img->qp = input->qpN2 + (img->nal_reference_idc ? 0 : input->DispPQPOffset);
+ else
+ #endif
+ img->qp = input->qpN + (img->nal_reference_idc ? 0 : input->DispPQPOffset);
+ if (img->type == SP_SLICE)
+ {
+ img->qp = input->qpsp;
+ img->qpsp = input->qpsp_pred;
+ }
+ }
+ }
+ img->mb_y_intra = img->mb_y_upd; // img->mb_y_intra indicates which GOB to intra code for this frame
+
+ if (input->intra_upd > 0) // if error robustness, find next GOB to update
+ {
+ img->mb_y_upd =
+ (img->number / input->intra_upd) % (img->width / MB_BLOCK_SIZE);
+ }
+ }
+ else
+ {
+ img->p_interval = input->jumpd + 2;
+ prevP_no = (img->number - 1) * img->p_interval + img->fld_type;
+ nextP_no = img->number * img->p_interval + img->fld_type;
+ #ifdef _ADAPT_LAST_GROUP_
+ if (!img->fld_type) // top field
+ {
+ last_P_no[0] = prevP_no + 1;
+ last_P_no[1] = prevP_no;
+ for (i = 1; i <= img->buf_cycle; i++)
+ {
+ last_P_no[2 * i] = last_P_no[2 * i - 2] - img->p_interval;
+ last_P_no[2 * i + 1] = last_P_no[2 * i - 1] - img->p_interval;
+ }
+ }
+ else // bottom field
+ {
+ last_P_no[0] = nextP_no - 1;
+ last_P_no[1] = prevP_no;
+ for (i = 1; i <= img->buf_cycle; i++)
+ {
+ last_P_no[2 * i] = last_P_no[2 * i - 2] - img->p_interval;
+ last_P_no[2 * i + 1] = last_P_no[2 * i - 1] - img->p_interval;
+ }
+ }
+
+ if (input->last_frame && img->number + 1 == input->no_frames)
+ {
+ nextP_no = input->last_frame;
+ img->p_interval = nextP_no - prevP_no;
+ }
+ #endif
+ img->b_interval =
+ ((double) (input->jumpd + 1) / (input->successive_Bframe + 1.0) );
+
+ if (input->PyramidCoding == 3)
+ img->b_interval = 1.0;
+
+ if (input->PyramidCoding)
+ img->tr = prevP_no + (int) ((img->b_interval + 1.0) * (double) (1 + gop_structure[img->b_frame_to_code - 1].display_no)); // from prev_P
+ else
+ img->tr = prevP_no + (int) ((img->b_interval + 1.0) * (double) img->b_frame_to_code); // from prev_P
+
+
+ if (img->tr >= nextP_no)
+ img->tr = nextP_no - 1; // ?????
+ //Rate control
+ if(!input->RCEnable && input->PyramidCoding == 0) // without using rate control
+ {
+ #ifdef _CHANGE_QP_
+ if (input->qp2start > 0 && img->tr >= input->qp2start)
+ img->qp = input->qpB2;
+ else
+ #endif
+ img->qp = input->qpB;
+ if (img->nal_reference_idc)
+ {
+ #ifdef _CHANGE_QP_
+ if (input->qp2start > 0 && img->tr >= input->qp2start)
+ img->qp = Clip3(-img->bitdepth_luma_qp_scale,51,input->qpB2 + input->qpBRS2Offset);
+ else
+ #endif
+ img->qp = Clip3(-img->bitdepth_luma_qp_scale,51,input->qpB + input->qpBRSOffset);
+
+ }
+ }
+ else if (input->PyramidCoding != 0)
+ {
+ img->qp = gop_structure[img->b_frame_to_code - 1].slice_qp;
+ }
+ }
+ input->jumpd /= 2;
+ input->successive_Bframe /= 2;
+ img->buf_cycle *= 2;
+ img->number = 2 * img->number + img->fld_type;
+ }
+
+
+ #define Clip(min,max,val) (((val)<(min))?(min):(((val)>(max))?(max):(val)))
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Generate Full Pel Representation
+ ************************************************************************
+ */
+ static void GenerateFullPelRepresentation (pel_t ** Fourthpel,
+ pel_t * Fullpel, int xsize,
+ int ysize)
+ {
+ int x, y, yy , y_pos;
+
+ for (y = 0; y < ysize; y++)
+ {
+ yy = (y + IMG_PAD_SIZE)<<2;
+ y_pos = y * xsize;
+ for (x = 0; x < xsize; x++)
+ PutPel_11 (Fullpel, y_pos + x, Fourthpel[yy][(x + IMG_PAD_SIZE)<<2]);
+ }
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Upsample 4 times, store them in out4x. Color is simply copied
+ *
+ * \par Input:
+ * srcy, srcu, srcv, out4y, out4u, out4v
+ *
+ * \par Side Effects_
+ * Uses (writes) img4Y_tmp. This should be moved to a static variable
+ * in this module
+ ************************************************************************/
+ void UnifiedOneForthPix (StorablePicture *s)
+ {
+ int is;
+ int i, j, j4;
+ int ie2, je2, jj , jpad;
+ int maxy = s->size_y + 2 * IMG_PAD_SIZE - 1;
+ int ii, i1;
+ imgpel **out4Y;
+ imgpel *ref11;
+ imgpel **imgY = s->imgY;
+ int size_x_minus1 = s->size_x - 1;
+ int size_y_minus1 = s->size_y - 1;
+
+ // don't upsample twice
+ if (s->imgY_ups || s->imgY_11)
+ return;
+
+ s->imgY_11 = malloc ((s->size_x * s->size_y) * sizeof (imgpel));
+ if (NULL == s->imgY_11)
+ no_mem_exit("alloc_storable_picture: s->imgY_11");
+
+ get_mem2Dpel (&(s->imgY_ups), (2*IMG_PAD_SIZE + s->size_y)*4, (2*IMG_PAD_SIZE + s->size_x)*4);
+
+ if (input->WeightedPrediction || input->WeightedBiprediction || input->GenerateMultiplePPS)
+ {
+ s->imgY_11_w = malloc ((s->size_x * s->size_y) * sizeof (imgpel));
+ if (NULL == s->imgY_11_w)
+ no_mem_exit("alloc_storable_picture: s->imgY_11_w");
+ get_mem2Dpel (&(s->imgY_ups_w), (2*IMG_PAD_SIZE + s->size_y)*4, (2*IMG_PAD_SIZE + s->size_x)*4);
+ }
+ out4Y = s->imgY_ups;
+ ref11 = s->imgY_11;
+
+ for (j = -IMG_PAD_SIZE; j < s->size_y + IMG_PAD_SIZE; j++)
+ {
+ jj = max (0, min (size_y_minus1, j));
+ jpad = j + IMG_PAD_SIZE;
+ for (i = -IMG_PAD_SIZE; i < s->size_x + IMG_PAD_SIZE; i++)
+ {
+ is =
+ (ONE_FOURTH_TAP[0][0] *
+ (imgY[jj][max (0, min (size_x_minus1, i))] +
+ imgY[jj][max (0, min (size_x_minus1, i + 1))]) +
+ ONE_FOURTH_TAP[1][0] *
+ (imgY[jj][max (0, min (size_x_minus1, i - 1))] +
+ imgY[jj][max (0, min (size_x_minus1, i + 2))]) +
+ ONE_FOURTH_TAP[2][0] *
+ (imgY[jj][max (0, min (size_x_minus1, i - 2))] +
+ imgY[jj][max (0, min (size_x_minus1, i + 3))]));
+
+ img4Y_tmp[jpad][(i + IMG_PAD_SIZE) * 2] = imgY[jj][max (0, min (size_x_minus1, i))] * 1024; // 1/1 pix pos
+ img4Y_tmp[jpad][(i + IMG_PAD_SIZE) * 2 + 1] = is * 32; // 1/2 pix pos
+ }
+ }
+
+ for (i = 0; i < (s->size_x + 2 * IMG_PAD_SIZE) * 2; i++)
+ {
+ ii = i * 2;
+ for (j = 0; j < s->size_y + 2 * IMG_PAD_SIZE; j++)
+ {
+ j4 = j * 4;
+
+ // change for TML4, use 6 TAP vertical filter
+ is =
+ ( ONE_FOURTH_TAP[0][0] *(img4Y_tmp[j][i] + img4Y_tmp[min (maxy, j + 1)][i])
+ + ONE_FOURTH_TAP[1][0] * (img4Y_tmp[max (0, j - 1)][i] + img4Y_tmp[min (maxy, j + 2)][i])
+ + ONE_FOURTH_TAP[2][0] * (img4Y_tmp[max (0, j - 2)][i] + img4Y_tmp[min (maxy, j + 3)][i])) / 32;
+
+ out4Y[j4 ][ii] = (pel_t) Clip3 (0, img->max_imgpel_value, (int) ((img4Y_tmp[j][i] + 512) / 1024)); // 1/2 pix
+ out4Y[j4 + 2][ii] = (pel_t) Clip3 (0, img->max_imgpel_value, (int) ((is + 512) / 1024)); // 1/2 pix
+ }
+ }
+
+ /* 1/4 pix */
+ /* luma */
+ ie2 = (s->size_x + 2 * IMG_PAD_SIZE - 1) * 4 + 2;
+ je2 = (s->size_y + 2 * IMG_PAD_SIZE - 1) * 4 + 2;
+
+ for (j = 0; j < je2 + 2; j += 2)
+ for (i = 0; i < ie2 + 1; i += 2)
+ {
+ /* '-' */
+ out4Y[j][i+1] = (pel_t) (Clip3 (0, img->max_imgpel_value, (int) (out4Y[j][i] + out4Y[j][min (ie2, i + 2)] + 1) >> 1));
+ }
+ for (i = 0; i < ie2 + 2; i++)
+ {
+ ii = min (ie2, i + 1);
+ i1 = i - 1;
+ for (j = 0; j < je2 + 1; j += 2)
+ {
+ if ((i & 0x1) == 0) /* '|' */
+ {
+ out4Y[j + 1][i] = (pel_t) (Clip3 (0, img->max_imgpel_value, (int) (out4Y[j][i] + out4Y[min (je2, j + 2)][i] + 1) >> 1));
+ }
+ else if (((j & 0x3) == 0 && (i & 0x3) == 1) || ((j & 0x3) == 2 && (i & 0x3) == 3)) /* '/' */
+ {
+ out4Y[j + 1][i] = (pel_t) (Clip3 (0, img->max_imgpel_value, (int) (out4Y[j][ii] + out4Y[min (je2, j + 2)][i1] + 1) >> 1));
+ }
+ else /* '\' */
+ {
+ out4Y[j + 1][i] = (pel_t) (Clip3 (0, img->max_imgpel_value, (int) (out4Y[j][i1] + out4Y[min (je2, j + 2)][ii] + 1) >> 1));
+ }
+ }
+ }
+
+ // Generate 1/1th pel representation (used for integer pel MV search)
+ GenerateFullPelRepresentation (out4Y, ref11, s->size_x, s->size_y);
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Find SNR for all three components
+ ************************************************************************
+ */
+ static void find_snr ()
+ {
+ int i, j;
+ int64 diff_y=0, diff_u=0, diff_v=0;
+ int impix;
+ int impix_cr;
+ unsigned int max_pix_value_sqd = img->max_imgpel_value * img->max_imgpel_value;
+ unsigned int max_pix_value_sqd_uv = img->max_imgpel_value_uv * img->max_imgpel_value_uv;
+
+ // Calculate PSNR for Y, U and V.
+
+ // Luma.
+ impix = input->img_height * input->img_width;
+ impix_cr = input->img_height_cr * input->img_width_cr;
+
+ if (img->fld_flag != 0)
+ {
+
+ diff_y = 0;
+ for (i = 0; i < input->img_width; ++i)
+ {
+ for (j = 0; j < input->img_height; ++j)
+ {
+ diff_y += img->quad[imgY_org[j][i] - imgY_com[j][i]];
+ }
+ }
+
+ if (img->yuv_format != YUV400)
+ {
+ // Chroma.
+ diff_u = 0;
+ diff_v = 0;
+
+ for (i = 0; i < input->img_width_cr; i++)
+ {
+ for (j = 0; j < input->img_height_cr; j++)
+ {
+ diff_u += img->quad[imgUV_org[0][j][i] - imgUV_com[0][j][i]];
+ diff_v += img->quad[imgUV_org[1][j][i] - imgUV_com[1][j][i]];
+ }
+ }
+ }
+ }
+ else
+ {
+ imgY_org = imgY_org_frm;
+ imgUV_org = imgUV_org_frm;
+
+ if(input->PicInterlace==ADAPTIVE_CODING)
+ {
+ enc_picture = enc_frame_picture;
+ }
+
+ diff_y = 0;
+ for (i = 0; i < input->img_width; ++i)
+ {
+ for (j = 0; j < input->img_height; ++j)
+ {
+ diff_y += img->quad[imgY_org[j][i] - enc_picture->imgY[j][i]];
+ }
+ }
+
+ if (img->yuv_format != YUV400)
+ {
+ // Chroma.
+ diff_u = 0;
+ diff_v = 0;
+
+ for (i = 0; i < input->img_width_cr; i++)
+ {
+ for (j = 0; j < input->img_height_cr; j++)
+ {
+ diff_u += img->quad[imgUV_org[0][j][i] - enc_picture->imgUV[0][j][i]];
+ diff_v += img->quad[imgUV_org[1][j][i] - enc_picture->imgUV[1][j][i]];
+ }
+ }
+ }
+ }
+ snr->sse_y = (float)diff_y;
+ snr->sse_u = (float)diff_u;
+ snr->sse_v = (float)diff_v;
+
+ #if ZEROSNR
+ if (diff_y == 0)
+ diff_y = 1;
+ if (diff_u == 0)
+ diff_u = 1;
+ if (diff_v == 0)
+ diff_v = 1;
+ #endif
+
+ // Collecting SNR statistics
+ if (diff_y != 0)
+ {
+ snr->snr_y = (float) (10 * log10 (max_pix_value_sqd * (double)((double) impix / diff_y))); // luma snr for current frame
+ if (img->yuv_format != YUV400)
+ {
+ snr->snr_u = (float) (10 * log10 (max_pix_value_sqd_uv * (double)((double) impix_cr / diff_u))); // u croma snr for current frame, 1/4 of luma samples
+ snr->snr_v = (float) (10 * log10 (max_pix_value_sqd_uv * (double)((double) impix_cr / diff_v))); // v croma snr for current frame, 1/4 of luma samples
+ }
+ else
+ {
+ snr->snr_u = 0.0;
+ snr->snr_v = 0.0;
+ }
+ }
+
+
+ if (img->number == 0)
+ {
+ snr->snr_y1 = snr->snr_y; // keep luma snr for first frame
+ snr->snr_u1 = snr->snr_u; // keep croma u snr for first frame
+ snr->snr_v1 = snr->snr_v; // keep croma v snr for first frame
+ snr->snr_ya = snr->snr_y1;
+ snr->snr_ua = snr->snr_u1;
+ snr->snr_va = snr->snr_v1;
+ // sse stats
+ snr->msse_y = snr->sse_y;
+ snr->msse_u = snr->sse_u;
+ snr->msse_v = snr->sse_v;
+ for (i=0; i<5; i++)
+ {
+ snr->snr_yt[i] = 0.0;
+ snr->snr_ut[i] = 0.0;
+ snr->snr_vt[i] = 0.0;
+ }
+ }
+ else
+ {
+ //int total_frames = img->number + frame_ctr[B_SLICE];
+ int total_frames = snr->frame_ctr - 1;
+
+ snr->snr_ya = (float) (snr->snr_ya * total_frames + snr->snr_y) / (total_frames + 1); // average snr luma for all frames inc. first
+ snr->snr_ua = (float) (snr->snr_ua * total_frames + snr->snr_u) / (total_frames + 1); // average snr u croma for all frames inc. first
+ snr->snr_va = (float) (snr->snr_va * total_frames + snr->snr_v) / (total_frames + 1); // average snr v croma for all frames inc. first
+ snr->msse_y = (float) (snr->msse_y * total_frames + snr->sse_y) / (total_frames + 1); // average mse luma for all frames inc. first
+ snr->msse_u = (float) (snr->msse_u * total_frames + snr->sse_u) / (total_frames + 1); // average mse u croma for all frames inc. first
+ snr->msse_v = (float) (snr->msse_v * total_frames + snr->sse_v) / (total_frames + 1); // average mse v croma for all frames inc. first
+ }
+
+ snr->snr_yt[img->type] = (float) (snr->snr_yt[img->type] * (frame_ctr[img->type] - 1) + snr->snr_y) / ( frame_ctr[img->type] ); // average luma snr for img->type coded frames
+ snr->snr_ut[img->type] = (float) (snr->snr_ut[img->type] * (frame_ctr[img->type] - 1) + snr->snr_u) / ( frame_ctr[img->type] ); // average chroma u snr for img->type coded frames
+ snr->snr_vt[img->type] = (float) (snr->snr_vt[img->type] * (frame_ctr[img->type] - 1) + snr->snr_v) / ( frame_ctr[img->type] ); // average chroma v snr for img->type coded frames
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Find distortion for all three components
+ ************************************************************************
+ */
+ static void find_distortion ()
+ {
+ int i, j;
+ int64 diff_y, diff_u, diff_v;
+ int impix;
+
+ // Calculate PSNR for Y, U and V.
+
+ // Luma.
+ impix = input->img_height * input->img_width;
+
+ if (img->structure!=FRAME)
+ {
+
+ diff_y = 0;
+ for (i = 0; i < input->img_width; ++i)
+ {
+ for (j = 0; j < input->img_height; ++j)
+ {
+ diff_y += img->quad[imgY_org[j][i] - imgY_com[j][i]];
+ }
+ }
+
+ diff_u = 0;
+ diff_v = 0;
+
+ if (img->yuv_format != YUV400)
+ {
+ // Chroma.
+ for (i = 0; i < input->img_width_cr; i++)
+ {
+ for (j = 0; j < input->img_height_cr; j++)
+ {
+ diff_u += img->quad[imgUV_org[0][j][i] - imgUV_com[0][j][i]];
+ diff_v += img->quad[imgUV_org[1][j][i] - imgUV_com[1][j][i]];
+ }
+ }
+ }
+ }
+ else
+ {
+ imgY_org = imgY_org_frm;
+ imgUV_org = imgUV_org_frm;
+
+ diff_y = 0;
+ for (i = 0; i < input->img_width; ++i)
+ {
+ for (j = 0; j < input->img_height; ++j)
+ {
+ diff_y += img->quad[imgY_org[j][i] - enc_picture->imgY[j][i]];
+ }
+ }
+
+ diff_u = 0;
+ diff_v = 0;
+
+ if (img->yuv_format != YUV400)
+ {
+ // Chroma.
+ for (i = 0; i < input->img_width_cr; i++)
+ {
+ for (j = 0; j < input->img_height_cr; j++)
+ {
+ diff_u += img->quad[imgUV_org[0][j][i] - enc_picture->imgUV[0][j][i]];
+ diff_v += img->quad[imgUV_org[1][j][i] - enc_picture->imgUV[1][j][i]];
+ }
+ }
+ }
+ }
+ // Calculate real PSNR at find_snr_avg()
+ snr->snr_y = (float) diff_y;
+ snr->snr_u = (float) diff_u;
+ snr->snr_v = (float) diff_v;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Just a placebo
+ ************************************************************************
+ */
+ Boolean dummy_slice_too_big (int bits_slice)
+ {
+ return FALSE;
+ }
+
+
+ /*!
+ ***************************************************************************
+ // For MB level field/frame coding
+ ***************************************************************************
+ */
+ void copy_rdopt_data (int bot_block)
+ {
+ int mb_nr = img->current_mb_nr;
+ Macroblock *currMB = &img->mb_data[mb_nr];
+ int i, j, k;
+
+ int bframe = (img->type == B_SLICE);
+ int mode;
+ int b8mode, b8pdir;
+ int block_y;
+
+ int list_offset = currMB->list_offset;
+
+ mode = rdopt->mode;
+ currMB->mb_type = rdopt->mb_type; // copy mb_type
+ currMB->cbp = rdopt->cbp; // copy cbp
+ currMB->cbp_blk = rdopt->cbp_blk; // copy cbp_blk
+ currMB->bi_pred_me = rdopt->bi_pred_me; // copy biprediction
+ img->i16offset = rdopt->i16offset;
+
+ currMB->prev_qp=rdopt->prev_qp;
+ currMB->prev_delta_qp=rdopt->prev_delta_qp;
+ currMB->prev_cbp=rdopt->prev_cbp;
+ currMB->delta_qp=rdopt->delta_qp;
+ currMB->qp=rdopt->qp;
+
+ currMB->c_ipred_mode = rdopt->c_ipred_mode;
+
+ for (i = 0; i < 4+img->num_blk8x8_uv; i++)
+ {
+ for (j = 0; j < 4; j++)
+ for (k = 0; k < 2; k++)
+ memcpy(img->cofAC[i][j][k],rdopt->cofAC[i][j][k], 65 * sizeof(int));
+ }
+
+ for (i = 0; i < 3; i++)
+ {
+ for (k = 0; k < 2; k++)
+ memcpy(img->cofDC[i][k],rdopt->cofDC[i][k], 18 * sizeof(int));
+ }
+
+ for (j = 0; j < BLOCK_MULTIPLE; j++)
+ {
+ block_y = img->block_y + j;
+ memcpy(&enc_picture->ref_idx[LIST_0][block_y][img->block_x], rdopt->refar[LIST_0][j], BLOCK_MULTIPLE * sizeof(char));
+ for (i = 0; i < BLOCK_MULTIPLE; i++)
+ enc_picture->ref_pic_id [LIST_0][block_y][img->block_x + i] =
+ enc_picture->ref_pic_num[LIST_0 + list_offset][(short)enc_picture->ref_idx[LIST_0][block_y][img->block_x+i]];
+ }
+ if (bframe)
+ {
+ for (j = 0; j < BLOCK_MULTIPLE; j++)
+ {
+ block_y = img->block_y + j;
+ memcpy(&enc_picture->ref_idx[LIST_1][block_y][img->block_x], rdopt->refar[LIST_1][j], BLOCK_MULTIPLE * sizeof(char));
+ for (i = 0; i < BLOCK_MULTIPLE; i++)
+ enc_picture->ref_pic_id [LIST_1][block_y][img->block_x + i] =
+ enc_picture->ref_pic_num[LIST_1 + list_offset][(short)enc_picture->ref_idx[LIST_1][block_y][img->block_x+i]];
+ }
+ }
+
+ //===== reconstruction values =====
+ for (j = 0; j < MB_BLOCK_SIZE; j++)
+ memcpy(&enc_picture->imgY[img->pix_y + j][img->pix_x],rdopt->rec_mbY[j], MB_BLOCK_SIZE * sizeof(imgpel));
+
+ if (img->yuv_format != YUV400)
+ {
+ for (j = 0; j < img->mb_cr_size_y; j++)
+ {
+ memcpy(&enc_picture->imgUV[0][img->pix_c_y + j][img->pix_c_x],rdopt->rec_mbU[j], img->mb_cr_size_x * sizeof(imgpel));
+ memcpy(&enc_picture->imgUV[1][img->pix_c_y + j][img->pix_c_x],rdopt->rec_mbV[j], img->mb_cr_size_x * sizeof(imgpel));
+ }
+ }
+
+ memcpy(currMB->b8mode,rdopt->b8mode, 4 * sizeof(int));
+ memcpy(currMB->b8pdir,rdopt->b8pdir, 4 * sizeof(int));
+
+ currMB->luma_transform_size_8x8_flag = rdopt->luma_transform_size_8x8_flag;
+
+ //==== intra prediction modes ====
+ if (mode == P8x8)
+ {
+ memcpy(currMB->intra_pred_modes,rdopt->intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
+ for (j = img->block_y; j < img->block_y + BLOCK_MULTIPLE; j++)
+ memcpy(&img->ipredmode[j][img->block_x],&rdopt->ipredmode[j][img->block_x], BLOCK_MULTIPLE * sizeof(char));
+ }
+ else if (mode != I4MB && mode != I8MB)
+ {
+ memset(currMB->intra_pred_modes,DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char));
+ for (j = img->block_y; j < img->block_y + BLOCK_MULTIPLE; j++)
+ memset(&img->ipredmode[j][img->block_x],DC_PRED, BLOCK_MULTIPLE * sizeof(char));
+ }
+ else if (mode == I4MB || mode == I8MB)
+ {
+ memcpy(currMB->intra_pred_modes,rdopt->intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
+ for (j = img->block_y; j < img->block_y + BLOCK_MULTIPLE; j++)
+ memcpy(&img->ipredmode[j][img->block_x],&rdopt->ipredmode[j][img->block_x], BLOCK_MULTIPLE * sizeof(char));
+ }
+
+ if (img->MbaffFrameFlag)
+ {
+ // motion vectors
+ copy_motion_vectors_MB ();
+
+ if (!IS_INTRA(currMB))
+ {
+ for (j = 0; j < 4; j++)
+ for (i = 0; i < 4; i++)
+ {
+ b8mode = currMB->b8mode[i/2+2*(j/2)];
+ b8pdir = currMB->b8pdir[i/2+2*(j/2)];
+
+ if (b8pdir!=1)
+ {
+ enc_picture->mv[LIST_0][j+img->block_y][i+img->block_x][0] = rdopt->all_mv[j][i][LIST_0][(short)rdopt->refar[LIST_0][j][i]][b8mode][0];
+ enc_picture->mv[LIST_0][j+img->block_y][i+img->block_x][1] = rdopt->all_mv[j][i][LIST_0][(short)rdopt->refar[LIST_0][j][i]][b8mode][1];
+ }
+ else
+ {
+ enc_picture->mv[LIST_0][j+img->block_y][i+img->block_x][0] = 0;
+ enc_picture->mv[LIST_0][j+img->block_y][i+img->block_x][1] = 0;
+ }
+ if (bframe)
+ {
+ if (b8pdir!=0)
+ {
+ enc_picture->mv[LIST_1][j+img->block_y][i+img->block_x][0] = rdopt->all_mv[j][i][LIST_1][(short)rdopt->refar[LIST_1][j][i]][b8mode][0];
+ enc_picture->mv[LIST_1][j+img->block_y][i+img->block_x][1] = rdopt->all_mv[j][i][LIST_1][(short)rdopt->refar[LIST_1][j][i]][b8mode][1];
+ }
+ else
+ {
+ enc_picture->mv[LIST_1][j+img->block_y][i+img->block_x][0] = 0;
+ enc_picture->mv[LIST_1][j+img->block_y][i+img->block_x][1] = 0;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (j = 0; j < 4; j++)
+ memset(enc_picture->mv[LIST_0][j+img->block_y][img->block_x], 0, 2 * BLOCK_MULTIPLE * sizeof(short));
+ if (bframe)
+ {
+ for (j = 0; j < 4; j++)
+ memset(enc_picture->mv[LIST_1][j+img->block_y][img->block_x], 0, 2 * BLOCK_MULTIPLE * sizeof(short));
+ }
+ }
+ }
+ } // end of copy_rdopt_data
+
+ static void copy_motion_vectors_MB ()
+ {
+ int i,j,k,l;
+
+ for (i = 0; i < 4; i++)
+ {
+ for (j = 0; j < 4; j++)
+ {
+ for (k = 0; k < img->max_num_references; k++)
+ {
+ for (l = 0; l < 9; l++)
+ {
+ img->all_mv[j][i][LIST_0][k][l][0] = rdopt->all_mv[j][i][LIST_0][k][l][0];
+ img->all_mv[j][i][LIST_0][k][l][1] = rdopt->all_mv[j][i][LIST_0][k][l][1];
+
+ img->all_mv[j][i][LIST_1][k][l][0] = rdopt->all_mv[j][i][LIST_1][k][l][0];
+ img->all_mv[j][i][LIST_1][k][l][1] = rdopt->all_mv[j][i][LIST_1][k][l][1];
+
+ img->pred_mv[j][i][LIST_0][k][l][0] = rdopt->pred_mv[j][i][LIST_0][k][l][0];
+ img->pred_mv[j][i][LIST_0][k][l][1] = rdopt->pred_mv[j][i][LIST_0][k][l][1];
+
+ img->pred_mv[j][i][LIST_1][k][l][0] = rdopt->pred_mv[j][i][LIST_1][k][l][0];
+ img->pred_mv[j][i][LIST_1][k][l][1] = rdopt->pred_mv[j][i][LIST_1][k][l][1];
+ }
+ }
+ }
+ }
+ }
+
+
+ static void ReportNALNonVLCBits(int tmp_time, int me_time)
+ {
+
+ //! Need to add type (i.e. SPS, PPS, SEI etc).
+ if (input->Verbose != 0)
+ printf ("%04d(NVB)%8d \n", frame_no, stats->bit_ctr_parametersets_n);
+ }
+ static void ReportFirstframe(int tmp_time,int me_time)
+ {
+ //Rate control
+ int bits;
+
+ #if 1 // FIXME: control with a runtime option.
+ tmp_time = me_time = 0;
+ #endif
+
+ if (input->Verbose == 1)
+ {
+ printf ("%04d(IDR)%8d %2d %7.3f %7.3f %7.3f %9d %7d %3s %d\n",
+ frame_no, stats->bit_ctr - stats->bit_ctr_n,
+ img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time, me_time,
+ img->fld_flag ? "FLD" : "FRM", img->nal_reference_idc);
+ }
+ else if (input->Verbose == 2)
+ {
+ printf ("%04d(IDR)%8d %1d %2d %7.3f %7.3f %7.3f %9d %7d %3s %5d %2d %2d %d %d\n",
+ frame_no, stats->bit_ctr - stats->bit_ctr_n,0,
+ img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time, me_time,
+ img->fld_flag ? "FLD" : "FRM", intras, img->num_ref_idx_l0_active, img->num_ref_idx_l1_active,img->rd_pass, img->nal_reference_idc);
+ }
+ //Rate control
+ if(input->RCEnable)
+ {
+ if((!input->PicInterlace)&&(!input->MbInterlace))
+ bits = stats->bit_ctr-stats->bit_ctr_n; // used for rate control update
+ else
+ {
+ bits = stats->bit_ctr - Iprev_bits; // used for rate control update
+ Iprev_bits = stats->bit_ctr;
+ }
+ }
+
+ stats->bit_ctr_I = stats->bit_ctr;
+ stats->bit_ctr = 0;
+
+ }
+
+
+ static void ReportIntra(int tmp_time, int me_time)
+ {
+ #if 1 // FIXME: control with a runtime option.
+ tmp_time = me_time = 0;
+ #endif
+ if (input->Verbose == 1)
+ {
+ if (img->currentPicture->idr_flag == 1)
+ printf ("%04d(IDR)%8d %2d %7.3f %7.3f %7.3f %9d %7d %3s %d\n",
+ frame_no, stats->bit_ctr - stats->bit_ctr_n,
+ img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time, me_time,
+ img->fld_flag ? "FLD" : "FRM", img->nal_reference_idc);
+ else
+ printf ("%04d(I) %8d %2d %7.3f %7.3f %7.3f %9d %7d %3s %d\n",
+ frame_no, stats->bit_ctr - stats->bit_ctr_n,
+ img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time, me_time,
+ img->fld_flag ? "FLD" : "FRM", img->nal_reference_idc);
+ }
+ else if (input->Verbose == 2)
+ {
+ if (img->currentPicture->idr_flag == 1)
+ printf ("%04d(IDR)%8d %1d %2d %7.3f %7.3f %7.3f %9d %7d %3s %5d %2d %2d %d %d\n",
+ frame_no, stats->bit_ctr - stats->bit_ctr_n, 0,
+ img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time, me_time,
+ img->fld_flag ? "FLD" : "FRM", intras, img->num_ref_idx_l0_active, img->num_ref_idx_l1_active,img->rd_pass, img->nal_reference_idc);
+ else
+ printf ("%04d(I) %8d %1d %2d %7.3f %7.3f %7.3f %9d %7d %3s %5d %2d %2d %d %d\n",
+ frame_no, stats->bit_ctr - stats->bit_ctr_n, 0,
+ img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time, me_time,
+ img->fld_flag ? "FLD" : "FRM", intras, img->num_ref_idx_l0_active, img->num_ref_idx_l1_active,img->rd_pass, img->nal_reference_idc);
+ }
+ }
+
+ static void ReportSP(int tmp_time, int me_time)
+ {
+ #if 1 // FIXME: control with a runtime option.
+ tmp_time = me_time = 0;
+ #endif
+ if (input->Verbose == 1)
+ {
+ printf ("%04d(SP) %8d %2d %7.3f %7.3f %7.3f %9d %7d %3s %d\n",
+ frame_no, stats->bit_ctr - stats->bit_ctr_n,
+ img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time, me_time,
+ img->fld_flag ? "FLD" : "FRM", img->nal_reference_idc);
+ }
+ else if (input->Verbose == 2)
+ {
+
+ printf ("%04d(SP) %8d %1d %2d %7.3f %7.3f %7.3f %9d %7d %3s %5d %2d %2d %d %d\n",
+ frame_no, stats->bit_ctr - stats->bit_ctr_n, active_pps->weighted_pred_flag,
+ img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time, me_time,
+ img->fld_flag ? "FLD" : "FRM", intras, img->num_ref_idx_l0_active, img->num_ref_idx_l1_active,img->rd_pass, img->nal_reference_idc);
+ }
+ }
+
+ static void ReportB(int tmp_time, int me_time)
+ {
+ #if 1 // FIXME: control with a runtime option.
+ tmp_time = me_time = 0;
+ #endif
+ if (input->Verbose == 1)
+ {
+ printf ("%04d(B) %8d %2d %7.3f %7.3f %7.3f %9d %7d %3s %d\n",
+ frame_no, stats->bit_ctr - stats->bit_ctr_n,
+ img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time,me_time,
+ img->fld_flag ? "FLD" : "FRM", img->nal_reference_idc);
+ }
+ else if (input->Verbose == 2)
+ {
+ printf ("%04d(B) %8d %1d %2d %7.3f %7.3f %7.3f %9d %7d %3s %5d %1d %2d %2d %d %d\n",
+ frame_no, stats->bit_ctr - stats->bit_ctr_n, active_pps->weighted_bipred_idc,
+ img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time,me_time,
+ img->fld_flag ? "FLD" : "FRM",intras,img->direct_spatial_mv_pred_flag, img->num_ref_idx_l0_active, img->num_ref_idx_l1_active,img->rd_pass, img->nal_reference_idc);
+ }
+ }
+
+
+ static void ReportP(int tmp_time, int me_time)
+ {
+ #if 1 // FIXME: control with a runtime option.
+ tmp_time = me_time = 0;
+ #endif
+ if (input->Verbose == 1)
+ {
+ printf ("%04d(P) %8d %2d %7.3f %7.3f %7.3f %9d %7d %3s %d\n",
+ frame_no, stats->bit_ctr - stats->bit_ctr_n,
+ img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time, me_time,
+ img->fld_flag ? "FLD" : "FRM", img->nal_reference_idc);
+ }
+ else if (input->Verbose == 2)
+ {
+ printf ("%04d(P) %8d %1d %2d %7.3f %7.3f %7.3f %9d %7d %3s %5d %2d %2d %d %d\n",
+ frame_no, stats->bit_ctr - stats->bit_ctr_n, active_pps->weighted_pred_flag,
+ img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time, me_time,
+ img->fld_flag ? "FLD" : "FRM", intras, img->num_ref_idx_l0_active, img->num_ref_idx_l1_active, img->rd_pass, img->nal_reference_idc);
+ }
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Padding of automatically added border for picture sizes that are not
+ * multiples of macroblock/macroblock pair size
+ *
+ * \param org_size_x
+ * original image horizontal size (luma)
+ * \param org_size_y
+ * original image vertical size (luma)
+ * \param img_size_x
+ * coded image horizontal size (luma)
+ * \param img_size_y
+ * code image vertical size (luma)
+ * \param org_size_x_cr
+ * original image horizontal size (chroma)
+ * \param org_size_y_cr
+ * original image vertical size (chroma)
+ * \param img_size_x_cr
+ * coded image horizontal size (chroma)
+ * \param img_size_y_cr
+ * code image vertical size (chroma)
+ ************************************************************************
+ */
+ static void PaddAutoCropBorders (int org_size_x, int org_size_y, int img_size_x, int img_size_y,
+ int org_size_x_cr, int org_size_y_cr, int img_size_x_cr, int img_size_y_cr)
+ {
+ int x, y;
+
+ //padding right border
+ for (y=0; y<org_size_y; y++)
+ for (x=org_size_x; x<img_size_x; x++)
+ imgY_org_frm [y][x] = imgY_org_frm [y][x-1];
+
+ //padding bottom border
+ for (y=org_size_y; y<img_size_y; y++)
+ for (x=0; x<img_size_x; x++)
+ imgY_org_frm [y][x] = imgY_org_frm [y-1][x];
+
+
+ if (img->yuv_format != YUV400)
+ {
+ //padding right border
+ for (y=0; y<org_size_y_cr; y++)
+ for (x=org_size_x_cr; x<img_size_x_cr; x++)
+ {
+ imgUV_org_frm [0][y][x] = imgUV_org_frm [0][y][x-1];
+ imgUV_org_frm [1][y][x] = imgUV_org_frm [1][y][x-1];
+ }
+
+ //padding bottom border
+ for (y=org_size_y_cr; y<img_size_y_cr; y++)
+ for (x=0; x<img_size_x_cr; x++)
+ {
+ imgUV_org_frm [0][y][x] = imgUV_org_frm [0][y-1][x];
+ imgUV_org_frm [1][y][x] = imgUV_org_frm [1][y-1][x];
+ }
+ }
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Calculates the absolute frame number in the source file out
+ * of various variables in img-> and input->
+ * \return
+ * frame number in the file to be read
+ * \par side effects
+ * global variable frame_no updated -- dunno, for what this one is necessary
+ ************************************************************************
+ */
+ static int CalculateFrameNumber()
+ {
+ if (img->b_frame_to_code)
+ {
+ if (input->PyramidCoding)
+ frame_no = start_tr_in_this_IGOP + (IMG_NUMBER - 1) * (input->jumpd + 1) + (int) (img->b_interval * (double) (1 + gop_structure[img->b_frame_to_code - 1].display_no));
+ else
+ frame_no = start_tr_in_this_IGOP + (IMG_NUMBER - 1) * (input->jumpd + 1) + (int) (img->b_interval * (double) img->b_frame_to_code);
+ }
+ else
+ {
+ frame_no = start_tr_in_this_IGOP + IMG_NUMBER * (input->jumpd + 1);
+ #ifdef _ADAPT_LAST_GROUP_
+ if (input->last_frame && img->number + 1 == input->no_frames)
+ frame_no = input->last_frame;
+ #endif
+ }
+
+ return frame_no;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Convert file read buffer to source picture structure
+ ************************************************************************
+ */
+ void buf2img ( imgpel** imgX, //!< Pointer to image plane
+ unsigned char* buf, //!< Buffer for file output
+ int size_x, //!< horizontal size of picture
+ int size_y, //!< vertical size of picture
+ int symbol_size_in_bytes //!< number of bytes in file used for one pixel
+ )
+ {
+ int i,j;
+
+ unsigned short tmp16, ui16;
+ unsigned long tmp32, ui32;
+
+ if (symbol_size_in_bytes> sizeof(imgpel))
+ {
+ error ("Source picture has higher bit depth than imgpel data type. Please recompile with larger data type for imgpel.", 500);
+ }
+
+ if (( sizeof(char) == sizeof (imgpel)) && ( sizeof(char) == symbol_size_in_bytes))
+ {
+ // imgpel == pixel_in_file == 1 byte -> simple copy
+ for(j=0;j<size_y;j++)
+ memcpy(imgX[j], buf+j*size_x, size_x);
+ }
+ else
+ {
+ // sizeof (imgpel) > sizeof(char)
+ if (testEndian())
+ {
+ // big endian
+ switch (symbol_size_in_bytes)
+ {
+ case 1:
+ {
+ for(j=0;j<size_y;j++)
+ for(i=0;i<size_x;i++)
+ {
+ imgX[j][i]= buf[i+j*size_x];
+ }
+ break;
+ }
+ case 2:
+ {
+ for(j=0;j<size_y;j++)
+ for(i=0;i<size_x;i++)
+ {
+ memcpy(&tmp16, buf+((i+j*size_x)*2), 2);
+ ui16 = (tmp16 >> 8) | ((tmp16&0xFF)<<8);
+ imgX[j][i] = (imgpel) ui16;
+ }
+ break;
+ }
+ case 4:
+ {
+ for(j=0;j<size_y;j++)
+ for(i=0;i<size_x;i++)
+ {
+ memcpy(&tmp32, buf+((i+j*size_x)*4), 4);
+ ui32 = ((tmp32&0xFF00)<<8) | ((tmp32&0xFF)<<24) | ((tmp32&0xFF0000)>>8) | ((tmp32&0xFF000000)>>24);
+ imgX[j][i] = (imgpel) ui32;
+ }
+ }
+ default:
+ {
+ error ("reading only from formats of 8, 16 or 32 bit allowed on big endian architecture", 500);
+ break;
+ }
+ }
+ }
+ else
+ {
+ // little endian
+ for (j=0; j < size_y; j++)
+ for (i=0; i < size_x; i++)
+ {
+ imgX[j][i]=0;
+ memcpy(&(imgX[j][i]), buf +((i+j*size_x)*symbol_size_in_bytes), symbol_size_in_bytes);
+ }
+ }
+ }
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Reads one new frame from file
+ *
+ * \param FrameNoInFile
+ * Frame number in the source file
+ * \param HeaderSize
+ * Number of bytes in the source file to be skipped
+ * \param xs
+ * horizontal size of frame in pixels
+ * \param ys
+ * vertical size of frame in pixels
+ * \param xs_cr
+ * horizontal chroma size of frame in pixels
+ * \param ys_cr
+ * vertical chroma size of frame in pixels
+ ************************************************************************
+ */
+ static void ReadOneFrame (int FrameNoInFile, int HeaderSize, int xs, int ys, int xs_cr, int ys_cr)
+ {
+ unsigned int symbol_size_in_bytes = img->pic_unit_size_on_disk/8;
+
+ const int imgsize_y = xs*ys;
+ const int imgsize_uv = xs_cr*ys_cr;
+
+ const int bytes_y = imgsize_y * symbol_size_in_bytes;
+ const int bytes_uv = imgsize_uv * symbol_size_in_bytes;
+
+ const int64 framesize_in_bytes = bytes_y + 2*bytes_uv;
+ unsigned char *buf;
+
+ Boolean rgb_input = (input->rgb_input_flag==1 && input->yuv_format==3);
+
+
+ assert (p_in != -1);
+
+ // KS: this buffer should actually be allocated only once, but this is still much faster than the previous version
+ if (NULL==(buf = malloc (xs*ys * symbol_size_in_bytes))) no_mem_exit("ReadOneFrame: buf");
+
+ // skip Header
+ if (lseek (p_in, HeaderSize, SEEK_SET) != HeaderSize)
+ {
+ error ("ReadOneFrame: cannot fseek to (Header size) in p_in", -1);
+ }
+
+ // skip starting frames
+ if (lseek (p_in, framesize_in_bytes * input->start_frame, SEEK_CUR) == -1)
+ {
+ snprintf(errortext, ET_SIZE, "ReadOneFrame: cannot advance file pointer in p_in beyond frame %d\n", input->start_frame);
+ error (errortext,-1);
+ }
+
+ // seek to current frame
+ if (lseek (p_in, framesize_in_bytes * FrameNoInFile, SEEK_CUR) == -1)
+ {
+ snprintf(errortext, ET_SIZE, "ReadOneFrame: cannot advance file pointer in p_in beyond frame %d\n", input->start_frame + FrameNoInFile);
+ error (errortext,-1);
+ }
+
+ // Here we are at the correct position for the source frame in the file. Now
+ // read it.
+ if (img->pic_unit_size_on_disk%8 == 0)
+ {
+ if(rgb_input)
+ lseek (p_in, framesize_in_bytes/3, SEEK_CUR);
+
+ if (read(p_in, buf, bytes_y) != bytes_y)
+ {
+ printf ("ReadOneFrame: cannot read %d bytes from input file, unexpected EOF?, exiting", bytes_y);
+ report_stats_on_error();
+ exit (-1);
+ }
+
+ buf2img(imgY_org_frm, buf, xs, ys, symbol_size_in_bytes);
+
+ if (img->yuv_format != YUV400)
+ {
+ if (read(p_in, buf, bytes_uv) != bytes_uv)
+ {
+ printf ("ReadOneFrame: cannot read %d bytes from input file, unexpected EOF?, exiting", bytes_y);
+ report_stats_on_error();
+ exit (-1);
+ }
+ buf2img(imgUV_org_frm[0], buf, xs_cr, ys_cr, symbol_size_in_bytes);
+
+ if(rgb_input)
+ lseek (p_in, -framesize_in_bytes, SEEK_CUR);
+
+ if (read(p_in, buf, bytes_uv) != bytes_uv)
+ {
+ printf ("ReadOneFrame: cannot read %d bytes from input file, unexpected EOF?, exiting", bytes_y);
+ report_stats_on_error();
+ exit (-1);
+ }
+ buf2img(imgUV_org_frm[1], buf, xs_cr, ys_cr, symbol_size_in_bytes);
+
+ if(rgb_input)
+ lseek (p_in, framesize_in_bytes*2/3, SEEK_CUR);
+ }
+ }
+ else
+ {
+ printf ("ReadOneFrame (NOT IMPLEMENTED): pic unit size on disk must be divided by 8");
+ exit (-1);
+ }
+ free (buf);
+
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * point to frame coding variables
+ ************************************************************************
+ */
+ static void put_buffer_frame()
+ {
+ imgY_org = imgY_org_frm;
+ imgUV_org = imgUV_org_frm;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * point to top field coding variables
+ ************************************************************************
+ */
+ static void put_buffer_top()
+ {
+ img->fld_type = 0;
+
+ imgY_org = imgY_org_top;
+ imgUV_org = imgUV_org_top;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * point to bottom field coding variables
+ ************************************************************************
+ */
+ static void put_buffer_bot()
+ {
+ img->fld_type = 1;
+
+ imgY_org = imgY_org_bot;
+ imgUV_org = imgUV_org_bot;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Writes a NAL unit of a partition or slice
+ ************************************************************************
+ */
+
+ static void writeUnit(Bitstream* currStream,int partition)
+ {
+ const int buffer_size = 500 + img->FrameSizeInMbs * (128 + 256 * img->bitdepth_luma + 512 * img->bitdepth_chroma);
+ // KS: this is approx. max. allowed code picture size
+ NALU_t *nalu;
+ assert (currStream->bits_to_go == 8);
+ nalu = AllocNALU(buffer_size);
+ nalu->startcodeprefix_len = 2+(img->current_mb_nr == 0?ZEROBYTES_SHORTSTARTCODE+1:ZEROBYTES_SHORTSTARTCODE);
+ //printf ("nalu->startcodeprefix_len %d\n", nalu->startcodeprefix_len);
+ nalu->len = currStream->byte_pos +1; // add one for the first byte of the NALU
+ //printf ("nalu->len %d\n", nalu->len);
+ memcpy (&nalu->buf[1], currStream->streamBuffer, nalu->len-1);
+ if (img->currentPicture->idr_flag)
+ {
+ nalu->nal_unit_type = NALU_TYPE_IDR;
+ nalu->nal_reference_idc = NALU_PRIORITY_HIGHEST;
+ }
+ else if (img->type == B_SLICE)
+ {
+ //different nal header for different partitions
+ if(input->partition_mode == 0)
+ {
+ nalu->nal_unit_type = NALU_TYPE_SLICE;
+ }
+ else
+ {
+ nalu->nal_unit_type = NALU_TYPE_DPA + partition;
+ }
+
+ if (img->nal_reference_idc !=0)
+ {
+ nalu->nal_reference_idc = NALU_PRIORITY_HIGH;
+ }
+ else
+ {
+ nalu->nal_reference_idc = NALU_PRIORITY_DISPOSABLE;
+ }
+ }
+ else // non-b frame, non IDR slice
+ {
+ //different nal header for different partitions
+ if(input->partition_mode == 0)
+ {
+ nalu->nal_unit_type = NALU_TYPE_SLICE;
+ }
+ else
+ {
+ nalu->nal_unit_type = NALU_TYPE_DPA + partition;
+ }
+ if (img->nal_reference_idc !=0)
+ {
+ nalu->nal_reference_idc = NALU_PRIORITY_HIGH;
+ }
+ else
+ {
+ nalu->nal_reference_idc = NALU_PRIORITY_DISPOSABLE;
+ }
+ }
+ nalu->forbidden_bit = 0;
+ stats->bit_ctr += WriteNALU (nalu);
+
+ FreeNALU(nalu);
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * performs multi-pass encoding of same picture using different
+ * coding conditions
+ ************************************************************************
+ */
+
+ static void rdPictureCoding()
+ {
+ int second_qp = img->qp, rd_qp = img->qp;
+ int previntras = intras;
+ int prevtype = img->type;
+ int skip_encode = 0;
+ pic_parameter_set_rbsp_t *sec_pps;
+
+
+ if (img->type!=I_SLICE && input->GenerateMultiplePPS)
+ {
+ if (img->type==P_SLICE)
+ {
+ if (test_wp_P_slice(0) == 1)
+ {
+ active_pps = PicParSet[1];
+ }
+ else
+ {
+ skip_encode = input->RDPSliceWeightOnly;
+ active_pps = PicParSet[0];
+ if (!img->AdaptiveRounding)
+ img->qp-=1;
+ }
+ }
+ else
+ {
+ active_pps = PicParSet[2];
+ }
+ }
+ else
+ {
+ if (!img->AdaptiveRounding)
+ img->qp-=1;
+ }
+
+ sec_pps = active_pps;
+ second_qp = img->qp;
+
+ img->write_macroblock = 0;
+
+ if (skip_encode)
+ {
+ img->rd_pass = 0;
+ enc_frame_picture2 = NULL;
+ }
+ else
+ {
+ frame_picture (frame_pic_2,1);
+ img->rd_pass=picture_coding_decision(frame_pic_1, frame_pic_2, rd_qp);
+ }
+ // update_rd_picture_contexts (img->rd_pass);
+ if (img->rd_pass==0)
+ {
+ enc_picture=enc_frame_picture;
+ if (img->type!=I_SLICE && input->GenerateMultiplePPS)
+ {
+ img->qp=rd_qp;
+ active_pps = PicParSet[0];
+ }
+ else
+ {
+ img->qp=rd_qp;
+ }
+ intras = previntras;
+ frame_pic = frame_pic_1;
+ }
+ else
+ {
+ previntras = intras;
+ frame_pic = frame_pic_2;
+ }
+ // Final Encoding pass - note that we should
+ // make this more flexible in a later version.
+
+ if (img->type!=I_SLICE && input->GenerateMultiplePPS)
+ {
+ skip_encode = 0;
+ img->qp = rd_qp;
+
+ if (img->type == P_SLICE && input->GenerateMultiplePPS && (intras * 100 )/img->FrameSizeInMbs >=75)
+ {
+ img->type=I_SLICE;
+ active_pps = PicParSet[0];
+ }
+ else if (img->type==P_SLICE)
+ {
+ if (test_wp_P_slice(1) == 1)
+ {
+ active_pps = PicParSet[1];
+ }
+ else if (input->RDPSliceBTest && active_sps->profile_idc != 66)
+ {
+ img->type = B_SLICE;
+ active_pps = PicParSet[0];
+ }
+ else
+ {
+ skip_encode = input->RDPSliceWeightOnly;
+ active_pps = PicParSet[0];
+ if (!img->AdaptiveRounding)
+ img->qp+=1;
+ }
+ }
+ else
+ {
+ if (test_wp_B_slice(0) == 1)
+ {
+ active_pps = PicParSet[1];
+ }
+ else
+ {
+ skip_encode = input->RDBSliceWeightOnly;
+ img->qp = rd_qp + (img->nal_reference_idc ? - 1 : 1);
+ }
+ }
+ }
+ else
+ {
+ active_pps = PicParSet[0];
+ if (!img->AdaptiveRounding)
+ img->qp = (rd_qp + 1);
+ }
+
+
+ img->write_macroblock = 0;
+
+ if (skip_encode)
+ {
+ enc_frame_picture3 = NULL;
+ img->qp = rd_qp;
+ }
+ else
+ {
+ frame_picture (frame_pic_3,2);
+
+ if (img->rd_pass==0)
+ img->rd_pass = 2*picture_coding_decision(frame_pic_1, frame_pic_3, rd_qp);
+ else
+ img->rd_pass += picture_coding_decision(frame_pic_2, frame_pic_3, rd_qp);
+ }
+
+ //update_rd_picture_contexts (img->rd_pass);
+ if (img->rd_pass==0)
+ {
+ enc_picture = enc_frame_picture;
+ img->type = prevtype;
+ active_pps = PicParSet[0];
+ img->qp = rd_qp;
+ intras = previntras;
+ }
+ else if (img->rd_pass==1)
+ {
+ enc_picture = enc_frame_picture2;
+ img->type = prevtype;
+ active_pps = sec_pps;
+ img->qp = second_qp;
+ intras = previntras;
+ }
+ }
+
Index: llvm-test/MultiSource/Applications/JM/lencod/image.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/image.h:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/image.h Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,34 ----
+
+ /*!
+ ************************************************************************
+ * \file image.h
+ *
+ * \brief
+ * headers for image processing
+ *
+ * \author
+ * Inge Lille-Langoy <inge.lille-langoy at telenor.com>
+ * Copyright (C) 1999 Telenor Satellite Services, Norway
+ ************************************************************************
+ */
+ #ifndef _IMAGE_H_
+ #define _IMAGE_H_
+
+ #include "mbuffer.h"
+
+ extern StorablePicture *enc_picture;
+ extern StorablePicture *enc_frame_picture;
+ extern StorablePicture *enc_frame_picture2;
+ extern StorablePicture *enc_frame_picture3;
+ extern StorablePicture *enc_top_picture;
+ extern StorablePicture *enc_bottom_picture;
+
+ int encode_one_frame ();
+ void report_frame_statistic();
+ Boolean dummy_slice_too_big(int bits_slice);
+ void copy_rdopt_data (int field_type); // For MB level field/frame coding tools
+
+ void UnifiedOneForthPix (StorablePicture *s);
+
+ #endif
+
Index: llvm-test/MultiSource/Applications/JM/lencod/intrarefresh.c
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/intrarefresh.c:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/intrarefresh.c Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,136 ----
+
+ /*!
+ *****************************************************************************
+ *
+ * \file intrarefresh.c
+ *
+ * \brief
+ * Encoder support for pseudo-random intra macroblock refresh
+ *
+ * \date
+ * 16 June 2002
+ *
+ * \author
+ * Stephan Wenger stewe at cs.tu-berlin.de
+ *****************************************************************************/
+
+ #include <stdlib.h>
+ #include <assert.h>
+
+ #include "global.h"
+
+ static int *RefreshPattern;
+ static int *IntraMBs;
+ static int WalkAround = 0;
+ static int NumberOfMBs = 0;
+ static int NumberIntraPerPicture;
+
+ /*!
+ ************************************************************************
+ * \brief
+ * RandomIntraInit: Initializes Random Intra module. Should be called
+ * only after initialization (or changes) of the picture size or the
+ * random intra refresh value. In version jm2.1 it is impossible to
+ * change those values on-the-fly, hence RandomIntraInit should be
+ * called immediately after the parsing of the config file
+ *
+ * \par Input:
+ * xsize, ysize: size of the picture (in MBs)
+ * refresh : refresh rate in MBs per picture
+ ************************************************************************
+ */
+
+ void RandomIntraInit(int xsize, int ysize, int refresh)
+ {
+ int i, pos;
+
+ srand (1); // A fixed random initializer to make things reproducible
+ NumberOfMBs = xsize * ysize;
+ NumberIntraPerPicture = refresh;
+
+ if (refresh != 0)
+ {
+ RefreshPattern = malloc (sizeof (int) * NumberOfMBs);
+ if (RefreshPattern == NULL) no_mem_exit("RandomIntraInit: RefreshPattern");
+
+ IntraMBs = malloc (sizeof (int) * refresh);
+ if (IntraMBs == NULL) no_mem_exit("RandomIntraInit: IntraMBs");
+
+ for (i= 0; i<NumberOfMBs; i++)
+ RefreshPattern[i] = -1;
+
+ for (i=0; i<NumberOfMBs; i++)
+ {
+ do
+ {
+ pos = rand() % NumberOfMBs;
+ } while (RefreshPattern [pos] != -1);
+ RefreshPattern [pos] = i;
+ }
+ /*
+ for (i=0; i<NumberOfMBs; i++) printf ("%d\t", RefreshPattern[i]);
+ getchar();
+ */
+ }
+ else
+ {
+ RefreshPattern = NULL;
+ IntraMBs = NULL;
+ }
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * RandomIntra: Code an MB as Intra?
+ *
+ * \par Input
+ * MacroblockNumberInScanOrder
+ * \par Output
+ * 1 if an MB should be forced to Intra, according the the
+ * RefreshPattern
+ * 0 otherwise
+ *
+ ************************************************************************
+ */
+
+ int RandomIntra (int mb)
+ {
+ int i;
+
+ for (i=0; i<NumberIntraPerPicture; i++)
+ if (IntraMBs[i] == mb)
+ return 1;
+ return 0;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * RandomIntraNewPicture: Selects new set of MBs for forced Intra
+ *
+ * \par
+ * This function should be called exactly once per picture, and
+ * requires a finished initialization
+ *
+ ************************************************************************
+ */
+
+ void RandomIntraNewPicture ()
+ {
+ int i, j;
+
+ WalkAround += NumberIntraPerPicture;
+ for (j=0,i=WalkAround; j<NumberIntraPerPicture; j++, i++)
+ IntraMBs[j] = RefreshPattern [i%NumberOfMBs];
+ }
+
+ void RandomIntraUninit()
+ {
+ if (NumberIntraPerPicture >0 )
+ {
+ free(RefreshPattern);
+ free(IntraMBs);
+ }
+ }
Index: llvm-test/MultiSource/Applications/JM/lencod/intrarefresh.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/intrarefresh.h:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/intrarefresh.h Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,26 ----
+
+ /*!
+ ***************************************************************************
+ *
+ * \file intrarefresh.h
+ *
+ * \brief
+ * Pseudo-Raqndom Intra macroblock refresh support
+ *
+ * \date
+ * 16 June 2002
+ *
+ * \author
+ * Stephan Wenger stewe at cs.tu-berlin.de
+ **************************************************************************/
+
+ #ifndef _INTRAREFRESH_H_
+ #define _INTRAREFRESH_H_
+
+ void RandomIntraInit(int xsize, int ysize, int refresh);
+ void RandomIntraUninit();
+ int RandomIntra (int mb); //! returns 1 for MBs that need forced Intra
+ void RandomIntraNewPicture (); //! to be called once per picture
+
+
+ #endif //_INTRAREFRESH_H_
Index: llvm-test/MultiSource/Applications/JM/lencod/leaky_bucket.c
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/leaky_bucket.c:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/leaky_bucket.c Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,296 ----
+
+ /*!
+ ***************************************************************************
+ * \file leaky_bucket.c
+ *
+ * \brief
+ * calculate Leaky Buffer parameters
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Shankar Regunathan <shanre at microsoft.com>
+ ***************************************************************************
+ */
+ #include <stdlib.h>
+
+ #include "contributors.h"
+ #include "global.h"
+
+ #ifdef _LEAKYBUCKET_
+
+ long Bit_Buffer[10000];
+ unsigned long total_frame_buffer = 0;
+
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * Function to get Leaky Bucket rates from rate file
+ * \param NumberLeakyBuckets
+ * Number of Leaky Bucket Parameters
+ * \param Rmin
+ * Rate values for each Bucket.
+ * \return
+ * returns 1 if successful; else returns zero.
+ * \para SideEffects
+ * None.
+ * \para Notes
+ * Failure if LeakyBucketRate is missing or if it does not have
+ * the correct number of entries.
+ * \author
+ * Shankar Regunathan shanre at microsoft.com
+ * \date
+ * December 06, 2001.
+ ***********************************************************************
+ */
+
+ int get_LeakyBucketRate(unsigned long NumberLeakyBuckets, unsigned long *Rmin)
+ {
+ FILE *f;
+ unsigned long i, buf;
+
+ if((f = fopen(input->LeakyBucketRateFile, "r")) == NULL)
+ {
+ printf(" LeakyBucketRate File does not exist. Using rate calculated from avg. rate \n");
+ return 0;
+ }
+
+ for(i=0; i<NumberLeakyBuckets; i++)
+ {
+ if(1 != fscanf(f, "%ld", &buf))
+ {
+ printf(" Leaky BucketRateFile does not have valid entries.\n Using rate calculated from avg. rate \n");
+ fclose (f);
+ return 0;
+ }
+ Rmin[i] = buf;
+ }
+ fclose (f);
+ return 1;
+ }
+ /*!
+ ***********************************************************************
+ * \brief
+ * Writes one unsigned long word in big endian order to a file.
+ * \param dw
+ * Value to be written
+ * \param fp
+ * File pointer
+ * \return
+ * None.
+ * \para SideEffects
+ * None.
+ * \author
+ * Shankar Regunathan shanre at microsoft.com
+ * \date
+ * December 06, 2001.
+ ***********************************************************************
+ */
+
+ void PutBigDoubleWord(unsigned long dw, FILE *fp)
+ {
+ fputc((dw >> 0x18) & 0xFF, fp);
+ fputc((dw >> 0x10) & 0xFF, fp);
+ fputc((dw >> 0x08) & 0xFF, fp);
+ fputc(dw & 0xFF, fp);
+ }
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * Stores the Leaky BucketParameters in file input->LeakyBucketParamFile.
+ * \param NumberLeakyBuckets
+ * Number of LeakyBuckets.
+ * \param Rmin
+ * Rate values of the buckets.
+ * \param Bmin
+ * Minimum buffer values of the buckets.
+ * \param Fmin
+ * Minimum initial buffer fullness of the buckets
+ * \return
+ * None.
+ * \para
+ * Returns error if LeakyBucketParamFile cannot be opened.
+ * \para SideEffects
+ * Prints the LeakyBucket Parameters in standard output.
+ * \author
+ * Shankar Regunathan shanre at microsoft.com
+ * \date
+ * December 06, 2001.
+ ***********************************************************************
+ */
+
+
+ void write_buffer(unsigned long NumberLeakyBuckets, unsigned long Rmin[], unsigned long Bmin[], unsigned long Fmin[])
+ {
+ FILE *outf;
+ unsigned long iBucket;
+
+ if ((outf=fopen(input->LeakyBucketParamFile,"wb"))==NULL)
+ {
+ snprintf(errortext, ET_SIZE, "Error open file lk %s \n",input->LeakyBucketParamFile);
+ error(errortext,1);
+ }
+
+ PutBigDoubleWord(NumberLeakyBuckets, outf);
+ if (input->Verbose != 0)
+ printf(" Number Leaky Buckets: %ld \n Rmin Bmin Fmin \n", NumberLeakyBuckets);
+ for(iBucket =0; iBucket < NumberLeakyBuckets; iBucket++)
+ {
+ //assert(Rmin[iBucket]<4294967296); //Overflow should be corrected already.
+ //assert(Bmin[iBucket]<4294967296);
+ //assert(Fmin[iBucket]<4294967296);
+ PutBigDoubleWord(Rmin[iBucket], outf);
+ PutBigDoubleWord(Bmin[iBucket], outf);
+ PutBigDoubleWord(Fmin[iBucket], outf);
+ if (input->Verbose != 0)
+ printf(" %8ld %8ld %8ld \n", Rmin[iBucket], Bmin[iBucket], Fmin[iBucket]);
+ }
+ fclose(outf);
+ }
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * Sorts the rate array in ascending order.
+ * \param NumberLeakyBuckets
+ * Number of LeakyBuckets.
+ * \param Rmin
+ * Rate values of the buckets.
+ * \return
+ * None.
+ * \author
+ * Shankar Regunathan shanre at microsoft.com
+ * \date
+ * December 06, 2001.
+ ***********************************************************************
+ */
+
+
+ void Sort(unsigned long NumberLeakyBuckets, unsigned long *Rmin)
+ {
+ unsigned long i, j;
+ unsigned long temp;
+ for(i=0; i< NumberLeakyBuckets-1; i++)
+ {
+ for(j=i+1; j<NumberLeakyBuckets; j++)
+ {
+ if(Rmin[i] > Rmin[j]) {
+ temp = Rmin[i];
+ Rmin[i] = Rmin[j];
+ Rmin[j] = temp;
+ }
+ }
+ }
+ }
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * Main Routine to calculate Leaky Buffer parameters
+ * \param NumberLeakyBuckets
+ * None.
+ * \return
+ * None.
+ * \author
+ * Shankar Regunathan shanre at microsoft.com
+ * \date
+ * December 06, 2001.
+ ***********************************************************************
+ */
+
+ void calc_buffer()
+ {
+ unsigned long AvgRate, TotalRate, NumberLeakyBuckets;
+ long *buffer_frame, minB;
+ unsigned long iBucket, iFrame, FrameIndex = 0;
+ long maxBuffer, actualBuffer, InitFullness, iChannelRate;
+ unsigned long *Rmin, *Bmin, *Fmin;
+
+ fprintf(stdout,"-------------------------------------------------------------------------------\n");
+ printf(" Total Frames: %ld (%d) \n", total_frame_buffer, input->no_frames);
+ NumberLeakyBuckets = (unsigned long) input->NumberLeakyBuckets;
+ buffer_frame = calloc(total_frame_buffer+1, sizeof(long));
+ if(!buffer_frame)
+ no_mem_exit("init_buffer: buffer_frame");
+ Rmin = calloc(NumberLeakyBuckets, sizeof(unsigned long));
+ if(!Rmin)
+ no_mem_exit("init_buffer: Rmin");
+ Bmin = calloc(NumberLeakyBuckets, sizeof(unsigned long));
+ if(!Bmin)
+ no_mem_exit("init_buffer: Bmin");
+ Fmin = calloc(NumberLeakyBuckets, sizeof(unsigned long));
+ if(!Fmin)
+ no_mem_exit("init_buffer: Fmin");
+
+ TotalRate = 0;
+ for(iFrame=0; iFrame < total_frame_buffer; iFrame++)
+ {
+ TotalRate += (unsigned long) Bit_Buffer[iFrame];
+ }
+ AvgRate = (unsigned long) ((float) TotalRate/ total_frame_buffer);
+
+ if(1 != get_LeakyBucketRate(NumberLeakyBuckets, Rmin))
+ { /* if rate file is not present, use default calculated from avg.rate */
+ for(iBucket=0; iBucket < NumberLeakyBuckets; iBucket++)
+ {
+ if(iBucket == 0)
+ Rmin[iBucket] = (unsigned long)((float) AvgRate * img->framerate)/(input->jumpd+1); /* convert bits/frame to bits/second */
+ else
+ Rmin[iBucket] = (unsigned long) ((float) Rmin[iBucket-1] + (AvgRate/4) * (img->framerate) / (input->jumpd+1));
+ }
+ }
+ Sort(NumberLeakyBuckets, Rmin);
+
+ maxBuffer = AvgRate * 20; /* any initialization is good. */
+ for(iBucket=0; iBucket< NumberLeakyBuckets; iBucket++)
+ {
+ iChannelRate = (long) (Rmin[iBucket] * (input->jumpd+1)/(img->framerate)); /* converts bits/second to bits/frame */
+ /* To calculate initial buffer size */
+ InitFullness = maxBuffer; /* set Initial Fullness to be buffer size */
+ buffer_frame[0] = InitFullness;
+ minB = maxBuffer;
+
+ for(iFrame=0; iFrame<total_frame_buffer ; iFrame++)
+ {
+ buffer_frame[iFrame] = buffer_frame[iFrame] - Bit_Buffer[iFrame];
+ if(buffer_frame[iFrame] < minB)
+ {
+ minB = buffer_frame[iFrame];
+ FrameIndex = iFrame;
+ }
+
+ buffer_frame[iFrame+1] = buffer_frame[iFrame] + iChannelRate;
+ if(buffer_frame[iFrame+1] > maxBuffer)
+ buffer_frame[iFrame+1] = maxBuffer;
+ }
+ actualBuffer = (maxBuffer - minB);
+
+ /* To calculate initial buffer Fullness */
+ InitFullness = Bit_Buffer[0];
+ buffer_frame[0] = InitFullness;
+ for(iFrame=0; iFrame < FrameIndex+1; iFrame++)
+ {
+ buffer_frame[iFrame] = buffer_frame[iFrame] - Bit_Buffer[iFrame];
+ if(buffer_frame[iFrame] < 0) {
+ InitFullness -= buffer_frame[iFrame];
+ buffer_frame[iFrame] = 0;
+ }
+ buffer_frame[iFrame+1] = buffer_frame[iFrame] + iChannelRate;
+ if(buffer_frame[iFrame+1] > actualBuffer)
+ break;
+ }
+ Bmin[iBucket] = (unsigned long) actualBuffer;
+ Fmin[iBucket] = (unsigned long) InitFullness;
+ }
+
+ write_buffer(NumberLeakyBuckets, Rmin, Bmin, Fmin);
+
+ free(buffer_frame);
+ free(Rmin);
+ free(Bmin);
+ free(Fmin);
+ return;
+ }
+ #endif
+
Index: llvm-test/MultiSource/Applications/JM/lencod/leaky_bucket.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/leaky_bucket.h:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/leaky_bucket.h Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,29 ----
+
+ /*!
+ ***************************************************************************
+ *
+ * \file leaky_bucket.h
+ *
+ * \brief
+ * Header for Leaky Buffer parameters
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Shankar Regunathan <shanre at microsoft.com>
+ **************************************************************************/
+
+ #ifndef _LEAKY_BUCKET_H_
+ #define _LEAKY_BUCKET_H_
+
+
+ /* Leaky Bucket Parameter Optimization */
+ #ifdef _LEAKYBUCKET_
+ int get_LeakyBucketRate(unsigned long NumberLeakyBuckets, unsigned long *Rmin);
+ void PutBigDoubleWord(unsigned long dw, FILE *fp);
+ void write_buffer(unsigned long NumberLeakyBuckets, unsigned long Rmin[], unsigned long Bmin[], unsigned long Fmin[]);
+ void Sort(unsigned long NumberLeakyBuckets, unsigned long *Rmin);
+ void calc_buffer();
+ #endif
+
+ #endif
+
Index: llvm-test/MultiSource/Applications/JM/lencod/lencod.c
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/lencod.c:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/lencod.c Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,2421 ----
+
+ /*!
+ ***********************************************************************
+ * \mainpage
+ * This is the H.264/AVC encoder reference software. For detailed documentation
+ * see the comments in each file.
+ *
+ * \author
+ * The main contributors are listed in contributors.h
+ *
+ * \version
+ * JM 10.1 (FRExt)
+ *
+ * \note
+ * tags are used for document system "doxygen"
+ * available at http://www.doxygen.org
+ */
+ /*!
+ * \file
+ * lencod.c
+ * \brief
+ * H.264/AVC reference encoder project main()
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Inge Lille-Langoy <inge.lille-langoy at telenor.com>
+ * - Rickard Sjoberg <rickard.sjoberg at era.ericsson.se>
+ * - Stephan Wenger <stewe at cs.tu-berlin.de>
+ * - Jani Lainema <jani.lainema at nokia.com>
+ * - Byeong-Moon Jeon <jeonbm at lge.com>
+ * - Yoon-Seong Soh <yunsung at lge.com>
+ * - Thomas Stockhammer <stockhammer at ei.tum.de>
+ * - Detlev Marpe <marpe at hhi.de>
+ * - Guido Heising <heising at hhi.de>
+ * - Valeri George <george at hhi.de>
+ * - Karsten Suehring <suehring at hhi.de>
+ * - Alexis Michael Tourapis <alexismt at ieee.org>
+ ***********************************************************************
+ */
+
+ #include "contributors.h"
+
+ #include <stdlib.h>
+ #include <string.h>
+ #include <time.h>
+ #include <math.h>
+ #include <sys/timeb.h>
+
+ #ifdef WIN32
+ #include <io.h>
+ #else
+ #include <unistd.h>
+ #endif
+
+ #include "global.h"
+
+ #include "configfile.h"
+ #include "leaky_bucket.h"
+ #include "memalloc.h"
+ #include "intrarefresh.h"
+ #include "fmo.h"
+ #include "sei.h"
+ #include "parset.h"
+ #include "image.h"
+ #include "output.h"
+ #include "fast_me.h"
+ #include "simplified_fast_me.h"
+ #include "ratectl.h"
+ #include "explicit_gop.h"
+ #include "epzs.h"
+
+ #define JM "10 (FRExt)"
+ #define VERSION "10.1"
+ #define EXT_VERSION "(FRExt)"
+
+ InputParameters inputs, *input = &inputs;
+ ImageParameters images, *img = &images;
+ StatParameters statistics, *stats = &statistics;
+ SNRParameters snrs, *snr = &snrs;
+ Decoders decoders, *decs=&decoders;
+
+
+ #ifdef _ADAPT_LAST_GROUP_
+ int initial_Bframes = 0;
+ #endif
+
+ Boolean In2ndIGOP = FALSE;
+ int start_frame_no_in_this_IGOP = 0;
+ int start_tr_in_this_IGOP = 0;
+ int FirstFrameIn2ndIGOP=0;
+ int cabac_encoding = 0;
+ int frame_statistic_start;
+ extern ColocatedParams *Co_located;
+
+ void Init_Motion_Search_Module ();
+ void Clear_Motion_Search_Module ();
+ void report_frame_statistic();
+ void SetLevelIndices();
+
+ void init_stats()
+ {
+ stats->successive_Bframe = input->successive_Bframe;
+ stats->bit_ctr_I = 0;
+ stats->bit_ctr_P = 0;
+ stats->bit_ctr_B = 0;
+ snr->snr_y = 0.0;
+ snr->snr_u = 0.0;
+ snr->snr_v = 0.0;
+ snr->snr_y1 = 0.0;
+ snr->snr_u1 = 0.0;
+ snr->snr_v1 = 0.0;
+ snr->snr_ya = 0.0;
+ snr->snr_ua = 0.0;
+ snr->snr_va = 0.0;
+ snr->sse_y = 0.0;
+ snr->sse_u = 0.0;
+ snr->sse_v = 0.0;
+ snr->msse_y = 0.0;
+ snr->msse_u = 0.0;
+ snr->msse_v = 0.0;
+ snr->frame_ctr = 0;
+ }
+ /*!
+ ***********************************************************************
+ * \brief
+ * Main function for encoder.
+ * \param argc
+ * number of command line arguments
+ * \param argv
+ * command line arguments
+ * \return
+ * exit code
+ ***********************************************************************
+ */
+ int main(int argc,char **argv)
+ {
+ int M,N,n,np,nb; //Rate control
+ int primary_disp = 0;
+
+ p_dec = p_in = -1;
+
+ p_stat = p_log = p_trace = NULL;
+
+ frame_statistic_start = 1;
+
+ Configure (argc, argv);
+
+ Init_QMatrix();
+
+ Init_QOffsetMatrix();
+
+ AllocNalPayloadBuffer();
+
+ init_poc();
+ GenerateParameterSets();
+ SetLevelIndices();
+
+ init_img();
+ frame_pic_1= malloc_picture();
+
+ if (input->RDPictureDecision)
+ {
+ frame_pic_2 = malloc_picture();
+ frame_pic_3 = malloc_picture();
+ }
+
+ if (input->PicInterlace != FRAME_CODING)
+ {
+ top_pic = malloc_picture();
+ bottom_pic = malloc_picture();
+ }
+ init_rdopt ();
+
+ if (input->PyramidCoding )
+ {
+ init_gop_structure();
+ if (input->PyramidCoding == 3)
+ {
+ interpret_gop_structure();
+ }
+ else
+ {
+ create_pyramid();
+ }
+ }
+
+ dpb.init_done = 0;
+ init_dpb(input);
+ init_out_buffer();
+ init_stats();
+
+
+ enc_picture = enc_frame_picture = enc_top_picture = enc_bottom_picture = NULL;
+
+ init_global_buffers();
+
+ create_context_memory ();
+
+ Init_Motion_Search_Module ();
+
+ information_init();
+
+ //Rate control
+ if(input->RCEnable)
+ rc_init_seq();
+
+ if(input->FMEnable == 1)
+ DefineThreshold();
+
+ // Init frame type counter. Only supports single slice per frame.
+ memset(frame_ctr, 0, 5 * sizeof(int));
+
+ img->last_valid_reference = 0;
+ tot_time=0; // time for total encoding session
+
+ #ifdef _ADAPT_LAST_GROUP_
+ if (input->last_frame > 0)
+ input->no_frames = 1 + (input->last_frame + input->jumpd) / (input->jumpd + 1);
+ initial_Bframes = input->successive_Bframe;
+ #endif
+
+ PatchInputNoFrames();
+
+ // Write sequence header (with parameter sets)
+ stats->bit_ctr_parametersets = 0;
+ stats->bit_slice = start_sequence();
+ stats->bit_ctr_parametersets += stats->bit_ctr_parametersets_n;
+ start_frame_no_in_this_IGOP = 0;
+
+ for (img->number=0; img->number < input->no_frames; img->number++)
+ {
+ //img->nal_reference_idc = 1;
+ if (input->intra_period)
+ img->nal_reference_idc = ((IMG_NUMBER % input->intra_period) && input->DisposableP) ? (img->number + 1)% 2 : 1;
+ else
+ img->nal_reference_idc = (img->number && input->DisposableP) ? (img->number + 1)% 2 : 1;
+
+ //much of this can go in init_frame() or init_field()?
+ //poc for this frame or field
+ img->toppoc = (input->intra_period && input->idr_enable ? IMG_NUMBER % input->intra_period : IMG_NUMBER) * (2*(input->jumpd+1));
+
+ if ((input->PicInterlace==FRAME_CODING)&&(input->MbInterlace==FRAME_CODING))
+ img->bottompoc = img->toppoc; //progressive
+ else
+ img->bottompoc = img->toppoc+1; //hard coded
+
+ img->framepoc = min (img->toppoc, img->bottompoc);
+
+ //frame_num for this frame
+ //if (input->BRefPictures== 0 || input->successive_Bframe == 0 || img-> number < 2)
+ if ((input->BRefPictures != 1 && input->PyramidCoding == 0) || input->successive_Bframe == 0 || img-> number < 2)// || input->PyramidCoding == 0)
+ {
+ if (input->intra_period && input->idr_enable)
+ {
+ img->frame_num = ((IMG_NUMBER - primary_disp) % input->intra_period ) % (1 << (log2_max_frame_num_minus4 + 4));
+ if (IMG_NUMBER % input->intra_period == 0)
+ {
+ img->frame_num = 0;
+ primary_disp = 0;
+ }
+ }
+ else
+ img->frame_num = (IMG_NUMBER - primary_disp) % (1 << (log2_max_frame_num_minus4 + 4));
+
+ }
+ else
+ {
+ //img->frame_num ++;
+ if (input->intra_period && input->idr_enable)
+ {
+ if (0== (img->number % input->intra_period))
+ {
+ img->frame_num=0;
+ primary_disp = 0;
+ }
+ }
+ img->frame_num %= (1 << (log2_max_frame_num_minus4 + 4));
+ }
+
+ //the following is sent in the slice header
+ img->delta_pic_order_cnt[0]=0;
+
+ if (input->BRefPictures == 1)
+ {
+ if (img->number)
+ {
+ img->delta_pic_order_cnt[0]=+2 * input->successive_Bframe;
+ }
+ }
+
+ SetImgType();
+
+ #ifdef _ADAPT_LAST_GROUP_
+ if (input->successive_Bframe && input->last_frame && IMG_NUMBER+1 == input->no_frames)
+ {
+ int bi = (int)((float)(input->jumpd+1)/(input->successive_Bframe+1.0)+0.499999);
+
+ input->successive_Bframe = (input->last_frame-(img->number-1)*(input->jumpd+1))/bi-1;
+
+ //about to code the last ref frame, adjust delta poc
+ img->delta_pic_order_cnt[0]= -2*(initial_Bframes - input->successive_Bframe);
+ img->toppoc += img->delta_pic_order_cnt[0];
+ img->bottompoc += img->delta_pic_order_cnt[0];
+ img->framepoc = min (img->toppoc, img->bottompoc);
+ }
+ #endif
+
+ //Rate control
+ if (img->type == I_SLICE)
+ {
+ if(input->RCEnable)
+ {
+ if (input->intra_period == 0)
+ {
+ n = input->no_frames + (input->no_frames - 1) * input->successive_Bframe;
+
+ /* number of P frames */
+ np = input->no_frames-1;
+
+ /* number of B frames */
+ nb = (input->no_frames - 1) * input->successive_Bframe;
+ }else
+ {
+ N = input->intra_period*(input->successive_Bframe+1);
+ M = input->successive_Bframe+1;
+ n = (img->number==0) ? N - ( M - 1) : N;
+
+ /* last GOP may contain less frames */
+ if(img->number/input->intra_period >= input->no_frames / input->intra_period)
+ {
+ if (img->number != 0)
+ n = (input->no_frames - img->number) + (input->no_frames - img->number - 1) * input->successive_Bframe + input->successive_Bframe;
+ else
+ n = input->no_frames + (input->no_frames - 1) * input->successive_Bframe;
+ }
+
+ /* number of P frames */
+ if (img->number == 0)
+ np = (n + 2 * (M - 1)) / M - 1; /* first GOP */
+ else
+ np = (n + (M - 1)) / M - 1;
+
+ /* number of B frames */
+ nb = n - np - 1;
+ }
+ rc_init_GOP(np,nb);
+ }
+ }
+
+
+ // which layer the image belonged to?
+ if ( IMG_NUMBER % (input->NumFramesInELSubSeq+1) == 0 )
+ img->layer = 0;
+ else
+ img->layer = 1;
+
+ encode_one_frame(); // encode one I- or P-frame
+ if (img->type == I_SLICE && input->EnableOpenGOP)
+ img->last_valid_reference = img->ThisPOC;
+
+ if (input->ReportFrameStats)
+ report_frame_statistic();
+
+ if (img->nal_reference_idc == 0)
+ {
+ primary_disp ++;
+ img->frame_num -= 1;
+ img->frame_num %= (1 << (log2_max_frame_num_minus4 + 4));
+ }
+ encode_enhancement_layer();
+
+ process_2nd_IGOP();
+ }
+ // terminate sequence
+ terminate_sequence();
+
+ flush_dpb();
+
+ close(p_in);
+ if (-1!=p_dec)
+ close(p_dec);
+ if (p_trace)
+ fclose(p_trace);
+
+ Clear_Motion_Search_Module ();
+
+ RandomIntraUninit();
+ FmoUninit();
+
+ if (input->PyramidCoding)
+ clear_gop_structure ();
+
+ // free structure for rd-opt. mode decision
+ clear_rdopt ();
+
+ #ifdef _LEAKYBUCKET_
+ calc_buffer();
+ #endif
+
+ // report everything
+ report();
+
+ free_picture (frame_pic_1);
+
+ if (input->RDPictureDecision)
+ {
+ free_picture (frame_pic_2);
+ free_picture (frame_pic_3);
+ }
+
+ if (top_pic)
+ free_picture (top_pic);
+ if (bottom_pic)
+ free_picture (bottom_pic);
+
+ free_dpb();
+ free_colocated(Co_located);
+ uninit_out_buffer();
+
+ free_global_buffers();
+
+ // free image mem
+ free_img ();
+ free_context_memory ();
+ FreeNalPayloadBuffer();
+ FreeParameterSets();
+ return 0; //encode JM73_FME version
+ }
+ /*!
+ ***********************************************************************
+ * \brief
+ * Terminates and reports statistics on error.
+ *
+ ***********************************************************************
+ */
+ void report_stats_on_error()
+ {
+ input->no_frames=img->number-1;
+ terminate_sequence();
+
+ flush_dpb();
+
+ close(p_in);
+ if (-1!=p_dec)
+ close(p_dec);
+
+ if (p_trace)
+ fclose(p_trace);
+
+ Clear_Motion_Search_Module ();
+
+ RandomIntraUninit();
+ FmoUninit();
+
+ if (input->PyramidCoding)
+ clear_gop_structure ();
+
+ // free structure for rd-opt. mode decision
+ clear_rdopt ();
+
+ #ifdef _LEAKYBUCKET_
+ calc_buffer();
+ #endif
+
+ if (input->ReportFrameStats)
+ report_frame_statistic();
+
+ // report everything
+ report();
+
+ free_picture (frame_pic_1);
+ if (top_pic)
+ free_picture (top_pic);
+ if (bottom_pic)
+ free_picture (bottom_pic);
+
+ free_dpb();
+ free_colocated(Co_located);
+ uninit_out_buffer();
+
+ free_global_buffers();
+
+ // free image mem
+ free_img ();
+ free_context_memory ();
+ FreeNalPayloadBuffer();
+ FreeParameterSets();
+ }
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * Initializes the POC structure with appropriate parameters.
+ *
+ ***********************************************************************
+ */
+ void init_poc()
+ {
+ //the following should probably go in sequence parameters
+ // frame poc's increase by 2, field poc's by 1
+
+ img->pic_order_cnt_type=input->pic_order_cnt_type;
+
+ img->delta_pic_order_always_zero_flag=0;
+ img->num_ref_frames_in_pic_order_cnt_cycle= 1;
+
+ if (input->BRefPictures == 1)
+ {
+ img->offset_for_non_ref_pic = 0;
+ img->offset_for_ref_frame[0] = 2;
+ }
+ else
+ {
+ img->offset_for_non_ref_pic = -2*(input->successive_Bframe);
+ img->offset_for_ref_frame[0] = 2*(input->successive_Bframe+1);
+ }
+
+ if ((input->PicInterlace==FRAME_CODING)&&(input->MbInterlace==FRAME_CODING))
+ img->offset_for_top_to_bottom_field=0;
+ else
+ img->offset_for_top_to_bottom_field=1;
+
+ if ((input->PicInterlace==FRAME_CODING)&&(input->MbInterlace==FRAME_CODING))
+ {
+ img->pic_order_present_flag=0;
+ img->delta_pic_order_cnt_bottom = 0;
+ }
+ else
+ {
+ img->pic_order_present_flag=1;
+ img->delta_pic_order_cnt_bottom = 1;
+ }
+ }
+
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * Initializes the img->nz_coeff
+ * \par Input:
+ * none
+ * \par Output:
+ * none
+ * \ side effects
+ * sets omg->nz_coef[][][][] to -1
+ ***********************************************************************
+ */
+ void CAVLC_init()
+ {
+ unsigned int i, k, l;
+
+ for (i=0;i < img->PicSizeInMbs; i++)
+ for (k=0;k<4;k++)
+ for (l=0;l < (4 + (unsigned int)img->num_blk8x8_uv);l++)
+ img->nz_coeff[i][k][l]=0;
+ }
+
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * Initializes the Image structure with appropriate parameters.
+ * \par Input:
+ * Input Parameters struct inp_par *inp
+ * \par Output:
+ * Image Parameters struct img_par *img
+ ***********************************************************************
+ */
+ void init_img()
+ {
+ int i,j;
+ int byte_abs_range;
+
+ static int mb_width_cr[4] = {0,8, 8,16};
+ static int mb_height_cr[4]= {0,8,16,16};
+
+ img->yuv_format = input->yuv_format;
+
+ //pel bitdepth init
+ img->bitdepth_luma = input->BitDepthLuma;
+
+ img->bitdepth_luma_qp_scale = 6*(img->bitdepth_luma - 8);
+ img->bitdepth_lambda_scale = 2*(img->bitdepth_luma - 8);
+
+ img->dc_pred_value = 1<<(img->bitdepth_luma - 1);
+ img->max_imgpel_value = (1<<img->bitdepth_luma) - 1;
+
+ if (img->yuv_format != YUV400)
+ {
+ img->bitdepth_chroma = input->BitDepthChroma;
+ img->max_imgpel_value_uv = (1<<img->bitdepth_chroma) - 1;
+ img->num_blk8x8_uv = (1<<img->yuv_format)&(~(0x1));
+ img->num_cdc_coeff = img->num_blk8x8_uv<<1;
+ img->mb_cr_size_x = (img->yuv_format==YUV420 || img->yuv_format==YUV422)? 8:16;
+ img->mb_cr_size_y = (img->yuv_format==YUV444 || img->yuv_format==YUV422)? 16:8;
+
+ img->bitdepth_chroma_qp_scale = 6*(img->bitdepth_chroma - 8);
+ if(img->residue_transform_flag)
+ img->bitdepth_chroma_qp_scale += 6;
+
+ img->chroma_qp_offset[0] = active_pps->cb_qp_index_offset;
+ img->chroma_qp_offset[1] = active_pps->cr_qp_index_offset;
+ }
+ else
+ {
+ img->bitdepth_chroma = 0;
+ img->max_imgpel_value_uv = 0;
+ img->num_blk8x8_uv = 0;
+ img->num_cdc_coeff = 0;
+ img->mb_cr_size_x = 0;
+ img->mb_cr_size_y = 0;
+
+ img->bitdepth_chroma_qp_scale = 0;
+ img->bitdepth_chroma_qp_scale = 0;
+
+ img->chroma_qp_offset[0] = 0;
+ img->chroma_qp_offset[1] = 0;
+ }
+
+ if((img->bitdepth_luma > img->bitdepth_chroma) || img->yuv_format == YUV400)
+ img->pic_unit_size_on_disk = (img->bitdepth_luma > 8)? 16:8;
+ else
+ img->pic_unit_size_on_disk = (img->bitdepth_chroma > 8)? 16:8;
+
+ img->num_ref_frames = active_sps->num_ref_frames;
+ img->max_num_references = active_sps->frame_mbs_only_flag ? active_sps->num_ref_frames : 2 * active_sps->num_ref_frames;
+
+ img->buf_cycle = input->num_ref_frames;
+
+ img->DeblockCall = 0;
+
+ // img->framerate=INIT_FRAME_RATE; // The basic frame rate (of the original sequence)
+ img->framerate=(float) input->FrameRate; // The basic frame rate (of the original sequence)
+
+
+ get_mem_mv (&(img->pred_mv));
+ get_mem_mv (&(img->all_mv));
+
+ if (input->BiPredMotionEstimation)
+ {
+ get_mem_mv (&(img->bipred_mv1));
+ get_mem_mv (&(img->bipred_mv2));
+ }
+
+ get_mem_ACcoeff (&(img->cofAC));
+ get_mem_DCcoeff (&(img->cofDC));
+
+
+ if(input->MbInterlace)
+ {
+ get_mem_mv (&(rddata_top_frame_mb.pred_mv));
+ get_mem_mv (&(rddata_top_frame_mb.all_mv));
+
+ get_mem_mv (&(rddata_bot_frame_mb.pred_mv));
+ get_mem_mv (&(rddata_bot_frame_mb.all_mv));
+
+ get_mem_mv (&(rddata_top_field_mb.pred_mv));
+ get_mem_mv (&(rddata_top_field_mb.all_mv));
+
+ get_mem_mv (&(rddata_bot_field_mb.pred_mv));
+ get_mem_mv (&(rddata_bot_field_mb.all_mv));
+
+ get_mem_ACcoeff (&(rddata_top_frame_mb.cofAC));
+ get_mem_DCcoeff (&(rddata_top_frame_mb.cofDC));
+
+ get_mem_ACcoeff (&(rddata_bot_frame_mb.cofAC));
+ get_mem_DCcoeff (&(rddata_bot_frame_mb.cofDC));
+
+ get_mem_ACcoeff (&(rddata_top_field_mb.cofAC));
+ get_mem_DCcoeff (&(rddata_top_field_mb.cofDC));
+
+ get_mem_ACcoeff (&(rddata_bot_field_mb.cofAC));
+ get_mem_DCcoeff (&(rddata_bot_field_mb.cofDC));
+ }
+
+ if(img->max_imgpel_value > img->max_imgpel_value_uv)
+ byte_abs_range = (img->max_imgpel_value + 1) * 2;
+ else
+ byte_abs_range = (img->max_imgpel_value_uv + 1) * 2;
+
+ if ((img->quad = (int*)calloc (byte_abs_range, sizeof(int))) == NULL)
+ no_mem_exit ("init_img: img->quad");
+ img->quad+=byte_abs_range/2;
+ for (i=0; i < byte_abs_range/2; ++i)
+ {
+ img->quad[i]=img->quad[-i]=i*i;
+ }
+
+ img->width = (input->img_width+img->auto_crop_right);
+ img->height = (input->img_height+img->auto_crop_bottom);
+ if (img->yuv_format != YUV400)
+ {
+ img->width_cr = img->width/(16/mb_width_cr[img->yuv_format]);
+ img->height_cr= img->height/(16/mb_height_cr[img->yuv_format]);
+
+ input->img_width_cr = input->img_width/(16/mb_width_cr[img->yuv_format]);
+ input->img_height_cr = input->img_height/(16/mb_height_cr[img->yuv_format]);
+ }
+ else
+ {
+ img->width_cr = 0;
+ img->height_cr= 0;
+
+ input->img_width_cr = 0;
+ input->img_height_cr = 0;
+ }
+ img->height_cr_frame = img->height_cr;
+
+ img->PicWidthInMbs = (input->img_width+img->auto_crop_right)/MB_BLOCK_SIZE;
+ img->FrameHeightInMbs = (input->img_height+img->auto_crop_bottom)/MB_BLOCK_SIZE;
+ img->FrameSizeInMbs = img->PicWidthInMbs * img->FrameHeightInMbs;
+
+ img->PicHeightInMapUnits = ( active_sps->frame_mbs_only_flag ? img->FrameHeightInMbs : img->FrameHeightInMbs/2 );
+
+ if(((img->mb_data) = (Macroblock *) calloc(img->FrameSizeInMbs,sizeof(Macroblock))) == NULL)
+ no_mem_exit("init_img: img->mb_data");
+
+ if(input->UseConstrainedIntraPred)
+ {
+ if(((img->intra_block) = (int*)calloc(img->FrameSizeInMbs,sizeof(int))) == NULL)
+ no_mem_exit("init_img: img->intra_block");
+ }
+
+ get_mem2D((byte***)&(img->ipredmode), img->height/BLOCK_SIZE, img->width/BLOCK_SIZE); //need two extra rows at right and bottom
+ get_mem2D((byte***)&(img->ipredmode8x8), img->height/BLOCK_SIZE, img->width/BLOCK_SIZE); // help storage for ipredmode 8x8, inserted by YV
+
+ get_mem2D((byte***)&(rddata_top_frame_mb.ipredmode), img->height/BLOCK_SIZE, img->width/BLOCK_SIZE);
+
+ if(input->MbInterlace)
+ {
+ get_mem2D((byte***)&(rddata_bot_frame_mb.ipredmode), img->height/BLOCK_SIZE, img->width/BLOCK_SIZE);
+ get_mem2D((byte***)&(rddata_top_field_mb.ipredmode), img->height/BLOCK_SIZE, img->width/BLOCK_SIZE);
+ get_mem2D((byte***)&(rddata_bot_field_mb.ipredmode), img->height/BLOCK_SIZE, img->width/BLOCK_SIZE);
+ }
+ // CAVLC mem
+ get_mem3Dint(&(img->nz_coeff), img->FrameSizeInMbs, 4, 4+img->num_blk8x8_uv);
+
+ CAVLC_init();
+
+ for (i=0; i < img->width/BLOCK_SIZE; i++)
+ for (j=0; j < img->height/BLOCK_SIZE; j++)
+ {
+ img->ipredmode[j][i]=-1;
+ img->ipredmode8x8[j][i]=-1;
+ }
+
+ img->mb_y_upd=0;
+
+ RandomIntraInit (img->width/16, img->height/16, input->RandomIntraMBRefresh);
+
+ InitSEIMessages(); // Tian Dong (Sept 2002)
+
+ // Initialize filtering parameters. If sending parameters, the offsets are
+ // multiplied by 2 since inputs are taken in "div 2" format.
+ // If not sending parameters, all fields are cleared
+ if (input->LFSendParameters)
+ {
+ input->LFAlphaC0Offset <<= 1;
+ input->LFBetaOffset <<= 1;
+ }
+ else
+ {
+ input->LFDisableIdc = 0;
+ input->LFAlphaC0Offset = 0;
+ input->LFBetaOffset = 0;
+ }
+ }
+
+ /*!
+ ***********************************************************************
+ * \brief
+ * Free the Image structures
+ * \par Input:
+ * Image Parameters struct img_par *img
+ ***********************************************************************
+ */
+ void free_img ()
+ {
+ CloseSEIMessages(); // Tian Dong (Sept 2002)
+ free_mem_mv (img->pred_mv);
+ free_mem_mv (img->all_mv);
+
+ if (input->BiPredMotionEstimation)
+ {
+ free_mem_mv (img->bipred_mv1);
+ free_mem_mv (img->bipred_mv2);
+ }
+
+ free_mem_ACcoeff (img->cofAC);
+ free_mem_DCcoeff (img->cofDC);
+
+ if(input->MbInterlace)
+ {
+ free_mem_mv (rddata_top_frame_mb.pred_mv);
+ free_mem_mv (rddata_top_frame_mb.all_mv);
+
+ free_mem_mv (rddata_bot_frame_mb.pred_mv);
+ free_mem_mv (rddata_bot_frame_mb.all_mv);
+
+ free_mem_mv (rddata_top_field_mb.pred_mv);
+ free_mem_mv (rddata_top_field_mb.all_mv);
+
+ free_mem_mv (rddata_bot_field_mb.pred_mv);
+ free_mem_mv (rddata_bot_field_mb.all_mv);
+
+ free_mem_ACcoeff (rddata_top_frame_mb.cofAC);
+ free_mem_DCcoeff (rddata_top_frame_mb.cofDC);
+
+ free_mem_ACcoeff (rddata_bot_frame_mb.cofAC);
+ free_mem_DCcoeff (rddata_bot_frame_mb.cofDC);
+
+ free_mem_ACcoeff (rddata_top_field_mb.cofAC);
+ free_mem_DCcoeff (rddata_top_field_mb.cofDC);
+
+ free_mem_ACcoeff (rddata_bot_field_mb.cofAC);
+ free_mem_DCcoeff (rddata_bot_field_mb.cofDC);
+ }
+
+ if(img->max_imgpel_value > img->max_imgpel_value_uv)
+ free (img->quad-(img->max_imgpel_value + 1));
+ else
+ free (img->quad-(img->max_imgpel_value_uv + 1));
+
+ if(input->MbInterlace)
+ {
+ free_mem2D((byte**)rddata_bot_frame_mb.ipredmode);
+ free_mem2D((byte**)rddata_top_field_mb.ipredmode);
+ free_mem2D((byte**)rddata_bot_field_mb.ipredmode);
+ }
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Allocates the picture structure along with its dependent
+ * data structures
+ * \return
+ * Pointer to a Picture
+ ************************************************************************
+ */
+
+ Picture *malloc_picture()
+ {
+ Picture *pic;
+ if ((pic = calloc (1, sizeof (Picture))) == NULL) no_mem_exit ("malloc_picture: Picture structure");
+ //! Note: slice structures are allocated as needed in code_a_picture
+ return pic;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Frees a picture
+ * \param
+ * pic: POinter to a Picture to be freed
+ ************************************************************************
+ */
+
+
+ void free_picture(Picture *pic)
+ {
+ if (pic != NULL)
+ {
+ free_slice_list(pic);
+ free (pic);
+ }
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Reports frame statistical data to a stats file
+ ************************************************************************
+ */
+ void report_frame_statistic()
+ {
+ FILE *p_stat_frm = NULL;
+ static int last_mode_use[NUM_PIC_TYPE][MAXMODE];
+ static int last_b8_mode_0[NUM_PIC_TYPE][2];
+ static int last_mode_chroma_use[4];
+ static int last_bit_ctr_n = 0;
+ int i;
+ char name[20];
+ int bitcounter;
+
+ #ifndef WIN32
+ time_t now;
+ struct tm *l_time;
+ char string[1000];
+ #else
+ char timebuf[128];
+ #endif
+
+
+ // write to log file
+ if ((p_stat_frm=fopen("stat_frame.dat","r"))==0) // check if file exist
+ {
+ if ((p_stat_frm=fopen("stat_frame.dat","a"))==NULL) // append new statistic at the end
+ {
+ snprintf(errortext, ET_SIZE, "Error open file %s \n","stat_frame.dat.dat");
+ error(errortext, 500);
+ }
+ else // Create header for new log file
+ {
+ fprintf(p_stat_frm," --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \n");
+ fprintf(p_stat_frm,"| Encoder statistics. This file is generated during first encoding session, new sessions will be appended |\n");
+ fprintf(p_stat_frm," --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \n");
+ }
+ }
+ else
+ {
+ fclose (p_stat_frm);
+ if ((p_stat_frm=fopen("stat_frame.dat","a"))==NULL) // File exist,just open for appending
+ {
+ snprintf(errortext, ET_SIZE, "Error open file %s \n","stat_frame.dat.dat");
+ error(errortext, 500);
+ }
+ }
+
+ if (frame_statistic_start)
+ {
+ fprintf(p_stat_frm,"| ver | Date | Time | Sequence |Frm | QP |P/MbInt| Bits | SNRY | SNRU | SNRV | I4 | I8 | I16 | IC0 | IC1 | IC2 | IC3 | PI4 | PI8 | PI16 | P0 | P1 | P2 | P3 | P1*8*| P1*4*| P2*8*| P2*4*| P3*8*| P3*4*| P8 | P8:4 | P4*8*| P4*4*| P8:5 | P8:6 | P8:7 | BI4 | BI8 | BI16 | B0 | B1 | B2 | B3 | B0*8*| B0*4*| B1*8*| B1*4*| B2*8*| B2*4*| B3*8*| B3*4*| B8 | B8:0 |B80*8*|B80*4*| B8:4 | B4*8*| B4*4*| B8:5 | B8:6 | B8:7 |\n");
+ fprintf(p_stat_frm," --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \n");
+ }
+
+ //report
+ fprintf(p_stat_frm,"|%4s/%s", VERSION, EXT_VERSION);
+
+ #ifdef WIN32
+ _strdate( timebuf );
+ fprintf(p_stat_frm,"| %1.5s |",timebuf );
+
+ _strtime( timebuf);
+ fprintf(p_stat_frm," % 1.5s |",timebuf);
+ #else
+ now = time ((time_t *) NULL); // Get the system time and put it into 'now' as 'calender time'
+ time (&now);
+ l_time = localtime (&now);
+ strftime (string, sizeof string, "%d-%b-%Y", l_time);
+ fprintf(p_stat_frm,"| %1.5s |",string );
+
+ strftime (string, sizeof string, "%H:%M:%S", l_time);
+ fprintf(p_stat_frm," %1.5s |",string );
+ #endif
+
+ for (i=0;i<20;i++)
+ name[i]=input->infile[i+max(0,(int) (strlen(input->infile)-20))]; // write last part of path, max 20 chars
+ fprintf(p_stat_frm,"%20.20s|",name);
+
+ fprintf(p_stat_frm,"%3d |",frame_no);
+
+ fprintf(p_stat_frm,"%3d |",img->qp);
+
+ fprintf(p_stat_frm," %d/%d |",input->PicInterlace, input->MbInterlace);
+
+
+ if (img->frame_num == 0)
+ {
+ bitcounter = stats->bit_ctr_I;
+ }
+ else
+ {
+ bitcounter = stats->bit_ctr_n - last_bit_ctr_n;
+ last_bit_ctr_n = stats->bit_ctr_n;
+ }
+
+ //report bitrate
+ fprintf(p_stat_frm, " %9d|", bitcounter);
+
+ //report snr's
+ fprintf(p_stat_frm, " %2.4f| %2.4f| %2.4f|", snr->snr_y, snr->snr_u, snr->snr_v);
+
+ //report modes
+ //I-Modes
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[I_SLICE][I4MB] - last_mode_use[I_SLICE][I4MB]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[I_SLICE][I8MB] - last_mode_use[I_SLICE][I8MB]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[I_SLICE][I16MB] - last_mode_use[I_SLICE][I16MB]);
+
+ //chroma intra mode
+ fprintf(p_stat_frm, " %5d|",stats->intra_chroma_mode[0] - last_mode_chroma_use[0]);
+ fprintf(p_stat_frm, " %5d|",stats->intra_chroma_mode[1] - last_mode_chroma_use[1]);
+ fprintf(p_stat_frm, " %5d|",stats->intra_chroma_mode[2] - last_mode_chroma_use[2]);
+ fprintf(p_stat_frm, " %5d|",stats->intra_chroma_mode[3] - last_mode_chroma_use[3]);
+
+ //P-Modes
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[P_SLICE][I4MB] - last_mode_use[P_SLICE][I4MB]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[P_SLICE][I8MB] - last_mode_use[P_SLICE][I8MB]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[P_SLICE][I16MB] - last_mode_use[P_SLICE][I16MB]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[P_SLICE][0 ] - last_mode_use[P_SLICE][0 ]);
+
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[P_SLICE][1 ] - last_mode_use[P_SLICE][1 ]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[P_SLICE][2 ] - last_mode_use[P_SLICE][2 ]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[P_SLICE][3 ] - last_mode_use[P_SLICE][3 ]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use_transform_8x8[0][1]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use_transform_4x4[0][1]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use_transform_8x8[0][2]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use_transform_4x4[0][2]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use_transform_8x8[0][3]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use_transform_4x4[0][3]);
+
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[P_SLICE][P8x8] - last_mode_use[P_SLICE][P8x8]);
+ // fprintf(p_stat_frm, " %5d|",stats->b8_mode_0_use[P_SLICE][0] - last_b8_mode_0[P_SLICE ][0]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[P_SLICE][4 ] - last_mode_use[P_SLICE][4 ]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use_transform_8x8[0][4]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use_transform_4x4[0][4]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[P_SLICE][5 ] - last_mode_use[P_SLICE][5 ]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[P_SLICE][6 ] - last_mode_use[P_SLICE][6 ]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[P_SLICE][7 ] - last_mode_use[P_SLICE][7 ]);
+
+ //B-Modes
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[B_SLICE][I4MB] - last_mode_use[B_SLICE][I4MB]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[B_SLICE][I8MB] - last_mode_use[B_SLICE][I8MB]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[B_SLICE][I16MB] - last_mode_use[B_SLICE][I16MB]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[B_SLICE][0 ] - last_mode_use[B_SLICE][0 ]);
+ /*
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[B_SLICE][1 ] - last_mode_use[B_SLICE][1 ]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[B_SLICE][2 ] - last_mode_use[B_SLICE][2 ]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[B_SLICE][3 ] - last_mode_use[B_SLICE][3 ]);
+ */
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[B_SLICE][1 ] - last_mode_use[B_SLICE][1 ]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[B_SLICE][2 ] - last_mode_use[B_SLICE][2 ]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[B_SLICE][3 ] - last_mode_use[B_SLICE][3 ]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use_transform_8x8[1][0]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use_transform_4x4[1][0]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use_transform_8x8[1][1]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use_transform_4x4[1][1]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use_transform_8x8[1][2]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use_transform_4x4[1][2]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use_transform_8x8[1][3]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use_transform_4x4[1][3]);
+
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[B_SLICE][P8x8] - last_mode_use[B_SLICE][P8x8]);
+ fprintf(p_stat_frm, " %5d|",(stats->b8_mode_0_use [B_SLICE][0]+stats->b8_mode_0_use [B_SLICE][1]) - (last_b8_mode_0[B_SLICE][0]+last_b8_mode_0[B_SLICE][1]));
+ fprintf(p_stat_frm, " %5d|",stats->b8_mode_0_use [B_SLICE][1] - last_b8_mode_0[B_SLICE][1]);
+ fprintf(p_stat_frm, " %5d|",stats->b8_mode_0_use [B_SLICE][0] - last_b8_mode_0[B_SLICE][0]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[B_SLICE][4 ] - last_mode_use[B_SLICE][4 ]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use_transform_8x8[1][4]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use_transform_4x4[1][4]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[B_SLICE][5 ] - last_mode_use[B_SLICE][5 ]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[B_SLICE][6 ] - last_mode_use[B_SLICE][6 ]);
+ fprintf(p_stat_frm, " %5d|",stats->mode_use[B_SLICE][7 ] - last_mode_use[B_SLICE][7 ]);
+
+ fprintf(p_stat_frm, "\n");
+
+ //save the last results
+ memcpy(last_mode_use[I_SLICE],stats->mode_use[I_SLICE], MAXMODE * sizeof(int));
+ memcpy(last_mode_use[P_SLICE],stats->mode_use[P_SLICE], MAXMODE * sizeof(int));
+ memcpy(last_mode_use[B_SLICE],stats->mode_use[B_SLICE], MAXMODE * sizeof(int));
+ memset(stats->mode_use_transform_8x8,0, 2 * MAXMODE * sizeof(int));
+ memset(stats->mode_use_transform_4x4,0, 2 * MAXMODE * sizeof(int));
+ memcpy(last_b8_mode_0[B_SLICE],stats->b8_mode_0_use[B_SLICE], 2 * sizeof(int));
+ memcpy(last_mode_chroma_use,stats->intra_chroma_mode, 4 * sizeof(int));
+
+ frame_statistic_start = 0;
+ fclose(p_stat_frm);
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Reports the gathered information to appropriate outputs
+ * \par Input:
+ * struct inp_par *inp, \n
+ * struct img_par *img, \n
+ * struct stat_par *stats, \n
+ * struct stat_par *stats \n
+ *
+ * \par Output:
+ * None
+ ************************************************************************
+ */
+ void report()
+ {
+ int bit_use[NUM_PIC_TYPE][2] ;
+ int i,j;
+ char name[30];
+ int total_bits;
+ float frame_rate;
+ float mean_motion_info_bit_use[2] = {0.0};
+
+ #ifndef WIN32
+ time_t now;
+ struct tm *l_time;
+ char string[1000];
+ #else
+ char timebuf[128];
+ #endif
+ bit_use[I_SLICE][0] = frame_ctr[I_SLICE];
+ bit_use[P_SLICE][0] = max(frame_ctr[P_SLICE] + frame_ctr[SP_SLICE],1);
+ bit_use[B_SLICE][0] = frame_ctr[B_SLICE];
+
+ // Accumulate bit usage for inter and intra frames
+ for (j=0;j<NUM_PIC_TYPE;j++)
+ {
+ bit_use[j][1] = 0;
+ }
+
+ for (j=0;j<NUM_PIC_TYPE;j++)
+ {
+ for(i=0; i<MAXMODE; i++)
+ bit_use[j][1] += stats->bit_use_mode [j][i];
+
+ bit_use[j][1]+=stats->bit_use_header[j];
+ bit_use[j][1]+=stats->bit_use_mb_type[j];
+ bit_use[j][1]+=stats->tmp_bit_use_cbp[j];
+ bit_use[j][1]+=stats->bit_use_coeffY[j];
+ bit_use[j][1]+=stats->bit_use_coeffC[j];
+ bit_use[j][1]+=stats->bit_use_delta_quant[j];
+ bit_use[j][1]+=stats->bit_use_stuffingBits[j];
+ }
+
+ frame_rate = (img->framerate *(float)(stats->successive_Bframe + 1)) / (float) (input->jumpd+1);
+
+ //! Currently adding NVB bits on P rate. Maybe additional stats info should be created instead and added in log file
+ stats->bitrate_I = (stats->bit_ctr_I)*(frame_rate)/(float) (input->no_frames + frame_ctr[B_SLICE]);
+ stats->bitrate_P = (stats->bit_ctr_P)*(frame_rate)/(float) (input->no_frames + frame_ctr[B_SLICE]);
+ stats->bitrate_B = (stats->bit_ctr_B)*(frame_rate)/(float) (input->no_frames + frame_ctr[B_SLICE]);
+
+ fprintf(stdout,"-------------------------------------------------------------------------------\n");
+ if (input->Verbose != 0)
+ {
+ fprintf(stdout, " Freq. for encoded bitstream : %1.0f\n",img->framerate/(float)(input->jumpd+1));
+ switch (input->hadamard)
+ {
+ case 2:
+ fprintf(stdout," Hadamard transform : Used for QPel\n");
+ break;
+ case 1:
+ fprintf(stdout," Hadamard transform : Used\n");
+ break;
+ default:
+ fprintf(stdout," Hadamard transform : Not used\n");
+ break;
+ }
+
+ fprintf(stdout, " Image format : %dx%d\n",input->img_width,input->img_height);
+
+ if(input->intra_upd)
+ fprintf(stdout," Error robustness : On\n");
+ else
+ fprintf(stdout," Error robustness : Off\n");
+ fprintf(stdout, " Search range : %d\n",input->search_range);
+
+ fprintf(stdout, " Total number of references : %d\n",input->num_ref_frames);
+ fprintf(stdout, " References for P slices : %d\n",input->P_List0_refs? input->P_List0_refs:input->num_ref_frames);
+ if(stats->successive_Bframe != 0)
+ {
+ fprintf(stdout," List0 references for B slices : %d\n",input->B_List0_refs? input->B_List0_refs:input->num_ref_frames);
+ fprintf(stdout," List1 references for B slices : %d\n",input->B_List1_refs? input->B_List1_refs:input->num_ref_frames);
+ }
+
+ #if 0 // FIXME: control with a runtime option.
+ fprintf(stdout, " Total encoding time for the seq. : %.3f sec (%.2f fps)\n",tot_time*0.001, 1000.0*(input->no_frames + frame_ctr[B_SLICE])/tot_time);
+ fprintf(stdout, " Total ME time for sequence : %.3f sec \n",me_tot_time*0.001);
+ #endif
+
+ // B pictures
+ fprintf(stdout, " Sequence type :" );
+
+ if(stats->successive_Bframe>0 && input->PyramidCoding)
+ {
+ fprintf(stdout, " Pyramid (QP: I %d, P %d, B %d) \n",
+ input->qp0, input->qpN, input->qpB);
+ }
+ else if(stats->successive_Bframe>0)
+ {
+ char seqtype[80];
+ int i,j;
+
+ strcpy (seqtype,"I");
+
+ for (j=0;j<2;j++)
+ {
+ for (i=0;i<stats->successive_Bframe;i++)
+ {
+ if (input->BRefPictures)
+ strncat(seqtype,"-RB",max (0, (int) (79-strlen(seqtype))));
+ else
+ strncat(seqtype,"-B",max (0, (int) (79-strlen(seqtype))));
+ }
+ strncat(seqtype,"-P",max (0, (int) (79-strlen(seqtype))));
+ }
+ if (input->BRefPictures)
+ fprintf(stdout, " %s (QP: I %d, P %d, RB %d) \n", seqtype,input->qp0, input->qpN, Clip3(0,51,input->qpB+input->qpBRSOffset));
+ else
+ fprintf(stdout, " %s (QP: I %d, P %d, B %d) \n", seqtype,input->qp0, input->qpN, input->qpB);
+ }
+ else if(stats->successive_Bframe==0 && input->sp_periodicity==0) fprintf(stdout, " IPPP (QP: I %d, P %d) \n", input->qp0, input->qpN);
+
+ else fprintf(stdout, " I-P-P-SP-P (QP: I %d, P %d, SP (%d, %d)) \n", input->qp0, input->qpN, input->qpsp, input->qpsp_pred);
+
+ // report on entropy coding method
+ if (input->symbol_mode == UVLC)
+ fprintf(stdout," Entropy coding method : CAVLC\n");
+ else
+ fprintf(stdout," Entropy coding method : CABAC\n");
+
+ fprintf(stdout, " Profile/Level IDC : (%d,%d)\n",input->ProfileIDC,input->LevelIDC);
+
+ if (input->FMEnable==1)
+ fprintf(stdout, " Motion Estimation Scheme : HEX\n");
+ else if (input->FMEnable==2)
+ fprintf(stdout, " Motion Estimation Scheme : SHEX\n");
+ else if (input->FMEnable == 3)
+ {
+ fprintf(stdout, " Motion Estimation Scheme : EPZS\n");
+ EPZSOutputStats(stdout, 0);
+ }
+ else
+ fprintf(stdout, " Motion Estimation Scheme : Full Search\n");
+
+
+
+ #ifdef _FULL_SEARCH_RANGE_
+ if (input->full_search == 2)
+ fprintf(stdout," Search range restrictions : none\n");
+ else if (input->full_search == 1)
+ fprintf(stdout," Search range restrictions : older reference frames\n");
+ else
+ fprintf(stdout," Search range restrictions : smaller blocks and older reference frames\n");
+ #endif
+
+ if (input->rdopt)
+ fprintf(stdout," RD-optimized mode decision : used\n");
+ else
+ fprintf(stdout," RD-optimized mode decision : not used\n");
+
+ switch(input->partition_mode)
+ {
+ case PAR_DP_1:
+ fprintf(stdout," Data Partitioning Mode : 1 partition \n");
+ break;
+ case PAR_DP_3:
+ fprintf(stdout," Data Partitioning Mode : 3 partitions \n");
+ break;
+ default:
+ fprintf(stdout," Data Partitioning Mode : not supported\n");
+ break;
+ }
+
+ switch(input->of_mode)
+ {
+ case PAR_OF_ANNEXB:
+ fprintf(stdout," Output File Format : H.264 Bit Stream File Format \n");
+ break;
+ case PAR_OF_RTP:
+ fprintf(stdout," Output File Format : RTP Packet File Format \n");
+ break;
+ default:
+ fprintf(stdout," Output File Format : not supported\n");
+ break;
+ }
+ // Residue Color Transform
+ if(input->residue_transform_flag)
+ fprintf(stdout," Residue Color Transform : used\n");
+ else
+ fprintf(stdout," Residue Color Transform : not used\n");
+ }
+
+ fprintf(stdout,"------------------ Average data all frames -----------------------------------\n");
+ if (input->Verbose != 0)
+ {
+ int impix = input->img_height * input->img_width;
+ int impix_cr = input->img_height_cr * input->img_width_cr;
+ unsigned int max_pix_value_sqd = img->max_imgpel_value * img->max_imgpel_value;
+ unsigned int max_pix_value_sqd_uv = img->max_imgpel_value_uv * img->max_imgpel_value_uv;
+ float csnr_y = (float) (10 * log10 (max_pix_value_sqd *
+ (double)((double) impix / (snr->msse_y == 0.0? 1.0 : snr->msse_y))));
+ float csnr_u = (float) (10 * log10 (max_pix_value_sqd_uv *
+ (double)((double) impix_cr / (snr->msse_u == 0.0? 1.0 : snr->msse_u))));
+ float csnr_v = (float) (10 * log10 (max_pix_value_sqd_uv *
+ (double)((double) impix_cr / (snr->msse_v == 0.0? 1.0 : snr->msse_v))));
+
+ fprintf(stdout," SNR Y(dB) : %5.2f\n",snr->snr_ya);
+ fprintf(stdout," SNR U(dB) : %5.2f\n",snr->snr_ua);
+ fprintf(stdout," SNR V(dB) : %5.2f\n",snr->snr_va);
+ fprintf(stdout," cSNR Y(dB) : %5.2f (%5.2f)\n",csnr_y,snr->msse_y/impix);
+ fprintf(stdout," cSNR U(dB) : %5.2f (%5.2f)\n",csnr_u,snr->msse_u/impix_cr);
+ fprintf(stdout," cSNR V(dB) : %5.2f (%5.2f)\n",csnr_v,snr->msse_v/impix_cr);
+ }
+ else
+ fprintf(stdout, " Total encoding time for the seq. : %.3f sec (%.2f fps)\n",tot_time*0.001, 1000.0*(input->no_frames + frame_ctr[B_SLICE])/tot_time);
+
+ if(frame_ctr[B_SLICE]!=0)
+ {
+ fprintf(stdout, " Total bits : %d (I %5d, P %5d, B %d NVB %d) \n",
+ total_bits=stats->bit_ctr_P + stats->bit_ctr_I + stats->bit_ctr_B + stats->bit_ctr_parametersets, stats->bit_ctr_I, stats->bit_ctr_P, stats->bit_ctr_B,stats->bit_ctr_parametersets);
+
+ frame_rate = (img->framerate *(float)(stats->successive_Bframe + 1)) / (float) (input->jumpd+1);
+ stats->bitrate= ((float) total_bits * frame_rate)/((float) (input->no_frames + frame_ctr[B_SLICE]));
+
+ fprintf(stdout, " Bit rate (kbit/s) @ %2.2f Hz : %5.2f\n", frame_rate, stats->bitrate/1000);
+
+ }
+ else if (input->sp_periodicity==0)
+ {
+ fprintf(stdout, " Total bits : %d (I %5d, P %5d, NVB %d) \n",
+ total_bits=stats->bit_ctr_P + stats->bit_ctr_I + stats->bit_ctr_parametersets, stats->bit_ctr_I, stats->bit_ctr_P, stats->bit_ctr_parametersets);
+
+
+ frame_rate = img->framerate / ( (float) (input->jumpd + 1) );
+ stats->bitrate= ((float) total_bits * frame_rate)/((float) input->no_frames );
+
+ fprintf(stdout, " Bit rate (kbit/s) @ %2.2f Hz : %5.2f\n", frame_rate, stats->bitrate/1000);
+ }
+ else
+ {
+ fprintf(stdout, " Total bits : %d (I %5d, P %5d, NVB %d) \n",
+ total_bits=stats->bit_ctr_P + stats->bit_ctr_I + stats->bit_ctr_parametersets, stats->bit_ctr_I, stats->bit_ctr_P, stats->bit_ctr_parametersets);
+
+
+ frame_rate = img->framerate / ( (float) (input->jumpd + 1) );
+ stats->bitrate= ((float) total_bits * frame_rate)/((float) input->no_frames );
+
+ fprintf(stdout, " Bit rate (kbit/s) @ %2.2f Hz : %5.2f\n", frame_rate, stats->bitrate/1000);
+ }
+
+ fprintf(stdout, " Bits to avoid Startcode Emulation : %d \n", stats->bit_ctr_emulationprevention);
+ fprintf(stdout, " Bits for parameter sets : %d \n", stats->bit_ctr_parametersets);
+
+ fprintf(stdout,"-------------------------------------------------------------------------------\n");
+ fprintf(stdout,"Exit JM %s encoder ver %s ", JM, VERSION);
+ fprintf(stdout,"\n");
+
+ // status file
+ if ((p_stat=fopen("stats.dat","wt"))==0)
+ {
+ snprintf(errortext, ET_SIZE, "Error open file %s", "stats.dat");
+ error(errortext, 500);
+ }
+ fprintf(p_stat," -------------------------------------------------------------- \n");
+ fprintf(p_stat," This file contains statistics for the last encoded sequence \n");
+ fprintf(p_stat," -------------------------------------------------------------- \n");
+ fprintf(p_stat, " Sequence : %s\n",input->infile);
+ fprintf(p_stat, " No.of coded pictures : %4d\n",input->no_frames+frame_ctr[B_SLICE]);
+ fprintf(p_stat, " Freq. for encoded bitstream : %4.0f\n",frame_rate);
+
+ fprintf(p_stat, " I Slice Bitrate(kb/s) : %6.2f\n", stats->bitrate_I/1000);
+ fprintf(p_stat, " P Slice Bitrate(kb/s) : %6.2f\n", stats->bitrate_P/1000);
+ // B pictures
+ if(stats->successive_Bframe != 0)
+ fprintf(p_stat, " B Slice Bitrate(kb/s) : %6.2f\n", stats->bitrate_B/1000);
+ fprintf(p_stat, " Total Bitrate(kb/s) : %6.2f\n", stats->bitrate/1000);
+
+ switch (input->hadamard)
+ {
+ case 2:
+ fprintf(p_stat," Hadamard transform : Used for QPel\n");
+ break;
+ case 1:
+ fprintf(p_stat," Hadamard transform : Used\n");
+ break;
+ default:
+ fprintf(p_stat," Hadamard transform : Not used\n");
+ break;
+ }
+
+ fprintf(p_stat, " Image format : %dx%d\n",input->img_width,input->img_height);
+
+ if(input->intra_upd)
+ fprintf(p_stat," Error robustness : On\n");
+ else
+ fprintf(p_stat," Error robustness : Off\n");
+
+ fprintf(p_stat, " Search range : %d\n",input->search_range);
+
+ fprintf(p_stat, " Total number of references : %d\n",input->num_ref_frames);
+ fprintf(p_stat, " References for P slices : %d\n",input->P_List0_refs? input->P_List0_refs:input->num_ref_frames);
+ if(stats->successive_Bframe != 0)
+ {
+ fprintf(p_stat, " List0 refs for B slices : %d\n",input->B_List0_refs? input->B_List0_refs:input->num_ref_frames);
+ fprintf(p_stat, " List1 refs for B slices : %d\n",input->B_List1_refs? input->B_List1_refs:input->num_ref_frames);
+ }
+
+ if (input->symbol_mode == UVLC)
+ fprintf(p_stat, " Entropy coding method : CAVLC\n");
+ else
+ fprintf(p_stat, " Entropy coding method : CABAC\n");
+
+ fprintf(p_stat, " Profile/Level IDC : (%d,%d)\n",input->ProfileIDC,input->LevelIDC);
+ if(input->MbInterlace)
+ fprintf(p_stat, " MB Field Coding : On \n");
+
+ if (input->FMEnable == 3)
+ EPZSOutputStats(p_stat, 1);
+
+ #ifdef _FULL_SEARCH_RANGE_
+ if (input->full_search == 2)
+ fprintf(p_stat," Search range restrictions : none\n");
+ else if (input->full_search == 1)
+ fprintf(p_stat," Search range restrictions : older reference frames\n");
+ else
+ fprintf(p_stat," Search range restrictions : smaller blocks and older reference frames\n");
+ #endif
+ if (input->rdopt)
+ fprintf(p_stat," RD-optimized mode decision : used\n");
+ else
+ fprintf(p_stat," RD-optimized mode decision : not used\n");
+
+ fprintf(p_stat," ---------------------|----------------|---------------|\n");
+ fprintf(p_stat," Item | Intra | All frames |\n");
+ fprintf(p_stat," ---------------------|----------------|---------------|\n");
+ fprintf(p_stat," SNR Y(dB) |");
+ fprintf(p_stat," %5.2f |",snr->snr_y1);
+ fprintf(p_stat," %5.2f |\n",snr->snr_ya);
+ fprintf(p_stat," SNR U/V (dB) |");
+ fprintf(p_stat," %5.2f/%5.2f |",snr->snr_u1,snr->snr_v1);
+ fprintf(p_stat," %5.2f/%5.2f |\n",snr->snr_ua,snr->snr_va);
+
+ // QUANT.
+ fprintf(p_stat," Average quant |");
+ fprintf(p_stat," %5d |",absm(input->qp0));
+ fprintf(p_stat," %5.2f |\n",(float)stats->quant1/max(1.0,(float)stats->quant0));
+
+ fprintf(p_stat,"\n ---------------------|----------------|---------------|---------------|\n");
+ fprintf(p_stat," SNR | I | P | B |\n");
+ fprintf(p_stat," ---------------------|----------------|---------------|---------------|\n");
+ fprintf(p_stat," SNR Y(dB) | %5.3f | %5.3f | %5.3f |\n",
+ snr->snr_yt[I_SLICE],snr->snr_yt[P_SLICE],snr->snr_yt[B_SLICE]);
+ fprintf(p_stat," SNR U(dB) | %5.3f | %5.3f | %5.3f |\n",
+ snr->snr_ut[I_SLICE],snr->snr_ut[P_SLICE],snr->snr_ut[B_SLICE]);
+ fprintf(p_stat," SNR V(dB) | %5.3f | %5.3f | %5.3f |\n",
+ snr->snr_vt[I_SLICE],snr->snr_vt[P_SLICE],snr->snr_vt[B_SLICE]);
+
+
+ // MODE
+ fprintf(p_stat,"\n ---------------------|----------------|\n");
+ fprintf(p_stat," Intra | Mode used |\n");
+ fprintf(p_stat," ---------------------|----------------|\n");
+
+ fprintf(p_stat," Mode 0 intra 4x4 | %5d |\n",stats->mode_use[I_SLICE][I4MB ]);
+ fprintf(p_stat," Mode 1 intra 8x8 | %5d |\n",stats->mode_use[I_SLICE][I8MB ]);
+ fprintf(p_stat," Mode 2+ intra 16x16 | %5d |\n",stats->mode_use[I_SLICE][I16MB]);
+ fprintf(p_stat," Mode intra IPCM | %5d |\n",stats->mode_use[I_SLICE][IPCM ]);
+
+ fprintf(p_stat,"\n ---------------------|----------------|-----------------|\n");
+ fprintf(p_stat," Inter | Mode used | MotionInfo bits |\n");
+ fprintf(p_stat," ---------------------|----------------|-----------------|");
+ fprintf(p_stat,"\n Mode 0 (copy) | %5d | %8.2f |",stats->mode_use[P_SLICE][0 ],(float)stats->bit_use_mode[P_SLICE][0 ]/(float)bit_use[P_SLICE][0]);
+ fprintf(p_stat,"\n Mode 1 (16x16) | %5d | %8.2f |",stats->mode_use[P_SLICE][1 ],(float)stats->bit_use_mode[P_SLICE][1 ]/(float)bit_use[P_SLICE][0]);
+ fprintf(p_stat,"\n Mode 2 (16x8) | %5d | %8.2f |",stats->mode_use[P_SLICE][2 ],(float)stats->bit_use_mode[P_SLICE][2 ]/(float)bit_use[P_SLICE][0]);
+ fprintf(p_stat,"\n Mode 3 (8x16) | %5d | %8.2f |",stats->mode_use[P_SLICE][3 ],(float)stats->bit_use_mode[P_SLICE][3 ]/(float)bit_use[P_SLICE][0]);
+ fprintf(p_stat,"\n Mode 4 (8x8) | %5d | %8.2f |",stats->mode_use[P_SLICE][P8x8],(float)stats->bit_use_mode[P_SLICE][P8x8]/(float)bit_use[P_SLICE][0]);
+ fprintf(p_stat,"\n Mode 5 intra 4x4 | %5d |-----------------|",stats->mode_use[P_SLICE][I4MB]);
+ fprintf(p_stat,"\n Mode 6 intra 8x8 | %5d |",stats->mode_use[P_SLICE][I8MB]);
+ fprintf(p_stat,"\n Mode 7+ intra 16x16 | %5d |",stats->mode_use[P_SLICE][I16MB]);
+ fprintf(p_stat,"\n Mode intra IPCM | %5d |",stats->mode_use[P_SLICE][IPCM ]);
+ mean_motion_info_bit_use[0] = (float)(stats->bit_use_mode[P_SLICE][0] + stats->bit_use_mode[P_SLICE][1] + stats->bit_use_mode[P_SLICE][2]
+ + stats->bit_use_mode[P_SLICE][3] + stats->bit_use_mode[P_SLICE][P8x8])/(float) bit_use[P_SLICE][0];
+
+ // B pictures
+ if(stats->successive_Bframe!=0 && frame_ctr[B_SLICE]!=0)
+ {
+
+ fprintf(p_stat,"\n\n ---------------------|----------------|-----------------|\n");
+ fprintf(p_stat," B frame | Mode used | MotionInfo bits |\n");
+ fprintf(p_stat," ---------------------|----------------|-----------------|");
+ fprintf(p_stat,"\n Mode 0 (copy) | %5d | %8.2f |",stats->mode_use[B_SLICE][0 ],(float)stats->bit_use_mode[B_SLICE][0 ]/(float)frame_ctr[B_SLICE]);
+ fprintf(p_stat,"\n Mode 1 (16x16) | %5d | %8.2f |",stats->mode_use[B_SLICE][1 ],(float)stats->bit_use_mode[B_SLICE][1 ]/(float)frame_ctr[B_SLICE]);
+ fprintf(p_stat,"\n Mode 2 (16x8) | %5d | %8.2f |",stats->mode_use[B_SLICE][2 ],(float)stats->bit_use_mode[B_SLICE][2 ]/(float)frame_ctr[B_SLICE]);
+ fprintf(p_stat,"\n Mode 3 (8x16) | %5d | %8.2f |",stats->mode_use[B_SLICE][3 ],(float)stats->bit_use_mode[B_SLICE][3 ]/(float)frame_ctr[B_SLICE]);
+ fprintf(p_stat,"\n Mode 4 (8x8) | %5d | %8.2f |",stats->mode_use[B_SLICE][P8x8],(float)stats->bit_use_mode[B_SLICE][P8x8]/(float)frame_ctr[B_SLICE]);
+ fprintf(p_stat,"\n Mode 5 intra 4x4 | %5d |-----------------|",stats->mode_use[B_SLICE][I4MB]);
+ fprintf(p_stat,"\n Mode 6 intra 8x8 | %5d |",stats->mode_use[B_SLICE][I8MB]);
+ fprintf(p_stat,"\n Mode 7+ intra 16x16 | %5d |",stats->mode_use[B_SLICE][I16MB]);
+ fprintf(p_stat,"\n Mode intra IPCM | %5d |",stats->mode_use[B_SLICE][IPCM ]);
+ mean_motion_info_bit_use[1] = (float)(stats->bit_use_mode[B_SLICE][0] + stats->bit_use_mode[B_SLICE][1] + stats->bit_use_mode[B_SLICE][2]
+ + stats->bit_use_mode[B_SLICE][3] + stats->bit_use_mode[B_SLICE][P8x8])/(float) frame_ctr[B_SLICE];
+ }
+
+ fprintf(p_stat,"\n\n ---------------------|----------------|----------------|----------------|\n");
+ fprintf(p_stat," Bit usage: | Intra | Inter | B frame |\n");
+ fprintf(p_stat," ---------------------|----------------|----------------|----------------|\n");
+
+ fprintf(p_stat," Header |");
+ fprintf(p_stat," %10.2f |",(float) stats->bit_use_header[I_SLICE]/bit_use[I_SLICE][0]);
+ fprintf(p_stat," %10.2f |",(float) stats->bit_use_header[P_SLICE]/bit_use[P_SLICE][0]);
+ if(stats->successive_Bframe!=0 && frame_ctr[B_SLICE]!=0)
+ fprintf(p_stat," %10.2f |",(float) stats->bit_use_header[B_SLICE]/frame_ctr[B_SLICE]);
+ else fprintf(p_stat," %10.2f |", 0.);
+ fprintf(p_stat,"\n");
+
+ fprintf(p_stat," Mode |");
+ fprintf(p_stat," %10.2f |",(float)stats->bit_use_mb_type[I_SLICE]/bit_use[I_SLICE][0]);
+ fprintf(p_stat," %10.2f |",(float)stats->bit_use_mb_type[P_SLICE]/bit_use[P_SLICE][0]);
+ if(stats->successive_Bframe!=0 && frame_ctr[B_SLICE]!=0)
+ fprintf(p_stat," %10.2f |",(float)stats->bit_use_mb_type[B_SLICE]/frame_ctr[B_SLICE]);
+ else fprintf(p_stat," %10.2f |", 0.);
+ fprintf(p_stat,"\n");
+
+ fprintf(p_stat," Motion Info |");
+ fprintf(p_stat," ./. |");
+ fprintf(p_stat," %10.2f |",mean_motion_info_bit_use[0]);
+ if(stats->successive_Bframe!=0 && frame_ctr[B_SLICE]!=0)
+ fprintf(p_stat," %10.2f |",mean_motion_info_bit_use[1]);
+ else fprintf(p_stat," %10.2f |", 0.);
+ fprintf(p_stat,"\n");
+
+ fprintf(p_stat," CBP Y/C |");
+ fprintf(p_stat," %10.2f |", (float)stats->tmp_bit_use_cbp[I_SLICE]/bit_use[I_SLICE][0]);
+ fprintf(p_stat," %10.2f |", (float)stats->tmp_bit_use_cbp[P_SLICE]/bit_use[P_SLICE][0]);
+ if(stats->successive_Bframe!=0 && bit_use[B_SLICE][0]!=0)
+ fprintf(p_stat," %10.2f |", (float)stats->tmp_bit_use_cbp[B_SLICE]/bit_use[B_SLICE][0]);
+ else fprintf(p_stat," %10.2f |", 0.);
+ fprintf(p_stat,"\n");
+
+ if(stats->successive_Bframe!=0 && frame_ctr[B_SLICE]!=0)
+ fprintf(p_stat," Coeffs. Y | %10.2f | %10.2f | %10.2f |\n",
+ (float)stats->bit_use_coeffY[I_SLICE]/bit_use[I_SLICE][0], (float)stats->bit_use_coeffY[P_SLICE]/bit_use[P_SLICE][0], (float)stats->bit_use_coeffY[B_SLICE]/frame_ctr[B_SLICE]);
+ else
+ fprintf(p_stat," Coeffs. Y | %10.2f | %10.2f | %10.2f |\n",
+ (float)stats->bit_use_coeffY[I_SLICE]/bit_use[I_SLICE][0], (float)stats->bit_use_coeffY[P_SLICE]/(float)bit_use[P_SLICE][0], 0.);
+
+ if(stats->successive_Bframe!=0 && frame_ctr[B_SLICE]!=0)
+ fprintf(p_stat," Coeffs. C | %10.2f | %10.2f | %10.2f |\n",
+ (float)stats->bit_use_coeffC[I_SLICE]/bit_use[I_SLICE][0], (float)stats->bit_use_coeffC[P_SLICE]/bit_use[P_SLICE][0], (float)stats->bit_use_coeffC[B_SLICE]/frame_ctr[B_SLICE]);
+ else
+ fprintf(p_stat," Coeffs. C | %10.2f | %10.2f | %10.2f |\n",
+ (float)stats->bit_use_coeffC[I_SLICE]/bit_use[I_SLICE][0], (float)stats->bit_use_coeffC[P_SLICE]/bit_use[P_SLICE][0], 0.);
+
+ if(stats->successive_Bframe!=0 && frame_ctr[B_SLICE]!=0)
+ fprintf(p_stat," Delta quant | %10.2f | %10.2f | %10.2f |\n",
+ (float)stats->bit_use_delta_quant[I_SLICE]/bit_use[I_SLICE][0], (float)stats->bit_use_delta_quant[P_SLICE]/bit_use[P_SLICE][0], (float)stats->bit_use_delta_quant[B_SLICE]/frame_ctr[B_SLICE]);
+ else
+ fprintf(p_stat," Delta quant | %10.2f | %10.2f | %10.2f |\n",
+ (float)stats->bit_use_delta_quant[I_SLICE]/bit_use[I_SLICE][0], (float)stats->bit_use_delta_quant[P_SLICE]/bit_use[P_SLICE][0], 0.);
+
+ if(stats->successive_Bframe!=0 && frame_ctr[B_SLICE]!=0)
+ fprintf(p_stat," Stuffing Bits | %10.2f | %10.2f | %10.2f |\n",
+ (float)stats->bit_use_stuffingBits[I_SLICE]/bit_use[I_SLICE][0], (float)stats->bit_use_stuffingBits[P_SLICE]/bit_use[P_SLICE][0], (float)stats->bit_use_stuffingBits[B_SLICE]/frame_ctr[B_SLICE]);
+ else
+ fprintf(p_stat," Stuffing Bits | %10.2f | %10.2f | %10.2f |\n",
+ (float)stats->bit_use_stuffingBits[I_SLICE]/bit_use[I_SLICE][0], (float)stats->bit_use_stuffingBits[P_SLICE]/bit_use[P_SLICE][0], 0.);
+
+
+
+ fprintf(p_stat," ---------------------|----------------|----------------|----------------|\n");
+
+ fprintf(p_stat," average bits/frame |");
+
+ fprintf(p_stat," %10.2f |", (float) bit_use[I_SLICE][1]/(float) bit_use[I_SLICE][0] );
+ fprintf(p_stat," %10.2f |", (float) bit_use[P_SLICE][1]/(float) bit_use[P_SLICE][0] );
+
+ if(stats->successive_Bframe!=0 && frame_ctr[B_SLICE]!=0)
+ fprintf(p_stat," %10.2f |", (float) bit_use[B_SLICE][1]/ (float) frame_ctr[B_SLICE] );
+ else fprintf(p_stat," %10.2f |", 0.);
+
+ fprintf(p_stat,"\n");
+ fprintf(p_stat," ---------------------|----------------|----------------|----------------|\n");
+
+ fclose(p_stat);
+
+ // write to log file
+ if ((p_log=fopen("log.dat","r"))==0) // check if file exist
+ {
+ if ((p_log=fopen("log.dat","a"))==NULL) // append new statistic at the end
+ {
+ snprintf(errortext, ET_SIZE, "Error open file %s \n","log.dat");
+ error(errortext, 500);
+ }
+ else // Create header for new log file
+ {
+ fprintf(p_log," ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ \n");
+ fprintf(p_log,"| Encoder statistics. This file is generated during first encoding session, new sessions will be appended |\n");
+ fprintf(p_log," ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ \n");
+ fprintf(p_log,"| ver | Date | Time | Sequence | #Img |P/MbInt| QPI| QPP| QPB| Format |Iperiod| #B | FMES | Hdmd | S.R |#Ref | Freq |Coding|RD-opt|Intra upd|8x8Tr| SNRY 1| SNRU 1| SNRV 1| SNRY N| SNRU N| SNRV N|#Bitr I|#Bitr P|#Bitr B|#Bitr IPB| Total Time | Me Time |\n");
+ fprintf(p_log," ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ \n");
+ }
+ }
+ else
+ {
+ fclose (p_log);
+ if ((p_log=fopen("log.dat","a"))==NULL) // File exist,just open for appending
+ {
+ snprintf(errortext, ET_SIZE, "Error open file %s \n","log.dat");
+ error(errortext, 500);
+ }
+ }
+ fprintf(p_log,"|%s/%-4s", VERSION, EXT_VERSION);
+
+ #ifdef WIN32
+ _strdate( timebuf );
+ fprintf(p_log,"| %1.5s |",timebuf );
+
+ _strtime( timebuf);
+ fprintf(p_log," % 1.5s |",timebuf);
+ #else
+ now = time ((time_t *) NULL); // Get the system time and put it into 'now' as 'calender time'
+ time (&now);
+ l_time = localtime (&now);
+ strftime (string, sizeof string, "%d-%b-%Y", l_time);
+ fprintf(p_log,"| %1.5s |",string );
+
+ strftime (string, sizeof string, "%H:%M:%S", l_time);
+ fprintf(p_log," %1.5s |",string );
+ #endif
+
+ for (i=0;i<30;i++)
+ name[i]=input->infile[i+max(0,((int)strlen(input->infile))-30)]; // write last part of path, max 20 chars
+ fprintf(p_log,"%30.30s|",name);
+
+ fprintf(p_log,"%5d |",input->no_frames);
+ fprintf(p_log," %d/%d |",input->PicInterlace, input->MbInterlace);
+ fprintf(p_log," %-3d|",input->qp0);
+ fprintf(p_log," %-3d|",input->qpN);
+ fprintf(p_log," %-3d|",input->qpB);
+
+ fprintf(p_log,"%4dx%-4d|",input->img_width,input->img_height);
+
+ fprintf(p_log," %3d |",input->intra_period);
+ fprintf(p_log,"%3d |",stats->successive_Bframe);
+
+ if (input->FMEnable==1)
+ fprintf(p_log," HEX |");
+ else if (input->FMEnable==2)
+ fprintf(p_log," SHEX |");
+ else if (input->FMEnable == 3)
+ fprintf(p_log," EPZS |");
+ else
+ fprintf(p_log," OFF |");
+
+ switch (input->hadamard)
+ {
+ case 2:
+ fprintf(p_log," QPL |");
+ break;
+ case 1:
+ fprintf(p_log," ON |");
+ break;
+ default:
+ fprintf(p_log," OFF |");
+ break;
+ }
+
+ fprintf(p_log," %3d |",input->search_range );
+
+ fprintf(p_log," %2d |",input->num_ref_frames);
+
+
+ // fprintf(p_log," %3d |",img->framerate/(input->jumpd+1));
+ fprintf(p_log," %5.2f|",(img->framerate *(float) (stats->successive_Bframe + 1)) / (float)(input->jumpd+1));
+
+ if (input->symbol_mode == UVLC)
+ fprintf(p_log," CAVLC|");
+ else
+ fprintf(p_log," CABAC|");
+
+ fprintf(p_log," %d |",input->rdopt);
+
+ if (input->intra_upd==1)
+ fprintf(p_log," ON |");
+ else
+ fprintf(p_log," OFF |");
+
+ fprintf(p_log," %d |",input->Transform8x8Mode);
+
+ fprintf(p_log,"%7.3f|",snr->snr_y1);
+ fprintf(p_log,"%7.3f|",snr->snr_u1);
+ fprintf(p_log,"%7.3f|",snr->snr_v1);
+ fprintf(p_log,"%7.3f|",snr->snr_ya);
+ fprintf(p_log,"%7.3f|",snr->snr_ua);
+ fprintf(p_log,"%7.3f|",snr->snr_va);
+ /*
+ fprintf(p_log,"%-5.3f|",snr->snr_yt[I_SLICE]);
+ fprintf(p_log,"%-5.3f|",snr->snr_ut[I_SLICE]);
+ fprintf(p_log,"%-5.3f|",snr->snr_vt[I_SLICE]);
+ fprintf(p_log,"%-5.3f|",snr->snr_yt[P_SLICE]);
+ fprintf(p_log,"%-5.3f|",snr->snr_ut[P_SLICE]);
+ fprintf(p_log,"%-5.3f|",snr->snr_vt[P_SLICE]);
+ fprintf(p_log,"%-5.3f|",snr->snr_yt[B_SLICE]);
+ fprintf(p_log,"%-5.3f|",snr->snr_ut[B_SLICE]);
+ fprintf(p_log,"%-5.3f|",snr->snr_vt[B_SLICE]);
+ */
+ fprintf(p_log,"%7.0f|",stats->bitrate_I);
+ fprintf(p_log,"%7.0f|",stats->bitrate_P);
+ fprintf(p_log,"%7.0f|",stats->bitrate_B);
+ fprintf(p_log,"%9.0f|",stats->bitrate);
+
+ fprintf(p_log," %12d |", tot_time);
+ fprintf(p_log," %12d |\n", me_tot_time);
+
+ fclose(p_log);
+
+ p_log=fopen("data.txt","a");
+
+ if(stats->successive_Bframe != 0 && frame_ctr[B_SLICE] != 0) // B picture used
+ {
+ fprintf(p_log, "%3d %2d %2d %2.2f %2.2f %2.2f %5d "
+ "%2.2f %2.2f %2.2f %5d "
+ "%2.2f %2.2f %2.2f %5d %5d %.3f\n",
+ input->no_frames, input->qp0, input->qpN,
+ snr->snr_y1,
+ snr->snr_u1,
+ snr->snr_v1,
+ stats->bit_ctr_I,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0,
+ snr->snr_ya,
+ snr->snr_ua,
+ snr->snr_va,
+ (stats->bit_ctr_I+stats->bit_ctr)/(input->no_frames+frame_ctr[B_SLICE]),
+ stats->bit_ctr_B/frame_ctr[B_SLICE],
+ (double)0.001*tot_time/(input->no_frames+frame_ctr[B_SLICE]));
+ }
+ else
+ {
+ if (input->no_frames!=0)
+ fprintf(p_log, "%3d %2d %2d %2.2f %2.2f %2.2f %5d "
+ "%2.2f %2.2f %2.2f %5d "
+ "%2.2f %2.2f %2.2f %5d %5d %.3f\n",
+ input->no_frames, input->qp0, input->qpN,
+ snr->snr_y1,
+ snr->snr_u1,
+ snr->snr_v1,
+ stats->bit_ctr_I,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0,
+ snr->snr_ya,
+ snr->snr_ua,
+ snr->snr_va,
+ (stats->bit_ctr_I+stats->bit_ctr)/input->no_frames,
+ 0,
+ (double)0.001*tot_time/input->no_frames);
+ }
+
+ fclose(p_log);
+
+ if (input->ReportFrameStats)
+ {
+ if ((p_log=fopen("stat_frame.dat","a"))==NULL) // append new statistic at the end
+ {
+ snprintf(errortext, ET_SIZE, "Error open file %s \n","stat_frame.dat.dat");
+ // error(errortext, 500);
+ }
+ else
+ {
+ fprintf(p_log," --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \n");
+ fclose(p_log);
+ }
+ }
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Prints the header of the protocol.
+ * \par Input:
+ * struct inp_par *inp
+ * \par Output:
+ * none
+ ************************************************************************
+ */
+ void information_init()
+ {
+ char yuv_types[4][10]= {"YUV 4:0:0","YUV 4:2:0","YUV 4:2:2","YUV 4:4:4"};
+ if (input->Verbose == 0 || input->Verbose == 1)
+ printf("------------------------------- JM %s %s --------------------------------\n",VERSION, EXT_VERSION);
+ else
+ printf("------------------------------- JM %s %s ------------------------------------------\n",VERSION, EXT_VERSION);
+ printf(" Input YUV file : %s \n",input->infile);
+ printf(" Output H.264 bitstream : %s \n",input->outfile);
+ if (p_dec != -1)
+ printf(" Output YUV file : %s \n",input->ReconFile);
+ printf(" YUV Format : %s \n", &yuv_types[img->yuv_format][0]);//img->yuv_format==YUV422?"YUV 4:2:2":(img->yuv_format==YUV444)?"YUV 4:4:4":"YUV 4:2:0");
+ printf(" Frames to be encoded I-P/B : %d/%d\n", input->no_frames, (input->successive_Bframe*(input->no_frames-1)));
+ printf(" PicInterlace / MbInterlace : %d/%d\n", input->PicInterlace, input->MbInterlace);
+ printf(" Transform8x8Mode : %d\n", input->Transform8x8Mode);
+
+ switch (input->Verbose)
+ {
+ case 1:
+ printf("-------------------------------------------------------------------------------\n");
+ printf(" Frame Bit/pic QP SnrY SnrU SnrV Time(ms) MET(ms) Frm/Fld Ref \n");
+ printf("-------------------------------------------------------------------------------\n");
+ break;
+ case 2:
+ printf("---------------------------------------------------------------------------------------------\n");
+ printf(" Frame Bit/pic WP QP SnrY SnrU SnrV Time(ms) MET(ms) Frm/Fld I D L0 L1 RDP Ref\n");
+ printf("---------------------------------------------------------------------------------------------\n");
+ break;
+ case 0:
+ default:
+ printf("-------------------------------------------------------------------------------\n");
+ printf("\nEncoding. Please Wait.\n\n");
+ break;
+ }
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * memory allocation for original picture buffers
+ ************************************************************************
+ */
+ int init_orig_buffers()
+ {
+ int memory_size = 0;
+
+ // allocate memory for reference frame buffers: imgY_org_frm, imgUV_org_frm
+ memory_size += get_mem2Dpel(&imgY_org_frm, img->height, img->width);
+
+ if (img->yuv_format != YUV400)
+ memory_size += get_mem3Dpel(&imgUV_org_frm, 2, img->height_cr, img->width_cr);
+
+
+ if(!active_sps->frame_mbs_only_flag)
+ {
+ // allocate memory for reference frame buffers: imgY_org, imgUV_org
+ init_top_bot_planes(imgY_org_frm, img->height, img->width, &imgY_org_top, &imgY_org_bot);
+
+ if (img->yuv_format != YUV400)
+ {
+ if(((imgUV_org_top) = (imgpel***)calloc(2,sizeof(imgpel**))) == NULL)
+ no_mem_exit("init_global_buffers: imgUV_org_top");
+ if(((imgUV_org_bot) = (imgpel***)calloc(2,sizeof(imgpel**))) == NULL)
+ no_mem_exit("init_global_buffers: imgUV_org_bot");
+
+ memory_size += 4*(sizeof(imgpel**));
+
+ memory_size += init_top_bot_planes(imgUV_org_frm[0], img->height_cr, img->width_cr, &(imgUV_org_top[0]), &(imgUV_org_bot[0]));
+ memory_size += init_top_bot_planes(imgUV_org_frm[1], img->height_cr, img->width_cr, &(imgUV_org_top[1]), &(imgUV_org_bot[1]));
+ }
+ }
+ return memory_size;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Dynamic memory allocation of frame size related global buffers
+ * buffers are defined in global.h, allocated memory must be freed in
+ * void free_global_buffers()
+ * \par Input:
+ * Input Parameters struct inp_par *inp, \n
+ * Image Parameters struct img_par *img
+ * \return Number of allocated bytes
+ ************************************************************************
+ */
+ int init_global_buffers()
+ {
+ int j,memory_size=0;
+ #ifdef _ADAPT_LAST_GROUP_
+ extern int *last_P_no_frm;
+ extern int *last_P_no_fld;
+
+ if ((last_P_no_frm = (int*)malloc(2*img->max_num_references*sizeof(int))) == NULL)
+ no_mem_exit("init_global_buffers: last_P_no");
+ if(!active_sps->frame_mbs_only_flag)
+ if ((last_P_no_fld = (int*)malloc(4*img->max_num_references*sizeof(int))) == NULL)
+ no_mem_exit("init_global_buffers: last_P_no");
+ #endif
+
+ memory_size += init_orig_buffers();
+
+
+ if (input->WeightedPrediction || input->WeightedBiprediction || input->GenerateMultiplePPS)
+ {
+ // Currently only use up to 20 references. Need to use different indicator such as maximum num of references in list
+ memory_size += get_mem3Dint(&wp_weight,6,MAX_REFERENCE_PICTURES,3);
+ memory_size += get_mem3Dint(&wp_offset,6,MAX_REFERENCE_PICTURES,3);
+
+ memory_size += get_mem4Dint(&wbp_weight, 6, MAX_REFERENCE_PICTURES, MAX_REFERENCE_PICTURES, 3);
+ }
+
+ // allocate memory for reference frames of each block: refFrArr
+
+ if(input->successive_Bframe!=0 || input->BRefPictures> 0)
+ {
+ memory_size += get_mem3D ((byte ****)(void*)(&direct_ref_idx), 2, img->height >> BLOCK_SHIFT, img->width >> BLOCK_SHIFT);
+ memory_size += get_mem2Dshort(&direct_pdir, img->height >> BLOCK_SHIFT, img->width >> BLOCK_SHIFT);
+ }
+
+ // allocate memory for temp quarter pel luma frame buffer: img4Y_tmp
+ // int img4Y_tmp[576][704]; (previously int imgY_tmp in global.h)
+ memory_size += get_mem2Dint(&img4Y_tmp, img->height+2*IMG_PAD_SIZE, (img->width+2*IMG_PAD_SIZE)*4);
+
+ if (input->rdopt==3)
+ {
+ memory_size += get_mem2Dint(&decs->resY, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
+ if ((decs->decref = (imgpel****) calloc(input->NoOfDecoders,sizeof(imgpel***))) == NULL)
+ no_mem_exit("init_global_buffers: decref");
+ for (j=0 ; j<input->NoOfDecoders; j++)
+ {
+ memory_size += get_mem3Dpel(&decs->decref[j], img->max_num_references+1, img->height, img->width);
+ }
+ memory_size += get_mem2Dpel(&decs->RefBlock, BLOCK_SIZE,BLOCK_SIZE);
+ memory_size += get_mem3Dpel(&decs->decY, input->NoOfDecoders, img->height, img->width);
+ memory_size += get_mem3Dpel(&decs->decY_best, input->NoOfDecoders, img->height, img->width);
+ memory_size += get_mem2D(&decs->status_map, img->height/MB_BLOCK_SIZE,img->width/MB_BLOCK_SIZE);
+ memory_size += get_mem2D(&decs->dec_mb_mode, img->width/MB_BLOCK_SIZE,img->height/MB_BLOCK_SIZE);
+ }
+ if (input->RestrictRef)
+ {
+ memory_size += get_mem2D(&pixel_map, img->height,img->width);
+ memory_size += get_mem2D(&refresh_map, img->height/8,img->width/8);
+ }
+
+ if(!active_sps->frame_mbs_only_flag)
+ {
+ memory_size += get_mem2Dpel(&imgY_com, img->height, img->width);
+
+ if (img->yuv_format != YUV400)
+ {
+ memory_size += get_mem3Dpel(&imgUV_com, 2, img->height_cr, img->width_cr);
+ }
+ }
+
+ if (input->FMEnable == 1)
+ {
+ memory_size += get_mem_FME();
+ }
+ else if (input->FMEnable == 2)
+ {
+ simplified_init_FME();
+ memory_size += simplified_get_mem_FME();
+ }
+ else if (input->FMEnable == 3)
+ memory_size += EPZSInit();
+
+
+ if (input->RCEnable)
+ {
+ rc_alloc();
+ }
+
+ return (memory_size);
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Free allocated memory of original picture buffers
+ ************************************************************************
+ */
+ void free_orig_planes()
+ {
+ free_mem2Dpel(imgY_org_frm); // free ref frame buffers
+
+ if (img->yuv_format != YUV400)
+ free_mem3Dpel(imgUV_org_frm, 2);
+
+
+ if(!active_sps->frame_mbs_only_flag)
+ {
+ free_top_bot_planes(imgY_org_top, imgY_org_bot);
+
+ if (img->yuv_format != YUV400)
+ {
+ free_top_bot_planes(imgUV_org_top[0], imgUV_org_bot[0]);
+ free_top_bot_planes(imgUV_org_top[1], imgUV_org_bot[1]);
+ free (imgUV_org_top);
+ free (imgUV_org_bot);
+ }
+ }
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Free allocated memory of frame size related global buffers
+ * buffers are defined in global.h, allocated memory is allocated in
+ * int get_mem4global_buffers()
+ * \par Input:
+ * Input Parameters struct inp_par *inp, \n
+ * Image Parameters struct img_par *img
+ * \par Output:
+ * none
+ ************************************************************************
+ */
+ void free_global_buffers()
+ {
+ int i,j;
+
+ #ifdef _ADAPT_LAST_GROUP_
+ extern int *last_P_no_frm;
+ extern int *last_P_no_fld;
+ free (last_P_no_frm);
+ free (last_P_no_fld);
+ #endif
+
+ free_orig_planes();
+
+ // Free Qmatrices and offsets
+ free_QMatrix();
+ free_QOffsets();
+
+ if (input->WeightedPrediction || input->WeightedBiprediction || input->GenerateMultiplePPS)
+ {
+ free_mem3Dint(wp_weight,6);
+ free_mem3Dint(wp_offset,6);
+ free_mem4Dint(wbp_weight,6,MAX_REFERENCE_PICTURES);
+ }
+
+ if(stats->successive_Bframe!=0 || input->BRefPictures> 0)
+ {
+ free_mem3D ((byte ***)direct_ref_idx,2);
+ free_mem2Dshort(direct_pdir);
+ } // end if B frame
+
+
+ free_mem2Dint(img4Y_tmp); // free temp quarter pel frame buffer
+
+ // free mem, allocated in init_img()
+ // free intra pred mode buffer for blocks
+ free_mem2D((byte**)img->ipredmode);
+ free_mem2D((byte**)img->ipredmode8x8);
+ free(img->mb_data);
+
+ free_mem2D((byte**)rddata_top_frame_mb.ipredmode);
+
+ if(input->UseConstrainedIntraPred)
+ {
+ free (img->intra_block);
+ }
+
+ if (input->rdopt==3)
+ {
+ free(decs->resY[0]);
+ free(decs->resY);
+ free(decs->RefBlock[0]);
+ free(decs->RefBlock);
+ for (j=0; j<input->NoOfDecoders; j++)
+ {
+ free(decs->decY[j][0]);
+ free(decs->decY[j]);
+ free(decs->decY_best[j][0]);
+ free(decs->decY_best[j]);
+ for (i=0; i<img->max_num_references+1; i++)
+ {
+ free(decs->decref[j][i][0]);
+ free(decs->decref[j][i]);
+ }
+ free(decs->decref[j]);
+ }
+ free(decs->decY);
+ free(decs->decY_best);
+ free(decs->decref);
+ free(decs->status_map[0]);
+ free(decs->status_map);
+ free(decs->dec_mb_mode[0]);
+ free(decs->dec_mb_mode);
+ }
+ if (input->RestrictRef)
+ {
+ free(pixel_map[0]);
+ free(pixel_map);
+ free(refresh_map[0]);
+ free(refresh_map);
+ }
+
+ if(!active_sps->frame_mbs_only_flag)
+ {
+ free_mem2Dpel(imgY_com);
+ if (img->yuv_format != YUV400)
+ {
+ free_mem3Dpel(imgUV_com,2);
+ }
+ }
+
+ free_mem3Dint(img->nz_coeff, img->FrameSizeInMbs);
+
+ if(input->FMEnable == 1)
+ {
+ free_mem_FME();
+ }
+ else if (input->FMEnable == 2)
+ {
+ simplified_free_mem_FME();
+ }
+ else if (input->FMEnable == 3)
+ {
+ EPZSDelete();
+ }
+
+
+ if (input->RCEnable)
+ {
+ rc_free();
+ }
+
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Allocate memory for mv
+ * \par Input:
+ * Image Parameters struct img_par *img \n
+ * int****** mv
+ * \return memory size in bytes
+ ************************************************************************
+ */
+ int get_mem_mv (short ******* mv)
+ {
+ int i, j, k, l, m;
+
+ if ((*mv = (short******)calloc(4,sizeof(short*****))) == NULL)
+ no_mem_exit ("get_mem_mv: mv");
+ for (i=0; i<4; i++)
+ {
+ if (((*mv)[i] = (short*****)calloc(4,sizeof(short****))) == NULL)
+ no_mem_exit ("get_mem_mv: mv");
+ for (j=0; j<4; j++)
+ {
+ if (((*mv)[i][j] = (short****)calloc(2,sizeof(short***))) == NULL)
+ no_mem_exit ("get_mem_mv: mv");
+ for (k=0; k<2; k++)
+ {
+ if (((*mv)[i][j][k] = (short***)calloc(img->max_num_references,sizeof(short**))) == NULL)
+ no_mem_exit ("get_mem_mv: mv");
+ for (l=0; l<img->max_num_references; l++)
+ {
+ if (((*mv)[i][j][k][l] = (short**)calloc(9,sizeof(short*))) == NULL)
+ no_mem_exit ("get_mem_mv: mv");
+ if (((*mv)[i][j][k][l][0] = (short*)calloc(2*9,sizeof(short))) == NULL)
+ no_mem_exit ("get_mem_mv: mv");
+ for (m=1; m<9; m++)
+ (*mv)[i][j][k][l][m] = (*mv)[i][j][k][l][m - 1] + 2;
+ }
+ }
+ }
+ }
+ return 4*4*img->max_num_references*9*2*sizeof(short);
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Free memory from mv
+ * \par Input:
+ * int****** mv
+ ************************************************************************
+ */
+ void free_mem_mv (short****** mv)
+ {
+ int i, j, k, l;
+
+ for (i=0; i<4; i++)
+ {
+ for (j=0; j<4; j++)
+ {
+ for (k=0; k<2; k++)
+ {
+ for (l=0; l<img->max_num_references; l++)
+ {
+ free (mv[i][j][k][l][0]);
+ free (mv[i][j][k][l]);
+ }
+ free (mv[i][j][k]);
+ }
+ free (mv[i][j]);
+ }
+ free (mv[i]);
+ }
+ free (mv);
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Allocate memory for AC coefficients
+ ************************************************************************
+ */
+ int get_mem_ACcoeff (int***** cofAC)
+ {
+ int i, j, k;
+ int num_blk8x8 = 4 + img->num_blk8x8_uv;
+
+ if ((*cofAC = (int****)calloc (num_blk8x8, sizeof(int***))) == NULL) no_mem_exit ("get_mem_ACcoeff: cofAC");
+ for (k=0; k<num_blk8x8; k++)
+ {
+ if (((*cofAC)[k] = (int***)calloc (4, sizeof(int**))) == NULL) no_mem_exit ("get_mem_ACcoeff: cofAC");
+ for (j=0; j<4; j++)
+ {
+ if (((*cofAC)[k][j] = (int**)calloc (2, sizeof(int*))) == NULL) no_mem_exit ("get_mem_ACcoeff: cofAC");
+ for (i=0; i<2; i++)
+ {
+ if (((*cofAC)[k][j][i] = (int*)calloc (65, sizeof(int))) == NULL) no_mem_exit ("get_mem_ACcoeff: cofAC"); // 18->65 for ABT
+ }
+ }
+ }
+ return num_blk8x8*4*2*65*sizeof(int);// 18->65 for ABT
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Allocate memory for DC coefficients
+ ************************************************************************
+ */
+ int get_mem_DCcoeff (int**** cofDC)
+ {
+ int j, k;
+
+ if ((*cofDC = (int***)calloc (3, sizeof(int**))) == NULL) no_mem_exit ("get_mem_DCcoeff: cofDC");
+ for (k=0; k<3; k++)
+ {
+ if (((*cofDC)[k] = (int**)calloc (2, sizeof(int*))) == NULL) no_mem_exit ("get_mem_DCcoeff: cofDC");
+ for (j=0; j<2; j++)
+ {
+ if (((*cofDC)[k][j] = (int*)calloc (65, sizeof(int))) == NULL) no_mem_exit ("get_mem_DCcoeff: cofDC"); // 18->65 for ABT
+ }
+ }
+ return 3*2*65*sizeof(int); // 18->65 for ABT
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Free memory of AC coefficients
+ ************************************************************************
+ */
+ void free_mem_ACcoeff (int**** cofAC)
+ {
+ int i, j, k;
+
+ for (k=0; k<4+img->num_blk8x8_uv; k++)
+ {
+ for (i=0; i<4; i++)
+ {
+ for (j=0; j<2; j++)
+ {
+ free (cofAC[k][i][j]);
+ }
+ free (cofAC[k][i]);
+ }
+ free (cofAC[k]);
+ }
+ free (cofAC);
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Free memory of DC coefficients
+ ************************************************************************
+ */
+ void free_mem_DCcoeff (int*** cofDC)
+ {
+ int i, j;
+
+ for (j=0; j<3; j++)
+ {
+ for (i=0; i<2; i++)
+ {
+ free (cofDC[j][i]);
+ }
+ free (cofDC[j]);
+ }
+ free (cofDC);
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * form frame picture from two field pictures
+ ************************************************************************
+ */
+ void combine_field()
+ {
+ int i;
+
+ for (i=0; i<img->height / 2; i++)
+ {
+ memcpy(imgY_com[i*2], enc_top_picture->imgY[i], img->width*sizeof(imgpel)); // top field
+ memcpy(imgY_com[i*2 + 1], enc_bottom_picture->imgY[i], img->width*sizeof(imgpel)); // bottom field
+ }
+
+ if (img->yuv_format != YUV400)
+ {
+ for (i=0; i<img->height_cr / 2; i++)
+ {
+ memcpy(imgUV_com[0][i*2], enc_top_picture->imgUV[0][i], img->width_cr*sizeof(imgpel));
+ memcpy(imgUV_com[0][i*2 + 1], enc_bottom_picture->imgUV[0][i], img->width_cr*sizeof(imgpel));
+ memcpy(imgUV_com[1][i*2], enc_top_picture->imgUV[1][i], img->width_cr*sizeof(imgpel));
+ memcpy(imgUV_com[1][i*2 + 1], enc_bottom_picture->imgUV[1][i], img->width_cr*sizeof(imgpel));
+ }
+ }
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * RD decision of frame and field coding
+ ************************************************************************
+ */
+ int decide_fld_frame(float snr_frame_Y, float snr_field_Y, int bit_field, int bit_frame, double lambda_picture)
+ {
+ double cost_frame, cost_field;
+
+ cost_frame = bit_frame * lambda_picture + snr_frame_Y;
+ cost_field = bit_field * lambda_picture + snr_field_Y;
+
+ if (cost_field > cost_frame)
+ return (0);
+ else
+ return (1);
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Do some initializaiton work for encoding the 2nd IGOP
+ ************************************************************************
+ */
+ void process_2nd_IGOP()
+ {
+ Boolean FirstIGOPFinished = FALSE;
+ if ( img->number == input->no_frames-1 )
+ FirstIGOPFinished = TRUE;
+ if (input->NumFrameIn2ndIGOP==0) return;
+ if (!FirstIGOPFinished || In2ndIGOP) return;
+ In2ndIGOP = TRUE;
+
+ // img->number = -1;
+ start_frame_no_in_this_IGOP = input->no_frames;
+ start_tr_in_this_IGOP = (input->no_frames-1)*(input->jumpd+1) +1;
+ input->no_frames = input->no_frames + input->NumFrameIn2ndIGOP;
+
+ /* reset_buffers();
+
+ frm->picbuf_short[0]->used=0;
+ frm->picbuf_short[0]->picID=-1;
+ frm->picbuf_short[0]->lt_picID=-1;
+ frm->short_used = 0; */
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Set the image type for I,P and SP pictures (not B!)
+ ************************************************************************
+ */
+ void SetImgType()
+ {
+ int intra_refresh = input->intra_period == 0 ? (IMG_NUMBER == 0) : ((IMG_NUMBER%input->intra_period) == 0);
+
+ if (intra_refresh)
+ {
+ img->type = I_SLICE; // set image type for first image to I-frame
+ }
+ else
+ {
+ img->type = input->sp_periodicity && ((IMG_NUMBER % input->sp_periodicity) ==0) ? SP_SLICE : ((input->BRefPictures == 2) ? B_SLICE : P_SLICE);
+ }
+ }
+
+
+ void SetLevelIndices()
+ {
+ switch(active_sps->level_idc)
+ {
+ case 10:
+ img->LevelIndex=0;
+ break;
+ case 11:
+ if (active_sps->constrained_set3_flag == 0)
+ img->LevelIndex=2;
+ else
+ img->LevelIndex=1;
+ break;
+ case 12:
+ img->LevelIndex=3;
+ break;
+ case 13:
+ img->LevelIndex=4;
+ break;
+ case 20:
+ img->LevelIndex=5;
+ break;
+ case 21:
+ img->LevelIndex=6;
+ break;
+ case 22:
+ img->LevelIndex=7;
+ break;
+ case 30:
+ img->LevelIndex=8;
+ break;
+ case 31:
+ img->LevelIndex=9;
+ break;
+ case 32:
+ img->LevelIndex=10;
+ break;
+ case 40:
+ img->LevelIndex=11;
+ break;
+ case 41:
+ img->LevelIndex=12;
+ break;
+ case 42:
+ if (active_sps->profile_idc <= 88)
+ img->LevelIndex=13;
+ else
+ img->LevelIndex=14;
+ break;
+ case 50:
+ img->LevelIndex=15;
+ break;
+ case 51:
+ default:
+ img->LevelIndex=16;
+ break;
+ }
+ }
+
Index: llvm-test/MultiSource/Applications/JM/lencod/loopFilter.c
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/loopFilter.c:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/loopFilter.c Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,482 ----
+
+ /*!
+ *************************************************************************************
+ * \file loopFilter.c
+ *
+ * \brief
+ * Filter to reduce blocking artifacts on a macroblock level.
+ * The filter strengh is QP dependent.
+ *
+ * \author
+ * Contributors:
+ * - Peter List Peter.List at t-systems.de: Original code (13-Aug-2001)
+ * - Jani Lainema Jani.Lainema at nokia.com: Some bug fixing, removal of recusiveness (16-Aug-2001)
+ * - Peter List Peter.List at t-systems.de: inplace filtering and various simplifications (10-Jan-2002)
+ * - Anthony Joch anthony at ubvideo.com: Simplified switching between filters and
+ * non-recursive default filter. (08-Jul-2002)
+ * - Cristina Gomila cristina.gomila at thomson.net: Simplification of the chroma deblocking
+ * from JVT-E089 (21-Nov-2002)
+ *************************************************************************************
+ */
+
+ #include <stdlib.h>
+ #include <assert.h>
+
+ #include "global.h"
+
+ #include "image.h"
+ #include "mb_access.h"
+
+ extern const byte QP_SCALE_CR[52] ;
+
+ byte mixedModeEdgeFlag, fieldModeFilteringFlag;
+
+ /*********************************************************************************************************/
+
+ #define IClip( Min, Max, Val) (((Val)<(Min))? (Min):(((Val)>(Max))? (Max):(Val)))
+
+
+ // NOTE: In principle, the alpha and beta tables are calculated with the formulas below
+ // Alpha( qp ) = 0.8 * (2^(qp/6) - 1)
+ // Beta ( qp ) = 0.5 * qp - 7
+
+ // The tables actually used have been "hand optimized" though (by Anthony Joch). So, the
+ // table values might be a little different to formula-generated values. Also, the first
+ // few values of both tables is set to zero to force the filter off at low qps
+
+ byte ALPHA_TABLE[52] = {0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,4,4,5,6, 7,8,9,10,12,13,15,17, 20,22,25,28,32,36,40,45, 50,56,63,71,80,90,101,113, 127,144,162,182,203,226,255,255} ;
+ byte BETA_TABLE[52] = {0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,2,2,2,3, 3,3,3, 4, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9,10,10, 11,11,12,12,13,13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18} ;
+ byte CLIP_TAB[52][5] =
+ {
+ { 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0},{ 0, 0, 0, 1, 1},{ 0, 0, 0, 1, 1},{ 0, 0, 0, 1, 1},{ 0, 0, 0, 1, 1},{ 0, 0, 1, 1, 1},{ 0, 0, 1, 1, 1},{ 0, 1, 1, 1, 1},
+ { 0, 1, 1, 1, 1},{ 0, 1, 1, 1, 1},{ 0, 1, 1, 1, 1},{ 0, 1, 1, 2, 2},{ 0, 1, 1, 2, 2},{ 0, 1, 1, 2, 2},{ 0, 1, 1, 2, 2},{ 0, 1, 2, 3, 3},
+ { 0, 1, 2, 3, 3},{ 0, 2, 2, 3, 3},{ 0, 2, 2, 4, 4},{ 0, 2, 3, 4, 4},{ 0, 2, 3, 4, 4},{ 0, 3, 3, 5, 5},{ 0, 3, 4, 6, 6},{ 0, 3, 4, 6, 6},
+ { 0, 4, 5, 7, 7},{ 0, 4, 5, 8, 8},{ 0, 4, 6, 9, 9},{ 0, 5, 7,10,10},{ 0, 6, 8,11,11},{ 0, 6, 8,13,13},{ 0, 7,10,14,14},{ 0, 8,11,16,16},
+ { 0, 9,12,18,18},{ 0,10,13,20,20},{ 0,11,15,23,23},{ 0,13,17,25,25}
+ } ;
+
+
+ char chroma_edge[2][4][4] = //[dir][edge][yuv_format]
+ { { {-1, 0, 0, 0},
+ {-1,-1,-1, 1},
+ {-1, 1, 1, 2},
+ {-1,-1,-1, 3}},
+
+ { {-1, 0, 0, 0},
+ {-1,-1, 1, 1},
+ {-1, 1, 2, 2},
+ {-1,-1, 3, 3}}};
+
+
+ void GetStrength(byte Strength[16],ImageParameters *img,int MbQAddr,int dir,int edge, int mvlimit);
+ void EdgeLoop(imgpel** Img, byte Strength[16],ImageParameters *img, int MbQAddr, int AlphaC0Offset, int BetaOffset, int dir, int edge, int width, int yuv, int uv);
+ void DeblockMb(ImageParameters *img, imgpel **imgY, imgpel ***imgUV, int MbQAddr) ;
+
+
+ /*!
+ *****************************************************************************************
+ * \brief
+ * Filter all macroblocks in order of increasing macroblock address.
+ *****************************************************************************************
+ */
+ void DeblockFrame(ImageParameters *img, imgpel **imgY, imgpel ***imgUV)
+ {
+ unsigned i;
+
+ for (i=0; i<img->PicSizeInMbs; i++)
+ {
+ DeblockMb( img, imgY, imgUV, i ) ;
+ }
+ }
+
+
+ /*!
+ *****************************************************************************************
+ * \brief
+ * Deblocking filter for one macroblock.
+ *****************************************************************************************
+ */
+
+ void DeblockMb(ImageParameters *img, imgpel **imgY, imgpel ***imgUV, int MbQAddr)
+ {
+ int EdgeCondition;
+ int dir,edge;
+ byte Strength[16];
+ int mb_x, mb_y;
+
+ int filterNon8x8LumaEdgesFlag[4] = {1,1,1,1};
+ int filterLeftMbEdgeFlag;
+ int filterTopMbEdgeFlag;
+ int fieldModeMbFlag;
+ int mvlimit=4;
+ int i, StrengthSum;
+ Macroblock *MbQ;
+
+ int edge_cr; //ADD-VG-15052004
+
+ img->DeblockCall = 1;
+ get_mb_pos (MbQAddr, &mb_x, &mb_y);
+ filterLeftMbEdgeFlag = (mb_x != 0);
+ filterTopMbEdgeFlag = (mb_y != 0);
+
+ MbQ = &(img->mb_data[MbQAddr]) ; // current Mb
+
+ if (MbQ->mb_type == I8MB)
+ assert(MbQ->luma_transform_size_8x8_flag);
+
+ filterNon8x8LumaEdgesFlag[1] =
+ filterNon8x8LumaEdgesFlag[3] = !(MbQ->luma_transform_size_8x8_flag);
+
+ if (img->MbaffFrameFlag && mb_y==16 && MbQ->mb_field)
+ filterTopMbEdgeFlag = 0;
+
+ fieldModeMbFlag = (img->structure!=FRAME) || (img->MbaffFrameFlag && MbQ->mb_field);
+ if (fieldModeMbFlag)
+ mvlimit = 2;
+
+ // return, if filter is disabled
+ if (MbQ->LFDisableIdc==1) {
+ img->DeblockCall = 0;
+ return;
+ }
+
+ if (MbQ->LFDisableIdc==2)
+ {
+ // don't filter at slice boundaries
+ filterLeftMbEdgeFlag = MbQ->mbAvailA;
+ // if this the bottom of a frame macroblock pair then always filter the top edge
+ if (img->MbaffFrameFlag && !MbQ->mb_field && (MbQAddr % 2)) filterTopMbEdgeFlag = 1;
+ else filterTopMbEdgeFlag = MbQ->mbAvailB;
+ }
+
+ img->current_mb_nr = MbQAddr;
+ CheckAvailabilityOfNeighbors();
+
+ for( dir=0 ; dir<2 ; dir++ ) // vertical edges, than horicontal edges
+ {
+ EdgeCondition = (dir && filterTopMbEdgeFlag) || (!dir && filterLeftMbEdgeFlag); // can not filter beyond picture boundaries
+ for( edge=0 ; edge<4 ; edge++ ) // first 4 vertical strips of 16 pel
+ { // then 4 horicontal
+ if( edge || EdgeCondition )
+ {
+ edge_cr = chroma_edge[dir][edge][img->yuv_format];
+
+ GetStrength(Strength,img,MbQAddr,dir,edge, mvlimit); // Strength for 4 blks in 1 stripe
+ StrengthSum = Strength[0];
+ for (i = 1; i < 16; i++) StrengthSum += Strength[i];
+ if( StrengthSum ) // only if one of the 16 Strength bytes is != 0
+ {
+ if (filterNon8x8LumaEdgesFlag[edge])
+ EdgeLoop( imgY, Strength, img, MbQAddr, MbQ->LFAlphaC0Offset, MbQ->LFBetaOffset, dir, edge, img->width, 0, 0) ;
+ if( (imgUV != NULL) && (edge_cr >= 0))
+ {
+ EdgeLoop( imgUV[0], Strength, img, MbQAddr, MbQ->LFAlphaC0Offset, MbQ->LFBetaOffset, dir, edge_cr, img->width_cr, 1 , 0) ;
+ EdgeLoop( imgUV[1], Strength, img, MbQAddr, MbQ->LFAlphaC0Offset, MbQ->LFBetaOffset, dir, edge_cr, img->width_cr, 1 , 1) ;
+ }
+ }
+
+ if (dir && !edge && !MbQ->mb_field && mixedModeEdgeFlag) {
+ // this is the extra horizontal edge between a frame macroblock pair and a field above it
+ img->DeblockCall = 2;
+ GetStrength(Strength,img,MbQAddr,dir,4, mvlimit); // Strength for 4 blks in 1 stripe
+ //if( *((int*)Strength) ) // only if one of the 4 Strength bytes is != 0
+ {
+ if (filterNon8x8LumaEdgesFlag[edge])
+ EdgeLoop( imgY, Strength, img, MbQAddr, MbQ->LFAlphaC0Offset, MbQ->LFBetaOffset, dir, 4, img->width, 0, 0) ;
+ if( (imgUV != NULL) && (edge_cr >= 0))
+ {
+ EdgeLoop( imgUV[0], Strength, img, MbQAddr, MbQ->LFAlphaC0Offset, MbQ->LFBetaOffset, dir, 4, img->width_cr, 1, 0) ;
+ EdgeLoop( imgUV[1], Strength, img, MbQAddr, MbQ->LFAlphaC0Offset, MbQ->LFBetaOffset, dir, 4, img->width_cr, 1, 1) ;
+ }
+ }
+ img->DeblockCall = 1;
+ }
+
+ }
+ }//end edge
+ }//end loop dir
+ img->DeblockCall = 0;
+
+ }
+
+ /*!
+ *********************************************************************************************
+ * \brief
+ * returns a buffer of 16 Strength values for one stripe in a mb (for different Frame types)
+ *********************************************************************************************
+ */
+
+ int ININT_STRENGTH[4] = {0x04040404, 0x03030303, 0x03030303, 0x03030303} ;
+ byte BLK_NUM[2][4][4] = {{{0,4,8,12},{1,5,9,13},{2,6,10,14},{3,7,11,15}},{{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15}}} ;
+ byte BLK_4_TO_8[16] = {0,0,1,1,0,0,1,1,2,2,3,3,2,2,3,3} ;
+ #define ANY_INTRA (MbP->mb_type==I4MB||MbP->mb_type==I16MB||MbP->mb_type==IPCM||MbQ->mb_type==I4MB||MbQ->mb_type==I16MB||MbQ->mb_type==IPCM)
+
+ void GetStrength(byte Strength[16],ImageParameters *img,int MbQAddr,int dir,int edge, int mvlimit)
+ {
+ int blkP, blkQ, idx;
+ int blk_x, blk_x2, blk_y, blk_y2 ;
+ short ***list0_mv = enc_picture->mv[LIST_0];
+ short ***list1_mv = enc_picture->mv[LIST_1];
+ char **list0_refIdxArr = enc_picture->ref_idx[LIST_0];
+ char **list1_refIdxArr = enc_picture->ref_idx[LIST_1];
+ int64 **list0_refPicIdArr = enc_picture->ref_pic_id[LIST_0];
+ int64 **list1_refPicIdArr = enc_picture->ref_pic_id[LIST_1];
+ int xQ, xP, yQ, yP;
+ int mb_x, mb_y;
+ Macroblock *MbQ;
+ Macroblock *MbP;
+ PixelPos pixP;
+
+ MbQ = &(img->mb_data[MbQAddr]);
+
+ for( idx=0 ; idx<16 ; idx++ )
+ {
+ xQ = dir ? idx : edge << 2;
+ yQ = dir ? (edge < 4 ? edge << 2 : 1) : idx;
+ getNeighbour(MbQAddr, xQ - (1 - dir), yQ - dir, 1, &pixP);
+ xP = pixP.x;
+ yP = pixP.y;
+ MbP = &(img->mb_data[pixP.mb_addr]);
+ mixedModeEdgeFlag = MbQ->mb_field != MbP->mb_field;
+
+ blkQ = ((yQ>>2)<<2) + (xQ>>2);
+ blkP = ((yP>>2)<<2) + (xP>>2);
+
+ if ((img->type==SP_SLICE)||(img->type==SI_SLICE) )
+ {
+ Strength[idx] = (edge == 0 && (((!img->MbaffFrameFlag && (img->structure==FRAME)) ||
+ (img->MbaffFrameFlag && !MbP->mb_field && !MbQ->mb_field)) ||
+ ((img->MbaffFrameFlag || (img->structure!=FRAME)) && !dir))) ? 4 : 3;
+ }
+ else
+ {
+ // Start with Strength=3. or Strength=4 for Mb-edge
+ Strength[idx] = (edge == 0 && (((!img->MbaffFrameFlag && (img->structure==FRAME)) ||
+ (img->MbaffFrameFlag && !MbP->mb_field && !MbQ->mb_field)) ||
+ ((img->MbaffFrameFlag || (img->structure!=FRAME)) && !dir))) ? 4 : 3;
+
+ if( !(MbP->mb_type==I4MB || MbP->mb_type==I16MB || MbP->mb_type==IPCM || MbP->mb_type==I8MB)
+ && !(MbQ->mb_type==I4MB || MbQ->mb_type==I16MB || MbQ->mb_type==IPCM || MbQ->mb_type==I8MB) )
+ {
+ if( ((MbQ->cbp_blk & (1 << blkQ )) != 0) || ((MbP->cbp_blk & (1 << blkP)) != 0) )
+ Strength[idx] = 2 ;
+ else
+ { // if no coefs, but vector difference >= 1 set Strength=1
+ // if this is a mixed mode edge then one set of reference pictures will be frame and the
+ // other will be field
+ if (mixedModeEdgeFlag)
+ {
+ (Strength[idx] = 1);
+ }
+ else
+ {
+ get_mb_block_pos (MbQAddr, &mb_x, &mb_y);
+ blk_y = (mb_y<<2) + (blkQ >> 2) ;
+ blk_x = (mb_x<<2) + (blkQ & 3) ;
+ blk_y2 = pixP.pos_y >> 2;
+ blk_x2 = pixP.pos_x >> 2;
+ {
+ int64 ref_p0,ref_p1,ref_q0,ref_q1;
+ ref_p0 = list0_refIdxArr[blk_y][blk_x]<0 ? INT64_MIN : list0_refPicIdArr[blk_y][blk_x];
+ ref_q0 = list0_refIdxArr[blk_y2][blk_x2]<0 ? INT64_MIN : list0_refPicIdArr[blk_y2][blk_x2];
+ ref_p1 = list1_refIdxArr[blk_y][blk_x]<0 ? INT64_MIN : list1_refPicIdArr[blk_y][blk_x];
+ ref_q1 = list1_refIdxArr[blk_y2][blk_x2]<0 ? INT64_MIN : list1_refPicIdArr[blk_y2][blk_x2];
+ if ( ((ref_p0==ref_q0) && (ref_p1==ref_q1)) ||
+ ((ref_p0==ref_q1) && (ref_p1==ref_q0)))
+ {
+ Strength[idx]=0;
+ // L0 and L1 reference pictures of p0 are different; q0 as well
+ if (ref_p0 != ref_p1)
+ {
+ // compare MV for the same reference picture
+ if (ref_p0==ref_q0)
+ {
+ Strength[idx] =
+ ( (abs( list0_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4)
+ | (abs( list0_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit)
+ | (abs( list1_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4)
+ | (abs( list1_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit));
+ }
+ else
+ {
+ Strength[idx] =
+ ( (abs( list0_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4)
+ | (abs( list0_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit)
+ | (abs( list1_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4)
+ | (abs( list1_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit));
+ }
+ }
+ else
+ { // L0 and L1 reference pictures of p0 are the same; q0 as well
+
+ Strength[idx] =
+ ( (abs( list0_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4)
+ | (abs( list0_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit )
+ | (abs( list1_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4)
+ | (abs( list1_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit))
+ &&
+ ( (abs( list0_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4)
+ | (abs( list0_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit)
+ | (abs( list1_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4)
+ | (abs( list1_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit));
+ }
+ }
+ else
+ {
+ Strength[idx] = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ #define CQPOF(qp, uv) (Clip3(0, 51, qp + img->chroma_qp_offset[uv]))
+
+ /*!
+ *****************************************************************************************
+ * \brief
+ * Filters one edge of 16 (luma) or 8 (chroma) pel
+ *****************************************************************************************
+ */
+ void EdgeLoop(imgpel** Img, byte Strength[16],ImageParameters *img, int MbQAddr, int AlphaC0Offset, int BetaOffset,
+ int dir, int edge, int width, int yuv, int uv)
+ {
+ int pel, ap = 0, aq = 0, Strng ;
+ int incP, incQ;
+ int C0, c0, Delta, dif, AbsDelta ;
+ int L2 = 0, L1, L0, R0, R1, R2 = 0, RL0, L3, R3 ;
+ int Alpha = 0, Beta = 0 ;
+ byte* ClipTab = NULL;
+ int small_gap;
+ int indexA, indexB;
+ int PelNum;
+ int StrengthIdx;
+ imgpel *SrcPtrP, *SrcPtrQ;
+ int QP;
+ int xP, xQ, yP, yQ;
+ Macroblock *MbQ, *MbP;
+ PixelPos pixP, pixQ;
+ int bitdepth_scale;
+ int pelnum_cr[2][4] = {{0,8,16,16}, {0,8, 8,16}}; //[dir:0=vert, 1=hor.][yuv_format]
+
+ if (!yuv)
+ bitdepth_scale = 1<<(img->bitdepth_luma - 8);
+ else
+ bitdepth_scale = 1<<(img->bitdepth_chroma - 8);
+
+ PelNum = yuv ? pelnum_cr[dir][img->yuv_format] : 16 ;
+
+ for( pel=0 ; pel<PelNum ; pel++ )
+ {
+ xQ = dir ? pel : edge << 2;
+ yQ = dir ? (edge < 4 ? edge << 2 : 1) : pel;
+ getNeighbour(MbQAddr, xQ, yQ, 1-yuv, &pixQ);
+ getNeighbour(MbQAddr, xQ - (1 - dir), yQ - dir, 1-yuv, &pixP);
+ xP = pixP.x;
+ yP = pixP.y;
+ MbQ = &(img->mb_data[MbQAddr]);
+ MbP = &(img->mb_data[pixP.mb_addr]);
+ fieldModeFilteringFlag = MbQ->mb_field || MbP->mb_field;
+ StrengthIdx = (yuv&&(PelNum==8)) ? ((MbQ->mb_field && !MbP->mb_field) ? pel<<1 :((pel>>1)<<2)+(pel%2)) : pel;
+
+ if (pixP.available || (MbQ->LFDisableIdc== 0)) {
+ incQ = dir ? ((fieldModeFilteringFlag && !MbQ->mb_field) ? 2 * width : width) : 1;
+ incP = dir ? ((fieldModeFilteringFlag && !MbP->mb_field) ? 2 * width : width) : 1;
+ SrcPtrQ = &(Img[pixQ.pos_y][pixQ.pos_x]);
+ SrcPtrP = &(Img[pixP.pos_y][pixP.pos_x]);
+
+ // Average QP of the two blocks
+ QP = yuv ? (QP_SCALE_CR[CQPOF(MbP->qp,uv)] + QP_SCALE_CR[CQPOF(MbQ->qp,uv)] + 1) >> 1 : (MbP->qp + MbQ->qp + 1) >> 1;
+
+ indexA = IClip(0, MAX_QP, QP + AlphaC0Offset);
+ indexB = IClip(0, MAX_QP, QP + BetaOffset);
+
+ Alpha =ALPHA_TABLE[indexA] * bitdepth_scale;
+ Beta =BETA_TABLE[indexB] * bitdepth_scale;
+ ClipTab=CLIP_TAB[indexA];
+
+ L0 = SrcPtrP[0] ;
+ R0 = SrcPtrQ[0] ;
+ L1 = SrcPtrP[-incP] ;
+ R1 = SrcPtrQ[ incQ] ;
+ L2 = SrcPtrP[-incP*2] ;
+ R2 = SrcPtrQ[ incQ*2] ;
+ L3 = SrcPtrP[-incP*3] ;
+ R3 = SrcPtrQ[ incQ*3] ;
+
+ if( (Strng = Strength[StrengthIdx]) )
+ {
+ AbsDelta = abs( Delta = R0 - L0 ) ;
+
+ if( AbsDelta < Alpha )
+ {
+ C0 = ClipTab[ Strng ] * bitdepth_scale;
+ if( ((abs( R0 - R1) - Beta ) & (abs(L0 - L1) - Beta )) < 0 )
+ {
+ if( !yuv)
+ {
+ aq = (abs( R0 - R2) - Beta ) < 0 ;
+ ap = (abs( L0 - L2) - Beta ) < 0 ;
+ }
+
+ RL0 = L0 + R0 ;
+
+ if(Strng == 4 ) // INTRA strong filtering
+ {
+ if( yuv) // Chroma
+ {
+ SrcPtrQ[0] = ((R1 << 1) + R0 + L1 + 2) >> 2;
+ SrcPtrP[0] = ((L1 << 1) + L0 + R1 + 2) >> 2;
+ }
+ else // Luma
+ {
+ small_gap = (AbsDelta < ((Alpha >> 2) + 2));
+
+ aq &= small_gap;
+ ap &= small_gap;
+
+ SrcPtrQ[0] = aq ? ( L1 + ((R1 + RL0) << 1) + R2 + 4) >> 3 : ((R1 << 1) + R0 + L1 + 2) >> 2 ;
+ SrcPtrP[0] = ap ? ( R1 + ((L1 + RL0) << 1) + L2 + 4) >> 3 : ((L1 << 1) + L0 + R1 + 2) >> 2 ;
+
+ SrcPtrQ[ incQ] = aq ? ( R2 + R0 + R1 + L0 + 2) >> 2 : R1;
+ SrcPtrP[-incP] = ap ? ( L2 + L1 + L0 + R0 + 2) >> 2 : L1;
+
+ SrcPtrQ[ incQ*2] = aq ? (((R3 + R2) <<1) + R2 + R1 + RL0 + 4) >> 3 : R2;
+ SrcPtrP[-incP*2] = ap ? (((L3 + L2) <<1) + L2 + L1 + RL0 + 4) >> 3 : L2;
+ }
+ }
+ else // normal filtering
+ {
+ c0 = yuv? (C0+1):(C0 + ap + aq) ;
+ dif = IClip( -c0, c0, ( (Delta << 2) + (L1 - R1) + 4) >> 3 ) ;
+ if(!yuv)
+ {
+ SrcPtrP[0] = IClip(0, img->max_imgpel_value , L0 + dif) ;
+ SrcPtrQ[0] = IClip(0, img->max_imgpel_value , R0 - dif) ;
+ }
+ else
+ {
+ SrcPtrP[0] = IClip(0, img->max_imgpel_value_uv , L0 + dif) ;
+ SrcPtrQ[0] = IClip(0, img->max_imgpel_value_uv , R0 - dif) ;
+ }
+
+ if( !yuv )
+ {
+ if( ap )
+ SrcPtrP[-incP] += IClip( -C0, C0, ( L2 + ((RL0 + 1) >> 1) - (L1<<1)) >> 1 ) ;
+ if( aq )
+ SrcPtrQ[ incQ] += IClip( -C0, C0, ( R2 + ((RL0 + 1) >> 1) - (R1<<1)) >> 1 ) ;
+ } ;
+ } ;
+ } ;
+ } ;
+ } ;
+ } ;
+ }
+ }
+
Index: llvm-test/MultiSource/Applications/JM/lencod/macroblock.c
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/macroblock.c:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/macroblock.c Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,4435 ----
+
+ /*!
+ *************************************************************************************
+ * \file macroblock.c
+ *
+ * \brief
+ * Process one macroblock
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Inge Lille-Langoy <inge.lille-langoy at telenor.com>
+ * - Rickard Sjoberg <rickard.sjoberg at era.ericsson.se>
+ * - Jani Lainema <jani.lainema at nokia.com>
+ * - Sebastian Purreiter <sebastian.purreiter at mch.siemens.de>
+ * - Detlev Marpe <marpe at hhi.de>
+ * - Thomas Wedi <wedi at tnt.uni-hannover.de>
+ * - Ragip Kurceren <ragip.kurceren at nokia.com>
+ * - Alexis Michael Tourapis <alexismt at ieee.org>
+ *************************************************************************************
+ */
+
+ #include "contributors.h"
+
+ #include <stdlib.h>
+ #include <assert.h>
+ #include <limits.h>
+ #include <memory.h>
+
+ #include "global.h"
+
+ #include "elements.h"
+ #include "macroblock.h"
+ #include "refbuf.h"
+ #include "fmo.h"
+ #include "vlc.h"
+ #include "image.h"
+ #include "mb_access.h"
+ #include "ratectl.h" // head file for rate control
+ #include "cabac.h"
+ #include "transform8x8.h"
+
+ //Rate control
+ int predict_error,dq;
+ extern int DELTA_QP,DELTA_QP2;
+ extern int QP,QP2;
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * updates the coordinates for the next macroblock to be processed
+ *
+ * \param mb_addr
+ * macroblock address in scan order
+ ************************************************************************
+ */
+ void set_MB_parameters (int mb_addr)
+ {
+ img->current_mb_nr = mb_addr;
+
+ get_mb_block_pos(mb_addr, &img->mb_x, &img->mb_y);
+
+ img->block_x = img->mb_x << 2;
+ img->block_y = img->mb_y << 2;
+
+ img->pix_x = img->block_x << 2;
+ img->pix_y = img->block_y << 2;
+
+ img->opix_x = img->pix_x;
+
+ if (img->MbaffFrameFlag)
+ {
+ if (img->mb_data[mb_addr].mb_field)
+ {
+ imgY_org = (mb_addr % 2) ? imgY_org_bot : imgY_org_top;
+ imgUV_org = (mb_addr % 2) ? imgUV_org_bot : imgUV_org_top;
+ img->opix_y = (img->mb_y >> 1 ) << 4;
+ img->mb_data[mb_addr].list_offset = (mb_addr % 2) ? 4 : 2;
+ }
+ else
+ {
+ imgY_org = imgY_org_frm;
+ imgUV_org = imgUV_org_frm;
+ img->opix_y = img->block_y << 2;
+ img->mb_data[mb_addr].list_offset = 0;
+ }
+ }
+ else
+ {
+ img->opix_y = img->block_y << 2;
+ img->mb_data[mb_addr].list_offset = 0;
+ }
+
+ if (img->yuv_format != YUV400)
+ {
+ img->pix_c_x = (img->mb_cr_size_x * img->pix_x) >> 4;
+ img->pix_c_y = (img->mb_cr_size_y * img->pix_y) >> 4;
+
+ img->opix_c_x = (img->mb_cr_size_x * img->opix_x) >> 4;
+ img->opix_c_y = (img->mb_cr_size_y * img->opix_y) >> 4;
+ }
+ // printf ("set_MB_parameters: mb %d, mb_x %d, mb_y %d\n", mb_addr, img->mb_x, img->mb_y);
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * clip to range [0..max luma pel value]
+ ************************************************************************
+ */
+ int clip1a(int a)
+ {
+ return ((a)>img->max_imgpel_value?img->max_imgpel_value:((a)<0?0:(a)));
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * clip to range [0..max chroma pel value]
+ ************************************************************************
+ */
+ int clip1a_chr(int a)
+ {
+ return ((a)>img->max_imgpel_value_uv?img->max_imgpel_value_uv:((a)<0?0:(a)));
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * updates the coordinates and statistics parameter for the
+ * next macroblock
+ ************************************************************************
+ */
+ void proceed2nextMacroblock()
+ {
+ #if TRACE
+ int use_bitstream_backing = (input->slice_mode == FIXED_RATE || input->slice_mode == CALLBACK);
+ #endif
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ int* bitCount = currMB->bitcounter;
+ int i;
+
+ #if TRACE
+
+ if (p_trace)
+ {
+ fprintf(p_trace, "\n*********** Pic: %i (I/P) MB: %i Slice: %i **********\n\n", frame_no, img->current_mb_nr, img->current_slice_nr);
+ if(use_bitstream_backing)
+ fprintf(p_trace, "\n*********** Pic: %i (I/P) MB: %i Slice: %i **********\n\n", frame_no, img->current_mb_nr, img->current_slice_nr);
+ // Write out the tracestring for each symbol
+ for (i=0; i<currMB->currSEnr; i++)
+ trace2out(&(img->MB_SyntaxElements[i]));
+ }
+ #endif
+
+ // Update the statistics
+ stats->bit_use_mb_type[img->type] += bitCount[BITS_MB_MODE];
+ stats->bit_use_coeffY[img->type] += bitCount[BITS_COEFF_Y_MB] ;
+ stats->tmp_bit_use_cbp[img->type] += bitCount[BITS_CBP_MB];
+ stats->bit_use_coeffC[img->type] += bitCount[BITS_COEFF_UV_MB];
+ stats->bit_use_delta_quant[img->type] += bitCount[BITS_DELTA_QUANT_MB];
+
+ if (IS_INTRA(currMB))
+ {
+ ++stats->intra_chroma_mode[currMB->c_ipred_mode];
+
+ if ((currMB->cbp&15) != 0)
+ {
+ if (currMB->luma_transform_size_8x8_flag)
+ ++stats->mode_use_transform_8x8[img->type][currMB->mb_type];
+ else
+ ++stats->mode_use_transform_4x4[img->type][currMB->mb_type];
+ }
+ }
+
+ ++stats->mode_use[img->type][currMB->mb_type];
+ stats->bit_use_mode[img->type][currMB->mb_type]+= bitCount[BITS_INTER_MB];
+
+ if (img->type != I_SLICE)
+ {
+ if (currMB->mb_type == P8x8)
+ {
+ for(i=0;i<4;i++)
+ {
+ if (currMB->b8mode[i] > 0)
+ ++stats->mode_use[img->type][currMB->b8mode[i]];
+ else
+ ++stats->b8_mode_0_use[img->type][currMB->luma_transform_size_8x8_flag];
+
+ if (currMB->b8mode[i]==4)
+ {
+ if ((currMB->luma_transform_size_8x8_flag && (currMB->cbp&15) != 0) || input->Transform8x8Mode == 2)
+ ++stats->mode_use_transform_8x8[img->type][4];
+ else
+ ++stats->mode_use_transform_4x4[img->type][4];
+ }
+ }
+ }
+ else if (currMB->mb_type >= 0 && currMB->mb_type <=3 && ((currMB->cbp&15) != 0))
+ {
+ if (currMB->luma_transform_size_8x8_flag)
+ ++stats->mode_use_transform_8x8[img->type][currMB->mb_type];
+ else
+ ++stats->mode_use_transform_4x4[img->type][currMB->mb_type];
+ }
+ }
+
+ // Statistics
+ if ((img->type == P_SLICE)||(img->type==SP_SLICE) )
+ {
+ ++stats->quant0;
+ stats->quant1 += currMB->qp; // to find average quant for inter frames
+ }
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * initializes the current macroblock
+ *
+ * \param mb_addr
+ * macroblock address in scan order
+ * \param mb_field
+ * true for field macroblock coding
+ ************************************************************************
+ */
+ void start_macroblock(int mb_addr, int mb_field)
+ {
+ int i,j,l;
+ int use_bitstream_backing = (input->slice_mode == FIXED_RATE || input->slice_mode == CALLBACK);
+ Macroblock *currMB = &img->mb_data[mb_addr];
+ Slice *curr_slice = img->currentSlice;
+ DataPartition *dataPart;
+ Bitstream *currStream;
+ EncodingEnvironmentPtr eep;
+ int max_qp_delta = 25 + img->bitdepth_luma_qp_scale/2;
+ int min_qp_delta = (26 + img->bitdepth_luma_qp_scale/2);
+
+ currMB->mb_field = mb_field;
+
+ enc_picture->mb_field[mb_addr] = mb_field;
+
+ set_MB_parameters (mb_addr);
+
+ if(use_bitstream_backing)
+ {
+ // Keep the current state of the bitstreams
+ if(!img->cod_counter)
+ for (i=0; i<curr_slice->max_part_nr; i++)
+ {
+ dataPart = &(curr_slice->partArr[i]);
+ currStream = dataPart->bitstream;
+ currStream->stored_bits_to_go = currStream->bits_to_go;
+ currStream->stored_byte_pos = currStream->byte_pos;
+ currStream->stored_byte_buf = currStream->byte_buf;
+
+ if (input->symbol_mode ==CABAC)
+ {
+ eep = &(dataPart->ee_cabac);
+ eep->ElowS = eep->Elow;
+ eep->ErangeS = eep->Erange;
+ eep->EbufferS = eep->Ebuffer;
+ eep->Ebits_to_goS = eep->Ebits_to_go;
+ eep->Ebits_to_followS = eep->Ebits_to_follow;
+ eep->EcodestrmS = eep->Ecodestrm;
+ eep->Ecodestrm_lenS = eep->Ecodestrm_len;
+ eep->CS = eep->C;
+ eep->ES = eep->E;
+ }
+ }
+ }
+
+ // Save the slice number of this macroblock. When the macroblock below
+ // is coded it will use this to decide if prediction for above is possible
+ currMB->slice_nr = img->current_slice_nr;
+
+ // Initialize delta qp change from last macroblock. Feature may be used for future rate control
+ // Rate control
+ currMB->qpsp = img->qpsp;
+ if(input->RCEnable)
+ {
+ int prev_mb = FmoGetPreviousMBNr(img->current_mb_nr);
+ if (prev_mb>-1)
+ {
+ currMB->prev_qp = img->mb_data[prev_mb].qp;
+ if (img->mb_data[prev_mb].slice_nr == img->current_slice_nr)
+ {
+ currMB->prev_delta_qp = img->mb_data[prev_mb].delta_qp;
+ }
+ else
+ {
+ currMB->prev_delta_qp = 0;
+ }
+ }
+ else
+ {
+ currMB->prev_qp = curr_slice->qp;
+ currMB->prev_delta_qp = 0;
+ }
+ // frame layer rate control
+ if(input->basicunit==img->Frame_Total_Number_MB)
+ {
+ currMB->delta_qp = 0;
+ currMB->qp = img->qp;
+ }
+ // basic unit layer rate control
+ else
+ {
+ // each I or B frame has only one QP
+ if((img->type==I_SLICE)||(img->type==B_SLICE))
+ {
+ currMB->delta_qp = 0;
+ currMB->qp = img->qp;
+ }
+ else if(img->type==P_SLICE)
+ {
+ if (!img->write_macroblock) //write macroblock
+ {
+ if (!currMB->mb_field) //frame macroblock
+ {
+ if (img->current_mb_nr == 0) //first macroblock
+ {
+ // Initialize delta qp change from last macroblock. Feature may be used for future rate control
+ currMB->delta_qp = 0;
+ currMB->qp = img->qp;
+ DELTA_QP = DELTA_QP2 = currMB->delta_qp;
+ QP = QP2 = currMB->qp;
+ }
+ else
+ {
+ if (!((input->MbInterlace) && img->bot_MB)) //top macroblock
+ {
+ if (img->mb_data[img->current_mb_nr-1].prev_cbp == 1)
+ {
+ currMB->delta_qp = 0;
+ currMB->qp = img->qp;
+ }
+ else
+ {
+ currMB->qp = img->mb_data[img->current_mb_nr-1].prev_qp;
+ currMB->delta_qp = currMB->qp - img->mb_data[img->current_mb_nr-1].qp;
+ img->qp = currMB->qp;
+ }
+ DELTA_QP = DELTA_QP2 = currMB->delta_qp;
+ QP = QP2 = currMB->qp;
+ }
+ else //bottom macroblock
+ {
+ // Initialize delta qp change from last macroblock. Feature may be used for future rate control
+ currMB->delta_qp = 0;
+ currMB->qp = img->qp; // needed in loop filter (even if constant QP is used)
+ }
+ }
+ }
+ else // field macroblock
+ {
+ if (!img->bot_MB) //top macroblock
+ {
+ currMB->delta_qp = DELTA_QP2;
+ currMB->qp = img->qp = QP2;
+ }
+ else // bottom macroblock
+ {
+ currMB->qp = img->qp;
+ currMB->delta_qp = 0;
+ }
+ }
+ }
+ else
+ {
+ if (!img->bot_MB) //write top macroblock
+ {
+ if (img->write_macroblock_frame)
+ {
+ currMB->delta_qp = DELTA_QP;
+ img->qp = currMB->qp = QP;
+ }
+ else
+ {
+ currMB->delta_qp = DELTA_QP2;
+ img->qp = currMB->qp = QP2;
+ }
+ }
+ else //write bottom macroblock
+ {
+ currMB->delta_qp = 0;
+ currMB->qp = img->qp;
+ }
+ }
+
+ // compute the quantization parameter for each basic unit of P frame
+ if(!((input->MbInterlace)&&img->bot_MB))
+ {
+ if(!currMB->mb_field)
+ {
+ if((img->NumberofCodedMacroBlocks>0)\
+ &&(img->NumberofCodedMacroBlocks%img->BasicUnit==0))
+ {
+ // frame coding
+ if(active_sps->frame_mbs_only_flag)
+ {
+ updateRCModel();
+ img->BasicUnitQP=updateQuantizationParameter(img->TopFieldFlag);
+ }
+ // adaptive field/frame coding
+ else if((input->PicInterlace==ADAPTIVE_CODING)&&(!input->MbInterlace)&&(img->IFLAG==0))
+ {
+ updateRCModel();
+ img->BasicUnitQP=updateQuantizationParameter(img->TopFieldFlag);
+ }
+ // field coding
+ else if((input->PicInterlace==FIELD_CODING)&&(!input->MbInterlace)&&(img->IFLAG==0))
+ {
+ updateRCModel();
+ img->BasicUnitQP=updateQuantizationParameter(img->TopFieldFlag);
+ }
+ // mb adaptive f/f coding, field coding
+ else if((input->MbInterlace)&&(img->IFLAG==0)&&(img->FieldControl==1))
+ {
+ updateRCModel();
+ img->BasicUnitQP=updateQuantizationParameter(img->TopFieldFlag);
+ }
+ // mb adaptive f/f coding, frame coding
+ else if((input->MbInterlace)&&(img->IFLAG==0)&&(img->FieldControl==0))
+ {
+ updateRCModel();
+ img->BasicUnitQP=updateQuantizationParameter(img->TopFieldFlag);
+ }
+ }
+
+ if(img->current_mb_nr==0)
+ img->BasicUnitQP=img->qp;
+
+ currMB->predict_qp=img->BasicUnitQP;
+
+ if(currMB->predict_qp>currMB->qp + max_qp_delta)
+ currMB->predict_qp=currMB->qp + max_qp_delta;
+ else if(currMB->predict_qp<currMB->qp - min_qp_delta)
+ currMB->predict_qp=currMB->qp - min_qp_delta;
+
+ dq = currMB->delta_qp + currMB->predict_qp-currMB->qp;
+ if(dq < -min_qp_delta)
+ {
+ dq = -min_qp_delta;
+ predict_error = dq-currMB->delta_qp;
+ img->qp = img->qp+predict_error;
+ currMB->delta_qp = -min_qp_delta;
+ }
+ else if(dq > max_qp_delta)
+ {
+ dq = max_qp_delta;
+ predict_error = dq - currMB->delta_qp;
+ img->qp = img->qp + predict_error;
+ currMB->delta_qp = max_qp_delta;
+ }
+ else
+ {
+ currMB->delta_qp = dq;
+ predict_error=currMB->predict_qp-currMB->qp;
+ img->qp = currMB->predict_qp;
+ }
+ currMB->qp = img->qp;
+ if (input->MbInterlace)
+ {
+ DELTA_QP = DELTA_QP2 = currMB->delta_qp;
+ QP = QP2 = currMB->qp;
+ DELTA_QP2 = currMB->delta_qp;
+ }
+ currMB->predict_error=predict_error;
+ }
+ else
+ predict_error=currMB->predict_error;
+ }
+ else
+ currMB->prev_qp=img->qp;
+ }
+ }
+ }
+ else
+ {
+ Slice* currSlice = img->currentSlice;
+
+ int prev_mb = FmoGetPreviousMBNr(img->current_mb_nr);
+ if (prev_mb>-1)
+ {
+ currMB->prev_qp = img->mb_data[prev_mb].qp;
+ if (img->mb_data[prev_mb].slice_nr == img->current_slice_nr)
+ {
+ currMB->prev_delta_qp = img->mb_data[prev_mb].delta_qp;
+ }
+ else
+ {
+ currMB->prev_delta_qp = 0;
+ }
+ }
+ else
+ {
+ currMB->prev_qp = currSlice->qp;
+ currMB->prev_delta_qp = 0;
+ }
+
+ currMB->qp = currSlice->qp ;
+
+ currMB->delta_qp = currMB->qp - currMB->prev_qp;
+ DELTA_QP = DELTA_QP2 = currMB->delta_qp;
+ QP = QP2 = currMB->qp;
+ }
+ // Initialize counter for MB symbols
+ currMB->currSEnr=0;
+
+ // loop filter parameter
+ if (active_pps->deblocking_filter_control_present_flag)
+ {
+ currMB->LFDisableIdc = img->LFDisableIdc;
+ currMB->LFAlphaC0Offset = img->LFAlphaC0Offset;
+ currMB->LFBetaOffset = img->LFBetaOffset;
+ }
+ else
+ {
+ currMB->LFDisableIdc = 0;
+ currMB->LFAlphaC0Offset = 0;
+ currMB->LFBetaOffset = 0;
+ }
+
+ // If MB is next to a slice boundary, mark neighboring blocks unavailable for prediction
+ CheckAvailabilityOfNeighbors();
+
+ if (input->symbol_mode == CABAC)
+ CheckAvailabilityOfNeighborsCABAC();
+
+ // Reset vectors and reference indices before doing motion search in motion_search().
+ for (l=0; l<2; l++)
+ {
+ for (j=img->block_y; j < img->block_y + BLOCK_MULTIPLE; j++)
+ {
+ memset(&enc_picture->ref_idx[l][j][img->block_x], -1, BLOCK_MULTIPLE * sizeof(char));
+ memset(enc_picture->mv [l][j][img->block_x], 0, 2 * BLOCK_MULTIPLE * sizeof(short));
+ for (i=img->block_x; i < img->block_x + BLOCK_MULTIPLE; i++)
+ enc_picture->ref_pic_id[l][j][i]= -1;
+ }
+ }
+
+ // Reset syntax element entries in MB struct
+ currMB->mb_type = 0;
+ currMB->cbp_blk = 0;
+ currMB->cbp = 0;
+ currMB->cbp_bits = 0;
+ currMB->c_ipred_mode = DC_PRED_8;
+
+ memset (currMB->mvd, 0, BLOCK_CONTEXT * sizeof(int));
+ memset (currMB->intra_pred_modes, DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char)); // changing this to char would allow us to use memset
+ memset (currMB->intra_pred_modes8x8, DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char));
+
+ //initialize the whole MB as INTRA coded
+ //Blocks ar set to notINTRA in write_one_macroblock
+ if (input->UseConstrainedIntraPred)
+ {
+ img->intra_block[img->current_mb_nr] = 1;
+ }
+
+ // Initialize bitcounters for this macroblock
+ if(img->current_mb_nr == 0) // No slice header to account for
+ {
+ currMB->bitcounter[BITS_HEADER] = 0;
+ }
+ else if (currMB->slice_nr == img->mb_data[img->current_mb_nr-1].slice_nr) // current MB belongs to the
+ // same slice as the last MB
+ {
+ currMB->bitcounter[BITS_HEADER] = 0;
+ }
+
+ currMB->bitcounter[BITS_MB_MODE ] = 0;
+ currMB->bitcounter[BITS_COEFF_Y_MB ] = 0;
+ currMB->bitcounter[BITS_INTER_MB ] = 0;
+ currMB->bitcounter[BITS_CBP_MB ] = 0;
+ currMB->bitcounter[BITS_DELTA_QUANT_MB] = 0;
+ currMB->bitcounter[BITS_COEFF_UV_MB ] = 0;
+
+ #ifdef _FAST_FULL_ME_
+ // if(input->FMEnable != 0 && input->FMEnable != 3)
+ if(!input->FMEnable)
+ ResetFastFullIntegerSearch ();
+ #endif
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * terminates processing of the current macroblock depending
+ * on the chosen slice mode
+ ************************************************************************
+ */
+ void terminate_macroblock( Boolean *end_of_slice, //!< returns true for last macroblock of a slice, otherwise false
+ Boolean *recode_macroblock //!< returns true if max. slice size is exceeded an macroblock must be recoded in next slice
+ )
+ {
+ int i;
+ Slice *currSlice = img->currentSlice;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ SyntaxElement *currSE = &img->MB_SyntaxElements[currMB->currSEnr];
+ int *partMap = assignSE2partition[input->partition_mode];
+ DataPartition *dataPart;
+ Bitstream *currStream;
+ int rlc_bits=0;
+ EncodingEnvironmentPtr eep;
+ int use_bitstream_backing = (input->slice_mode == FIXED_RATE || input->slice_mode == CALLBACK);
+ int new_slice;
+ static int skip = FALSE;
+
+
+ // if previous mb in the same slice group has different slice number as the current, it's the
+ // the start of new slice
+ new_slice=0;
+ if ( (img->current_mb_nr==0) || (FmoGetPreviousMBNr(img->current_mb_nr)<0) )
+ new_slice=1;
+ else if( img->mb_data[FmoGetPreviousMBNr(img->current_mb_nr)].slice_nr != img->current_slice_nr )
+ new_slice=1;
+
+ *recode_macroblock=FALSE;
+
+ switch(input->slice_mode)
+ {
+ case NO_SLICES:
+ currSlice->num_mb++;
+ *recode_macroblock = FALSE;
+ if ((currSlice->num_mb) == (int)img->PicSizeInMbs) // maximum number of MBs reached
+ *end_of_slice = TRUE;
+
+ // if it's end of current slice group, slice ends too
+ *end_of_slice |= (img->current_mb_nr == FmoGetLastCodedMBOfSliceGroup (FmoMB2SliceGroup (img->current_mb_nr)));
+
+ break;
+ case FIXED_MB:
+ // For slice mode one, check if a new slice boundary follows
+ currSlice->num_mb++;
+ *recode_macroblock = FALSE;
+ //! Check end-of-slice group condition first
+ *end_of_slice = (img->current_mb_nr == FmoGetLastCodedMBOfSliceGroup (FmoMB2SliceGroup (img->current_mb_nr)));
+ //! Now check maximum # of MBs in slice
+ *end_of_slice |= (currSlice->num_mb >= input->slice_argument);
+
+ break;
+
+ // For slice modes two and three, check if coding of this macroblock
+ // resulted in too many bits for this slice. If so, indicate slice
+ // boundary before this macroblock and code the macroblock again
+ case FIXED_RATE:
+ // in case of skip MBs check if there is a slice boundary
+ // only for UVLC (img->cod_counter is always 0 in case of CABAC)
+ if(img->cod_counter)
+ {
+ // write out the skip MBs to know how many bits we need for the RLC
+ currSE->value1 = img->cod_counter;
+ currSE->value2 = 0;
+ currSE->mapping = ue_linfo;
+ currSE->type = SE_MBTYPE;
+ dataPart = &(currSlice->partArr[partMap[currSE->type]]);
+
+ dataPart->writeSyntaxElement( currSE, dataPart);
+ rlc_bits=currSE->len;
+
+ currStream = dataPart->bitstream;
+ // save the bitstream as it would be if we write the skip MBs
+ currStream->bits_to_go_skip = currStream->bits_to_go;
+ currStream->byte_pos_skip = currStream->byte_pos;
+ currStream->byte_buf_skip = currStream->byte_buf;
+ // restore the bitstream
+ currStream->bits_to_go = currStream->stored_bits_to_go;
+ currStream->byte_pos = currStream->stored_byte_pos;
+ currStream->byte_buf = currStream->stored_byte_buf;
+ skip = TRUE;
+ }
+ //! Check if the last coded macroblock fits into the size of the slice
+ //! But only if this is not the first macroblock of this slice
+ if (!new_slice)
+ {
+ if(slice_too_big(rlc_bits))
+ {
+ *recode_macroblock = TRUE;
+ *end_of_slice = TRUE;
+ }
+ else if(!img->cod_counter)
+ skip = FALSE;
+ }
+ // maximum number of MBs
+
+ // check if current slice group is finished
+ if ((*recode_macroblock == FALSE) && (img->current_mb_nr == FmoGetLastCodedMBOfSliceGroup (FmoMB2SliceGroup (img->current_mb_nr))))
+ {
+ *end_of_slice = TRUE;
+ if(!img->cod_counter)
+ skip = FALSE;
+ }
+
+ //! (first MB OR first MB in a slice) AND bigger that maximum size of slice
+ if (new_slice && slice_too_big(rlc_bits))
+ {
+ *end_of_slice = TRUE;
+ if(!img->cod_counter)
+ skip = FALSE;
+ }
+ if (!*recode_macroblock)
+ currSlice->num_mb++;
+ break;
+
+ case CALLBACK:
+ if (img->current_mb_nr > 0 && !new_slice)
+ {
+ if (currSlice->slice_too_big(rlc_bits))
+ {
+ *recode_macroblock = TRUE;
+ *end_of_slice = TRUE;
+ }
+ }
+
+ if ( (*recode_macroblock == FALSE) && (img->current_mb_nr == FmoGetLastCodedMBOfSliceGroup (FmoMB2SliceGroup (img->current_mb_nr))))
+ *end_of_slice = TRUE;
+ break;
+
+ default:
+ snprintf(errortext, ET_SIZE, "Slice Mode %d not supported", input->slice_mode);
+ error(errortext, 600);
+ }
+
+ if(*recode_macroblock == TRUE)
+ {
+ // Restore everything
+ for (i=0; i<currSlice->max_part_nr; i++)
+ {
+ dataPart = &(currSlice->partArr[i]);
+ currStream = dataPart->bitstream;
+ currStream->bits_to_go = currStream->stored_bits_to_go;
+ currStream->byte_pos = currStream->stored_byte_pos;
+ currStream->byte_buf = currStream->stored_byte_buf;
+ if (input->symbol_mode == CABAC)
+ {
+ eep = &(dataPart->ee_cabac);
+ eep->Elow = eep->ElowS;
+ eep->Erange = eep->ErangeS;
+ eep->Ebuffer = eep->EbufferS;
+ eep->Ebits_to_go = eep->Ebits_to_goS;
+ eep->Ebits_to_follow = eep->Ebits_to_followS;
+ eep->Ecodestrm = eep->EcodestrmS;
+ eep->Ecodestrm_len = eep->Ecodestrm_lenS;
+ eep->C = eep->CS;
+ eep->E = eep->ES;
+ }
+ }
+ }
+
+ if(*end_of_slice == TRUE && skip == TRUE) //! TO 4.11.2001 Skip MBs at the end of this slice
+ {
+ //! only for Slice Mode 2 or 3
+ // If we still have to write the skip, let's do it!
+ if(img->cod_counter && *recode_macroblock == TRUE) //! MB that did not fit in this slice
+ {
+ // If recoding is true and we have had skip,
+ // we have to reduce the counter in case of recoding
+ img->cod_counter--;
+ if(img->cod_counter)
+ {
+ currSE->value1 = img->cod_counter;
+ currSE->value2 = 0;
+ currSE->mapping = ue_linfo;
+ currSE->type = SE_MBTYPE;
+ dataPart = &(currSlice->partArr[partMap[currSE->type]]);
+ dataPart->writeSyntaxElement( currSE, dataPart);
+ rlc_bits=currSE->len;
+ currMB->bitcounter[BITS_MB_MODE]+=rlc_bits;
+ img->cod_counter = 0;
+ }
+ }
+ else //! MB that did not fit in this slice anymore is not a Skip MB
+ {
+ dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);
+ currStream = dataPart->bitstream;
+ // update the bitstream
+ currStream->bits_to_go = currStream->bits_to_go_skip;
+ currStream->byte_pos = currStream->byte_pos_skip;
+ currStream->byte_buf = currStream->byte_buf_skip;
+
+ // update the statistics
+ img->cod_counter = 0;
+ skip = FALSE;
+ }
+ }
+
+ //! TO 4.11.2001 Skip MBs at the end of this slice for Slice Mode 0 or 1
+ if(*end_of_slice == TRUE && img->cod_counter && !use_bitstream_backing)
+ {
+ currSE->value1 = img->cod_counter;
+ currSE->value2 = 0;
+ currSE->mapping = ue_linfo;
+ currSE->type = SE_MBTYPE;
+ dataPart = &(currSlice->partArr[partMap[currSE->type]]);
+ dataPart->writeSyntaxElement( currSE, dataPart);
+ currMB->currSEnr ++;
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "Final MB runlength = %3d",img->cod_counter);
+ #endif
+
+ rlc_bits=currSE->len;
+ currMB->bitcounter[BITS_MB_MODE]+=rlc_bits;
+ img->cod_counter = 0;
+ }
+ }
+
+ /*!
+ *****************************************************************************
+ *
+ * \brief
+ * For Slice Mode 2: Checks if one partition of one slice exceeds the
+ * allowed size
+ *
+ * \return
+ * FALSE if all Partitions of this slice are smaller than the allowed size
+ * TRUE is at least one Partition exceeds the limit
+ *
+ * \par Side effects
+ * none
+ *
+ * \date
+ * 4 November 2001
+ *
+ * \author
+ * Tobias Oelbaum drehvial at gmx.net
+ *****************************************************************************/
+
+ int slice_too_big(int rlc_bits)
+ {
+ Slice *currSlice = img->currentSlice;
+ DataPartition *dataPart;
+ Bitstream *currStream;
+ EncodingEnvironmentPtr eep;
+ int i;
+ int size_in_bytes;
+
+ //! UVLC
+ if (input->symbol_mode == UVLC)
+ {
+ for (i=0; i<currSlice->max_part_nr; i++)
+ {
+ dataPart = &(currSlice->partArr[i]);
+ currStream = dataPart->bitstream;
+ size_in_bytes = currStream->byte_pos /*- currStream->tmp_byte_pos*/;
+
+ if (currStream->bits_to_go < 8)
+ size_in_bytes++;
+ if (currStream->bits_to_go < rlc_bits)
+ size_in_bytes++;
+ if(size_in_bytes > input->slice_argument)
+ return TRUE;
+ }
+ }
+
+ //! CABAC
+ if (input->symbol_mode ==CABAC)
+ {
+ for (i=0; i<currSlice->max_part_nr; i++)
+ {
+ dataPart= &(currSlice->partArr[i]);
+ eep = &(dataPart->ee_cabac);
+
+ if( arienco_bits_written(eep) > (input->slice_argument*8))
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+
+ static pel_t *(*get_line) (pel_t**, int, int, int, int);
+ /*!
+ ************************************************************************
+ * \brief
+ * Predict one component of a 4x4 Luma block
+ ************************************************************************
+ */
+ void OneComponentLumaPrediction4x4 ( int* mpred, //!< array of prediction values (row by row)
+ int pic_pix_x, //!< absolute horizontal coordinate of 4x4 block
+ int pic_pix_y, //!< absolute vertical coordinate of 4x4 block
+ short* mv, //!< motion vector
+ short ref, //!< reference frame
+ StorablePicture **list //!< reference picture list
+ )
+ {
+ pel_t** ref_pic = list[ref]->imgY_ups;
+ int j0 = (pic_pix_y << 2) + mv[1] + IMG_PAD_SIZE_TIMES4;
+ int i0 = (pic_pix_x << 2) + mv[0] + IMG_PAD_SIZE_TIMES4;
+ int j;
+ pel_t *ref_line;
+
+ int img_width =((list[ref]->size_x + 2*IMG_PAD_SIZE - 1)<<2);
+ int img_height=((list[ref]->size_y + 2*IMG_PAD_SIZE - 1)<<2);
+
+ if ((i0 > 0) && (i0 < img_width - 4*BLOCK_SIZE - 1) && (j0 > 0) && (j0 < img_height - 4*BLOCK_SIZE - 1))
+ get_line = FastLine4X;
+ else
+ get_line = UMVLine4X;
+
+ for (j = j0; j < j0 + MB_BLOCK_SIZE; j+=BLOCK_SIZE)
+ {
+ ref_line = get_line (ref_pic, j, i0, img_height, img_width);
+ *mpred++ = *ref_line;
+ *mpred++ = *(ref_line + 4);
+ *mpred++ = *(ref_line + 8);
+ *mpred++ = *(ref_line + 12);
+ }
+
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * copy foward/backward prediction values of one component of a 4x4 Luma block
+ ************************************************************************
+ */
+ void copyblock4x4 ( int* mpred, //!< array of prediction values (row by row)
+ int block[BLOCK_SIZE][BLOCK_SIZE] //!< target block
+ )
+ {
+ *mpred++ = block[0][0];
+ *mpred++ = block[1][0];
+ *mpred++ = block[2][0];
+ *mpred++ = block[3][0];
+ *mpred++ = block[0][1];
+ *mpred++ = block[1][1];
+ *mpred++ = block[2][1];
+ *mpred++ = block[3][1];
+ *mpred++ = block[0][2];
+ *mpred++ = block[1][2];
+ *mpred++ = block[2][2];
+ *mpred++ = block[3][2];
+ *mpred++ = block[0][3];
+ *mpred++ = block[1][3];
+ *mpred++ = block[2][3];
+ *mpred++ = block[3][3];
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Predict one 4x4 Luma block
+ ************************************************************************
+ */
+ void LumaPrediction4x4 ( int block_x, //!< relative horizontal block coordinate of 4x4 block
+ int block_y, //!< relative vertical block coordinate of 4x4 block
+ int p_dir, //!< prediction direction (0=list0, 1=list1, 2=bipred)
+ int fw_mode, //!< list0 prediction mode (1-7, 0=DIRECT if bw_mode=0)
+ int bw_mode, //!< list1 prediction mode (1-7, 0=DIRECT if fw_mode=0)
+ short fw_ref_idx, //!< reference frame for list0 prediction (-1: Intra4x4 pred. with fw_mode)
+ short bw_ref_idx //!< reference frame for list1 prediction
+ )
+ {
+ static int fw_pred[16];
+ static int bw_pred[16];
+
+ int i, j;
+ int block_x4 = block_x+4;
+ int block_y4 = block_y+4;
+ int pic_opix_x = img->opix_x + block_x;
+ int pic_opix_y = img->opix_y + block_y;
+ int bx = block_x >> 2;
+ int by = block_y >> 2;
+ int* fpred = fw_pred;
+ int* bpred = bw_pred;
+ Macroblock* currMB = &img->mb_data[img->current_mb_nr];
+
+ int apply_weights = ( (active_pps->weighted_pred_flag && (img->type== P_SLICE || img->type == SP_SLICE)) ||
+ (active_pps->weighted_bipred_idc && (img->type== B_SLICE)));
+ short**** mv_array = img->all_mv[by][bx];
+
+
+ if (currMB->bi_pred_me && fw_ref_idx == 0 && bw_ref_idx == 0 && p_dir == 2 && fw_mode==1 && bw_mode==1)
+ {
+ mv_array = currMB->bi_pred_me == 1? img->bipred_mv1[by][bx] : img->bipred_mv2[by][bx];
+ }
+
+ if ((p_dir==0)||(p_dir==2))
+ {
+ OneComponentLumaPrediction4x4 (fw_pred, pic_opix_x, pic_opix_y, mv_array[LIST_0][fw_ref_idx][fw_mode], fw_ref_idx, listX[0+currMB->list_offset]);
+ }
+
+ if ((p_dir==1)||(p_dir==2))
+ {
+ OneComponentLumaPrediction4x4 (bw_pred, pic_opix_x, pic_opix_y, mv_array[LIST_1][bw_ref_idx][bw_mode], bw_ref_idx, listX[1+currMB->list_offset]);
+ }
+
+ if (apply_weights)
+ {
+
+ if (p_dir==2)
+ {
+ for (j=block_y; j<block_y4; j++)
+ for (i=block_x; i<block_x4; i++)
+ img->mpr[j][i] = clip1a(((wbp_weight[0][fw_ref_idx][bw_ref_idx][0] * *fpred++ +
+ wbp_weight[1][fw_ref_idx][bw_ref_idx][0] * *bpred++ +
+ 2*wp_luma_round) >> (luma_log_weight_denom + 1)) +
+ ((wp_offset[0][fw_ref_idx][0] + wp_offset[1][bw_ref_idx][0] + 1)>>1));
+ }
+ else if (p_dir==0)
+ {
+ for (j=block_y; j<block_y4; j++)
+ for (i=block_x; i<block_x4; i++)
+ img->mpr[j][i] = clip1a(((wp_weight[0][fw_ref_idx][0] * *fpred++ + wp_luma_round) >> luma_log_weight_denom) +
+ wp_offset[0][fw_ref_idx][0] );
+ }
+ else // p_dir==1
+ {
+ for (j=block_y; j<block_y4; j++)
+ for (i=block_x; i<block_x4; i++)
+ img->mpr[j][i] = clip1a(((wp_weight[1][bw_ref_idx][0] * *bpred++ + wp_luma_round) >> luma_log_weight_denom) +
+ wp_offset[1][bw_ref_idx][0] );
+ }
+ }
+ else
+ {
+ if (p_dir==2)
+ {
+ for (j=block_y; j<block_y4; j++)
+ for (i=block_x; i<block_x4; i++)
+ img->mpr[j][i] = (*fpred++ + *bpred++ + 1) >> 1;
+ }
+ else if (p_dir==0)
+ {
+ for (j=block_y; j<block_y4; j++)
+ for (i=block_x; i<block_x4; i++)
+ img->mpr[j][i] = *fpred++;
+ }
+ else // p_dir==1
+ {
+ for (j=block_y; j<block_y4; j++)
+ for (i=block_x; i<block_x4; i++)
+ img->mpr[j][i] = *bpred++;
+ }
+ }
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Predict one 4x4 Luma block
+ ************************************************************************
+ */
+ void LumaPrediction4x4Bi ( int block_x, //!< relative horizontal block coordinate of 4x4 block
+ int block_y, //!< relative vertical block coordinate of 4x4 block
+ int p_dir, //!< prediction direction (0=list0, 1=list1, 2=bidir)
+ int fw_mode, //!< list0 prediction mode (1-7, 0=DIRECT if bw_mode=0)
+ int bw_mode, //!< list1 prediction mode (1-7, 0=DIRECT if fw_mode=0)
+ short fw_ref_idx, //!< reference frame for list0 prediction (-1: Intra4x4 pred. with fw_mode)
+ short bw_ref_idx, //!< reference frame for list1 prediction
+ int list //!< current list for prediction.
+ )
+ {
+ static int fw_pred[16];
+ static int bw_pred[16];
+
+ int i, j;
+ int block_x4 = block_x+4;
+ int block_y4 = block_y+4;
+ int pic_opix_x = img->opix_x + block_x;
+ int pic_opix_y = img->opix_y + block_y;
+ int bx = block_x >> 2;
+ int by = block_y >> 2;
+ int* fpred = fw_pred;
+ int* bpred = bw_pred;
+ Macroblock* currMB = &img->mb_data[img->current_mb_nr];
+
+ int apply_weights = ( (active_pps->weighted_pred_flag && (img->type == P_SLICE || img->type == SP_SLICE)) ||
+ (active_pps->weighted_bipred_idc && (img->type == B_SLICE)));
+ short ****mv_array = list ? img->bipred_mv1[by][bx] : img->bipred_mv2[by][bx];
+
+
+ if ((p_dir==0)||(p_dir==2))
+ {
+ OneComponentLumaPrediction4x4 (fw_pred, pic_opix_x, pic_opix_y, mv_array[LIST_0][fw_ref_idx][fw_mode], fw_ref_idx, listX[0+currMB->list_offset]);
+ }
+
+ if ((p_dir==1)||(p_dir==2))
+ {
+ OneComponentLumaPrediction4x4 (bw_pred, pic_opix_x, pic_opix_y, mv_array[LIST_1][bw_ref_idx][bw_mode], bw_ref_idx, listX[1+currMB->list_offset]);
+ }
+
+ if (apply_weights)
+ {
+ if (p_dir==2)
+ {
+ for (j=block_y; j<block_y4; j++)
+ for (i=block_x; i<block_x4; i++)
+ img->mpr[j][i] = clip1a(((wbp_weight[0][fw_ref_idx][bw_ref_idx][0] * *fpred++ +
+ wbp_weight[1][fw_ref_idx][bw_ref_idx][0] * *bpred++ +
+ 2*wp_luma_round) >> (luma_log_weight_denom + 1)) +
+ ((wp_offset[0][fw_ref_idx][0] + wp_offset[1][bw_ref_idx][0] + 1)>>1));
+ }
+ else if (p_dir==0)
+ {
+ for (j=block_y; j<block_y4; j++)
+ for (i=block_x; i<block_x4; i++)
+ img->mpr[j][i] = clip1a(((wp_weight[0][fw_ref_idx][0] * *fpred++ + wp_luma_round) >> luma_log_weight_denom) +
+ wp_offset[0][fw_ref_idx][0] );
+ }
+ else // p_dir==1
+ {
+ for (j=block_y; j<block_y4; j++)
+ for (i=block_x; i<block_x4; i++)
+ img->mpr[j][i] = clip1a(((wp_weight[1][bw_ref_idx][0] * *bpred++ + wp_luma_round) >> luma_log_weight_denom)
+ + wp_offset[1][bw_ref_idx][0] );
+ }
+ }
+ else
+ {
+ if (p_dir==2)
+ {
+ for (j=block_y; j<block_y4; j++)
+ for (i=block_x; i<block_x4; i++)
+ img->mpr[j][i] = (*fpred++ + *bpred++ + 1) / 2;
+ }
+ else if (p_dir==0)
+ {
+ for (j=block_y; j<block_y4; j++)
+ for (i=block_x; i<block_x4; i++)
+ img->mpr[j][i] = *fpred++;
+ }
+ else // p_dir==1
+ {
+ for (j=block_y; j<block_y4; j++)
+ for (i=block_x; i<block_x4; i++)
+ img->mpr[j][i] = *bpred++;
+ }
+ }
+ }
+
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Residual Coding of an 8x8 Luma block (not for intra)
+ *
+ * \return
+ * coefficient cost
+ ************************************************************************
+ */
+ int LumaResidualCoding8x8 ( int *cbp, //!< Output: cbp (updated according to processed 8x8 luminance block)
+ int64 *cbp_blk, //!< Output: block cbp (updated according to processed 8x8 luminance block)
+ int block8x8, //!< block number of 8x8 block
+ short p_dir, //!< prediction direction
+ int fw_mode, //!< list0 prediction mode (1-7, 0=DIRECT)
+ int bw_mode, //!< list1 prediction mode (1-7, 0=DIRECT)
+ short fw_refframe, //!< reference picture for list0 prediction
+ short bw_refframe //!< reference picture for list0 prediction
+ )
+ {
+ int block_y, block_x, pic_pix_y, pic_pix_x, i, j, nonzero = 0, cbp_blk_mask;
+ int coeff_cost = 0;
+ int mb_y = (block8x8 >> 1) << 3;
+ int mb_x = (block8x8 & 0x01) << 3;
+ int pix_y;
+ int cbp_mask = 1 << block8x8;
+ int bxx, byy; // indexing curr_blk
+ int scrFlag = 0; // 0=noSCR, 1=strongSCR, 2=jmSCR
+ int skipped = (fw_mode == 0 && bw_mode == 0 && (img->type != B_SLICE));
+ Macroblock* currMB = &img->mb_data[img->current_mb_nr];
+ //set transform size
+ int need_8x8_transform = currMB->luma_transform_size_8x8_flag;
+ // Residue Color Transform
+ int residue_R, residue_G, residue_B, temp;
+
+ if (img->type==B_SLICE)
+ scrFlag = 1;
+
+ //===== loop over 4x4 blocks =====
+ for (byy=0, block_y=mb_y; block_y<mb_y+8; byy+=4, block_y+=4)
+ {
+ pic_pix_y = img->opix_y + block_y;
+
+ for (bxx=0, block_x=mb_x; block_x<mb_x+8; bxx+=4, block_x+=4)
+ {
+ pic_pix_x = img->opix_x + block_x;
+
+ cbp_blk_mask = (block_x>>2) + block_y;
+
+ // Residue Color Transform
+ if(img->residue_transform_flag)
+ {
+ ChromaPrediction4x4 (0, block_x, block_y, p_dir, fw_mode, bw_mode, fw_refframe, bw_refframe);
+ for (j=0; j<4; j++)
+ for (i=0; i<4; i++)
+ mprRGB[1][j+block_y][i+block_x] = img->mpr[j+block_y][i+block_x];
+
+ ChromaPrediction4x4 (1, block_x, block_y, p_dir, fw_mode, bw_mode, fw_refframe, bw_refframe);
+ for (j=0; j<4; j++)
+ for (i=0; i<4; i++)
+ mprRGB[2][j+block_y][i+block_x] = img->mpr[j+block_y][i+block_x];
+ }
+
+ //===== prediction of 4x4 block =====
+ LumaPrediction4x4 (block_x, block_y, p_dir, fw_mode, bw_mode, fw_refframe, bw_refframe);
+
+ // Residue Color Transform
+ if(img->residue_transform_flag)
+ {
+ for (j=0; j<4; j++)
+ for (i=0; i<4; i++)
+ mprRGB[0][j+block_y][i+block_x] = img->mpr[j+block_y][i+block_x];
+ }
+
+ //===== get displaced frame difference ======
+ if(!img->residue_transform_flag)
+ {
+ if(!need_8x8_transform)
+ {
+
+ //===== get displaced frame difference ======
+ for (j=0; j<4; j++)
+ {
+ pix_y = pic_pix_y + j;
+ for (i=0; i<4; i++)
+ {
+ img->m7[j][i] = imgY_org[pix_y][pic_pix_x + i] - img->mpr[j+block_y][i+block_x];
+ }
+ }
+ //===== DCT, Quantization, inverse Quantization, IDCT, Reconstruction =====
+ if (img->NoResidueDirect != 1 && !skipped )
+ {
+ //===== DCT, Quantization, inverse Quantization, IDCT, Reconstruction =====
+ if (img->type!=SP_SLICE)
+ nonzero = dct_luma (block_x, block_y, &coeff_cost, 0);
+ else
+ nonzero = dct_luma_sp(block_x, block_y, &coeff_cost);
+
+ if (nonzero)
+ {
+ (*cbp_blk) |= 1 << cbp_blk_mask; // one bit for every 4x4 block
+ (*cbp) |= cbp_mask; // one bit for the 4x4 blocks of an 8x8 block
+ }
+ }
+ }
+ else
+ {
+ for (j=0; j<4; j++)
+ {
+ pix_y = pic_pix_y + j;
+ for (i=0; i<4; i++)
+ {
+ img->m7[j+byy][i+bxx] = imgY_org[pix_y][pic_pix_x+i] - img->mpr[j+block_y][i+block_x];
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Forward Residue Transform */
+ for (j=0; j<4; j++)
+ for (i=0; i<4; i++)
+ {
+ residue_B = imgUV_org[0][pic_pix_y+j][pic_pix_x+i] - mprRGB[1][j+block_y][i+block_x];
+ residue_G = imgY_org[pic_pix_y+j][pic_pix_x+i] - mprRGB[0][j+block_y][i+block_x];
+ residue_R = imgUV_org[1][pic_pix_y+j][pic_pix_x+i] - mprRGB[2][j+block_y][i+block_x];
+
+ resTrans_R[j+block_y][i+block_x] = residue_R-residue_B;
+ temp = residue_B+(resTrans_R[j+block_y][i+block_x]>>1);
+ resTrans_B[j+block_y][i+block_x] = residue_G-temp;
+ resTrans_G[j+block_y][i+block_x] = temp+(resTrans_B[j+block_y][i+block_x]>>1);
+
+ if(!need_8x8_transform)
+ img->m7[j][i] = resTrans_G[j+block_y][i+block_x];
+ else
+ img->m7[j+byy][i+bxx] = resTrans_G[j+block_y][i+block_x];
+ }
+
+ // Residue Color Transform
+ //===== DCT, Quantization, inverse Quantization, IDCT, Reconstruction =====
+ if (img->NoResidueDirect != 1 && !skipped && !need_8x8_transform )
+ {
+ //===== DCT, Quantization, inverse Quantization, IDCT, Reconstruction =====
+ if (img->type!=SP_SLICE) nonzero = dct_luma (block_x, block_y, &coeff_cost, 0);
+ else nonzero = dct_luma_sp(block_x, block_y, &coeff_cost);
+
+ for (j=0; j<4; j++)
+ for (i=0; i<4; i++)
+ rec_resG[j+block_y][i+block_x] = img->m7[j][i];
+
+ if (nonzero)
+ {
+ (*cbp_blk) |= 1 << cbp_blk_mask; // one bit for every 4x4 block
+ (*cbp) |= cbp_mask; // one bit for the 4x4 blocks of an 8x8 block
+ }
+ }
+ }
+ }
+ }
+
+ if(need_8x8_transform)
+ {
+ if (img->NoResidueDirect != 1 && !skipped)
+ {
+ if (img->type!=SP_SLICE)
+ nonzero = dct_luma8x8 (block8x8, &coeff_cost, 0);
+
+ // Residue Color Transform
+ if(img->residue_transform_flag)
+ {
+ for (j=0; j<8; j++)
+ for (i=0; i<8; i++)
+ rec_resG[mb_y+j][mb_x+i] = img->m7[j][i];
+ }
+
+ if (nonzero)
+ {
+ (*cbp_blk) |= 51 << (4*block8x8-2*(block8x8 & 0x01)); // corresponds to 110011, as if all four 4x4 blocks contain coeff, shifted to block position
+ (*cbp) |= cbp_mask; // one bit for the 4x4 blocks of an 8x8 block
+ }
+ }
+ }
+
+ /*
+ The purpose of the action below is to prevent that single or 'expensive' coefficients are coded.
+ With 4x4 transform there is larger chance that a single coefficient in a 8x8 or 16x16 block may be nonzero.
+ A single small (level=1) coefficient in a 8x8 block will cost: 3 or more bits for the coefficient,
+ 4 bits for EOBs for the 4x4 blocks,possibly also more bits for CBP. Hence the total 'cost' of that single
+ coefficient will typically be 10-12 bits which in a RD consideration is too much to justify the distortion improvement.
+ The action below is to watch such 'single' coefficients and set the reconstructed block equal to the prediction according
+ to a given criterium. The action is taken only for inter luma blocks.
+
+ Notice that this is a pure encoder issue and hence does not have any implication on the standard.
+ coeff_cost is a parameter set in dct_luma() and accumulated for each 8x8 block. If level=1 for a coefficient,
+ coeff_cost is increased by a number depending on RUN for that coefficient.The numbers are (see also dct_luma()): 3,2,2,1,1,1,0,0,...
+ when RUN equals 0,1,2,3,4,5,6, etc.
+ If level >1 coeff_cost is increased by 9 (or any number above 3). The threshold is set to 3. This means for example:
+ 1: If there is one coefficient with (RUN,level)=(0,1) in a 8x8 block this coefficient is discarded.
+ 2: If there are two coefficients with (RUN,level)=(1,1) and (4,1) the coefficients are also discarded
+ sum_cnt_nonz is the accumulation of coeff_cost over a whole macro block. If sum_cnt_nonz is 5 or less for the whole MB,
+ all nonzero coefficients are discarded for the MB and the reconstructed block is set equal to the prediction.
+ */
+
+ if (img->NoResidueDirect != 1 && !skipped && coeff_cost <= _LUMA_COEFF_COST_ &&
+ ((img->qp + img->bitdepth_luma_qp_scale)!=0 || img->lossless_qpprime_flag==0))
+ {
+ coeff_cost = 0;
+ (*cbp) &= (63 - cbp_mask);
+ (*cbp_blk) &= ~(51 << (4*block8x8-2*(block8x8 & 0x01)));
+
+ if(!img->residue_transform_flag)
+ {
+ for (j=mb_y; j<mb_y+8; j++)
+ memcpy(&enc_picture->imgY[img->pix_y + j][img->pix_x + mb_x], &img->mpr[j][mb_x], 2 * BLOCK_SIZE * sizeof(imgpel));
+ }
+ else // Residue Color Transform
+ {
+ for (i=mb_x; i<mb_x+8; i++)
+ for (j=mb_y; j<mb_y+8; j++)
+ {
+ rec_resG[j][i] = 0;
+ }
+ }
+ if (img->type==SP_SLICE)
+ {
+ for (i=mb_x; i < mb_x+BLOCK_SIZE*2; i+=BLOCK_SIZE)
+ for (j=mb_y; j < mb_y+BLOCK_SIZE*2; j+=BLOCK_SIZE)
+ copyblock_sp(i,j);
+ }
+ }
+
+ return coeff_cost;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Set mode parameters and reference frames for an 8x8 block
+ ************************************************************************
+ */
+ void SetModesAndRefframe (int b8, short* p_dir, int* fw_mode, int* bw_mode, short* fw_ref, short* bw_ref)
+ {
+ Macroblock* currMB = &img->mb_data[img->current_mb_nr];
+ int j = 2*(b8>>1);
+ int i = 2*(b8 & 0x01);
+
+ *fw_mode = *bw_mode = *fw_ref = *bw_ref = -1;
+
+ *p_dir = currMB->b8pdir[b8];
+
+ if (img->type!=B_SLICE)
+ {
+ *fw_ref = enc_picture->ref_idx[LIST_0][img->block_y+j][img->block_x+i];
+ *bw_ref = 0;
+ *fw_mode = currMB->b8mode[b8];
+ *bw_mode = 0;
+ }
+ else
+ {
+ if (currMB->b8pdir[b8]==-1)
+ {
+ *fw_ref = -1;
+ *bw_ref = -1;
+ *fw_mode = 0;
+ *bw_mode = 0;
+ }
+ else if (currMB->b8pdir[b8]==0)
+ {
+ *fw_ref = enc_picture->ref_idx[LIST_0][img->block_y+j][img->block_x+i];
+ *bw_ref = 0;
+ *fw_mode = currMB->b8mode[b8];
+ *bw_mode = 0;
+ }
+ else if (currMB->b8pdir[b8]==1)
+ {
+ *fw_ref = 0;
+ *bw_ref = enc_picture->ref_idx[LIST_1][img->block_y+j][img->block_x+i];
+ *fw_mode = 0;
+ *bw_mode = currMB->b8mode[b8];
+ }
+ else
+ {
+ *fw_ref = enc_picture->ref_idx[LIST_0][img->block_y+j][img->block_x+i];
+ *bw_ref = enc_picture->ref_idx[LIST_1][img->block_y+j][img->block_x+i];
+ *fw_mode = currMB->b8mode[b8];
+ *bw_mode = currMB->b8mode[b8];
+ }
+ }
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Residual Coding of a Luma macroblock (not for intra)
+ ************************************************************************
+ */
+ void LumaResidualCoding ()
+ {
+ int i,j,block8x8,b8_x,b8_y;
+ int fw_mode, bw_mode;
+ short p_dir, refframe;
+ int sum_cnt_nonz;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+
+ currMB->cbp = 0 ;
+ currMB->cbp_blk = 0 ;
+ sum_cnt_nonz = 0 ;
+
+ for (block8x8=0; block8x8<4; block8x8++)
+ {
+ short bw_ref;
+ SetModesAndRefframe (block8x8, &p_dir, &fw_mode, &bw_mode, &refframe, &bw_ref);
+
+ sum_cnt_nonz += LumaResidualCoding8x8 (&(currMB->cbp), &(currMB->cbp_blk), block8x8,
+ p_dir, fw_mode, bw_mode, refframe, bw_ref);
+ }
+
+ if (sum_cnt_nonz <= _LUMA_MB_COEFF_COST_ &&
+ ((img->qp + img->bitdepth_luma_qp_scale)!=0 || img->lossless_qpprime_flag==0))
+ {
+ currMB->cbp &= 0xfffff0 ;
+ currMB->cbp_blk &= 0xff0000 ;
+ if(!img->residue_transform_flag)
+ {
+ for (j=0; j < MB_BLOCK_SIZE; j++)
+ memcpy(&enc_picture->imgY[img->pix_y+j][img->pix_x], img->mpr[j], MB_BLOCK_SIZE * sizeof (imgpel));
+ }
+ else
+ {
+ for (i=0; i < MB_BLOCK_SIZE; i++)
+ for (j=0; j < MB_BLOCK_SIZE; j++)
+ {
+ rec_resG[j][i] = 0;
+ }
+ }
+
+ if (img->type==SP_SLICE)
+ {
+ for(block8x8=0;block8x8<4;block8x8++)
+ {
+ b8_x=(block8x8&1)<<3;
+ b8_y=(block8x8&2)<<2;
+ for (i=b8_x;i<b8_x+8;i+=4)
+ for (j=b8_y;j<b8_y+8;j+=4)
+ copyblock_sp(i,j);
+ }
+ }
+ }
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Makes the decision if 8x8 tranform will be used (for RD-off)
+ ************************************************************************
+ */
+ int TransformDecision (int block_check, int *cost)
+ {
+ int block_y, block_x, pic_pix_y, pic_pix_x, i, j, k;
+ int mb_y, mb_x, block8x8;
+ int fw_mode, bw_mode;
+ short p_dir, fw_ref, bw_ref;
+ int num_blks;
+ int cost8x8=0, cost4x4=0;
+ int diff[64], *diff_ptr;
+
+ if(block_check==-1)
+ {
+ block8x8=0;
+ num_blks=4;
+ }
+ else
+ {
+ block8x8=block_check;
+ num_blks=block_check+1;
+ }
+
+ for (; block8x8<num_blks; block8x8++)
+ {
+ SetModesAndRefframe (block8x8, &p_dir, &fw_mode, &bw_mode, &fw_ref, &bw_ref);
+
+ mb_y = (block8x8 >> 1) << 3;
+ mb_x = (block8x8 & 0x01) << 3;
+ //===== loop over 4x4 blocks =====
+ k=0;
+ for (block_y=mb_y; block_y<mb_y+8; block_y+=4)
+ {
+ pic_pix_y = img->opix_y + block_y;
+
+ for (block_x=mb_x; block_x<mb_x+8; block_x+=4)
+ {
+ pic_pix_x = img->opix_x + block_x;
+
+ //===== prediction of 4x4 block =====
+ LumaPrediction4x4 (block_x, block_y, p_dir, fw_mode, bw_mode, fw_ref, bw_ref);
+
+ //===== get displaced frame difference ======
+ diff_ptr=&diff[k];
+ for (j=0; j<4; j++)
+ {
+ for (i=0; i<4; i++, k++)
+ diff[k] = imgY_org[pic_pix_y+j][pic_pix_x+i] - img->mpr[j+block_y][i+block_x];
+ }
+ cost4x4 += SATD (diff_ptr, input->hadamard);
+ }
+ }
+ cost8x8 += SATD8X8 (diff, input->hadamard);
+ }
+
+ if(input->Transform8x8Mode==2) //always allow 8x8 transform
+ return 1;
+ else if(cost8x8<cost4x4)
+ return 1;
+ else
+ {
+ *cost = (*cost-cost8x8+cost4x4);
+ return 0;
+ }
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Predict one component of a chroma 4x4 block
+ ************************************************************************
+ */
+ void OneComponentChromaPrediction4x4 (int* mpred, //!< array to store prediction values
+ int block_c_x, //!< horizontal pixel coordinate of 4x4 block
+ int block_c_y, //!< vertical pixel coordinate of 4x4 block
+ short****** mv, //!< motion vector array
+ int list_idx, //!< reference picture list
+ short ref, //!< reference index
+ int blocktype, //!< block type
+ int uv) //!< chroma component
+ {
+ int i, j, ii, jj, ii0, jj0, ii1, jj1, if0, if1, jf0, jf1;
+ short* mvb;
+
+ int f1_x = 64/img->mb_cr_size_x;
+ int f2_x=f1_x-1;
+
+ int f1_y = 64/img->mb_cr_size_y;
+ int f2_y=f1_y-1;
+
+ int f3=f1_x*f1_y, f4=f3>>1;
+ int list_offset = img->mb_data[img->current_mb_nr].list_offset;
+ int max_y_cr = (int) (list_offset ? (img->height_cr >> 1) - 1 : img->height_cr - 1);
+ int max_x_cr = (int) (img->width_cr - 1);
+ int jjx, iix;
+ int mb_cr_y_div4 = img->mb_cr_size_y>>2;
+ int mb_cr_x_div4 = img->mb_cr_size_x>>2;
+ int jpos;
+
+ StorablePicture **list = listX[list_idx + list_offset];
+ pel_t** refimage = list[ref]->imgUV[uv];
+
+ for (j=block_c_y; j < block_c_y + BLOCK_SIZE; j++)
+ {
+ jjx = j/mb_cr_y_div4;
+ jpos = (j + img->opix_c_y)*f1_y;
+
+ for (i=block_c_x; i < block_c_x + BLOCK_SIZE; i++)
+ {
+ iix = i/mb_cr_x_div4;
+ mvb = mv [jjx][iix][list_idx][ref][blocktype];
+
+ ii = (i + img->opix_c_x)*f1_x + mvb[0];
+ jj = jpos + mvb[1];
+
+ if (active_sps->chroma_format_idc == 1)
+ jj += list[ref]->chroma_vector_adjustment;
+
+ ii0 = Clip3 (0, max_x_cr, ii/f1_x);
+ jj0 = Clip3 (0, max_y_cr, jj/f1_y);
+ ii1 = Clip3 (0, max_x_cr, (ii+f2_x)/f1_x);
+ jj1 = Clip3 (0, max_y_cr, (jj+f2_y)/f1_y);
+
+ if1 = (ii&f2_x); if0 = f1_x-if1;
+ jf1 = (jj&f2_y); jf0 = f1_y-jf1;
+
+ *mpred++ = (if0 * jf0 * refimage[jj0][ii0] +
+ if1 * jf0 * refimage[jj0][ii1] +
+ if0 * jf1 * refimage[jj1][ii0] +
+ if1 * jf1 * refimage[jj1][ii1] + f4) / f3;
+ }
+ }
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Predict an intra chroma 4x4 block
+ ************************************************************************
+ */
+ void IntraChromaPrediction4x4 (int uv, // <-- colour component
+ int block_x, // <-- relative horizontal block coordinate of 4x4 block
+ int block_y) // <-- relative vertical block coordinate of 4x4 block
+ {
+ int mode = img->mb_data[img->current_mb_nr].c_ipred_mode;
+ int j;
+
+ //===== prediction =====
+ for (j=block_y; j<block_y+4; j++)
+ memcpy(&img->mpr[j][block_x],&img->mprr_c[uv][mode][j][block_x], BLOCK_MULTIPLE * sizeof(imgpel));
+ }
+
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Predict one chroma 4x4 block
+ ************************************************************************
+ */
+ void
+ ChromaPrediction4x4 (int uv, // <-- colour component
+ int block_x, // <-- relative horizontal block coordinate of 4x4 block
+ int block_y, // <-- relative vertical block coordinate of 4x4 block
+ int p_dir, // <-- prediction direction
+ int fw_mode, // <-- list0 prediction mode (1-7, 0=DIRECT if bw_mode=0)
+ int bw_mode, // <-- list1 prediction mode (1-7, 0=DIRECT if fw_mode=0)
+ short fw_ref_idx, // <-- reference frame for list0 prediction (if (<0) -> intra prediction)
+ short bw_ref_idx) // <-- reference frame for list1 prediction
+ {
+ static int fw_pred[MB_BLOCK_SIZE];
+ static int bw_pred[MB_BLOCK_SIZE];
+
+ int i, j;
+ int block_x4 = block_x+4;
+ int block_y4 = block_y+4;
+ int* fpred = fw_pred;
+ int* bpred = bw_pred;
+ short****** mv_array = img->all_mv;
+
+ Macroblock* currMB = &img->mb_data[img->current_mb_nr];
+
+ int apply_weights = ( (active_pps->weighted_pred_flag && (img->type == P_SLICE || img->type == SP_SLICE)) ||
+ (active_pps->weighted_bipred_idc && (img->type == B_SLICE)));
+
+ if (currMB->bi_pred_me && fw_ref_idx == 0 && bw_ref_idx == 0 && p_dir == 2 && fw_mode==1 && bw_mode==1)
+ mv_array = currMB->bi_pred_me == 1? img->bipred_mv1 : img->bipred_mv2 ;
+
+ //===== INTRA PREDICTION =====
+ if (p_dir==-1)
+ {
+ IntraChromaPrediction4x4 (uv, block_x, block_y);
+ return;
+ }
+
+ //===== INTER PREDICTION =====
+ if ((p_dir==0) || (p_dir==2))
+ {
+ OneComponentChromaPrediction4x4 (fw_pred, block_x, block_y, mv_array, LIST_0, fw_ref_idx, fw_mode, uv);
+ }
+ if ((p_dir==1) || (p_dir==2))
+ {
+ OneComponentChromaPrediction4x4 (bw_pred, block_x, block_y, mv_array, LIST_1, bw_ref_idx, bw_mode, uv);
+ }
+
+ if (apply_weights)
+ {
+ if (p_dir==2)
+ {
+ for (j=block_y; j<block_y4; j++)
+ for (i=block_x; i<block_x4; i++)
+ img->mpr[j][i] = clip1a_chr(((wbp_weight[0][fw_ref_idx][bw_ref_idx][uv+1] * *fpred++ + wbp_weight[1][fw_ref_idx][bw_ref_idx][uv+1] * *bpred++
+ + 2*wp_chroma_round) >> (chroma_log_weight_denom + 1)) + ((wp_offset[0][fw_ref_idx][uv+1] + wp_offset[1][bw_ref_idx][uv+1] + 1)>>1) );
+ }
+ else if (p_dir==0)
+ {
+ for (j=block_y; j<block_y4; j++)
+ for (i=block_x; i<block_x4; i++)
+ img->mpr[j][i] = clip1a_chr(((wp_weight[0][fw_ref_idx][uv+1] * *fpred++ + wp_chroma_round) >> chroma_log_weight_denom) + wp_offset[0][fw_ref_idx][uv+1]);
+ }
+ else // (p_dir==1)
+ {
+ for (j=block_y; j<block_y4; j++)
+ for (i=block_x; i<block_x4; i++)
+ img->mpr[j][i] = clip1a_chr(((wp_weight[1][bw_ref_idx][uv+1] * *bpred++ + wp_chroma_round) >> chroma_log_weight_denom) + wp_offset[1][bw_ref_idx][uv+1]);
+ }
+ }
+ else
+ {
+ if (p_dir==2)
+ {
+ for (j=block_y; j<block_y4; j++)
+ for (i=block_x; i<block_x4; i++)
+ img->mpr[j][i] = (*fpred++ + *bpred++ + 1) >> 1;
+ }
+ else if (p_dir==0)
+ {
+ for (j=block_y; j<block_y4; j++)
+ for (i=block_x; i<block_x4; i++)
+ img->mpr[j][i] = *fpred++;
+ }
+ else // (p_dir==1)
+ {
+ for (j=block_y; j<block_y4; j++)
+ for (i=block_x; i<block_x4; i++)
+ img->mpr[j][i] = *bpred++;
+ }
+ }
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Chroma residual coding for an macroblock
+ ************************************************************************
+ */
+ void ChromaResidualCoding (int* cr_cbp)
+ {
+ int uv, block8, block_y, block_x, j, i;
+ int fw_mode, bw_mode;
+ short p_dir, refframe, bw_ref;
+ int skipped = (img->mb_data[img->current_mb_nr].mb_type == 0 && (img->type == P_SLICE || img->type == SP_SLICE));
+ int yuv = img->yuv_format - 1; //ADD-VG-15052004
+
+ int block8x8_idx[3][4][4] = //ADD-VG-15052004
+ { { {0, 1, 0, 0},
+ {2, 3, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}, },
+
+ { {0, 1, 0, 0},
+ {0, 1, 0, 0},
+ {2, 3, 0, 0},
+ {2, 3, 0, 0} },
+
+ { {0, 0, 1, 1},
+ {0, 0, 1, 1},
+ {2, 2, 3, 3},
+ {2, 2, 3, 3} }
+ };
+ int residue_R, residue_G, residue_B, temp;
+
+ for (*cr_cbp=0, uv=0; uv<2; uv++)
+ {
+ //===== prediction of chrominance blocks ===d==
+ block8 = 0;
+ for (block_y=0; block_y < img->mb_cr_size_y; block_y+=4)
+ for (block_x=0; block_x < img->mb_cr_size_x; block_x+=4)
+ {
+ block8 = block8x8_idx[yuv][block_y>>2][block_x>>2];
+ SetModesAndRefframe (block8, &p_dir, &fw_mode, &bw_mode, &refframe, &bw_ref);
+
+ ChromaPrediction4x4 (uv, block_x, block_y, p_dir, fw_mode, bw_mode, refframe, bw_ref);
+ }
+
+ // ==== set chroma residue to zero for skip Mode in SP frames
+ if (img->NoResidueDirect)
+ {
+ // Residue Color Transform
+ if(!img->residue_transform_flag)
+ {
+ for (j=0; j<img->mb_cr_size_y; j++)
+ memcpy(&enc_picture->imgUV[uv][img->pix_c_y+j][img->pix_c_x], img->mpr[j], img->mb_cr_size_x * sizeof(imgpel));
+ ;
+ }
+ else
+ {
+ if(uv==0)
+ {
+ for (j=0; j<img->mb_cr_size_y; j++)
+ memset(rec_resB[j], 0, img->mb_cr_size_x * sizeof(int));
+ }
+ else
+ {
+ for (j=0; j<img->mb_cr_size_y; j++)
+ memset(rec_resR[j], 0, img->mb_cr_size_x * sizeof(int));
+ }
+ }
+ }
+ else if (skipped && img->type==SP_SLICE)
+ {
+ for (j=0; j<8; j++)
+ memset(img->m7[j], 0 , 8 * sizeof(int));
+ }
+ else
+ if (skipped)
+ {
+ // Residue Color Transform
+ if(!img->residue_transform_flag)
+ {
+ for (j=0; j<img->mb_cr_size_y; j++)
+ memcpy(&enc_picture->imgUV[uv][img->pix_c_y+j][img->pix_c_x], img->mpr[j], img->mb_cr_size_x * sizeof(imgpel));
+ }
+ else
+ {
+ if(uv==0)
+ {
+ for (j=0; j<img->mb_cr_size_y; j++)
+ memset(rec_resB[j],0, img->mb_cr_size_x * sizeof(int));
+ }
+ else
+ {
+ for (j=0; j<img->mb_cr_size_y; j++)
+ memset(rec_resR[j],0, img->mb_cr_size_x * sizeof(int));
+ }
+ }
+ }
+ else
+ {
+ for (j=0; j<img->mb_cr_size_y; j++)
+ for (i=0; i<img->mb_cr_size_x; i++)
+ {
+ // Residue Color Transform
+ if(!img->residue_transform_flag)
+ {
+ img->m7[j][i] = imgUV_org[uv][img->opix_c_y+j][img->opix_c_x+i] - img->mpr[j][i];
+ }
+ else
+ {
+ if(uv==0) img->m7[j][i] = resTrans_B[j][i];
+ else img->m7[j][i] = resTrans_R[j][i];
+ }
+ }
+ }
+
+ //===== DCT, Quantization, inverse Quantization, IDCT, and Reconstruction =====
+ //===== Call function for skip mode in SP frames to properly process frame ====
+
+ if (skipped && img->type==SP_SLICE)
+ {
+ *cr_cbp=dct_chroma_sp(uv,*cr_cbp);
+ }
+ else
+ {
+ if (!img->NoResidueDirect && !skipped)
+ {
+ if (img->type!=SP_SLICE || IS_INTRA (&img->mb_data[img->current_mb_nr]))
+ *cr_cbp=dct_chroma (uv,*cr_cbp);
+ else
+ *cr_cbp=dct_chroma_sp(uv,*cr_cbp);
+
+ if(img->residue_transform_flag){
+ for (j=0; j < img->mb_cr_size_y; j++)
+ for (i=0; i < img->mb_cr_size_x; i++)
+ {
+ if(uv==0)
+ rec_resB[j][i] = img->m7[j][i];
+ else
+ rec_resR[j][i] = img->m7[j][i];
+ }
+ }
+ }
+ }
+ }
+
+ //===== update currMB->cbp =====
+ img->mb_data[img->current_mb_nr].cbp += ((*cr_cbp)<<4);
+
+ // Residue Color Transform
+ /* Inverse Residue Transform */
+ if(img->residue_transform_flag)
+ {
+ for (j=0; j<MB_BLOCK_SIZE; j++)
+ for (i=0; i<MB_BLOCK_SIZE; i++)
+ {
+ /* YCoCg-R */
+ temp = rec_resG[j][i]-(rec_resB[j][i]>>1);
+ residue_G = rec_resB[j][i]+temp;
+ residue_B = temp - (rec_resR[j][i]>>1);
+ residue_R = residue_B+rec_resR[j][i];
+ enc_picture->imgUV[0][img->pix_y+j][img->pix_x+i] = min(img->max_imgpel_value_uv,max(0,residue_B+mprRGB[1][j][i]));
+ enc_picture->imgY[img->pix_y+j][img->pix_x+i] = min(img->max_imgpel_value, max(0,residue_G+mprRGB[0][j][i]));
+ enc_picture->imgUV[1][img->pix_y+j][img->pix_x+i] = min(img->max_imgpel_value_uv,max(0,residue_R+mprRGB[2][j][i]));
+ }
+ }
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Intra prediction of the chrminance layers of one macroblock
+ ************************************************************************
+ */
+ void IntraChromaPrediction (int *mb_up, int *mb_left, int*mb_up_left)
+ {
+
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ int s, s0, s1, s2, s3, i, j, k;
+ pel_t** image;
+ int block_x, block_y;
+ int mb_nr = img->current_mb_nr;
+ int mb_available_up;
+ int mb_available_left[2];
+ int mb_available_up_left;
+ int ih,iv;
+ int ib,ic,iaa;
+ int uv;
+ imgpel hline[16], vline[16];
+ int mode;
+ int best_mode = DC_PRED_8; //just an initilaization here, should always be overwritten
+ int cost;
+ int min_cost;
+ int diff[16];
+ PixelPos up; //!< pixel position p(0,-1)
+ PixelPos left[17]; //!< pixel positions p(-1, -1..15)
+ int cr_MB_x = img->mb_cr_size_x;
+ int cr_MB_y = img->mb_cr_size_y;
+
+ //ADD-VG-07062004
+ int blk_x;
+ int blk_y;
+ int b8,b4;
+ int yuv = img->yuv_format - 1;
+
+ static int block_pos[3][4][4]= //[yuv][b8][b4]
+ {
+ { {0, 1, 2, 3},{0, 0, 0, 0},{0, 0, 0, 0},{0, 0, 0, 0}},
+ { {0, 1, 2, 3},{2, 3, 2, 3},{0, 0, 0, 0},{0, 0, 0, 0}},
+ { {0, 1, 2, 3},{1, 1, 3, 3},{2, 3, 2, 3},{3, 3, 3, 3}}
+ };
+
+ //ADD-VG-07062004-END
+
+
+ for (i=0;i<cr_MB_y+1;i++)
+ {
+ getNeighbour(mb_nr, -1 , i-1 , 0, &left[i]);
+ }
+
+ getNeighbour(mb_nr, 0 , -1 , 0, &up);
+
+
+ mb_available_up = up.available;
+ mb_available_up_left = left[0].available;
+ mb_available_left[0] = mb_available_left[1] = left[1].available;
+
+ if(input->UseConstrainedIntraPred)
+ {
+ mb_available_up = up.available ? img->intra_block[up.mb_addr] : 0;
+ for (i=0, mb_available_left[0]=1; i<(cr_MB_y>>1);i++)
+ mb_available_left[0] &= left[i+1].available ? img->intra_block[left[i+1].mb_addr]: 0;
+ for (i=(cr_MB_y>>1), mb_available_left[1]=1; i<cr_MB_y;i++)
+ mb_available_left[1] &= left[i+1].available ? img->intra_block[left[i+1].mb_addr]: 0;
+ mb_available_up_left = left[0].available ? img->intra_block[left[0].mb_addr]: 0;
+ }
+
+ if (mb_up)
+ *mb_up = mb_available_up;
+ if (mb_left)
+ *mb_left = mb_available_left[0] && mb_available_left[1];
+ if (mb_up_left)
+ *mb_up_left = mb_available_up_left;
+
+
+ // compute all chroma intra prediction modes for both U and V
+ for (uv=0; uv<2; uv++)
+ {
+ image = enc_picture->imgUV[uv];
+
+ // DC prediction
+ for(b8=0; b8<img->num_blk8x8_uv >> 1;b8++)
+ {
+ for (b4=0; b4<4; b4++)
+ {
+ block_y = subblk_offset_y[yuv][b8][b4];
+ block_x = subblk_offset_x[yuv][b8][b4];
+ blk_x = block_x;
+ blk_y = block_y + 1;
+
+ s=img->dc_pred_value;
+ s0=s1=s2=s3=0;
+
+ //===== get prediction value =====
+ switch (block_pos[yuv][b8][b4])
+ {
+ case 0: //===== TOP LEFT =====
+ if (mb_available_up) for (i=blk_x;i<(blk_x+4);i++) s0 += image[up.pos_y][up.pos_x + i];
+ if (mb_available_left[0]) for (i=blk_y;i<(blk_y+4);i++) s2 += image[left[i].pos_y][left[i].pos_x];
+ if (mb_available_up && mb_available_left[0]) s = (s0+s2+4) >> 3;
+ else if (mb_available_up) s = (s0 +2) >> 2;
+ else if (mb_available_left[0]) s = (s2 +2) >> 2;
+ break;
+ case 1: //===== TOP RIGHT =====
+ if (mb_available_up) for (i=blk_x;i<(blk_x+4);i++) s1 += image[up.pos_y][up.pos_x + i];
+ else if (mb_available_left[0]) for (i=blk_y;i<(blk_y+4);i++) s2 += image[left[i].pos_y][left[i].pos_x];
+ if (mb_available_up) s = (s1 +2) >> 2;
+ else if (mb_available_left[0]) s = (s2 +2) >> 2;
+ break;
+ case 2: //===== BOTTOM LEFT =====
+ if (mb_available_left[1]) for (i=blk_y;i<(blk_y+4);i++) s3 += image[left[i].pos_y][left[i].pos_x];
+ else if (mb_available_up) for (i=blk_x;i<(blk_x+4);i++) s0 += image[up.pos_y][up.pos_x + i];
+ if (mb_available_left[1]) s = (s3 +2) >> 2;
+ else if (mb_available_up) s = (s0 +2) >> 2;
+ break;
+ case 3: //===== BOTTOM RIGHT =====
+ if (mb_available_up) for (i=blk_x;i<(blk_x+4);i++) s1 += image[up.pos_y][up.pos_x + i];
+ if (mb_available_left[1]) for (i=blk_y;i<(blk_y+4);i++) s3 += image[left[i].pos_y][left[i].pos_x];
+ if (mb_available_up && mb_available_left[1]) s = (s1+s3+4) >> 3;
+ else if (mb_available_up) s = (s1 +2) >> 2;
+ else if (mb_available_left[1]) s = (s3 +2) >> 2;
+ break;
+ }
+
+ //===== prediction =====
+ for (j=block_y; j<block_y+4; j++)
+ for (i=block_x; i<block_x+4; i++)
+ {
+ img->mprr_c[uv][DC_PRED_8][j][i] = s;
+ }
+ }
+ }
+
+ // vertical prediction
+ if (mb_available_up)
+ {
+ memcpy(hline,&image[up.pos_y][up.pos_x], cr_MB_x * sizeof(imgpel));
+ for (j=0; j<cr_MB_y; j++)
+ memcpy(img->mprr_c[uv][VERT_PRED_8][j], hline, cr_MB_x * sizeof(imgpel));
+ }
+
+ // horizontal prediction
+ if (mb_available_left[0] && mb_available_left[1])
+ {
+ for (i=0; i<cr_MB_y; i++)
+ vline[i] = image[left[i+1].pos_y][left[i+1].pos_x];
+ for (i=0; i<cr_MB_x; i++)
+ for (j=0; j<cr_MB_y; j++)
+ img->mprr_c[uv][HOR_PRED_8][j][i] = vline[j];
+ }
+
+ // plane prediction
+ if (mb_available_left[0] && mb_available_left[1] && mb_available_up && mb_available_up_left)
+ {
+ ih = (cr_MB_x>>1)*(hline[cr_MB_x-1] - image[left[0].pos_y][left[0].pos_x]);
+ for (i=0;i<(cr_MB_x>>1)-1;i++)
+ ih += (i+1)*(hline[(cr_MB_x>>1)+i] - hline[(cr_MB_x>>1)-2-i]);
+
+ iv = (cr_MB_y>>1)*(vline[cr_MB_y-1] - image[left[0].pos_y][left[0].pos_x]);
+ for (i=0;i<(cr_MB_y>>1)-1;i++)
+ iv += (i+1)*(vline[(cr_MB_y>>1)+i] - vline[(cr_MB_y>>1)-2-i]);
+
+ ib= ((cr_MB_x == 8?17:5)*ih+2*cr_MB_x)>>(cr_MB_x == 8?5:6);
+ ic= ((cr_MB_y == 8?17:5)*iv+2*cr_MB_y)>>(cr_MB_y == 8?5:6);
+
+ iaa=16*(hline[cr_MB_x-1]+vline[cr_MB_y-1]);
+ for (j=0; j<cr_MB_y; j++)
+ for (i=0; i<cr_MB_x; i++)
+ img->mprr_c[uv][PLANE_8][j][i]=max(0,min(img->max_imgpel_value_uv,
+ (iaa+(i-(cr_MB_x>>1)+1)*ib+(j-(cr_MB_y>>1)+1)*ic+16)>>5));
+ }
+ }
+
+ if (!input->rdopt) // the rd-opt part does not work correctly (see encode_one_macroblock)
+ { // since ipredmodes could be overwritten => encoder-decoder-mismatches
+ // pick lowest cost prediction mode
+ min_cost = INT_MAX;
+ for (i=0;i<cr_MB_y;i++)
+ {
+ getNeighbour(mb_nr, 0 , i, 0, &left[i]);
+ }
+ for (mode=DC_PRED_8; mode<=PLANE_8; mode++)
+ {
+ if ((img->type != I_SLICE || !input->IntraDisableInterOnly) && input->ChromaIntraDisable == 1 && mode!=DC_PRED_8)
+ continue;
+
+ if ((mode==VERT_PRED_8 && !mb_available_up) ||
+ (mode==HOR_PRED_8 && (!mb_available_left[0] || !mb_available_left[1])) ||
+ (mode==PLANE_8 && (!mb_available_left[0] || !mb_available_left[1] || !mb_available_up || !mb_available_up_left)))
+ continue;
+
+ cost = 0;
+ for (uv=0; uv<2; uv++)
+ {
+ image = imgUV_org[uv];
+ for (block_y=0; block_y<cr_MB_y; block_y+=4)
+ for (block_x=0; block_x<cr_MB_x; block_x+=4)
+ {
+ for (k=0,j=block_y; j<block_y+4; j++)
+ {
+ for (i=block_x; i<block_x+4; i++,k++)
+ diff[k] = image[left[j].pos_y][left[j].pos_x+i] - img->mprr_c[uv][mode][j][i];
+ }
+ cost += SATD(diff, input->hadamard);
+ }
+ }
+ if (cost < min_cost)
+ {
+ best_mode = mode;
+ min_cost = cost;
+ }
+ }
+ currMB->c_ipred_mode = best_mode;
+ }
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Check if all reference frames for a macroblock are zero
+ ************************************************************************
+ */
+ int
+ ZeroRef (Macroblock* currMB)
+ {
+ int i,j;
+
+ for (j=img->block_y; j<img->block_y + BLOCK_MULTIPLE; j++)
+ for (i=img->block_x; i<img->block_x + BLOCK_MULTIPLE; i++)
+ {
+ if (enc_picture->ref_idx[LIST_0][j][i]!=0)
+ return 0;
+ }
+ return 1;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Converts macroblock type to coding value
+ ************************************************************************
+ */
+ int
+ MBType2Value (Macroblock* currMB)
+ {
+ static const int dir1offset[3] = { 1, 2, 3};
+ static const int dir2offset[3][3] = {{ 0, 4, 8}, // 1. block forward
+ { 6, 2, 10}, // 1. block backward
+ {12, 14, 16}}; // 1. block bi-directional
+
+ int mbtype, pdir0, pdir1;
+
+ if (img->type!=B_SLICE)
+ {
+ if (currMB->mb_type==I8MB ||currMB->mb_type==I4MB)
+ return (img->type==I_SLICE ? 0 : 6);
+ else if (currMB->mb_type==I16MB) return (img->type==I_SLICE ? 0 : 6) + img->i16offset;
+ else if (currMB->mb_type==IPCM) return (img->type==I_SLICE ? 25 : 31);
+ else if (currMB->mb_type==P8x8)
+ {
+ if (input->symbol_mode==UVLC
+ && ZeroRef (currMB)) return 5;
+ else return 4;
+ }
+ else return currMB->mb_type;
+ }
+ else
+ {
+ mbtype = currMB->mb_type;
+ pdir0 = currMB->b8pdir[0];
+ pdir1 = currMB->b8pdir[3];
+
+ if (mbtype==0) return 0;
+ else if (mbtype==I4MB || mbtype==I8MB)
+ return 23;
+ else if (mbtype==I16MB) return 23 + img->i16offset;
+ else if (mbtype==IPCM) return 48;
+ else if (mbtype==P8x8) return 22;
+ else if (mbtype==1) return dir1offset[pdir0];
+ else if (mbtype==2) return 4 + dir2offset[pdir0][pdir1];
+ else return 5 + dir2offset[pdir0][pdir1];
+ }
+ }
+
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Writes intra prediction modes for an 8x8 block
+ ************************************************************************
+ */
+ int writeIntra4x4Modes(int only_this_block)
+ {
+ int i,j,bs_x,bs_y,ii,jj;
+ int block8x8;
+ int rate;
+ char ipred_array[16];
+ int cont_array[16],ipred_number;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ SyntaxElement *currSE = &img->MB_SyntaxElements[currMB->currSEnr];
+ int *bitCount = currMB->bitcounter;
+ Slice *currSlice = img->currentSlice;
+ DataPartition *dataPart;
+ const int *partMap = assignSE2partition[input->partition_mode];
+
+ ipred_number=0;
+ for(block8x8=0;block8x8<4;block8x8++)
+ {
+ if((( currMB->b8mode[block8x8]==IBLOCK && (only_this_block<0||only_this_block==block8x8)) ||
+ ((currMB->b8mode[block8x8]==I8MB) && (only_this_block<0||only_this_block==block8x8))))
+ {
+ bs_x = bs_y = (currMB->b8mode[block8x8] == I8MB)?8:4;
+ ii=(bs_x>>2); // bug fix for solaris. mwi
+ jj=(bs_y>>2); // bug fix for solaris. mwi
+
+ for(j=0;j<4;j+=(jj<<1))
+ {
+ for(i=0;i<2;i+=ii)
+ {
+ ipred_array[ipred_number]=currMB->intra_pred_modes[(block8x8<<2)|j|i];
+ cont_array[ipred_number]=(block8x8<<2)+j+i;
+ ipred_number++;
+ }
+ }
+ }
+ }
+ rate=0;
+
+ for(i=0;i<ipred_number;i++)
+ {
+ currMB->IntraChromaPredModeFlag = 1;
+ currSE->context = cont_array[i];
+ currSE->value1 = ipred_array[i];
+ currSE->value2 = 0;
+
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "Intra mode = %3d %d",currSE->value1,currSE->context);
+ #endif
+
+ /*--- set symbol type and function pointers ---*/
+ if (input->symbol_mode != UVLC)
+ currSE->writing = writeIntraPredMode_CABAC;
+ currSE->type = SE_INTRAPREDMODE;
+
+ /*--- choose data partition ---*/
+ dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);
+ /*--- encode and update rate ---*/
+ if (input->symbol_mode == UVLC)
+ writeSyntaxElement_Intra4x4PredictionMode(currSE, dataPart);
+ else
+ dataPart->writeSyntaxElement (currSE, dataPart);
+ bitCount[BITS_COEFF_Y_MB]+=currSE->len;
+ rate += currSE->len;
+ currSE++;
+ currMB->currSEnr++;
+ }
+
+ return rate;
+ }
+
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Converts 8x8 block type to coding value
+ ************************************************************************
+ */
+ int B8Mode2Value (int b8mode, int b8pdir)
+ {
+ static const int b8start[8] = {0,0,0,0, 1, 4, 5, 10};
+ static const int b8inc [8] = {0,0,0,0, 1, 2, 2, 1};
+
+ if (img->type!=B_SLICE)
+ {
+ return (b8mode-4);
+ }
+ else
+ {
+ return b8start[b8mode] + b8inc[b8mode] * b8pdir;
+ }
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Codes macroblock header
+ * \param rdopt
+ * true for calls during RD-optimization
+ * \param coeff_rate
+ * bitrate of Luma and Chroma coeff
+ ************************************************************************
+ */
+ int writeMBLayer (int rdopt, int *coeff_rate)
+ {
+ int i,j;
+ int mb_nr = img->current_mb_nr;
+ Macroblock* currMB = &img->mb_data[mb_nr];
+ Macroblock* prevMB = mb_nr ? (&img->mb_data[mb_nr-1]) : NULL;
+ SyntaxElement *currSE = &img->MB_SyntaxElements[currMB->currSEnr];
+ int* bitCount = currMB->bitcounter;
+ Slice* currSlice = img->currentSlice;
+ DataPartition* dataPart;
+ const int* partMap = assignSE2partition[input->partition_mode];
+ int no_bits = 0;
+ int skip = currMB->mb_type ? 0:((img->type == B_SLICE) ? !currMB->cbp:1);
+ int mb_type;
+ int prevMbSkipped = 0;
+ int mb_field_tmp;
+ Macroblock *topMB = NULL;
+
+ int WriteFrameFieldMBInHeader = 0;
+
+ if (img->MbaffFrameFlag)
+ {
+ if (0==(mb_nr & 0x01))
+ {
+ WriteFrameFieldMBInHeader = 1; // top field
+
+ prevMbSkipped = 0;
+ }
+ else
+ {
+ if (prevMB->mb_type ? 0:((img->type == B_SLICE) ? !prevMB->cbp:1))
+ {
+ WriteFrameFieldMBInHeader = 1; // bottom, if top was skipped
+ }
+
+ topMB= &img->mb_data[img->current_mb_nr-1];
+ prevMbSkipped = topMB->skip_flag;
+ }
+ }
+ currMB->IntraChromaPredModeFlag = IS_INTRA(currMB);
+
+ // choose the appropriate data partition
+ dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);
+
+ if(img->type == I_SLICE)
+ {
+ //========= write mb_aff (I_SLICE) =========
+ if(WriteFrameFieldMBInHeader)
+ {
+ currSE->value1 = currMB->mb_field;
+ currSE->value2 = 0;
+ currSE->type = SE_MBTYPE;
+
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "mb_field_decoding_flag");
+ #endif
+ if( input->symbol_mode==UVLC)
+ {
+ currSE->mapping = ue_linfo;
+ currSE->bitpattern = (currMB->mb_field ? 1 : 0);
+ currSE->len = 1;
+ writeSyntaxElement2Buf_Fixed(currSE, dataPart->bitstream);
+ }
+ else
+ {
+ currSE->writing = writeFieldModeInfo_CABAC;
+ dataPart->writeSyntaxElement(currSE, dataPart);
+ }
+
+ bitCount[BITS_MB_MODE] += currSE->len;
+ no_bits += currSE->len;
+ currSE++;
+ currMB->currSEnr++;
+ }
+
+ //========= write mb_type (I_SLICE) =========
+ currSE->value1 = MBType2Value (currMB);
+ currSE->value2 = 0;
+ currSE->type = SE_MBTYPE;
+
+ if (input->symbol_mode == UVLC)
+ currSE->mapping = ue_linfo;
+ else
+ currSE->writing = writeMB_typeInfo_CABAC;
+
+ dataPart->writeSyntaxElement( currSE, dataPart);
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "mb_type (I_SLICE) (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->mb_type);
+ #endif
+ bitCount[BITS_MB_MODE] += currSE->len;
+ no_bits += currSE->len;
+ currSE++;
+ currMB->currSEnr++;
+ }
+ // not I_SLICE, CABAC
+ else if (input->symbol_mode == CABAC)
+ {
+ if (img->MbaffFrameFlag && ((img->current_mb_nr & 0x01) == 0||prevMbSkipped))
+ {
+ mb_field_tmp = currMB->mb_field;
+ currMB->mb_field = field_flag_inference();
+ CheckAvailabilityOfNeighborsCABAC();
+ currMB->mb_field = mb_field_tmp;
+ }
+
+ //========= write mb_skip_flag (CABAC) =========
+ mb_type = MBType2Value (currMB);
+ currSE->value1 = mb_type;
+ currSE->value2 = currMB->cbp;
+ currSE->type = SE_MBTYPE;
+ currSE->writing = writeMB_skip_flagInfo_CABAC;
+ dataPart->writeSyntaxElement( currSE, dataPart);
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "mb_skip_flag");
+ #endif
+ bitCount[BITS_MB_MODE] += currSE->len;
+ no_bits += currSE->len;
+ currSE++;
+ currMB->currSEnr++;
+
+ CheckAvailabilityOfNeighborsCABAC();
+
+ //========= write mb_aff (CABAC) =========
+ if(img->MbaffFrameFlag && !skip) // check for copy mode
+ {
+ if(WriteFrameFieldMBInHeader)
+ {
+ currSE->value1 = currMB->mb_field;
+ currSE->value2 = 0;
+ currSE->type = SE_MBTYPE;
+
+ currSE->writing = writeFieldModeInfo_CABAC;
+ dataPart->writeSyntaxElement(currSE, dataPart);
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "mb_field_decoding_flag");
+ #endif
+ bitCount[BITS_MB_MODE] += currSE->len;
+ no_bits += currSE->len;
+ currSE++;
+ currMB->currSEnr++;
+ }
+ }
+
+ //========= write mb_type (CABAC) =========
+ if (currMB->mb_type != 0 || ((img->type == B_SLICE) && currMB->cbp != 0))
+ {
+ currSE->value1 = mb_type;
+ currSE->value2 = 0;
+ currSE->type = SE_MBTYPE;
+ currSE->writing = writeMB_typeInfo_CABAC;
+ dataPart->writeSyntaxElement( currSE, dataPart);
+ #if TRACE
+ if (img->type == B_SLICE)
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "mb_type (B_SLICE) (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->mb_type);
+ else
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "mb_type (P_SLICE) (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->mb_type);
+ #endif
+ bitCount[BITS_MB_MODE] += currSE->len;
+ no_bits += currSE->len;
+ currSE++;
+ currMB->currSEnr++;
+ }
+ }
+ // VLC not intra
+ else if (currMB->mb_type != 0 || ((img->type == B_SLICE) && currMB->cbp != 0))
+ {
+ //===== Run Length Coding: Non-Skipped macroblock =====
+ currSE->value1 = img->cod_counter;
+ currSE->value2 = 0;
+ currSE->mapping = ue_linfo;
+ currSE->type = SE_MBTYPE;
+ dataPart->writeSyntaxElement( currSE, dataPart);
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "mb_skip_run");
+ #endif
+ bitCount[BITS_MB_MODE] += currSE->len;
+ no_bits += currSE->len;
+ currSE++;
+ currMB->currSEnr++;
+
+ // Reset cod counter
+ img->cod_counter = 0;
+
+ // write mb_aff
+ if(img->MbaffFrameFlag && !skip) // check for copy mode
+ {
+ if(WriteFrameFieldMBInHeader)
+ {
+ currSE->value1 = currMB->mb_field;
+ currSE->type = SE_MBTYPE;
+ currSE->mapping = ue_linfo;
+
+ //dataPart->writeSyntaxElement(currSE, dataPart);
+ currSE->bitpattern = (currMB->mb_field ? 1 : 0);
+ currSE->len = 1;
+ writeSyntaxElement2Buf_Fixed(currSE, dataPart->bitstream);
+
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "mb_field_decoding_flag");
+ #endif
+ bitCount[BITS_MB_MODE] += currSE->len;
+ no_bits += currSE->len;
+ currSE++;
+ currMB->currSEnr++;
+ }
+ }
+ // Put out mb mode
+ currSE->value1 = MBType2Value (currMB);
+
+ if (img->type != B_SLICE)
+ {
+ currSE->value1--;
+ }
+ currSE->mapping = ue_linfo;
+ currSE->type = SE_MBTYPE;
+ currSE->value2 = 0;
+
+ dataPart->writeSyntaxElement( currSE, dataPart);
+ #if TRACE
+ if (img->type == B_SLICE)
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "mb_type (B_SLICE) (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->mb_type);
+ else
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "mb_type (P_SLICE) (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->mb_type);
+ #endif
+ bitCount[BITS_MB_MODE] += currSE->len;
+ no_bits += currSE->len;
+ currSE++;
+ currMB->currSEnr++;
+ }
+ else
+ {
+ //Run Length Coding: Skipped macroblock
+ img->cod_counter++;
+
+ currMB->skip_flag = 1;
+ // CAVLC
+ for (j=0; j < (4 + img->num_blk8x8_uv); j++)
+ for (i=0; i < 4; i++)
+ img->nz_coeff [img->current_mb_nr][i][j]=0;
+
+
+ if(FmoGetNextMBNr(img->current_mb_nr) == -1 && img->cod_counter>0)
+ {
+ // Put out run
+ currSE->value1 = img->cod_counter;
+ currSE->value2 = 0;
+ currSE->mapping = ue_linfo;
+ currSE->type = SE_MBTYPE;
+
+ dataPart->writeSyntaxElement( currSE, dataPart);
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "mb_skip_run");
+ #endif
+ bitCount[BITS_MB_MODE] += currSE->len;
+ no_bits += currSE->len;
+ currSE++;
+ currMB->currSEnr++;
+
+ // Reset cod counter
+ img->cod_counter = 0;
+ }
+ }
+
+ //init NoMbPartLessThan8x8Flag
+ currMB->NoMbPartLessThan8x8Flag = (IS_DIRECT(currMB) && !(active_sps->direct_8x8_inference_flag))? 0: 1;
+
+ if (currMB->mb_type == IPCM)
+ {
+ int jj, uv;
+
+ if (dataPart->bitstream->bits_to_go < 8)
+ {
+ if (input->symbol_mode == CABAC) {
+ }
+ else
+ {
+ currSE->len = dataPart->bitstream->bits_to_go;
+ no_bits += currSE->len;
+ currSE->bitpattern = 0;
+ bitCount[BITS_COEFF_Y_MB]+= currSE->len;
+ writeSyntaxElement2Buf_Fixed(currSE, dataPart->bitstream);
+ currSE->mapping = ue_linfo;
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "IPCM aligment bits = %d", currSE->len);
+ #endif
+ currSE++;
+ currMB->currSEnr++;
+ }
+ }
+ for (j=0;j<MB_BLOCK_SIZE;j++)
+ {
+ jj = img->pix_y+j;
+ for (i=0;i<MB_BLOCK_SIZE;i++)
+ {
+ if (input->symbol_mode == CABAC) {
+ }
+ else
+ {
+ currSE->mapping = ue_linfo;
+ currSE->len = img->bitdepth_luma;
+ no_bits += currSE->len;
+ currSE->bitpattern = enc_picture->imgY[jj][img->pix_x+i];
+ bitCount[BITS_COEFF_Y_MB]+=currSE->len;
+ writeSyntaxElement2Buf_Fixed(currSE, dataPart->bitstream);
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "IPCM Luma (%d %d) = %d", j,i,currSE->bitpattern);
+ #endif
+ currSE++;
+ currMB->currSEnr++;
+ }
+ }
+ }
+ if (img->yuv_format != YUV400)
+ {
+ for (uv = 0; uv < 2; uv ++)
+ {
+ for (j=0;j<img->mb_cr_size_y;j++)
+ {
+ jj = img->pix_c_y+j;
+ for (i=0;i<img->mb_cr_size_x;i++)
+ {
+ if (input->symbol_mode == CABAC) {
+ }
+ else
+ {
+ currSE->mapping = ue_linfo;
+ currSE->len = img->bitdepth_chroma;
+ no_bits += currSE->len;
+ currSE->bitpattern = enc_picture->imgUV[uv][jj][img->pix_c_x+i];
+ writeSyntaxElement2Buf_Fixed(currSE, dataPart->bitstream);
+ bitCount[BITS_COEFF_UV_MB]+=currSE->len;
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "IPCM chroma(%d) (%d %d) = %d", uv, j,i,currSE->bitpattern);
+ #endif
+ currSE++;
+ currMB->currSEnr++;
+ }
+ }
+ }
+ }
+ }
+ return no_bits;
+ }
+
+ //===== BITS FOR 8x8 SUB-PARTITION MODES =====
+ if (IS_P8x8 (currMB))
+ {
+ dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);
+
+ for (i=0; i<4; i++)
+ {
+ if (input->symbol_mode==UVLC)
+ currSE->mapping = ue_linfo;
+ else
+ currSE->writing = writeB8_typeInfo_CABAC;
+
+ currSE->value1 = B8Mode2Value (currMB->b8mode[i], currMB->b8pdir[i]);
+ currSE->value2 = 0;
+ currSE->type = SE_MBTYPE;
+ dataPart->writeSyntaxElement (currSE, dataPart);
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "8x8 mode/pdir(%2d) = %3d/%d", i, currMB->b8mode[i], currMB->b8pdir[i]);
+ #endif
+ bitCount[BITS_MB_MODE]+= currSE->len;
+ no_bits += currSE->len;
+ currSE++;
+ currMB->currSEnr++;
+
+ //set NoMbPartLessThan8x8Flag for P8x8 mode
+ currMB->NoMbPartLessThan8x8Flag &= (currMB->b8mode[i]==0 && active_sps->direct_8x8_inference_flag) ||
+ (currMB->b8mode[i]==4);
+ }
+ no_bits += writeMotionInfo2NAL ();
+ currSE = &img->MB_SyntaxElements[currMB->currSEnr];
+ }
+
+ //============= Transform size flag for INTRA MBs =============
+ //-------------------------------------------------------------
+ //transform size flag for INTRA_4x4 and INTRA_8x8 modes
+ if ((currMB->mb_type == I8MB || currMB->mb_type == I4MB) && input->Transform8x8Mode)
+ {
+ currSE->value1 = currMB->luma_transform_size_8x8_flag;
+ currSE->type = SE_HEADER;
+
+ if( input->symbol_mode==UVLC)
+ {
+ currSE->mapping = ue_linfo;
+ currSE->bitpattern = currMB->luma_transform_size_8x8_flag;
+ currSE->len = 1;
+ writeSyntaxElement2Buf_Fixed(currSE, dataPart->bitstream);
+ }
+ else
+ {
+ currSE->writing = writeMB_transform_size_CABAC;
+ dataPart->writeSyntaxElement(currSE, dataPart);
+ }
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "transform size 8x8 flag = %3d", currMB->luma_transform_size_8x8_flag);
+ #endif
+
+ bitCount[BITS_MB_MODE] += currSE->len;
+ no_bits += currSE->len;
+ currSE++;
+ currMB->currSEnr++;
+ }
+
+
+ //===== BITS FOR INTRA PREDICTION MODES ====
+ no_bits += writeIntra4x4Modes(-1);
+ //===== BITS FOR CHROMA INTRA PREDICTION MODE ====
+ if (currMB->IntraChromaPredModeFlag && img->yuv_format != YUV400)
+ no_bits += writeChromaIntraPredMode();
+ else if(!rdopt) //GB CHROMA !!!!!
+ currMB->c_ipred_mode = DC_PRED_8; //setting c_ipred_mode to default is not the right place here
+ //resetting in rdopt.c (but where ??)
+ //with cabac and bframes maybe it could crash without this default
+ //since cabac needs the right neighborhood for the later MBs
+
+ //----- motion information -----
+ if (currMB->mb_type !=0 && currMB->mb_type !=P8x8)
+ {
+ no_bits += writeMotionInfo2NAL ();
+ }
+
+ if ((currMB->mb_type!=0) || (img->type==B_SLICE && (currMB->cbp!=0)))
+ {
+ *coeff_rate = writeCBPandLumaCoeff ();
+ if (img->yuv_format != YUV400)
+ *coeff_rate += writeChromaCoeff ();
+
+ no_bits += *coeff_rate;
+ }
+
+ return no_bits;
+ }
+
+ void write_terminating_bit (short bit)
+ {
+ DataPartition* dataPart;
+ const int* partMap = assignSE2partition[input->partition_mode];
+ EncodingEnvironmentPtr eep_dp;
+
+ //--- write non-slice termination symbol if the macroblock is not the first one in its slice ---
+ dataPart = &(img->currentSlice->partArr[partMap[SE_MBTYPE]]);
+ dataPart->bitstream->write_flag = 1;
+ eep_dp = &(dataPart->ee_cabac);
+
+ biari_encode_symbol_final(eep_dp, bit);
+ #if TRACE
+ fprintf (p_trace, " CABAC terminating bit = %d\n",bit);
+ #endif
+
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Write chroma intra prediction mode.
+ ************************************************************************
+ */
+ int writeChromaIntraPredMode()
+ {
+ Macroblock* currMB = &img->mb_data[img->current_mb_nr];
+ SyntaxElement* currSE = &img->MB_SyntaxElements[currMB->currSEnr];
+ Slice* currSlice = img->currentSlice;
+ int* bitCount = currMB->bitcounter;
+ const int* partMap = assignSE2partition[input->partition_mode];
+ int rate = 0;
+ DataPartition* dataPart;
+
+ //===== BITS FOR CHROMA INTRA PREDICTION MODES
+ if (input->symbol_mode==UVLC)
+ currSE->mapping = ue_linfo;
+ else
+ currSE->writing = writeCIPredMode_CABAC;
+
+ currSE->value1 = currMB->c_ipred_mode;
+ currSE->value2 = 0;
+ currSE->type = SE_INTRAPREDMODE;
+ dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);
+
+ dataPart->writeSyntaxElement (currSE, dataPart);
+ bitCount[BITS_COEFF_UV_MB] += currSE->len;
+ rate += currSE->len;
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "Chroma intra pred mode");
+ #endif
+ currSE++;
+ currMB->currSEnr++;
+
+ return rate;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Set global last_dquant according to macroblock delta qp
+ ************************************************************************
+ */
+
+ extern int last_dquant;
+
+ void set_last_dquant()
+ {
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+
+ if ((IS_INTERMV (currMB) || IS_INTRA (currMB))
+ || ((img->type==B_SLICE) && currMB->cbp != 0))
+ {
+ // non-skip
+ last_dquant = currMB->delta_qp;
+ }
+ else
+ {
+ // skip
+ last_dquant = 0;
+ }
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Passes the chosen syntax elements to the NAL
+ ************************************************************************
+ */
+ void write_one_macroblock (int eos_bit)
+ {
+ Macroblock* currMB = &img->mb_data[img->current_mb_nr];
+ int* bitCount = currMB->bitcounter;
+ int i;
+
+ extern int cabac_encoding;
+
+ //===== init and update number of intra macroblocks =====
+ if (img->current_mb_nr==0)
+ intras=0;
+
+ if (IS_INTRA(currMB))
+ intras++;
+
+ //--- write non-slice termination symbol if the macroblock is not the first one in its slice ---
+ if (input->symbol_mode==CABAC && img->current_mb_nr!=img->currentSlice->start_mb_nr && eos_bit)
+ {
+ write_terminating_bit (0);
+ }
+
+ cabac_encoding = 1;
+
+ //--- write macroblock ---
+ writeMBLayer (0, &i); // i is temporary
+
+ if (!((currMB->mb_type !=0 ) || ((img->type==B_SLICE) && currMB->cbp != 0) ))
+ {
+ for (i=0; i < 4; i++)
+ memset(img->nz_coeff [img->current_mb_nr][i], 0, (4 + img->num_blk8x8_uv) * sizeof(int)); // CAVLC
+ }
+
+ set_last_dquant();
+
+ //--- constrain intra prediction ---
+ if(input->UseConstrainedIntraPred && (img->type==P_SLICE || img->type==B_SLICE))
+ {
+ if( !IS_INTRA(currMB) )
+ {
+ img->intra_block[img->current_mb_nr] = 0;
+ }
+ }
+
+ //--- set total bit-counter ---
+ bitCount[BITS_TOTAL_MB] = bitCount[BITS_MB_MODE] + bitCount[BITS_COEFF_Y_MB]
+ + bitCount[BITS_INTER_MB] + bitCount[BITS_CBP_MB]
+ + bitCount[BITS_DELTA_QUANT_MB] + bitCount[BITS_COEFF_UV_MB];
+
+ //Rate control
+ img->NumberofMBHeaderBits=bitCount[BITS_MB_MODE] + bitCount[BITS_INTER_MB]
+ + bitCount[BITS_CBP_MB] + bitCount[BITS_DELTA_QUANT_MB];
+ img->NumberofMBTextureBits= bitCount[BITS_COEFF_Y_MB]+ bitCount[BITS_COEFF_UV_MB];
+ img->NumberofTextureBits +=img->NumberofMBTextureBits;
+ img->NumberofHeaderBits +=img->NumberofMBHeaderBits;
+ /*basic unit layer rate control*/
+ if(img->BasicUnit<img->Frame_Total_Number_MB)
+ {
+ img->NumberofBasicUnitHeaderBits +=img->NumberofMBHeaderBits;
+ img->NumberofBasicUnitTextureBits +=img->NumberofMBTextureBits;
+ }
+ /*record the total number of MBs*/
+ img->NumberofCodedMacroBlocks++;
+
+ stats->bit_slice += bitCount[BITS_TOTAL_MB];
+
+ cabac_encoding = 0;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Sets context for reference frame parameter
+ ************************************************************************
+ */
+ int BType2CtxRef (int btype)
+ {
+ return (btype<4 ? 0 : 1);
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Codes the reference frame
+ ************************************************************************
+ */
+ int writeReferenceFrame (int mode, int i, int j, int fwd_flag, int ref)
+ {
+ Macroblock* currMB = &img->mb_data[img->current_mb_nr];
+ SyntaxElement* currSE = &img->MB_SyntaxElements[currMB->currSEnr];
+ Slice* currSlice = img->currentSlice;
+ int* bitCount = currMB->bitcounter;
+ const int* partMap = assignSE2partition[input->partition_mode];
+ int rate = 0;
+ DataPartition* dataPart;
+ int num_ref = ( fwd_flag ? listXsize[LIST_0+currMB->list_offset]: listXsize[LIST_1+currMB->list_offset]);
+ int flag_mode = 0;
+
+ if( num_ref == 1 )
+ {
+ return 0;
+ }
+
+ if ( num_ref == 2 )
+ {
+ flag_mode = 1;
+ }
+
+ currSE->value1 = ref;
+ currSE->value2 = 0;
+ currSE->type = SE_REFFRAME;
+
+ dataPart = &(currSlice->partArr[partMap[currSE->type]]);
+ if (input->symbol_mode == UVLC)
+ {
+ if( flag_mode )
+ {
+ currSE->bitpattern = 1 - currSE->value1;
+ currSE->len = 1;
+ writeSyntaxElement2Buf_Fixed(currSE, dataPart->bitstream);
+ }
+ else
+ {
+ currSE->mapping = ue_linfo;
+ dataPart->writeSyntaxElement (currSE, dataPart);
+ }
+ }
+ else
+ {
+ currSE->context = BType2CtxRef (mode);
+ img->subblock_x = i; // position used for context determination
+ img->subblock_y = j; // position used for context determination
+ currSE->writing = writeRefFrame_CABAC;
+ currSE->value2 = (fwd_flag)? LIST_0:LIST_1;
+ dataPart->writeSyntaxElement (currSE, dataPart);
+ }
+
+ bitCount[BITS_INTER_MB] += currSE->len;
+ rate += currSE->len;
+ #if TRACE
+ if (fwd_flag)
+ {
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "ref_idx_l0 = %d", currSE->value1);
+ }
+ else
+ {
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "ref_idx_l1 = %d", currSE->value1);
+ }
+ #endif
+ currSE++;
+ currMB->currSEnr++;
+
+ return rate;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Writes motion vectors of an 8x8 block
+ ************************************************************************
+ */
+ int writeMotionVector8x8 (int i0,
+ int j0,
+ int i1,
+ int j1,
+ int refframe,
+ int list_idx,
+ int mv_mode)
+ {
+ int i, j, k, l, m;
+ int curr_mvd;
+ DataPartition* dataPart;
+
+ int rate = 0;
+ int step_h = input->part_size[mv_mode][0];
+ int step_v = input->part_size[mv_mode][1];
+ Macroblock* currMB = &img->mb_data[img->current_mb_nr];
+ SyntaxElement* currSE = &img->MB_SyntaxElements[currMB->currSEnr];
+ Slice* currSlice = img->currentSlice;
+ int* bitCount = currMB->bitcounter;
+ const int* partMap = assignSE2partition[input->partition_mode];
+ int refindex = refframe;
+
+ short****** all_mv = img->all_mv;
+ short****** pred_mv = img->pred_mv;
+
+ if (currMB->bi_pred_me && currMB->b8pdir[0]==2 && mv_mode == 1 && refindex == 0)
+ all_mv = currMB->bi_pred_me == 1? img->bipred_mv1 : img->bipred_mv2 ;
+
+ for (j=j0; j<j1; j+=step_v)
+ {
+ for (i=i0; i<i1; i+=step_h)
+ {
+ for (k=0; k<2; k++)
+ {
+ curr_mvd = all_mv[j][i][list_idx][refindex][mv_mode][k] - pred_mv[j][i][list_idx][refindex][mv_mode][k];
+
+ //--- store (oversampled) mvd ---
+ for (l=0; l < step_v; l++)
+ for (m=0; m < step_h; m++)
+ {
+ currMB->mvd[list_idx][j+l][i+m][k] = curr_mvd;
+ }
+ currSE->value1 = curr_mvd;
+ currSE->value2 = 0;
+ currSE->type = SE_MVD;
+ if (input->symbol_mode == UVLC)
+ {
+ currSE->mapping = se_linfo;
+ }
+ else
+ {
+ img->subblock_x = i; // position used for context determination
+ img->subblock_y = j; // position used for context determination
+ currSE->value2 = 2*k+list_idx; // identifies the component and the direction; only used for context determination
+ currSE->writing = writeMVD_CABAC;
+ }
+ dataPart = &(currSlice->partArr[partMap[SE_MVD]]);
+ dataPart->writeSyntaxElement (currSE, dataPart);
+ #if TRACE
+ if (!list_idx)
+ {
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "mvd_l0 (%d) = %3d (org_mv %3d pred_mv %3d)",k, curr_mvd, all_mv[j][i][list_idx][refindex][mv_mode][k], pred_mv[j][i][list_idx][refindex][mv_mode][k]);
+ }
+ else
+ {
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "mvd_l1 (%d) = %3d (org_mv %3d pred_mv %3d)",k, curr_mvd, all_mv[j][i][list_idx][refindex][mv_mode][k], pred_mv[j][i][list_idx][refindex][mv_mode][k]);
+ }
+
+ #endif
+ bitCount[BITS_INTER_MB] += currSE->len;
+ rate += currSE->len;
+ currSE++;
+ currMB->currSEnr++;
+ }
+ }
+ }
+ return rate;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Writes motion info
+ ************************************************************************
+ */
+ int writeMotionInfo2NAL ()
+ {
+ int k, j0, i0, refframe;
+ int jj;
+ Macroblock* currMB = &img->mb_data[img->current_mb_nr];
+ int no_bits = 0;
+ int bframe = (img->type==B_SLICE);
+ int step_h0 = (input->blc_size[IS_P8x8(currMB) ? 4 : currMB->mb_type][0] >> 2);
+ int step_v0 = (input->blc_size[IS_P8x8(currMB) ? 4 : currMB->mb_type][1] >> 2);
+
+ //=== If multiple ref. frames, write reference frame for the MB ===
+ if (IS_INTERMV (currMB))
+ {
+ // if UVLC is turned on, a 8x8 macroblock with all ref=0 in a P-frame is signalled in macroblock mode
+ if (!IS_P8x8 (currMB) || !ZeroRef (currMB) || input->symbol_mode==CABAC || bframe)
+ {
+ for (j0=0; j0<4; j0+=step_v0)
+ {
+ jj = img->block_y+j0;
+ for (i0=0; i0<4; i0+=step_h0)
+ {
+ k=j0+(i0 >> 1);
+
+ if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)//has forward vector
+ {
+ no_bits += writeReferenceFrame (currMB->b8mode[k], i0, j0, 1, enc_picture->ref_idx[LIST_0][jj][img->block_x+i0]);
+ }
+ }
+ }
+ for (j0=0; j0<4; j0+=step_v0)
+ {
+ jj = img->block_y+j0;
+ for (i0=0; i0<4; i0+=step_h0)
+ {
+ k=j0+(i0 >> 1);
+ if ((currMB->b8pdir[k]==1 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)//has backward vector
+ {
+ no_bits += writeReferenceFrame (currMB->b8mode[k], i0, j0, 0, enc_picture->ref_idx[LIST_1][jj][img->block_x+i0]);
+ }
+ }
+ }
+ }
+ }
+
+ //===== write forward motion vectors =====
+ if (IS_INTERMV (currMB))
+ {
+ for (j0=0; j0<4; j0+=step_v0)
+ {
+ jj = img->block_y+j0;
+ for (i0=0; i0<4; i0+=step_h0)
+ {
+ k=j0+(i0 >> 1);
+ if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)//has forward vector
+ {
+ refframe = enc_picture->ref_idx[LIST_0][jj][img->block_x+i0];
+ no_bits += writeMotionVector8x8 (i0, j0, i0+step_h0, j0+step_v0, refframe, LIST_0, currMB->b8mode[k]);
+ }
+ }
+ }
+ }
+
+
+ //===== write backward motion vectors =====
+ if (IS_INTERMV (currMB) && bframe)
+ {
+ for (j0=0; j0<4; j0+=step_v0)
+ {
+ jj = img->block_y+j0;
+ for (i0=0; i0<4; i0+=step_h0)
+ {
+ k=j0+(i0 >> 1);
+ if ((currMB->b8pdir[k]==1 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)//has backward vector
+ {
+ refframe = enc_picture->ref_idx[LIST_1][jj][img->block_x+i0];
+ no_bits += writeMotionVector8x8 (i0, j0, i0+step_h0, j0+step_v0, refframe, LIST_1, currMB->b8mode[k]);
+ }
+ }
+ }
+ }
+ return no_bits;
+ }
+
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Writes chrominance coefficients
+ ************************************************************************
+ */
+ int writeChromaCoeff ()
+ {
+ int rate = 0;
+ Macroblock* currMB = &img->mb_data[img->current_mb_nr];
+ SyntaxElement* currSE = &img->MB_SyntaxElements[currMB->currSEnr];
+ int* bitCount = currMB->bitcounter;
+ Slice* currSlice = img->currentSlice;
+ const int* partMap = assignSE2partition[input->partition_mode];
+ int cbp = currMB->cbp;
+ DataPartition* dataPart;
+
+ int level, run;
+ int k, uv;
+ int b8, b4, param;
+ int* ACLevel;
+ int* ACRun;
+ int* DCLevel;
+ int* DCRun;
+ //ADD-VG-14052004
+ int chroma_dc_context[3]={CHROMA_DC, CHROMA_DC_2x4, CHROMA_DC_4x4};
+ int yuv = img->yuv_format - 1;
+
+ static unsigned char chroma_ac_param[3][8][4] =
+ {
+ {{ 4, 20, 5, 21},
+ {36, 52, 37, 53},
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0}},
+
+ {{ 4, 20, 5, 21},
+ { 6, 22, 7, 23},
+ {36, 52, 37, 53},
+ {38, 54, 39, 55},
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0}},
+
+ {{ 4, 20, 5, 21},
+ {36, 52, 37, 53},
+ { 6, 22, 7, 23},
+ {38, 54, 39, 55},
+ { 8, 24, 9, 25},
+ {40, 56, 41, 57},
+ {10, 26, 11, 27},
+ {42, 58, 43, 59}}};
+ //ADD-VG-14052004-END
+
+ //=====
+ //===== D C - C O E F F I C I E N T S
+ //=====
+ if (cbp > 15) // check if any chroma bits in coded block pattern is set
+ {
+ for (uv=0; uv < 2; uv++)
+ {
+ if (input->symbol_mode == UVLC)
+ {
+ param = uv;
+ rate += writeCoeff4x4_CAVLC (CHROMA_DC, 0, 0, param);
+ // CAVLC
+ }
+ else
+ {
+
+ DCLevel = img->cofDC[uv+1][0];
+ DCRun = img->cofDC[uv+1][1];
+
+ level=1;
+ for (k=0; k <= img->num_cdc_coeff && level != 0; ++k)
+ {
+ level = currSE->value1 = DCLevel[k]; // level
+ run = currSE->value2 = DCRun [k]; // run
+
+ if (input->symbol_mode == UVLC)
+ currSE->mapping = levrun_linfo_c2x2;
+ else
+ currSE->writing = writeRunLevel_CABAC;
+
+ currSE->context = chroma_dc_context[yuv];
+ currSE->type = (IS_INTRA(currMB) ? SE_CHR_DC_INTRA : SE_CHR_DC_INTER);
+ img->is_intra_block = IS_INTRA(currMB);
+ img->is_v_block = uv;
+
+ // choose the appropriate data partition
+ dataPart = &(currSlice->partArr[partMap[currSE->type]]);
+ dataPart->writeSyntaxElement (currSE, dataPart);
+ bitCount[BITS_COEFF_UV_MB] += currSE->len;
+ rate += currSE->len;
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "DC Chroma %2d: level =%3d run =%2d",k, level, run);
+ #endif
+ // proceed to next SE
+ currSE++;
+ currMB->currSEnr++;
+ }
+ }
+ }
+ }
+
+ //=====
+ //===== A C - C O E F F I C I E N T S
+ //=====
+ uv=-1;
+ if (cbp >> 4 == 2) // check if chroma bits in coded block pattern = 10b
+ {
+ for (b8=4; b8 < (4+img->num_blk8x8_uv); b8++)
+ for (b4=0; b4 < 4; b4++)
+ {
+ if (input->symbol_mode == UVLC)
+ {
+ param = chroma_ac_param[yuv][b8-4][b4];
+ rate += writeCoeff4x4_CAVLC (CHROMA_AC, b8, b4, param);
+ // CAVLC
+ }
+ else
+ {
+
+ ACLevel = img->cofAC[b8][b4][0];
+ ACRun = img->cofAC[b8][b4][1];
+
+ level=1;
+ uv++;
+
+ img->subblock_y = subblk_offset_y[yuv][b8-4][b4]>>2;
+ img->subblock_x = subblk_offset_x[yuv][b8-4][b4]>>2;
+
+ for (k=0; k < 16 && level != 0; k++)
+ {
+ level = currSE->value1 = ACLevel[k]; // level
+ run = currSE->value2 = ACRun [k]; // run
+
+ if (input->symbol_mode == UVLC) currSE->mapping = levrun_linfo_inter;
+ else currSE->writing = writeRunLevel_CABAC;
+
+ currSE->context = CHROMA_AC;
+ currSE->type = (IS_INTRA(currMB) ? SE_CHR_AC_INTRA : SE_CHR_AC_INTER);
+ img->is_intra_block = IS_INTRA(currMB);
+ img->is_v_block = (uv>=(img->num_blk8x8_uv<<1));
+
+ // choose the appropriate data partition
+ dataPart = &(currSlice->partArr[partMap[currSE->type]]);
+ dataPart->writeSyntaxElement (currSE, dataPart);
+ bitCount[BITS_COEFF_UV_MB] += currSE->len;
+ rate += currSE->len;
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "AC Chroma %2d: level =%3d run =%2d",k, level, run);
+ #endif
+
+ // proceed to next SE
+ currSE++;
+ currMB->currSEnr++;
+ }
+ }
+ }
+ }
+
+ return rate;
+ }
+
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Writes Luma coeff of an 4x4 block
+ ************************************************************************
+ */
+ int writeLumaCoeff4x4_CABAC (int b8, int b4, int intra4x4mode)
+ {
+ int rate = 0;
+ Macroblock* currMB = &img->mb_data[img->current_mb_nr];
+ SyntaxElement* currSE = &img->MB_SyntaxElements[currMB->currSEnr];
+ Slice* currSlice = img->currentSlice;
+ const int* partMap = assignSE2partition[input->partition_mode];
+ int* bitCount = currMB->bitcounter;
+ DataPartition* dataPart;
+
+ int level, run;
+ int k;
+ int* ACLevel = img->cofAC[b8][b4][0];
+ int* ACRun = img->cofAC[b8][b4][1];
+
+ img->subblock_x = ((b8&0x1)==0) ? (((b4&0x1)==0)? 0: 1) : (((b4&0x1)==0)? 2: 3); // horiz. position for coeff_count context
+ img->subblock_y = (b8<2) ? ((b4<2) ? 0: 1) : ((b4<2) ? 2: 3); // vert. position for coeff_count context
+
+ level=1; // get inside loop
+ for(k=0; k<=16 && level !=0; k++)
+ {
+ level = currSE->value1 = ACLevel[k]; // level
+ run = currSE->value2 = ACRun [k]; // run
+
+ currSE->writing = writeRunLevel_CABAC;
+
+ currSE->context = LUMA_4x4;
+ currSE->type = (k==0
+ ? (intra4x4mode ? SE_LUM_DC_INTRA : SE_LUM_DC_INTER)
+ : (intra4x4mode ? SE_LUM_AC_INTRA : SE_LUM_AC_INTER));
+ img->is_intra_block = intra4x4mode;
+
+ // choose the appropriate data partition
+ dataPart = &(currSlice->partArr[partMap[currSE->type]]);
+ dataPart->writeSyntaxElement (currSE, dataPart);
+ bitCount[BITS_COEFF_Y_MB] += currSE->len;
+ rate += currSE->len;
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "Luma sng(%2d) level =%3d run =%2d", k, level,run);
+ #endif
+ /* proceed to next SE */
+ currSE++;
+ currMB->currSEnr++;
+ }
+
+ return rate;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Writes Luma coeff of an 8x8 block
+ ************************************************************************
+ */
+ int writeLumaCoeff8x8_CABAC (int b8, int intra_mode)
+ {
+ int rate = 0;
+ Macroblock* currMB = &img->mb_data[img->current_mb_nr];
+ SyntaxElement* currSE = &img->MB_SyntaxElements[currMB->currSEnr];
+ Slice* currSlice = img->currentSlice;
+ const int* partMap = assignSE2partition[input->partition_mode];
+ int* bitCount = currMB->bitcounter;
+ DataPartition* dataPart;
+
+ int level, run;
+ int k;
+ int* ACLevel = img->cofAC[b8][0][0];
+ int* ACRun = img->cofAC[b8][0][1];
+
+ img->subblock_x = ((b8&0x1)==0)?0:2; // horiz. position for coeff_count context
+ img->subblock_y = (b8<2)?0:2; // vert. position for coeff_count context
+
+
+ level=1; // get inside loop
+ for(k=0; k<=64 && level !=0; k++)
+ {
+ level = currSE->value1 = ACLevel[k]; // level
+ run = currSE->value2 = ACRun [k]; // run
+
+ currSE->writing = writeRunLevel_CABAC;
+
+ currSE->context = LUMA_8x8;
+ currSE->type = (k==0
+ ? (intra_mode ? SE_LUM_DC_INTRA : SE_LUM_DC_INTER)
+ : (intra_mode ? SE_LUM_AC_INTRA : SE_LUM_AC_INTER));
+ img->is_intra_block = intra_mode;
+
+ // choose the appropriate data partition
+ dataPart = &(currSlice->partArr[partMap[img->type != B_SLICE ? currSE->type : SE_BFRAME]]);
+
+ dataPart->writeSyntaxElement (currSE, dataPart);
+ bitCount[BITS_COEFF_Y_MB] += currSE->len;
+ rate += currSE->len;
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "Luma8x8 sng(%2d) level =%3d run =%2d", k, level,run);
+ #endif
+ /* proceed to next SE */
+ currSE++;
+ currMB->currSEnr++;
+
+ }
+
+ return rate;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Writes Luma Coeff of an 8x8 block
+ ************************************************************************
+ */
+ int writeLumaCoeff8x8 (int block8x8, int block_mode, int transform_size_flag)
+ {
+ int block4x4, rate = 0;
+ int intra4x4mode = (block_mode==IBLOCK);
+
+ if (block_mode == I8MB)
+ assert(transform_size_flag == 1);
+
+
+ if((!transform_size_flag) || input->symbol_mode == UVLC) // allow here if 4x4 or UVLC
+ {
+ if (input->symbol_mode == UVLC )
+ {
+ for (block4x4=0; block4x4<4; block4x4++)
+ rate += writeCoeff4x4_CAVLC (LUMA, block8x8, block4x4, (transform_size_flag)?(block_mode==I8MB):intra4x4mode);// CAVLC, pass new intra
+ }
+ else
+ {
+ for (block4x4=0; block4x4<4; block4x4++)
+ rate += writeLumaCoeff4x4_CABAC (block8x8, block4x4, intra4x4mode);
+ }
+ }
+ else
+ rate += writeLumaCoeff8x8_CABAC (block8x8, (block_mode == I8MB));
+
+ return rate;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Writes CBP, DQUANT, and Luma Coefficients of an macroblock
+ ************************************************************************
+ */
+ int writeCBPandLumaCoeff ()
+ {
+ int mb_x, mb_y, i, j, k;
+ int level, run;
+ int rate = 0;
+ Macroblock* currMB = &img->mb_data[img->current_mb_nr];
+ int* bitCount = currMB->bitcounter;
+ SyntaxElement* currSE = &img->MB_SyntaxElements[currMB->currSEnr];
+ Slice* currSlice = img->currentSlice;
+ const int* partMap = assignSE2partition[input->partition_mode];
+ int cbp = currMB->cbp;
+ DataPartition* dataPart;
+ int need_transform_size_flag; //ADD-VG-24062004
+
+ int b8, b4;
+ int* DCLevel = img->cofDC[0][0];
+ int* DCRun = img->cofDC[0][1];
+ int* ACLevel;
+ int* ACRun;
+
+ if (!IS_NEWINTRA (currMB))
+ {
+ //===== C B P =====
+ //---------------------
+ currSE->value1 = cbp;
+
+ if (IS_OLDINTRA (currMB) || currMB->mb_type == SI4MB || currMB->mb_type == I8MB)
+ {
+ if (input->symbol_mode == UVLC) currSE->mapping = cbp_linfo_intra;
+ currSE->type = SE_CBP_INTRA;
+ }
+ else
+ {
+ if (input->symbol_mode == UVLC) currSE->mapping = cbp_linfo_inter;
+ currSE->type = SE_CBP_INTER;
+ }
+ if (input->symbol_mode == CABAC) currSE->writing = writeCBP_CABAC;
+
+ // choose the appropriate data partition
+ dataPart = &(currSlice->partArr[partMap[currSE->type]]);
+
+ dataPart->writeSyntaxElement(currSE, dataPart);
+ bitCount[BITS_CBP_MB] += currSE->len;
+ rate += currSE->len;
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "CBP (%2d,%2d) = %3d",img->mb_x, img->mb_y, cbp);
+ #endif
+ // proceed to next SE
+ currSE++;
+ currMB->currSEnr++;
+
+
+ //============= Transform Size Flag for INTER MBs =============
+ //-------------------------------------------------------------
+ need_transform_size_flag = (((currMB->mb_type >= 1 && currMB->mb_type <= 3)||
+ (IS_DIRECT(currMB) && active_sps->direct_8x8_inference_flag) ||
+ (currMB->NoMbPartLessThan8x8Flag))
+ && currMB->mb_type != I8MB && currMB->mb_type != I4MB
+ && (currMB->cbp&15)
+ && input->Transform8x8Mode);
+
+ if (need_transform_size_flag)
+ {
+ currSE->value1 = currMB->luma_transform_size_8x8_flag;
+ currSE->type = SE_HEADER;
+
+ if (input->symbol_mode==UVLC) currSE->mapping = ue_linfo;
+ else currSE->writing = writeMB_transform_size_CABAC;
+
+ if( input->symbol_mode==UVLC)
+ {
+ currSE->bitpattern = currMB->luma_transform_size_8x8_flag;
+ currSE->len = 1;
+ writeSyntaxElement2Buf_Fixed(currSE, dataPart->bitstream);
+ }
+ else
+ {
+ dataPart->writeSyntaxElement(currSE, dataPart);
+ }
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "transform size 8x8 flag = %3d", currMB->luma_transform_size_8x8_flag);
+ #endif
+
+ bitCount[BITS_MB_MODE] += currSE->len;
+ rate += currSE->len;
+ currSE++;
+ currMB->currSEnr++;
+ }
+ }
+
+ //===== DQUANT =====
+ //----------------------
+ if (cbp!=0 || IS_NEWINTRA (currMB))
+ {
+ currSE->value1 = currMB->delta_qp;
+
+ if (input->symbol_mode==UVLC) currSE->mapping = se_linfo;
+ else currSE->writing = writeDquant_CABAC;
+
+ if (IS_INTER (currMB)) currSE->type = SE_DELTA_QUANT_INTER;
+ else currSE->type = SE_DELTA_QUANT_INTRA;
+
+
+ // choose the appropriate data partition
+ dataPart = &(img->currentSlice->partArr[partMap[currSE->type]]);
+ dataPart->writeSyntaxElement( currSE, dataPart);
+ bitCount[BITS_DELTA_QUANT_MB] += currSE->len;
+ rate += currSE->len;
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "Delta QP (%2d,%2d) = %3d",img->mb_x, img->mb_y, currMB->delta_qp);
+ #endif
+ // proceed to next SE
+ currSE++;
+ currMB->currSEnr++;
+ }
+
+ for (i=0; i < 4; i++)
+ memset(img->nz_coeff [img->current_mb_nr][i], 0, (4 + img->num_blk8x8_uv) * sizeof(int));
+
+ if (!IS_NEWINTRA (currMB))
+ {
+ //===== L U M I N A N C E =====
+ //--------------------------------
+ for (i=0; i<4; i++) if (cbp & (1<<i))
+ {
+ rate += writeLumaCoeff8x8 (i, currMB->b8mode[i], currMB->luma_transform_size_8x8_flag);
+ }
+ }
+ else
+ {
+ //===== L U M I N A N C E f o r 1 6 x 1 6 =====
+ //----------------------------------------------------
+ // DC coeffs
+ if (input->symbol_mode == UVLC)
+ {
+ rate += writeCoeff4x4_CAVLC (LUMA_INTRA16x16DC, 0, 0, 0); // CAVLC
+ }
+ else
+ {
+ level=1; // get inside loop
+ for (k=0; k<=16 && level!=0; k++)
+ {
+ level = currSE->value1 = DCLevel[k]; // level
+ run = currSE->value2 = DCRun [k]; // run
+
+ if (input->symbol_mode == UVLC)
+ {
+ currSE->mapping = levrun_linfo_inter;
+ }
+ else
+ {
+ currSE->writing = writeRunLevel_CABAC;
+ }
+
+ currSE->context = LUMA_16DC;
+ currSE->type = SE_LUM_DC_INTRA; // element is of type DC
+ img->is_intra_block = 1;
+
+ // choose the appropriate data partition
+ dataPart = &(currSlice->partArr[partMap[currSE->type]]);
+
+ dataPart->writeSyntaxElement (currSE, dataPart);
+ bitCount[BITS_COEFF_Y_MB] += currSE->len;
+ rate += currSE->len;
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "DC luma 16x16 sng(%2d) level =%3d run =%2d", k, level, run);
+ #endif
+ // proceed to next SE
+ currSE++;
+ currMB->currSEnr++;
+ }
+ }
+
+ // AC coeffs
+ if (cbp & 15)
+ {
+ for (mb_y=0; mb_y < 4; mb_y += 2)
+ for (mb_x=0; mb_x < 4; mb_x += 2)
+ for (j=mb_y; j < mb_y+2; j++)
+ for (i=mb_x; i < mb_x+2; i++)
+ {
+ b8 = 2*(j >> 1) + (i >> 1);
+ b4 = 2*(j & 0x01) + (i & 0x01);
+ if (input->symbol_mode == UVLC)
+ {
+ rate += writeCoeff4x4_CAVLC (LUMA_INTRA16x16AC, b8, b4, 0); // CAVLC
+ }
+ else
+ {
+ ACLevel = img->cofAC[b8][b4][0];
+ ACRun = img->cofAC[b8][b4][1];
+
+ img->subblock_y = j;
+ img->subblock_x = i;
+
+ level=1; // get inside loop
+ for (k=0;k<16 && level !=0;k++)
+ {
+ level = currSE->value1 = ACLevel[k]; // level
+ run = currSE->value2 = ACRun [k]; // run
+
+ if (input->symbol_mode == UVLC)
+ {
+ currSE->mapping = levrun_linfo_inter;
+ }
+ else
+ {
+ currSE->writing = writeRunLevel_CABAC;
+ }
+ currSE->context = LUMA_16AC;
+ currSE->type = SE_LUM_AC_INTRA; // element is of type AC
+ img->is_intra_block = 1;
+
+ // choose the appropriate data partition
+ dataPart = &(currSlice->partArr[partMap[currSE->type]]);
+
+ dataPart->writeSyntaxElement (currSE, dataPart);
+ bitCount[BITS_COEFF_Y_MB] += currSE->len;
+ rate += currSE->len;
+ #if TRACE
+ snprintf(currSE->tracestring, TRACESTRING_SIZE, "AC luma 16x16 sng(%2d) level =%3d run =%2d", k, level, run);
+ #endif
+ // proceed to next SE
+ currSE++;
+ currMB->currSEnr++;
+ }
+ }
+ }
+ }
+ }
+
+ return rate;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Get the Prediction from the Neighboring Blocks for Number of Nonzero Coefficients
+ *
+ * Luma Blocks
+ ************************************************************************
+ */
+ int predict_nnz(int i,int j)
+ {
+ PixelPos pix;
+
+ int pred_nnz = 0;
+ int cnt = 0;
+ int mb_nr = img->current_mb_nr;
+
+ // left block
+ getLuma4x4Neighbour(mb_nr, i, j, -1, 0, &pix);
+
+ if (pix.available && active_pps->constrained_intra_pred_flag && (input->partition_mode != 0))
+ {
+ pix.available &= img->intra_block[pix.mb_addr];
+ }
+
+ if (pix.available)
+ {
+ pred_nnz = img->nz_coeff [pix.mb_addr ][pix.x][pix.y];
+ cnt++;
+ }
+
+ // top block
+ getLuma4x4Neighbour(mb_nr, i, j, 0, -1, &pix);
+
+ if (pix.available && active_pps->constrained_intra_pred_flag && (input->partition_mode != 0))
+ {
+ pix.available &= img->intra_block[pix.mb_addr];
+ }
+
+ if (pix.available)
+ {
+ pred_nnz += img->nz_coeff [pix.mb_addr ][pix.x][pix.y];
+ cnt++;
+ }
+
+ if (cnt==2)
+ {
+ pred_nnz++;
+ pred_nnz/=cnt;
+ }
+
+ return pred_nnz;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Get the Prediction from the Neighboring Blocks for Number of Nonzero Coefficients
+ *
+ * Chroma Blocks
+ ************************************************************************
+ */
+ int predict_nnz_chroma(int i,int j)
+ {
+ PixelPos pix;
+
+ int pred_nnz = 0;
+ int cnt = 0;
+ int mb_nr = img->current_mb_nr;
+ static int j_off_tab [12] = {0,0,0,0,4,4,4,4,8,8,8,8};
+ int j_off = j_off_tab[j];
+
+
+ if (img->yuv_format != YUV444)
+ {
+ //YUV420 and YUV422
+ // left block
+ getChroma4x4Neighbour(mb_nr, i & 0x01, j-4, -1, 0, &pix);
+
+ if (pix.available && active_pps->constrained_intra_pred_flag && (input->partition_mode != 0))
+ {
+ pix.available &= img->intra_block[pix.mb_addr];
+ }
+
+ if (pix.available)
+ {
+ pred_nnz = img->nz_coeff [pix.mb_addr ][2 * (i >> 1) + pix.x][4 + pix.y];
+ cnt++;
+ }
+
+ // top block
+ getChroma4x4Neighbour(mb_nr, i & 0x01, j-4, 0, -1, &pix);
+
+ if (pix.available && active_pps->constrained_intra_pred_flag && (input->partition_mode != 0))
+ {
+ pix.available &= img->intra_block[pix.mb_addr];
+ }
+
+ if (pix.available)
+ {
+ pred_nnz += img->nz_coeff [pix.mb_addr ][2 * (i >> 1) + pix.x][4 + pix.y];
+ cnt++;
+ }
+ }
+ else
+ {
+ //YUV444
+ // left block
+ getChroma4x4Neighbour(mb_nr, i, j-j_off, -1, 0, &pix);
+
+ if (pix.available && active_pps->constrained_intra_pred_flag && (input->partition_mode != 0))
+ {
+ pix.available &= img->intra_block[pix.mb_addr];
+ }
+
+ if (pix.available)
+ {
+ pred_nnz = img->nz_coeff [pix.mb_addr ][pix.x][j_off + pix.y];
+ cnt++;
+ }
+
+ // top block
+ getChroma4x4Neighbour(mb_nr, i, j-j_off, 0, -1, &pix);
+
+ if (pix.available && active_pps->constrained_intra_pred_flag && (input->partition_mode != 0))
+ {
+ pix.available &= img->intra_block[pix.mb_addr];
+ }
+
+ if (pix.available)
+ {
+ pred_nnz += img->nz_coeff [pix.mb_addr ][pix.x][j_off + pix.y];
+ cnt++;
+ }
+
+ }
+
+ if (cnt==2)
+ {
+ pred_nnz++;
+ pred_nnz/=cnt;
+ }
+
+ return pred_nnz;
+ }
+
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Writes coeff of an 4x4 block (CAVLC)
+ *
+ * \author
+ * Karl Lillevold <karll at real.com>
+ * contributions by James Au <james at ubvideo.com>
+ ************************************************************************
+ */
+
+ int writeCoeff4x4_CAVLC (int block_type, int b8, int b4, int param)
+ {
+ int no_bits = 0;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ SyntaxElement *currSE = &img->MB_SyntaxElements[currMB->currSEnr];
+ int *bitCount = currMB->bitcounter;
+ Slice *currSlice = img->currentSlice;
+ DataPartition *dataPart;
+ int *partMap = assignSE2partition[input->partition_mode];
+
+ int k,level,run,vlcnum;
+ int numcoeff, lastcoeff, numtrailingones;
+ int numones, totzeros, zerosleft, numcoef;
+ int numcoeff_vlc;
+ int code, level_two_or_higher;
+ int dptype = 0, bitcounttype = 0;
+ int nnz, max_coeff_num = 0, cdc=0, cac=0;
+ int subblock_x, subblock_y;
+ char type[15];
+
+ static int incVlc[] = {0,3,6,12,24,48,32768}; // maximum vlc = 6
+
+
+ int* pLevel = NULL;
+ int* pRun = NULL;
+
+ switch (block_type)
+ {
+ case LUMA:
+ max_coeff_num = 16;
+ bitcounttype = BITS_COEFF_Y_MB;
+
+ pLevel = img->cofAC[b8][b4][0];
+ pRun = img->cofAC[b8][b4][1];
+
+ sprintf(type, "%s", "Luma");
+ if (IS_INTRA (currMB))
+ {
+ dptype = SE_LUM_AC_INTRA;
+ }
+ else
+ {
+ dptype = SE_LUM_AC_INTER;
+ }
+ break;
+ case LUMA_INTRA16x16DC:
+ max_coeff_num = 16;
+ bitcounttype = BITS_COEFF_Y_MB;
+
+ pLevel = img->cofDC[0][0];
+ pRun = img->cofDC[0][1];
+
+ sprintf(type, "%s", "Lum16DC");
+ dptype = SE_LUM_DC_INTRA;
+ break;
+ case LUMA_INTRA16x16AC:
+ max_coeff_num = 15;
+ bitcounttype = BITS_COEFF_Y_MB;
+
+ pLevel = img->cofAC[b8][b4][0];
+ pRun = img->cofAC[b8][b4][1];
+
+ sprintf(type, "%s", "Lum16AC");
+ dptype = SE_LUM_AC_INTRA;
+ break;
+
+ case CHROMA_DC:
+ max_coeff_num = img->num_cdc_coeff;
+ bitcounttype = BITS_COEFF_UV_MB;
+ cdc = 1;
+
+ pLevel = img->cofDC[param+1][0];
+ pRun = img->cofDC[param+1][1];
+
+ sprintf(type, "%s", "ChrDC");
+ if (IS_INTRA (currMB))
+ {
+ dptype = SE_CHR_DC_INTRA;
+ }
+ else
+ {
+ dptype = SE_CHR_DC_INTER;
+ }
+ break;
+ case CHROMA_AC:
+ max_coeff_num = 15;
+ bitcounttype = BITS_COEFF_UV_MB;
+ cac = 1;
+
+ pLevel = img->cofAC[b8][b4][0];
+ pRun = img->cofAC[b8][b4][1];
+
+ sprintf(type, "%s", "ChrAC");
+ if (IS_INTRA (currMB))
+ {
+ dptype = SE_CHR_AC_INTRA;
+ }
+ else
+ {
+ dptype = SE_CHR_AC_INTER;
+ }
+ break;
+ default:
+ error("writeCoeff4x4_CAVLC: Invalid block type", 600);
+ break;
+ }
+
+ dataPart = &(currSlice->partArr[partMap[dptype]]);
+
+ numcoeff = 0;
+ numtrailingones = 0;
+ numones = 0;
+ lastcoeff = 0;
+ totzeros = 0;
+ level = 1;
+
+ for(k = 0; (k <= ((cdc)?img->num_cdc_coeff:16))&& level !=0; k++)
+ {
+ level = pLevel[k]; // level
+ run = pRun[k]; // run
+
+ if (level)
+ {
+ if (run)
+ totzeros += run;
+ if (abs(level) == 1)
+ {
+ numtrailingones ++;
+ numones ++;
+ if (numtrailingones > 3)
+ {
+ numtrailingones = 3; /* clip to 3 */
+ }
+ }
+ else
+ {
+ numtrailingones = 0;
+ }
+ numcoeff ++;
+ lastcoeff = k;
+ }
+ }
+
+ if (!cdc)
+ {
+ if (!cac)
+ {
+ // luma
+ subblock_x = ((b8&0x1)==0)?(((b4&0x1)==0)?0:1):(((b4&0x1)==0)?2:3);
+ // horiz. position for coeff_count context
+ subblock_y = (b8<2)?((b4<2)?0:1):((b4<2)?2:3);
+ // vert. position for coeff_count context
+ nnz = predict_nnz(subblock_x,subblock_y);
+ }
+ else
+ {
+ // chroma AC
+ subblock_x = param >> 4;
+ subblock_y = param & 15;
+ nnz = predict_nnz_chroma(subblock_x,subblock_y);
+ }
+
+ img->nz_coeff [img->current_mb_nr ][subblock_x][subblock_y] = numcoeff;
+
+
+ if (nnz < 2)
+ {
+ numcoeff_vlc = 0;
+ }
+ else if (nnz < 4)
+ {
+ numcoeff_vlc = 1;
+ }
+ else if (nnz < 8)
+ {
+ numcoeff_vlc = 2;
+ }
+ else
+ {
+ numcoeff_vlc = 3;
+ }
+
+ }
+ else
+ {
+ // chroma DC (has its own VLC)
+ // numcoeff_vlc not relevant
+ numcoeff_vlc = 0;
+
+ subblock_x = param;
+ subblock_y = param;
+ }
+
+ currSE->type = dptype;
+
+ currSE->value1 = numcoeff;
+ currSE->value2 = numtrailingones;
+ currSE->len = numcoeff_vlc; /* use len to pass vlcnum */
+
+ #if TRACE
+ snprintf(currSE->tracestring,
+ TRACESTRING_SIZE, "%s # c & tr.1s(%d,%d) vlc=%d #c=%d #t1=%d",
+ type, subblock_x, subblock_y, numcoeff_vlc, numcoeff, numtrailingones);
+ #endif
+
+ if (!cdc)
+ writeSyntaxElement_NumCoeffTrailingOnes(currSE, dataPart);
+ else
+ writeSyntaxElement_NumCoeffTrailingOnesChromaDC(currSE, dataPart);
+
+ bitCount[bitcounttype]+=currSE->len;
+ no_bits +=currSE->len;
+
+ // proceed to next SE
+ currSE++;
+ currMB->currSEnr++;
+
+
+ if (!numcoeff)
+ return no_bits;
+
+ if (numcoeff)
+ {
+ code = 0;
+ for (k = lastcoeff; k > lastcoeff-numtrailingones; k--)
+ {
+ level = pLevel[k]; // level
+ if (abs(level) > 1)
+ {
+ printf("ERROR: level > 1\n");
+ exit(-1);
+ }
+ code <<= 1;
+ if (level < 0)
+ {
+ code |= 0x1;
+ }
+ }
+
+ if (numtrailingones)
+ {
+ currSE->type = dptype;
+
+ currSE->value2 = numtrailingones;
+ currSE->value1 = code;
+
+ #if TRACE
+ snprintf(currSE->tracestring,
+ TRACESTRING_SIZE, "%s trailing ones sign (%d,%d)",
+ type, subblock_x, subblock_y);
+ #endif
+
+ writeSyntaxElement_VLC (currSE, dataPart);
+ bitCount[bitcounttype]+=currSE->len;
+ no_bits +=currSE->len;
+
+ // proceed to next SE
+ currSE++;
+ currMB->currSEnr++;
+ }
+
+ // encode levels
+ level_two_or_higher = 1;
+ if (numcoeff > 3 && numtrailingones == 3)
+ level_two_or_higher = 0;
+
+ if (numcoeff > 10 && numtrailingones < 3)
+ vlcnum = 1;
+ else
+ vlcnum = 0;
+
+ for (k = lastcoeff - numtrailingones; k >= 0; k--)
+ {
+ level = pLevel[k]; // level
+
+ currSE->value1 = level;
+ currSE->type = dptype;
+
+ #if TRACE
+ snprintf(currSE->tracestring,
+ TRACESTRING_SIZE, "%s lev (%d,%d) k=%d vlc=%d lev=%3d",
+ type, subblock_x, subblock_y, k, vlcnum, level);
+ #endif
+
+ if (level_two_or_higher)
+ {
+ if (currSE->value1 > 0)
+ currSE->value1 --;
+ else
+ currSE->value1 ++;
+ level_two_or_higher = 0;
+ }
+
+ // encode level
+ if (vlcnum == 0)
+ writeSyntaxElement_Level_VLC1(currSE, dataPart);
+ else
+ writeSyntaxElement_Level_VLCN(currSE, vlcnum, dataPart);
+
+ // update VLC table
+ if (abs(level)>incVlc[vlcnum])
+ vlcnum++;
+
+ if (k == lastcoeff - numtrailingones && abs(level)>3)
+ vlcnum = 2;
+
+ bitCount[bitcounttype]+=currSE->len;
+ no_bits +=currSE->len;
+
+ // proceed to next SE
+ currSE++;
+ currMB->currSEnr++;
+ }
+
+ // encode total zeroes
+ if (numcoeff < max_coeff_num)
+ {
+
+ currSE->type = dptype;
+ currSE->value1 = totzeros;
+
+ vlcnum = numcoeff-1;
+
+ currSE->len = vlcnum;
+
+ #if TRACE
+ snprintf(currSE->tracestring,
+ TRACESTRING_SIZE, "%s totalrun (%d,%d) vlc=%d totzeros=%3d",
+ type, subblock_x, subblock_y, vlcnum, totzeros);
+ #endif
+ if (!cdc)
+ writeSyntaxElement_TotalZeros(currSE, dataPart);
+ else
+ writeSyntaxElement_TotalZerosChromaDC(currSE, dataPart);
+
+ bitCount[bitcounttype]+=currSE->len;
+ no_bits +=currSE->len;
+
+ // proceed to next SE
+ currSE++;
+ currMB->currSEnr++;
+ }
+
+ // encode run before each coefficient
+ zerosleft = totzeros;
+ numcoef = numcoeff;
+ for (k = lastcoeff; k >= 0; k--)
+ {
+ run = pRun[k]; // run
+
+ currSE->value1 = run;
+ currSE->type = dptype;
+
+ // for last coeff, run is remaining totzeros
+ // when zerosleft is zero, remaining coeffs have 0 run
+ if (numcoeff <= 1 || !zerosleft)
+ break;
+
+ if (numcoef > 1 && zerosleft)
+ {
+
+ vlcnum = zerosleft - 1;
+ if (vlcnum > RUNBEFORE_NUM-1)
+ vlcnum = RUNBEFORE_NUM-1;
+
+ currSE->len = vlcnum;
+
+ #if TRACE
+ snprintf(currSE->tracestring,
+ TRACESTRING_SIZE, "%s run (%d,%d) k=%d vlc=%d run=%2d",
+ type, subblock_x, subblock_y, k, vlcnum, run);
+ #endif
+
+ writeSyntaxElement_Run(currSE, dataPart);
+
+ bitCount[bitcounttype]+=currSE->len;
+ no_bits +=currSE->len;
+
+ zerosleft -= run;
+ numcoef --;
+
+ // proceed to next SE
+ currSE++;
+ currMB->currSEnr++;
+ }
+ }
+ }
+
+ return no_bits;
+ }
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Find best 16x16 based intra mode
+ *
+ * \par Input:
+ * Image parameters, pointer to best 16x16 intra mode
+ *
+ * \par Output:
+ * best 16x16 based SAD
+ ************************************************************************/
+ int find_sad_16x16(int *intra_mode)
+ {
+ int current_intra_sad_2,best_intra_sad2;
+ int M1[16][16],M0[4][4][4][4],M3[4],M4[4][4];
+
+ int i,j,k;
+ int ii,jj;
+ int mb_nr = img->current_mb_nr;
+
+ PixelPos up; //!< pixel position p(0,-1)
+ PixelPos left[17]; //!< pixel positions p(-1, -1..15)
+
+ int up_avail, left_avail, left_up_avail;
+
+ for (i=0;i<17;i++)
+ {
+ getNeighbour(mb_nr, -1 , i-1 , 1, &left[i]);
+ }
+
+ getNeighbour(mb_nr, 0 , -1 , 1, &up);
+
+ if (!(input->UseConstrainedIntraPred))
+ {
+ up_avail = up.available;
+ left_avail = left[1].available;
+ left_up_avail = left[0].available;
+ }
+ else
+ {
+ up_avail = up.available ? img->intra_block[up.mb_addr] : 0;
+ for (i=1, left_avail=1; i<17;i++)
+ left_avail &= left[i].available ? img->intra_block[left[i].mb_addr]: 0;
+ left_up_avail = left[0].available ? img->intra_block[left[0].mb_addr]: 0;
+ }
+
+ best_intra_sad2=MAX_VALUE;
+ *intra_mode = DC_PRED_16;
+
+ for (k=0;k<4;k++)
+ {
+ if (input->IntraDisableInterOnly == 0 || img->type != I_SLICE)
+ {
+ if (input->Intra16x16ParDisable && (k==VERT_PRED_16||k==HOR_PRED_16))
+ continue;
+
+ if (input->Intra16x16PlaneDisable && k==PLANE_16)
+ continue;
+ }
+ //check if there are neighbours to predict from
+ if ((k==0 && !up_avail) || (k==1 && !left_avail) || (k==3 && (!left_avail || !up_avail || !left_up_avail)))
+ {
+ ; // edge, do nothing
+ }
+ else
+ {
+ for (j=0;j<16;j++)
+ {
+ for (i=0;i<16;i++)
+ {
+ M1[j][i]=imgY_org[img->opix_y+j][img->opix_x+i]-img->mprr_2[k][j][i];
+ M0[i & 0x03][i >> 2][j & 0x03][j >> 2]=M1[j][i];
+ }
+ }
+ current_intra_sad_2=0; // no SAD start handicap here
+ for (jj=0;jj<4;jj++)
+ {
+ for (ii=0;ii<4;ii++)
+ {
+ for (j=0;j<4;j++)
+ {
+ M3[0]=M0[0][ii][j][jj]+M0[3][ii][j][jj];
+ M3[1]=M0[1][ii][j][jj]+M0[2][ii][j][jj];
+ M3[2]=M0[1][ii][j][jj]-M0[2][ii][j][jj];
+ M3[3]=M0[0][ii][j][jj]-M0[3][ii][j][jj];
+
+ M0[0][ii][j][jj]=M3[0]+M3[1];
+ M0[2][ii][j][jj]=M3[0]-M3[1];
+ M0[1][ii][j][jj]=M3[2]+M3[3];
+ M0[3][ii][j][jj]=M3[3]-M3[2];
+ }
+
+ for (i=0;i<4;i++)
+ {
+ M3[0]=M0[i][ii][0][jj]+M0[i][ii][3][jj];
+ M3[1]=M0[i][ii][1][jj]+M0[i][ii][2][jj];
+ M3[2]=M0[i][ii][1][jj]-M0[i][ii][2][jj];
+ M3[3]=M0[i][ii][0][jj]-M0[i][ii][3][jj];
+
+ M0[i][ii][0][jj]=M3[0]+M3[1];
+ M0[i][ii][2][jj]=M3[0]-M3[1];
+ M0[i][ii][1][jj]=M3[2]+M3[3];
+ M0[i][ii][3][jj]=M3[3]-M3[2];
+ for (j=0;j<4;j++)
+ if ((i+j)!=0)
+ current_intra_sad_2 += abs(M0[i][ii][j][jj]);
+ }
+ }
+ }
+
+ for (j=0;j<4;j++)
+ for (i=0;i<4;i++)
+ M4[j][i]=M0[0][i][0][j]/4;
+
+ // Hadamard of DC koeff
+ for (j=0;j<4;j++)
+ {
+ M3[0]=M4[j][0]+M4[j][3];
+ M3[1]=M4[j][1]+M4[j][2];
+ M3[2]=M4[j][1]-M4[j][2];
+ M3[3]=M4[j][0]-M4[j][3];
+
+ M4[j][0]=M3[0]+M3[1];
+ M4[j][2]=M3[0]-M3[1];
+ M4[j][1]=M3[2]+M3[3];
+ M4[j][3]=M3[3]-M3[2];
+ }
+
+ for (i=0;i<4;i++)
+ {
+ M3[0]=M4[0][i]+M4[3][i];
+ M3[1]=M4[1][i]+M4[2][i];
+ M3[2]=M4[1][i]-M4[2][i];
+ M3[3]=M4[0][i]-M4[3][i];
+
+ M4[0][i]=M3[0]+M3[1];
+ M4[2][i]=M3[0]-M3[1];
+ M4[1][i]=M3[2]+M3[3];
+ M4[3][i]=M3[3]-M3[2];
+
+ for (j=0;j<4;j++)
+ current_intra_sad_2 += abs(M4[j][i]);
+ }
+ if(current_intra_sad_2 < best_intra_sad2)
+ {
+ best_intra_sad2=current_intra_sad_2;
+ *intra_mode = k; // update best intra mode
+
+ }
+ }
+ }
+ best_intra_sad2 = best_intra_sad2/2;
+
+ return best_intra_sad2;
+
+ }
Index: llvm-test/MultiSource/Applications/JM/lencod/macroblock.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/macroblock.h:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/macroblock.h Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,112 ----
+
+ /*!
+ ************************************************************************
+ * \file
+ * macroblock.h
+ *
+ * \brief
+ * Arrays for macroblock processing
+ *
+ * \author
+ * Inge Lille-Langoy <inge.lille-langoy at telenor.com> \n
+ * Telenor Satellite Services \n
+ * P.O.Box 6914 St.Olavs plass \n
+ * N-0130 Oslo, Norway
+ *
+ ************************************************************************/
+
+ #ifndef _MACROBLOCK_H_
+ #define _MACROBLOCK_H_
+
+
+ //! just to make new temp intra mode table
+ const int MODTAB[3][2]=
+ {
+ { 0, 4},
+ {16,12},
+ { 8,20}
+ };
+
+ //! gives codeword number from CBP value, both for intra and inter
+ const unsigned char NCBP[2][48][2]=
+ {
+ { // 0 1 2 3 4 5 6 7 8 9 10 11
+ { 1, 0},{10, 1},{11, 2},{ 6, 5},{12, 3},{ 7, 6},{14,14},{ 2,10},{13, 4},{15,15},{ 8, 7},{ 3,11},
+ { 9, 8},{ 4,12},{ 5,13},{ 0, 9},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},
+ { 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},
+ { 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}
+ },
+ {
+ { 3, 0},{29, 2},{30, 3},{17, 7},{31, 4},{18, 8},{37,17},{ 8,13},{32, 5},{38,18},{19, 9},{ 9,14},
+ {20,10},{10,15},{11,16},{ 2,11},{16, 1},{33,32},{34,33},{21,36},{35,34},{22,37},{39,44},{ 4,40},
+ {36,35},{40,45},{23,38},{ 5,41},{24,39},{ 6,42},{ 7,43},{ 1,19},{41, 6},{42,24},{43,25},{25,20},
+ {44,26},{26,21},{46,46},{12,28},{45,27},{47,47},{27,22},{13,29},{28,23},{14,30},{15,31},{ 0,12}
+ },
+ };
+
+
+ extern int QP2QUANT[40];
+ extern int ver_offset[4][8][4];
+ extern int hor_offset[4][8][4];
+
+ const unsigned char subblk_offset_x[3][8][4] =
+ {
+ { {0, 4, 0, 4},
+ {0, 4, 0, 4},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}, },
+
+ { {0, 4, 0, 4},
+ {0, 4, 0, 4},
+ {0, 4, 0, 4},
+ {0, 4, 0, 4},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}, },
+
+ { {0, 4, 0, 4},
+ {8,12, 8,12},
+ {0, 4, 0, 4},
+ {8,12, 8,12},
+ {0, 4, 0, 4},
+ {8,12, 8,12},
+ {0, 4, 0, 4},
+ {8,12, 8,12} }
+ };
+
+ const unsigned char subblk_offset_y[3][8][4] =
+ { { {0, 0, 4, 4},
+ {0, 0, 4, 4},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}, },
+
+ { {0, 0, 4, 4},
+ {8, 8,12,12},
+ {0, 0, 4, 4},
+ {8, 8,12,12},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0} },
+
+ { {0, 0, 4, 4},
+ {0, 0, 4, 4},
+ {8, 8,12,12},
+ {8, 8,12,12},
+ {0, 0, 4, 4},
+ {0, 0, 4, 4},
+ {8, 8,12,12},
+ {8, 8,12,12} }
+ };
+
+ #endif
+
Index: llvm-test/MultiSource/Applications/JM/lencod/mb_access.c
diff -c /dev/null llvm-test/MultiSource/Applications/JM/lencod/mb_access.c:1.1
*** /dev/null Sat Feb 11 04:33:42 2006
--- llvm-test/MultiSource/Applications/JM/lencod/mb_access.c Sat Feb 11 04:33:22 2006
***************
*** 0 ****
--- 1,683 ----
+
+ /*!
+ *************************************************************************************
+ * \file mb_access.c
+ *
+ * \brief
+ * Functions for macroblock neighborhoods
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Karsten Sühring <suehring at hhi.de>
+ *************************************************************************************
+ */
+ #include <assert.h>
+
+ #include "global.h"
+
+ /*!
+ ************************************************************************
+ * \brief
+ * returns 1 if the macroblock at the given address is available
+ ************************************************************************
+ */
+ int mb_is_available(int mbAddr, int currMbAddr)
+ {
+ if ((mbAddr < 0) || (mbAddr > ((int)img->PicSizeInMbs - 1)))
+ return 0;
+
+ // the following line checks both: slice number and if the mb has been decoded
+ if (!img->DeblockCall)
+ {
+ if (img->mb_data[mbAddr].slice_nr != img->mb_data[currMbAddr].slice_nr)
+ return 0;
+ }
+
+ return 1;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Checks the availability of neighboring macroblocks of
+ * the current macroblock for prediction and context determination;
+ ************************************************************************
+ */
+ void CheckAvailabilityOfNeighbors()
+ {
+ const int mb_nr = img->current_mb_nr;
+ Macroblock *currMB = &img->mb_data[mb_nr];
+
+ // mark all neighbors as unavailable
+ currMB->mb_available_up = NULL;
+ currMB->mb_available_left = NULL;
+
+ if (img->MbaffFrameFlag)
+ {
+ currMB->mbAddrA = 2 * (mb_nr/2 - 1);
+ currMB->mbAddrB = 2 * (mb_nr/2 - img->PicWidthInMbs);
+ currMB->mbAddrC = 2 * (mb_nr/2 - img->PicWidthInMbs + 1);
+ currMB->mbAddrD = 2 * (mb_nr/2 - img->PicWidthInMbs - 1);
+
+ currMB->mbAvailA = mb_is_available(currMB->mbAddrA, mb_nr) && (((mb_nr/2) % img->PicWidthInMbs)!=0);
+ currMB->mbAvailB = mb_is_available(currMB->mbAddrB, mb_nr);
+ currMB->mbAvailC = mb_is_available(currMB->mbAddrC, mb_nr) && (((mb_nr/2 +1) % img->PicWidthInMbs)!=0);
+ currMB->mbAvailD = mb_is_available(currMB->mbAddrD, mb_nr) && (((mb_nr/2) % img->PicWidthInMbs)!=0);
+ }
+ else
+ {
+ currMB->mbAddrA = mb_nr - 1;
+ currMB->mbAddrB = mb_nr - img->PicWidthInMbs;
+ currMB->mbAddrC = mb_nr - img->PicWidthInMbs + 1;
+ currMB->mbAddrD = mb_nr - img->PicWidthInMbs - 1;
+
+ currMB->mbAvailA = mb_is_available(currMB->mbAddrA, mb_nr) && ((mb_nr % img->PicWidthInMbs)!=0);
+ currMB->mbAvailB = mb_is_available(currMB->mbAddrB, mb_nr);
+ currMB->mbAvailC = mb_is_available(currMB->mbAddrC, mb_nr) && (((mb_nr+1) % img->PicWidthInMbs)!=0);
+ currMB->mbAvailD = mb_is_available(currMB->mbAddrD, mb_nr) && ((mb_nr % img->PicWidthInMbs)!=0);
+ }
+
+ if (currMB->mbAvailA) currMB->mb_available_left = &(img->mb_data[currMB->mbAddrA]);
+ if (currMB->mbAvailB) currMB->mb_available_up = &(img->mb_data[currMB->mbAddrB]);
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * returns the x and y macroblock coordinates for a given MbAddress
+ ************************************************************************
+ */
+ void get_mb_block_pos (int mb_addr, int *x, int*y)
+ {
+
+ if (img->MbaffFrameFlag)
+ {
+ *x = ( (mb_addr/2) % img->PicWidthInMbs);
+ *y = (((mb_addr/2) / img->PicWidthInMbs) * 2 + (mb_addr%2));
+ }
+ else
+ {
+ *x = (mb_addr % img->PicWidthInMbs);
+ *y = (mb_addr / img->PicWidthInMbs);
+ }
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * returns the x and y sample coordinates for a given MbAddress
+ ************************************************************************
+ */
+ void get_mb_pos (int mb_addr, int *x, int*y)
+ {
+ get_mb_block_pos(mb_addr, x, y);
+
+ (*x) *= MB_BLOCK_SIZE;
+ (*y) *= MB_BLOCK_SIZE;
+ }
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * get neighbouring positions for non-aff coding
+ * \param curr_mb_nr
+ * current macroblock number (decoding order)
+ * \param xN
+ * input x position
+ * \param yN
+ * input y position
+ * \param luma
+ * 1 if luma coding, 0 for chroma
+ * \param pix
+ * returns position informations
+ ************************************************************************
+ */
+ void getNonAffNeighbour(unsigned int curr_mb_nr, int xN, int yN, int luma, PixelPos *pix)
+ {
+ Macroblock *currMb = &img->mb_data[curr_mb_nr];
+ int maxW, maxH;
+
+ if (luma)
+ {
+ maxW = 16;
+ maxH = 16;
+ }
+ else
+ {
+ assert(img->yuv_format != 0);
+ maxW = img->mb_cr_size_x;
+ maxH = img->mb_cr_size_y;
+ }
+
+ if ((xN<0)&&(yN<0))
+ {
+ pix->mb_addr = currMb->mbAddrD;
+ pix->available = currMb->mbAvailD;
+ }
+ else if ((xN<0)&&((yN>=0)&&(yN<maxH)))
+ {
+ pix->mb_addr = currMb->mbAddrA;
+ pix->available = currMb->mbAvailA;
+ }
+ else if (((xN>=0)&&(xN<maxW))&&(yN<0))
+ {
+ pix->mb_addr = currMb->mbAddrB;
+ pix->available = currMb->mbAvailB;
+ }
+ else if (((xN>=0)&&(xN<maxW))&&((yN>=0)&&(yN<maxH)))
+ {
+ pix->mb_addr = curr_mb_nr;
+ pix->available = 1;
+ }
+ else if ((xN>=maxW)&&(yN<0))
+ {
+ pix->mb_addr = currMb->mbAddrC;
+ pix->available = currMb->mbAvailC;
+ }
+ else
+ {
+ pix->available = 0;
+ }
+
+ if (pix->available || img->DeblockCall)
+ {
+ pix->x = (xN + maxW) % maxW;
+ pix->y = (yN + maxH) % maxH;
+
+ get_mb_pos(pix->mb_addr, &(pix->pos_x), &(pix->pos_y));
+
+ if (luma)
+ {
+ pix->pos_x += pix->x;
+ pix->pos_y += pix->y;
+ }
+ else
+ {
+ //pix->pos_x = pix->pos_x/(16/img->mb_cr_size_x) + pix->x;
+ //pix->pos_y = pix->pos_y/(16/img->mb_cr_size_y) + pix->y;
+ pix->pos_x = ((img->mb_cr_size_x * pix->pos_x) >> 4) + pix->x;
+ pix->pos_y = ((img->mb_cr_size_y * pix->pos_y) >> 4) + pix->y;
+ }
+ }
+ }
+
+ /*!
+ ***********************************