[llvm-commits] CVS: llvm-test/MultiSource/Applications/JM/ldecod/.cvsignore Makefile annexb.c annexb.h biaridecod.c biaridecod.h block.c block.h cabac.c cabac.h context_ini.c context_ini.h contributors.h ctx_tables.h defines.h elements.h erc_api.c erc_api.h erc_do.h erc_do_i.c erc_do_p.c erc_globals.h errorconcealment.c errorconcealment.h filehandle.c fmo.c fmo.h global.h header.c header.h ifunctions.h image.c image.h ldecod.c leaky_bucket.c leaky_bucket.h loopFilter.c loopfilter.h macroblock.c macroblock.h mb_access.c mb_access.h mbuffer.c mbuffer.h memalloc.c memalloc.h nal.c nal_part.c nalu.c nalu.h nalucommon.c nalucommon.h output.c output.h parset.c parset.h parsetcommon.c parsetcommon.h rtp.c rtp.h sei.c sei.h transform8x8.c transform8x8.h vlc.c vlc.h win32.h
Anton Korobeynikov
asl at math.spbu.ru
Sun Feb 4 06:38:53 PST 2007
Changes in directory llvm-test/MultiSource/Applications/JM/ldecod:
.cvsignore updated: 1.4 -> 1.5
Makefile updated: 1.5 -> 1.6
annexb.c updated: 1.2 -> 1.3
annexb.h updated: 1.2 -> 1.3
biaridecod.c updated: 1.2 -> 1.3
biaridecod.h updated: 1.2 -> 1.3
block.c updated: 1.2 -> 1.3
block.h updated: 1.2 -> 1.3
cabac.c updated: 1.2 -> 1.3
cabac.h updated: 1.2 -> 1.3
context_ini.c updated: 1.2 -> 1.3
context_ini.h updated: 1.2 -> 1.3
contributors.h updated: 1.2 -> 1.3
ctx_tables.h updated: 1.2 -> 1.3
defines.h updated: 1.2 -> 1.3
elements.h updated: 1.2 -> 1.3
erc_api.c updated: 1.2 -> 1.3
erc_api.h updated: 1.2 -> 1.3
erc_do.h updated: 1.2 -> 1.3
erc_do_i.c updated: 1.2 -> 1.3
erc_do_p.c updated: 1.2 -> 1.3
erc_globals.h updated: 1.2 -> 1.3
errorconcealment.c updated: 1.2 -> 1.3
errorconcealment.h updated: 1.2 -> 1.3
filehandle.c updated: 1.2 -> 1.3
fmo.c updated: 1.2 -> 1.3
fmo.h updated: 1.2 -> 1.3
global.h updated: 1.3 -> 1.4
header.c updated: 1.2 -> 1.3
header.h updated: 1.2 -> 1.3
ifunctions.h added (r1.1)
image.c updated: 1.2 -> 1.3
image.h updated: 1.2 -> 1.3
ldecod.c updated: 1.2 -> 1.3
leaky_bucket.c updated: 1.2 -> 1.3
leaky_bucket.h updated: 1.2 -> 1.3
loopFilter.c updated: 1.2 -> 1.3
loopfilter.h updated: 1.2 -> 1.3
macroblock.c updated: 1.2 -> 1.3
macroblock.h updated: 1.2 -> 1.3
mb_access.c updated: 1.2 -> 1.3
mb_access.h updated: 1.2 -> 1.3
mbuffer.c updated: 1.2 -> 1.3
mbuffer.h updated: 1.2 -> 1.3
memalloc.c updated: 1.2 -> 1.3
memalloc.h updated: 1.2 -> 1.3
nal.c updated: 1.2 -> 1.3
nal_part.c updated: 1.2 -> 1.3
nalu.c updated: 1.2 -> 1.3
nalu.h updated: 1.2 -> 1.3
nalucommon.c updated: 1.2 -> 1.3
nalucommon.h updated: 1.2 -> 1.3
output.c updated: 1.2 -> 1.3
output.h updated: 1.2 -> 1.3
parset.c updated: 1.2 -> 1.3
parset.h updated: 1.2 -> 1.3
parsetcommon.c updated: 1.2 -> 1.3
parsetcommon.h updated: 1.2 -> 1.3
rtp.c updated: 1.2 -> 1.3
rtp.h updated: 1.2 -> 1.3
sei.c updated: 1.2 -> 1.3
sei.h updated: 1.2 -> 1.3
transform8x8.c updated: 1.2 -> 1.3
transform8x8.h updated: 1.2 -> 1.3
vlc.c updated: 1.2 -> 1.3
vlc.h updated: 1.2 -> 1.3
win32.h added (r1.1)
---
Log message:
Updated JM to version 12.1. Also fixed input files. This
(finally!) closes PR963: http://llvm.org/PR963
---
Diffs of the changes: (+32689 -0)
.cvsignore | 3
Makefile | 8
annexb.c | 316 +++
annexb.h | 28
biaridecod.c | 386 ++++
biaridecod.h | 39
block.c | 1358 ++++++++++++++
block.h | 31
cabac.c | 1788 +++++++++++++++++++
cabac.h | 54
context_ini.c | 74
context_ini.h | 23
contributors.h | 208 ++
ctx_tables.h | 729 +++++++
defines.h | 155 +
elements.h | 107 +
erc_api.c | 382 ++++
erc_api.h | 166 +
erc_do.h | 44
erc_do_i.c | 537 +++++
erc_do_p.c | 1826 +++++++++++++++++++
erc_globals.h | 52
errorconcealment.c | 242 ++
errorconcealment.h | 21
filehandle.c | 165 +
fmo.c | 551 +++++
fmo.h | 30
global.h | 804 ++++++++
header.c | 802 ++++++++
header.h | 23
ifunctions.h | 121 +
image.c | 2059 ++++++++++++++++++++++
image.h | 24
ldecod.c | 999 ++++++++++
leaky_bucket.c | 138 +
leaky_bucket.h | 26
loopFilter.c | 476 +++++
loopfilter.h | 18
macroblock.c | 4938 +++++++++++++++++++++++++++++++++++++++++++++++++++++
macroblock.h | 335 +++
mb_access.c | 679 +++++++
mb_access.h | 36
mbuffer.c | 3864 +++++++++++++++++++++++++++++++++++++++++
mbuffer.h | 223 ++
memalloc.c | 591 ++++++
memalloc.h | 55
nal.c | 118 +
nal_part.c | 44
nalu.c | 44
nalu.h | 28
nalucommon.c | 80
nalucommon.h | 55
output.c | 703 +++++++
output.h | 27
parset.c | 702 +++++++
parset.h | 44
parsetcommon.c | 218 ++
parsetcommon.h | 214 ++
rtp.c | 372 +++
rtp.h | 48
sei.c | 1825 +++++++++++++++++++
sei.h | 68
transform8x8.c | 1034 +++++++++++
transform8x8.h | 38
vlc.c | 1369 ++++++++++++++
vlc.h | 56
win32.h | 68
67 files changed, 32689 insertions(+)
Index: llvm-test/MultiSource/Applications/JM/ldecod/.cvsignore
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/.cvsignore:1.5
--- /dev/null Sun Feb 4 08:38:42 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/.cvsignore Sun Feb 4 08:38:31 2007
@@ -0,0 +1,3 @@
+Output
+dataDec.txt
+log.dec
Index: llvm-test/MultiSource/Applications/JM/ldecod/Makefile
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/Makefile:1.6
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/Makefile Sun Feb 4 08:38:31 2007
@@ -0,0 +1,8 @@
+LEVEL = ../../../..
+PROG = ldecod
+CPPFLAGS = -D __USE_LARGEFILE64 -D _FILE_OFFSET_BITS=64 -g
+LDFLAGS = -lm $(TOOLLINKOPTS)
+
+RUN_OPTIONS = -i $(PROJ_SRC_DIR)/data/test.264 -o $(PROJ_SRC_DIR)/data/test_dec.yuv -r $(PROJ_SRC_DIR)/data/test_rec.yuv
+
+include ../../../Makefile.multisrc
Index: llvm-test/MultiSource/Applications/JM/ldecod/annexb.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/annexb.c:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/annexb.c Sun Feb 4 08:38:31 2007
@@ -0,0 +1,316 @@
+
+/*!
+ *************************************************************************************
+ * \file annexb.c
+ *
+ * \brief
+ * Annex B Byte Stream format
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Stephan Wenger <stewe at cs.tu-berlin.de>
+ *************************************************************************************
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "global.h"
+#include "annexb.h"
+#include "memalloc.h"
+
+
+FILE *bits = NULL; //!< the bit stream file
+static int FindStartCode (unsigned char *Buf, int zeros_in_startcode);
+
+int IsFirstByteStreamNALU=1;
+int LastAccessUnitExists=0;
+int NALUCount=0;
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Returns the size of the NALU (bits between start codes in case of
+ * Annex B. nalu->buf and nalu->len are filled. Other field in
+ * nalu-> remain uninitialized (will be taken care of by NALUtoRBSP.
+ *
+ * \return
+ * 0 if there is nothing any more to read (EOF)
+ * -1 in case of any error
+ *
+ * \note Side-effect: Returns length of start-code in bytes.
+ *
+ * \note
+ * GetAnnexbNALU expects start codes at byte aligned positions in the file
+ *
+ ************************************************************************
+ */
+
+int GetAnnexbNALU (NALU_t *nalu)
+{
+ int info2, info3, pos = 0;
+ int StartCodeFound, rewind;
+ unsigned char *Buf;
+ int LeadingZero8BitsCount=0, TrailingZero8Bits=0;
+
+ if ((Buf = (unsigned char*)calloc (nalu->max_size , sizeof(char))) == NULL) no_mem_exit("GetAnnexbNALU: Buf");
+
+ while(!feof(bits) && (Buf[pos++]=fgetc(bits))==0);
+
+ if(feof(bits))
+ {
+ if(pos==0)
+ {
+ free (Buf);
+ return 0;
+ }
+ else
+ {
+ printf( "GetAnnexbNALU can't read start code\n");
+ free(Buf);
+ return -1;
+ }
+ }
+
+ if(Buf[pos-1]!=1)
+ {
+ printf ("GetAnnexbNALU: no Start Code at the begin of the NALU, return -1\n");
+ free(Buf);
+ return -1;
+ }
+
+ if(pos<3)
+ {
+ printf ("GetAnnexbNALU: no Start Code at the begin of the NALU, return -1\n");
+ free(Buf);
+ return -1;
+ }
+ else if(pos==3)
+ {
+ nalu->startcodeprefix_len = 3;
+ LeadingZero8BitsCount = 0;
+ }
+ else
+ {
+ LeadingZero8BitsCount = pos-4;
+ nalu->startcodeprefix_len = 4;
+ }
+
+ //the 1st byte stream NAL unit can has leading_zero_8bits, but subsequent ones are not
+ //allowed to contain it since these zeros(if any) are considered trailing_zero_8bits
+ //of the previous byte stream NAL unit.
+ if(!IsFirstByteStreamNALU && LeadingZero8BitsCount>0)
+ {
+ printf ("GetAnnexbNALU: The leading_zero_8bits syntax can only be present in the first byte stream NAL unit, return -1\n");
+ free(Buf);
+ return -1;
+ }
+ IsFirstByteStreamNALU=0;
+
+ StartCodeFound = 0;
+ info2 = 0;
+ info3 = 0;
+
+ while (!StartCodeFound)
+ {
+ if (feof (bits))
+ {
+ //Count the trailing_zero_8bits
+ while(Buf[pos-2-TrailingZero8Bits]==0)
+ TrailingZero8Bits++;
+ nalu->len = (pos-1)-nalu->startcodeprefix_len-LeadingZero8BitsCount-TrailingZero8Bits;
+ memcpy (nalu->buf, &Buf[LeadingZero8BitsCount+nalu->startcodeprefix_len], nalu->len);
+ nalu->forbidden_bit = (nalu->buf[0]>>7) & 1;
+ nalu->nal_reference_idc = (nalu->buf[0]>>5) & 3;
+ nalu->nal_unit_type = (nalu->buf[0]) & 0x1f;
+
+// printf ("GetAnnexbNALU, eof case: pos %d nalu->len %d, nalu->reference_idc %d, nal_unit_type %d \n", pos, nalu->len, nalu->nal_reference_idc, nalu->nal_unit_type);
+
+#if TRACE
+ fprintf (p_trace, "\n\nLast NALU in File\n\n");
+ fprintf (p_trace, "Annex B NALU w/ %s startcode, len %d, forbidden_bit %d, nal_reference_idc %d, nal_unit_type %d\n\n",
+ nalu->startcodeprefix_len == 4?"long":"short", nalu->len, nalu->forbidden_bit, nalu->nal_reference_idc, nalu->nal_unit_type);
+ fflush (p_trace);
+#endif
+ free(Buf);
+ return pos-1;
+ }
+ Buf[pos++] = fgetc (bits);
+ info3 = FindStartCode(&Buf[pos-4], 3);
+ if(info3 != 1)
+ info2 = FindStartCode(&Buf[pos-3], 2);
+ StartCodeFound = (info2 == 1 || info3 == 1);
+ }
+
+ //Count the trailing_zero_8bits
+ if(info3==1) //if the detected start code is 00 00 01, trailing_zero_8bits is sure not to be present
+ {
+ while(Buf[pos-5-TrailingZero8Bits]==0)
+ TrailingZero8Bits++;
+ }
+ // Here, we have found another start code (and read length of startcode bytes more than we should
+ // have. Hence, go back in the file
+ rewind = 0;
+ if(info3 == 1)
+ rewind = -4;
+ else if (info2 == 1)
+ rewind = -3;
+ else
+ printf(" Panic: Error in next start code search \n");
+
+ if (0 != fseek (bits, rewind, SEEK_CUR))
+ {
+ snprintf (errortext, ET_SIZE, "GetAnnexbNALU: Cannot fseek %d in the bit stream file", rewind);
+ free(Buf);
+ error(errortext, 600);
+ }
+
+ // Here the leading zeros(if any), Start code, the complete NALU, trailing zeros(if any)
+ // and the next start code is in the Buf.
+ // The size of Buf is pos, pos+rewind are the number of bytes excluding the next
+ // start code, and (pos+rewind)-startcodeprefix_len-LeadingZero8BitsCount-TrailingZero8Bits
+ // is the size of the NALU.
+
+ nalu->len = (pos+rewind)-nalu->startcodeprefix_len-LeadingZero8BitsCount-TrailingZero8Bits;
+ memcpy (nalu->buf, &Buf[LeadingZero8BitsCount+nalu->startcodeprefix_len], nalu->len);
+ nalu->forbidden_bit = (nalu->buf[0]>>7) & 1;
+ nalu->nal_reference_idc = (nalu->buf[0]>>5) & 3;
+ nalu->nal_unit_type = (nalu->buf[0]) & 0x1f;
+
+
+//printf ("GetAnnexbNALU, regular case: pos %d nalu->len %d, nalu->reference_idc %d, nal_unit_type %d \n", pos, nalu->len, nalu->nal_reference_idc, nalu->nal_unit_type);
+#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",
+ nalu->startcodeprefix_len == 4?"long":"short", nalu->len, nalu->forbidden_bit, nalu->nal_reference_idc, nalu->nal_unit_type);
+ fflush (p_trace);
+#endif
+
+ free(Buf);
+
+ return (pos+rewind);
+}
+
+
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Opens the bit stream file named fn
+ * \return
+ * none
+ ************************************************************************
+ */
+void OpenBitstreamFile (char *fn)
+{
+ if (NULL == (bits=fopen(fn, "rb")))
+ {
+ snprintf (errortext, ET_SIZE, "Cannot open Annex B ByteStream file '%s'", input->infile);
+ error(errortext,500);
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Closes the bit stream file
+ ************************************************************************
+ */
+void CloseBitstreamFile()
+{
+ fclose (bits);
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * returns if new start code is found at byte aligned position buf.
+ * new-startcode is of form N 0x00 bytes, followed by a 0x01 byte.
+ *
+ * \return
+ * 1 if start-code is found or \n
+ * 0, indicating that there is no start code
+ *
+ * \param Buf
+ * pointer to byte-stream
+ * \param zeros_in_startcode
+ * indicates number of 0x00 bytes in start-code.
+ ************************************************************************
+ */
+static int FindStartCode (unsigned char *Buf, int zeros_in_startcode)
+{
+ int info;
+ int i;
+
+ info = 1;
+ for (i = 0; i < zeros_in_startcode; i++)
+ if(Buf[i] != 0)
+ info = 0;
+
+ if(Buf[i] != 1)
+ info = 0;
+ return info;
+}
+
+void CheckZeroByteNonVCL(NALU_t *nalu, int * ret)
+{
+ int CheckZeroByte=0;
+
+ //This function deals only with non-VCL NAL units
+ if(nalu->nal_unit_type>=1&&nalu->nal_unit_type<=5)
+ return;
+
+ //for SPS and PPS, zero_byte shall exist
+ if(nalu->nal_unit_type==NALU_TYPE_SPS || nalu->nal_unit_type==NALU_TYPE_PPS)
+ CheckZeroByte=1;
+ //check the possibility of the current NALU to be the start of a new access unit, according to 7.4.1.2.3
+ if(nalu->nal_unit_type==NALU_TYPE_AUD || nalu->nal_unit_type==NALU_TYPE_SPS ||
+ nalu->nal_unit_type==NALU_TYPE_PPS || nalu->nal_unit_type==NALU_TYPE_SEI ||
+ (nalu->nal_unit_type>=13 && nalu->nal_unit_type<=18))
+ {
+ if(LastAccessUnitExists)
+ {
+ LastAccessUnitExists=0; //deliver the last access unit to decoder
+ NALUCount=0;
+ }
+ }
+ NALUCount++;
+ //for the first NAL unit in an access unit, zero_byte shall exists
+ if(NALUCount==1)
+ CheckZeroByte=1;
+ if(CheckZeroByte && nalu->startcodeprefix_len==3)
+ {
+ printf("warning: zero_byte shall exist\n");
+ //because it is not a very serious problem, we may not indicate an error by setting ret to -1
+ //*ret=-1;
+ }
+}
+
+void CheckZeroByteVCL(NALU_t *nalu, int * ret)
+{
+ int CheckZeroByte=0;
+
+ //This function deals only with VCL NAL units
+ if(!(nalu->nal_unit_type>=1&&nalu->nal_unit_type<=5))
+ return;
+
+ if(LastAccessUnitExists)
+ {
+ NALUCount=0;
+ }
+ NALUCount++;
+ //the first VCL NAL unit that is the first NAL unit after last VCL NAL unit indicates
+ //the start of a new access unit and hence the first NAL unit of the new access unit. (sounds like a tongue twister :-)
+ if(NALUCount==1)
+ CheckZeroByte=1;
+ LastAccessUnitExists=1;
+ if(CheckZeroByte && nalu->startcodeprefix_len==3)
+ {
+ printf("warning: zero_byte shall exist\n");
+ //because it is not a very serious problem, we may not indicate an error by setting ret to -1
+ //*ret=-1;
+ }
+}
Index: llvm-test/MultiSource/Applications/JM/ldecod/annexb.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/annexb.h:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/annexb.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,28 @@
+
+/*!
+ *************************************************************************************
+ * \file annexb.h
+ *
+ * \brief
+ * Annex B byte stream buffer handling.
+ *
+ *************************************************************************************
+ */
+
+#ifndef _ANNEXB_H_
+#define _ANNEXB_H_
+
+#include "nalucommon.h"
+
+extern int IsFirstByteStreamNALU;
+extern int LastAccessUnitExists;
+extern int NALUCount;
+
+int GetAnnexbNALU (NALU_t *nalu);
+void OpenBitstreamFile (char *fn);
+void CloseBitstreamFile();
+void CheckZeroByteNonVCL(NALU_t *nalu, int * ret);
+void CheckZeroByteVCL(NALU_t *nalu, int * ret);
+
+#endif
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/biaridecod.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/biaridecod.c:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/biaridecod.c Sun Feb 4 08:38:31 2007
@@ -0,0 +1,386 @@
+
+/*!
+ *************************************************************************************
+ * \file biaridecod.c
+ *
+ * \brief
+ * binary arithmetic decoder routines
+ * \date
+ * 21. Oct 2000
+ * \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 "global.h"
+#include "memalloc.h"
+
+extern int symbolCount;
+
+int binCount = 0;
+
+#define Dbuffer (dep->Dbuffer)
+#define Dbits_to_go (dep->Dbits_to_go)
+#define Dcodestrm (dep->Dcodestrm)
+#define Dcodestrm_len (dep->Dcodestrm_len)
+
+#define B_BITS 10 // Number of bits to represent the whole coding interval
+#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
+};
+
+/************************************************************************
+ * M a c r o s
+ ************************************************************************
+ */
+
+#define get_byte(){ \
+ Dbuffer = Dcodestrm[(*Dcodestrm_len)++];\
+ Dbits_to_go = 7; \
+ }
+
+
+/************************************************************************
+ ************************************************************************
+ init / exit decoder
+ ************************************************************************
+ ************************************************************************/
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocates memory for the DecodingEnvironment struct
+ * \return DecodingContextPtr
+ * allocates memory
+ ************************************************************************
+ */
+DecodingEnvironmentPtr arideco_create_decoding_environment()
+{
+ DecodingEnvironmentPtr dep;
+
+ if ((dep = calloc(1,sizeof(DecodingEnvironment))) == NULL)
+ no_mem_exit("arideco_create_decoding_environment: dep");
+ return dep;
+}
+
+
+/*!
+ ***********************************************************************
+ * \brief
+ * Frees memory of the DecodingEnvironment struct
+ ***********************************************************************
+ */
+void arideco_delete_decoding_environment(DecodingEnvironmentPtr dep)
+{
+ if (dep == NULL)
+ {
+ snprintf(errortext, ET_SIZE, "Error freeing dep (NULL pointer)");
+ error (errortext, 200);
+ }
+ else
+ free(dep);
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Initializes the DecodingEnvironment for the arithmetic coder
+ ************************************************************************
+ */
+void arideco_start_decoding(DecodingEnvironmentPtr dep, unsigned char *cpixcode,
+ int firstbyte, int *cpixcode_len, int slice_type )
+{
+
+ int value = 0;
+
+ Dcodestrm = cpixcode;
+ Dcodestrm_len = cpixcode_len;
+ *Dcodestrm_len = firstbyte;
+
+ {
+ int i;
+ Dbits_to_go = 0;
+ for (i = 0; i < B_BITS -1 ; i++) // insertion of redundant bit
+ {
+ if (--Dbits_to_go < 0)
+ get_byte();
+ value = (value<<1) | ((Dbuffer >> Dbits_to_go) & 0x01);
+ }
+ }
+ dep->Drange = HALF-2;
+ dep->Dvalue = value;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * arideco_bits_read
+ ************************************************************************
+ */
+int arideco_bits_read(DecodingEnvironmentPtr dep)
+{
+ return 8 * ((*Dcodestrm_len)-1) + (8 - Dbits_to_go) - 16;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * arideco_done_decoding():
+ ************************************************************************
+ */
+void arideco_done_decoding(DecodingEnvironmentPtr dep)
+{
+ (*Dcodestrm_len)++;
+}
+
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * biari_decode_symbol():
+ * \return
+ * the decoded symbol
+ ************************************************************************
+ */
+unsigned int biari_decode_symbol(DecodingEnvironmentPtr dep, BiContextTypePtr bi_ct )
+{
+ register unsigned int bit = bi_ct->MPS;
+ register unsigned int value = dep->Dvalue;
+ register unsigned int range = dep->Drange;
+ register unsigned int rLPS = (unsigned int) rLPS_table_64x4[bi_ct->state][(range>>6) & 0x03];
+
+#if (2==TRACE)
+ fprintf(p_trace, "%d 0x%04x %d %d\n", binCount++, dep->Drange, bi_ct->state, bi_ct->MPS );
+#endif
+
+ range -= rLPS;
+
+ if (value < range) /* MPS */
+ bi_ct->state = AC_next_state_MPS_64[bi_ct->state]; // next state
+ else /* LPS */
+ {
+ value -= range;
+ range = rLPS;
+ bit = !bit;
+ if (!bi_ct->state) // switch meaning of MPS if necessary
+ bi_ct->MPS ^= 0x01;
+ bi_ct->state = AC_next_state_LPS_64[bi_ct->state]; // next state
+ }
+
+ while (range < QUARTER)
+ {
+ /* Double range */
+ range <<= 1;
+ if (--Dbits_to_go < 0)
+ get_byte();
+ /* Shift in next bit and add to value */
+ value = (value << 1) | ((Dbuffer >> Dbits_to_go) & 0x01);
+
+ }
+
+ dep->Drange = range;
+ dep->Dvalue = value;
+
+ return(bit);
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * biari_decode_symbol_eq_prob():
+ * \return
+ * the decoded symbol
+ ************************************************************************
+ */
+unsigned int biari_decode_symbol_eq_prob(DecodingEnvironmentPtr dep)
+{
+ register unsigned int bit = 0;
+ register unsigned int value = (dep->Dvalue<<1);
+
+#if TRACE
+// fprintf(p_trace, "%d 0x%04x\n", binCount++, dep->Drange );
+#endif
+
+ if (--Dbits_to_go < 0)
+ get_byte();
+ /* Shift in next bit and add to value */
+ value |= (Dbuffer >> Dbits_to_go) & 0x01;
+ if (value >= dep->Drange)
+ {
+ bit = 1;
+ value -= dep->Drange;
+ }
+
+ dep->Dvalue = value;
+
+ return(bit);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * biari_decode_symbol_final():
+ * \return
+ * the decoded symbol
+ ************************************************************************
+ */
+unsigned int biari_decode_final(DecodingEnvironmentPtr dep)
+{
+ register unsigned int value = dep->Dvalue;
+ register unsigned int range = dep->Drange - 2;
+
+#if (2==TRACE)
+ fprintf(p_trace, "%d 0x%04x\n", binCount++, dep->Drange );
+#endif
+
+ if (value >= range)
+ {
+ return 1;
+ }
+ else
+ {
+ while (range < QUARTER)
+ {
+ /* Double range */
+ range <<= 1;
+ if (--Dbits_to_go < 0)
+ get_byte();
+ /* Shift in next bit and add to value */
+ value = (value << 1) | ((Dbuffer >> Dbits_to_go) & 0x01);
+ }
+ dep->Dvalue = value;
+ dep->Drange = range;
+ return 0;
+ }
+}
+
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Initializes a given context with some pre-defined probability state
+ ************************************************************************
+ */
+void biari_init_context (struct img_par* img, BiContextTypePtr ctx, const int* ini)
+{
+ int pstate;
+
+ pstate = ((ini[0]* imax(0,img->qp) )>>4) + ini[1];
+ pstate = iClip3(1, 126, pstate);
+
+ if ( pstate >= 64 )
+ {
+ ctx->state = (unsigned short) (pstate - 64);
+ ctx->MPS = 1;
+ }
+ else
+ {
+ ctx->state = (unsigned short) (63 - pstate);
+ ctx->MPS = 0;
+ }
+}
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/biaridecod.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/biaridecod.h:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/biaridecod.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,39 @@
+
+/*!
+ ***************************************************************************
+ * \file
+ * biaridecod.h
+ *
+ * \brief
+ * Headerfile for binary arithmetic decoder routines
+ *
+ * \author
+ * Detlev Marpe,
+ * Gabi Blättermann
+ * Copyright (C) 2000 HEINRICH HERTZ INSTITUTE All Rights Reserved.
+ *
+ * \date
+ * 21. Oct 2000
+ **************************************************************************
+ */
+
+#ifndef _BIARIDECOD_H_
+#define _BIARIDECOD_H_
+
+
+/************************************************************************
+ * D e f i n i t i o n s
+ ***********************************************************************
+ */
+
+void arideco_start_decoding(DecodingEnvironmentPtr eep, unsigned char *code_buffer, int firstbyte, int *code_len, int slice_type);
+int arideco_bits_read(DecodingEnvironmentPtr dep);
+void arideco_done_decoding(DecodingEnvironmentPtr dep);
+void biari_init_context (struct img_par *img, BiContextTypePtr ctx, const int* ini);
+void rescale_cum_freq(BiContextTypePtr bi_ct);
+unsigned int biari_decode_symbol(DecodingEnvironmentPtr dep, BiContextTypePtr bi_ct );
+unsigned int biari_decode_symbol_eq_prob(DecodingEnvironmentPtr dep);
+unsigned int biari_decode_final(DecodingEnvironmentPtr dep);
+
+#endif // BIARIDECOD_H_
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/block.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/block.c:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/block.c Sun Feb 4 08:38:31 2007
@@ -0,0 +1,1358 @@
+
+/*!
+ ***********************************************************************
+ * \file
+ * block.c
+ *
+ * \brief
+ * Block functions
+ *
+ * \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>
+ ***********************************************************************
+ */
+
+#include "contributors.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "global.h"
+#include "block.h"
+#include "image.h"
+#include "mb_access.h"
+
+
+#define Q_BITS 15
+
+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}}
+};
+static const int A[4][4] = {
+ { 16, 20, 16, 20},
+ { 20, 25, 20, 25},
+ { 16, 20, 16, 20},
+ { 20, 25, 20, 25}
+};
+
+int quant_intra_default[16] = {
+ 6,13,20,28,
+13,20,28,32,
+20,28,32,37,
+28,32,37,42
+};
+
+int quant_inter_default[16] = {
+10,14,20,24,
+14,20,24,27,
+20,24,27,30,
+24,27,30,34
+};
+
+int quant8_intra_default[64] = {
+ 6,10,13,16,18,23,25,27,
+10,11,16,18,23,25,27,29,
+13,16,18,23,25,27,29,31,
+16,18,23,25,27,29,31,33,
+18,23,25,27,29,31,33,36,
+23,25,27,29,31,33,36,38,
+25,27,29,31,33,36,38,40,
+27,29,31,33,36,38,40,42
+};
+
+int quant8_inter_default[64] = {
+ 9,13,15,17,19,21,22,24,
+13,13,17,19,21,22,24,25,
+15,17,19,21,22,24,25,27,
+17,19,21,22,24,25,27,28,
+19,21,22,24,25,27,28,30,
+21,22,24,25,27,28,30,32,
+22,24,25,27,28,30,32,33,
+24,25,27,28,30,32,33,35
+};
+
+int quant_org[16] = { //to be use if no q matrix is chosen
+16,16,16,16,
+16,16,16,16,
+16,16,16,16,
+16,16,16,16
+};
+
+int quant8_org[64] = { //to be use if no q matrix is chosen
+16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16
+};
+
+// 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..L, 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
+ * makes and returns 4x4 blocks with all 5 intra prediction modes
+ *
+ * \return
+ * DECODING_OK decoding of intraprediction mode was sucessfull \n
+ * SEARCH_SYNC search next sync element as errors while decoding occured
+ ***********************************************************************
+ */
+
+int intrapred( struct img_par *img, //!< image parameters
+ int ioff, //!< pixel offset X within MB
+ int joff, //!< pixel offset Y within MB
+ int img_block_x, //!< location of block X, multiples of 4
+ int img_block_y) //!< location of block Y, multiples of 4
+{
+ int i,j;
+ int s0;
+ int img_y,img_x;
+ imgpel PredPel[13]; // array of predictor pels
+
+ imgpel **imgY = dec_picture->imgY;
+
+ 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;
+
+ int mb_nr=img->current_mb_nr;
+
+ byte predmode = img->ipredmode[img_block_y][img_block_x];
+ int jpos0 = joff, jpos1 = joff + 1, jpos2 = joff + 2, jpos3 = joff + 3;
+ int ipos0 = ioff, ipos1 = ioff + 1, ipos2 = ioff + 2, ipos3 = ioff + 3;
+
+
+ img_x=img_block_x*4;
+ img_y=img_block_y*4;
+
+ for (i=0;i<4;i++)
+ {
+ getNeighbour(mb_nr, ioff -1 , joff +i , IS_LUMA, &pix_a[i]);
+ }
+
+ getNeighbour(mb_nr, ioff , joff -1 , IS_LUMA, &pix_b);
+ getNeighbour(mb_nr, ioff +4 , joff -1 , IS_LUMA, &pix_c);
+ getNeighbour(mb_nr, ioff -1 , joff -1 , IS_LUMA, &pix_d);
+
+ pix_c.available = pix_c.available && !((ioff==4) && ((joff==4)||(joff==12)));
+
+ if (active_pps->constrained_intra_pred_flag)
+ {
+ 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;
+ }
+
+ // 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_luma;
+ }
+
+ 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_luma;
+ }
+
+ if (block_available_up_left)
+ {
+ P_X = imgY[pix_d.pos_y][pix_d.pos_x];
+ }
+ else
+ {
+ P_X = img->dc_pred_value_luma;
+ }
+
+
+ switch (predmode)
+ {
+ case DC_PRED: /* 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)/(2*BLOCK_SIZE);
+ }
+ else if (!block_available_up && block_available_left)
+ {
+ // upper edge
+ s0 = (P_I + P_J + P_K + P_L + 2)/BLOCK_SIZE;
+ }
+ else if (block_available_up && !block_available_left)
+ {
+ // left edge
+ s0 = (P_A + P_B + P_C + P_D + 2)/BLOCK_SIZE;
+ }
+ else //if (!block_available_up && !block_available_left)
+ {
+ // top left corner, nothing to predict from
+ s0 = img->dc_pred_value_luma;
+ }
+
+ for (j=0; j < BLOCK_SIZE; j++)
+ {
+ for (i=0; i < BLOCK_SIZE; i++)
+ {
+ // store DC prediction
+ img->mpr[j+joff][i+ioff] = (imgpel) s0;
+ }
+ }
+ break;
+
+ case VERT_PRED: /* vertical prediction from block above */
+ if (!block_available_up)
+ printf ("warning: Intra_4x4_Vertical prediction mode not allowed at mb %d\n", (int) img->current_mb_nr);
+
+ for(j=0;j<BLOCK_SIZE;j++)
+ for(i=0;i<BLOCK_SIZE;i++)
+ img->mpr[j+joff][i+ioff]=imgY[pix_b.pos_y][pix_b.pos_x+i];/* store predicted 4x4 block */
+ break;
+
+ case HOR_PRED: /* horizontal prediction from left block */
+ if (!block_available_left)
+ printf ("warning: Intra_4x4_Horizontal prediction mode not allowed at mb %d\n",(int) img->current_mb_nr);
+
+ for(j=0;j<BLOCK_SIZE;j++)
+ for(i=0;i<BLOCK_SIZE;i++)
+ img->mpr[j+joff][i+ioff]=imgY[pix_a[j].pos_y][pix_a[j].pos_x]; /* store predicted 4x4 block */
+ break;
+
+ case DIAG_DOWN_RIGHT_PRED:
+ if ((!block_available_up)||(!block_available_left)||(!block_available_up_left))
+ printf ("warning: Intra_4x4_Diagonal_Down_Right prediction mode not allowed at mb %d\n",(int) img->current_mb_nr);
+
+ img->mpr[jpos3][ipos0] = (imgpel) ((P_L + 2*P_K + P_J + 2) >> 2);
+ img->mpr[jpos2][ipos0] =
+ img->mpr[jpos3][ipos1] = (imgpel) ((P_K + 2*P_J + P_I + 2) >> 2);
+ img->mpr[jpos1][ipos0] =
+ img->mpr[jpos2][ipos1] =
+ img->mpr[jpos3][ipos2] = (imgpel) ((P_J + 2*P_I + P_X + 2) >> 2);
+ img->mpr[jpos0][ipos0] =
+ img->mpr[jpos1][ipos1] =
+ img->mpr[jpos2][ipos2] =
+ img->mpr[jpos3][ipos3] = (imgpel) ((P_I + 2*P_X + P_A + 2) >> 2);
+ img->mpr[jpos0][ipos1] =
+ img->mpr[jpos1][ipos2] =
+ img->mpr[jpos2][ipos3] = (imgpel) ((P_X + 2*P_A + P_B + 2) >> 2);
+ img->mpr[jpos0][ipos2] =
+ img->mpr[jpos1][ipos3] = (imgpel) ((P_A + 2*P_B + P_C + 2) >> 2);
+ img->mpr[jpos0][ipos3] = (imgpel) ((P_B + 2*P_C + P_D + 2) >> 2);
+ break;
+
+ case DIAG_DOWN_LEFT_PRED:
+ if (!block_available_up)
+ printf ("warning: Intra_4x4_Diagonal_Down_Left prediction mode not allowed at mb %d\n",img->current_mb_nr);
+
+ img->mpr[jpos0][ipos0] = (imgpel) ((P_A + P_C + 2*(P_B) + 2) >> 2);
+ img->mpr[jpos0][ipos1] =
+ img->mpr[jpos1][ipos0] = (imgpel) ((P_B + P_D + 2*(P_C) + 2) >> 2);
+ img->mpr[jpos0][ipos2] =
+ img->mpr[jpos1][ipos1] =
+ img->mpr[jpos2][ipos0] = (imgpel) ((P_C + P_E + 2*(P_D) + 2) >> 2);
+ img->mpr[jpos0][ipos3] =
+ img->mpr[jpos1][ipos2] =
+ img->mpr[jpos2][ipos1] =
+ img->mpr[jpos3][ipos0] = (imgpel) ((P_D + P_F + 2*(P_E) + 2) >> 2);
+ img->mpr[jpos1][ipos3] =
+ img->mpr[jpos2][ipos2] =
+ img->mpr[jpos3][ipos1] = (imgpel) ((P_E + P_G + 2*(P_F) + 2) >> 2);
+ img->mpr[jpos2][ipos3] =
+ img->mpr[jpos3][ipos2] = (imgpel) ((P_F + P_H + 2*(P_G) + 2) >> 2);
+ img->mpr[jpos3][ipos3] = (imgpel) ((P_G + 3*(P_H) + 2) >> 2);
+ break;
+
+ case VERT_RIGHT_PRED:/* diagonal prediction -22.5 deg to horizontal plane */
+ if ((!block_available_up)||(!block_available_left)||(!block_available_up_left))
+ printf ("warning: Intra_4x4_Vertical_Right prediction mode not allowed at mb %d\n",img->current_mb_nr);
+
+ img->mpr[jpos0][ipos0] =
+ img->mpr[jpos2][ipos1] = (imgpel) ((P_X + P_A + 1) >> 1);
+ img->mpr[jpos0][ipos1] =
+ img->mpr[jpos2][ipos2] = (imgpel) ((P_A + P_B + 1) >> 1);
+ img->mpr[jpos0][ipos2] =
+ img->mpr[jpos2][ipos3] = (imgpel) ((P_B + P_C + 1) >> 1);
+ img->mpr[jpos0][ipos3] = (imgpel) ((P_C + P_D + 1) >> 1);
+ img->mpr[jpos1][ipos0] =
+ img->mpr[jpos3][ipos1] = (imgpel) ((P_I + 2*P_X + P_A + 2) >> 2);
+ img->mpr[jpos1][ipos1] =
+ img->mpr[jpos3][ipos2] = (imgpel) ((P_X + 2*P_A + P_B + 2) >> 2);
+ img->mpr[jpos1][ipos2] =
+ img->mpr[jpos3][ipos3] = (imgpel) ((P_A + 2*P_B + P_C + 2) >> 2);
+ img->mpr[jpos1][ipos3] = (imgpel) ((P_B + 2*P_C + P_D + 2) >> 2);
+ img->mpr[jpos2][ipos0] = (imgpel) ((P_X + 2*P_I + P_J + 2) >> 2);
+ img->mpr[jpos3][ipos0] = (imgpel) ((P_I + 2*P_J + P_K + 2) >> 2);
+ break;
+
+ case VERT_LEFT_PRED:/* diagonal prediction -22.5 deg to horizontal plane */
+ if (!block_available_up)
+ printf ("warning: Intra_4x4_Vertical_Left prediction mode not allowed at mb %d\n",img->current_mb_nr);
+
+ img->mpr[jpos0][ipos0] = (imgpel) ((P_A + P_B + 1) >> 1);
+ img->mpr[jpos0][ipos1] =
+ img->mpr[jpos2][ipos0] = (imgpel) ((P_B + P_C + 1) >> 1);
+ img->mpr[jpos0][ipos2] =
+ img->mpr[jpos2][ipos1] = (imgpel) ((P_C + P_D + 1) >> 1);
+ img->mpr[jpos0][ipos3] =
+ img->mpr[jpos2][ipos2] = (imgpel) ((P_D + P_E + 1) >> 1);
+ img->mpr[jpos2][ipos3] = (imgpel) ((P_E + P_F + 1) >> 1);
+ img->mpr[jpos1][ipos0] = (imgpel) ((P_A + 2*P_B + P_C + 2) >> 2);
+ img->mpr[jpos1][ipos1] =
+ img->mpr[jpos3][ipos0] = (imgpel) ((P_B + 2*P_C + P_D + 2) >> 2);
+ img->mpr[jpos1][ipos2] =
+ img->mpr[jpos3][ipos1] = (imgpel) ((P_C + 2*P_D + P_E + 2) >> 2);
+ img->mpr[jpos1][ipos3] =
+ img->mpr[jpos3][ipos2] = (imgpel) ((P_D + 2*P_E + P_F + 2) >> 2);
+ img->mpr[jpos3][ipos3] = (imgpel) ((P_E + 2*P_F + P_G + 2) >> 2);
+ break;
+
+ case HOR_UP_PRED:/* diagonal prediction -22.5 deg to horizontal plane */
+ if (!block_available_left)
+ printf ("warning: Intra_4x4_Horizontal_Up prediction mode not allowed at mb %d\n",img->current_mb_nr);
+
+ img->mpr[jpos0][ipos0] = (imgpel) ((P_I + P_J + 1) >> 1);
+ img->mpr[jpos0][ipos1] = (imgpel) ((P_I + 2*P_J + P_K + 2) >> 2);
+ img->mpr[jpos0][ipos2] =
+ img->mpr[jpos1][ipos0] = (imgpel) ((P_J + P_K + 1) >> 1);
+ img->mpr[jpos0][ipos3] =
+ img->mpr[jpos1][ipos1] = (imgpel) ((P_J + 2*P_K + P_L + 2) >> 2);
+ img->mpr[jpos1][ipos2] =
+ img->mpr[jpos2][ipos0] = (imgpel) ((P_K + P_L + 1) >> 1);
+ img->mpr[jpos1][ipos3] =
+ img->mpr[jpos2][ipos1] = (imgpel) ((P_K + 2*P_L + P_L + 2) >> 2);
+ img->mpr[jpos2][ipos3] =
+ img->mpr[jpos3][ipos1] =
+ img->mpr[jpos3][ipos0] =
+ img->mpr[jpos2][ipos2] =
+ img->mpr[jpos3][ipos2] =
+ img->mpr[jpos3][ipos3] = (imgpel) P_L;
+ break;
+
+ case HOR_DOWN_PRED:/* diagonal prediction -22.5 deg to horizontal plane */
+ if ((!block_available_up)||(!block_available_left)||(!block_available_up_left))
+ printf ("warning: Intra_4x4_Horizontal_Down prediction mode not allowed at mb %d\n",img->current_mb_nr);
+
+ img->mpr[jpos0][ipos0] =
+ img->mpr[jpos1][ipos2] = (imgpel) ((P_X + P_I + 1) >> 1);
+ img->mpr[jpos0][ipos1] =
+ img->mpr[jpos1][ipos3] = (imgpel) ((P_I + 2*P_X + P_A + 2) >> 2);
+ img->mpr[jpos0][ipos2] = (imgpel) ((P_X + 2*P_A + P_B + 2) >> 2);
+ img->mpr[jpos0][ipos3] = (imgpel) ((P_A + 2*P_B + P_C + 2) >> 2);
+ img->mpr[jpos1][ipos0] =
+ img->mpr[jpos2][ipos2] = (imgpel) ((P_I + P_J + 1) >> 1);
+ img->mpr[jpos1][ipos1] =
+ img->mpr[jpos2][ipos3] = (imgpel) ((P_X + 2*P_I + P_J + 2) >> 2);
+ img->mpr[jpos2][ipos0] =
+ img->mpr[jpos3][ipos2] = (imgpel) ((P_J + P_K + 1) >> 1);
+ img->mpr[jpos2][ipos1] =
+ img->mpr[jpos3][ipos3] = (imgpel) ((P_I + 2*P_J + P_K + 2) >> 2);
+ img->mpr[jpos3][ipos0] = (imgpel) ((P_K + P_L + 1) >> 1);
+ img->mpr[jpos3][ipos1] = (imgpel) ((P_J + 2*P_K + P_L + 2) >> 2);
+ break;
+
+ default:
+ printf("Error: illegal intra_4x4 prediction mode: %d\n",predmode);
+ return SEARCH_SYNC;
+ break;
+ }
+
+ return DECODING_OK;
+}
+
+
+/*!
+ ***********************************************************************
+ * \return
+ * best SAD
+ ***********************************************************************
+ */
+int intrapred_luma_16x16(struct img_par *img, //!< image parameters
+ int predmode) //!< prediction mode
+{
+ int s0=0,s1,s2;
+
+ int i,j;
+
+ int ih,iv;
+ int ib,ic,iaa;
+
+ imgpel **imgY=dec_picture->imgY;
+
+ 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;
+
+ s1=s2=0;
+
+ for (i=0;i<17;i++)
+ {
+ getNeighbour(mb_nr, -1 , i-1 , IS_LUMA, &left[i]);
+ }
+ getNeighbour(mb_nr, 0 , -1 , IS_LUMA, &up);
+
+ if (!active_pps->constrained_intra_pred_flag)
+ {
+ 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;
+ }
+
+ switch (predmode)
+ {
+ case VERT_PRED_16: // vertical prediction from block above
+ if (!up_avail)
+ error ("invalid 16x16 intra pred Mode VERT_PRED_16",500);
+ for(j=0;j<MB_BLOCK_SIZE;j++)
+ for(i=0;i<MB_BLOCK_SIZE;i++)
+ img->mpr[j][i]=imgY[up.pos_y][up.pos_x+i];// store predicted 16x16 block
+ break;
+
+ case HOR_PRED_16: // horizontal prediction from left block
+ if (!left_avail)
+ error ("invalid 16x16 intra pred Mode HOR_PRED_16",500);
+ for(j=0;j<MB_BLOCK_SIZE;j++)
+ for(i=0;i<MB_BLOCK_SIZE;i++)
+ img->mpr[j][i]=imgY[left[j+1].pos_y][left[j+1].pos_x]; // store predicted 16x16 block
+ break;
+
+ case DC_PRED_16: // DC prediction
+ s1=s2=0;
+ for (i=0; i < MB_BLOCK_SIZE; i++)
+ {
+ if (up_avail)
+ s1 += imgY[up.pos_y][up.pos_x+i]; // sum hor pix
+ if (left_avail)
+ s2 += imgY[left[i+1].pos_y][left[i+1].pos_x]; // sum vert pix
+ }
+ if (up_avail && left_avail)
+ s0=(s1+s2+16)>>5; // no edge
+ if (!up_avail && left_avail)
+ s0=(s2+8)>>4; // upper edge
+ if (up_avail && !left_avail)
+ s0=(s1+8)>>4; // left edge
+ if (!up_avail && !left_avail)
+ s0=img->dc_pred_value_luma; // top left corner, nothing to predict from
+ for(i=0;i<MB_BLOCK_SIZE;i++)
+ for(j=0;j<MB_BLOCK_SIZE;j++)
+ {
+ img->mpr[j][i]=(imgpel) s0;
+ }
+ break;
+ case PLANE_16:// 16 bit integer plan pred
+ if (!up_avail || !left_up_avail || !left_avail)
+ error ("invalid 16x16 intra pred Mode PLANE_16",500);
+
+ ih=0;
+ iv=0;
+ for (i=1;i<9;i++)
+ {
+ if (i<8)
+ ih += i*(imgY[up.pos_y][up.pos_x+7+i] - imgY[up.pos_y][up.pos_x+7-i]);
+ else
+ ih += i*(imgY[up.pos_y][up.pos_x+7+i] - imgY[left[0].pos_y][left[0].pos_x]);
+
+ iv += i*(imgY[left[8+i].pos_y][left[8+i].pos_x] - imgY[left[8-i].pos_y][left[8-i].pos_x]);
+ }
+ ib=(5*ih+32)>>6;
+ ic=(5*iv+32)>>6;
+
+ iaa=16*(imgY[up.pos_y][up.pos_x+15]+imgY[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->mpr[j][i]=(imgpel) iClip1(img->max_imgpel_value,((iaa+(i-7)*ib +(j-7)*ic + 16)>>5));
+ }
+ }// store plane prediction
+ break;
+
+ default:
+ { // indication of fault in bitstream,exit
+ printf("illegal 16x16 intra prediction mode input: %d\n",predmode);
+ return SEARCH_SYNC;
+ }
+ }
+
+ return DECODING_OK;
+}
+
+
+void intrapred_chroma(struct img_par *img, int uv)
+{
+ int i,j, ii, jj, ioff, joff;
+
+ imgpel ***imgUV = dec_picture->imgUV;
+
+ int js[4][4];
+
+ int pred;
+ int ih, iv, ib, ic, iaa;
+
+ int b8, b4;
+ int yuv = dec_picture->chroma_format_idc - 1;
+ int blk_x, blk_y;
+ 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}}
+ };
+ int s0, s1, s2, s3;
+
+ int mb_nr=img->current_mb_nr;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+
+ PixelPos up; //!< pixel position p(0,-1)
+ PixelPos left[17]; //!< pixel positions p(-1, -1..16)
+
+ int up_avail, left_avail[2], left_up_avail;
+
+ int cr_MB_x = img->mb_cr_size_x;
+ int cr_MB_y = img->mb_cr_size_y;
+
+ for (i=0;i<cr_MB_y+1;i++)
+ {
+ getNeighbour(mb_nr, -1, i-1, IS_CHROMA, &left[i]);
+ }
+
+ getNeighbour(mb_nr, 0, -1, IS_CHROMA, &up);
+
+ if (!active_pps->constrained_intra_pred_flag)
+ {
+ up_avail = up.available;
+ left_avail[0] = left_avail[1] = left[1].available;
+ left_up_avail = left[0].available;
+ }
+ else
+ {
+ up_avail = up.available ? img->intra_block[up.mb_addr] : 0;
+ for (i=0, left_avail[0]=1; i<cr_MB_y/2;i++)
+ left_avail[0] &= left[i+1].available ? img->intra_block[left[i+1].mb_addr]: 0;
+ for (i=cr_MB_y/2, left_avail[1]=1; i<cr_MB_y;i++)
+ left_avail[1] &= left[i+1].available ? img->intra_block[left[i+1].mb_addr]: 0;
+ left_up_avail = left[0].available ? img->intra_block[left[0].mb_addr]: 0;
+ }
+
+
+ if (currMB->c_ipred_mode == DC_PRED_8)
+ {
+ // DC prediction
+ for(b8=0; b8<img->num_blk8x8_uv/2;b8++)
+ {
+ for (b4=0; b4<4; b4++)
+ {
+ blk_y = subblk_offset_y[yuv][b8][b4] + 1;
+ blk_x = subblk_offset_x[yuv][b8][b4];
+
+ s0=s1=s2=s3=0;
+ js[b8][b4]=img->dc_pred_value_chroma;
+
+ //===== get prediction value =====
+ switch (block_pos[yuv][b8][b4])
+ {
+ case 0: //===== TOP LEFT =====
+ if (up_avail) for (i=blk_x;i<(blk_x+4);i++) s0 += imgUV[uv][up.pos_y][up.pos_x + i];
+ if (left_avail[0]) for (i=blk_y;i<(blk_y+4);i++) s2 += imgUV[uv][left[i].pos_y][left[i].pos_x];
+ if (up_avail && left_avail[0]) js[b8][b4] = (s0+s2+4) >> 3;
+ else if (up_avail) js[b8][b4] = (s0 +2) >> 2;
+ else if (left_avail[0]) js[b8][b4] = (s2 +2) >> 2;
+ break;
+ case 1: //===== TOP RIGHT =====
+ if (up_avail) for (i=blk_x;i<(blk_x+4);i++) s1 += imgUV[uv][up.pos_y][up.pos_x + i];
+ else if (left_avail[0]) for (i=blk_y;i<(blk_y+4);i++) s2 += imgUV[uv][left[i].pos_y][left[i].pos_x];
+ if (up_avail) js[b8][b4] = (s1 +2) >> 2;
+ else if (left_avail[0]) js[b8][b4] = (s2 +2) >> 2;
+ break;
+ case 2: //===== BOTTOM LEFT =====
+ if (left_avail[1]) for (i=blk_y;i<(blk_y+4);i++) s3 += imgUV[uv][left[i].pos_y][left[i].pos_x];
+ else if (up_avail) for (i=blk_x;i<(blk_x+4);i++) s0 += imgUV[uv][up.pos_y][up.pos_x + i];
+ if (left_avail[1]) js[b8][b4] = (s3 +2) >> 2;
+ else if (up_avail) js[b8][b4] = (s0 +2) >> 2;
+ break;
+ case 3: //===== BOTTOM RIGHT =====
+ if (up_avail) for (i=blk_x;i<(blk_x+4);i++) s1 += imgUV[uv][up.pos_y][up.pos_x + i];
+ if (left_avail[1]) for (i=blk_y;i<(blk_y+4);i++) s3 += imgUV[uv][left[i].pos_y][left[i].pos_x];
+ if (up_avail && left_avail[1]) js[b8][b4] = (s1+s3+4) >> 3;
+ else if (up_avail) js[b8][b4] = (s1 +2) >> 2;
+ else if (left_avail[1]) js[b8][b4] = (s3 +2) >> 2;
+ break;
+ }
+ }
+ }
+ }
+ if (PLANE_8 == currMB->c_ipred_mode)
+ {
+ // plane prediction
+ if (!left_up_avail || !left_avail[0] || !left_avail[1] || !up_avail)
+ error("unexpected PLANE_8 chroma intra prediction mode",-1);
+
+ ih = cr_MB_x/2*(imgUV[uv][up.pos_y][up.pos_x+cr_MB_x-1] - imgUV[uv][left[0].pos_y][left[0].pos_x]);
+ for (i=0;i<cr_MB_x/2-1;i++)
+ ih += (i+1)*(imgUV[uv][up.pos_y][up.pos_x+cr_MB_x/2 +i] -
+ imgUV[uv][up.pos_y][up.pos_x+cr_MB_x/2-2-i]);
+
+ iv = cr_MB_y/2*(imgUV[uv][left[cr_MB_y].pos_y][left[cr_MB_y].pos_x] - imgUV[uv][left[0].pos_y][left[0].pos_x]);
+ for (i=0;i<cr_MB_y/2-1;i++)
+ iv += (i+1)*(imgUV[uv][left[cr_MB_y/2+1+i].pos_y][left[cr_MB_y/2+1+i].pos_x] -
+ imgUV[uv][left[cr_MB_y/2-1-i].pos_y][left[cr_MB_y/2-1-i].pos_x]);
+
+ 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*(imgUV[uv][left[cr_MB_y].pos_y][left[cr_MB_y].pos_x] +
+ imgUV[uv][up.pos_y][up.pos_x+cr_MB_x-1]);
+
+ for (j=0; j<cr_MB_y; j++)
+ for (i=0; i<cr_MB_x; i++)
+ img->mpr[j][i]=(imgpel) iClip1(img->max_imgpel_value_uv,((iaa+(i-cr_MB_x/2+1)*ib+(j-cr_MB_y/2+1)*ic+16)>>5));
+ }
+ else
+ {
+ switch (currMB->c_ipred_mode)
+ {
+ case DC_PRED_8:
+ for (b8=0;b8<img->num_blk8x8_uv/2;b8++)
+ {
+ for (b4=0;b4<4;b4++)
+ {
+ joff = subblk_offset_y[yuv][b8][b4];
+ ioff = subblk_offset_x[yuv][b8][b4];
+ for (jj=joff; jj<joff + BLOCK_SIZE; jj++)
+ for (ii=ioff; ii<ioff + BLOCK_SIZE; ii++)
+ {
+ img->mpr[jj][ii]=(imgpel) js[b8][b4];
+ }
+ }
+ }
+ break;
+ case HOR_PRED_8:
+ if (!left_avail[0] || !left_avail[1])
+ error("unexpected HOR_PRED_8 chroma intra prediction mode",-1);
+
+ for (j=0;j<2;j++)
+ {
+ joff=j*cr_MB_y/2;
+ for(i=0;i<2;i++)
+ {
+ ioff=i*cr_MB_x/2;
+ for (jj=joff; jj<joff + cr_MB_y/2; jj++)
+ {
+ pred = imgUV[uv][left[1+jj].pos_y][left[1+jj].pos_x];
+ for (ii=ioff; ii<ioff + cr_MB_x/2; ii++)
+ img->mpr[jj][ii]=(imgpel) pred;
+ }
+ }
+ }
+ break;
+ case VERT_PRED_8:
+ if (!up_avail)
+ error("unexpected VERT_PRED_8 chroma intra prediction mode",-1);
+
+ for (j=0;j<2;j++)
+ {
+ joff=j*cr_MB_y/2;
+ for(i=0;i<2;i++)
+ {
+ ioff=i*cr_MB_x/2;
+ for (ii=ioff; ii<ioff + cr_MB_x/2; ii++)
+ {
+ pred = imgUV[uv][up.pos_y][up.pos_x+ii];
+ for (jj=joff; jj<joff + cr_MB_y/2; jj++)
+ img->mpr[jj][ii]=(imgpel) pred;
+ }
+ }
+ }
+ break;
+ default:
+ error("illegal chroma intra prediction mode", 600);
+ break;
+ }
+ }
+}
+
+/*!
+ ***********************************************************************
+ * \brief
+ * Inverse 4x4 transformation, transforms cof to m7
+ ***********************************************************************
+ */
+void itrans(struct img_par *img, //!< image parameters
+ int ioff, //!< index to 4x4 block
+ int joff, //!<
+ int i0, //!<
+ int j0,
+ int chroma)
+{
+ int i,j;
+ int m5[4];
+ int m6[4];
+
+ Boolean lossless_qpprime = (Boolean) ((img->qp + img->bitdepth_luma_qp_scale)==0 && img->lossless_qpprime_flag==1);
+ int max_imgpel_value = chroma ? img->max_imgpel_value_uv : img->max_imgpel_value;
+
+ if (!lossless_qpprime)
+ {
+ // horizontal
+ for (j=0;j<BLOCK_SIZE;j++)
+ {
+ memcpy(&m5[0],&img->cof[i0][j0][j][0], BLOCK_SIZE * sizeof(int));
+
+ 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[j][0] = m6[0] + m6[3];
+ img->m7[j][3] = m6[0] - m6[3];
+ img->m7[j][1] = m6[1] + m6[2];
+ img->m7[j][2] = m6[1] - m6[2];
+ }
+ // vertical
+ for (i=0;i<BLOCK_SIZE;i++)
+ {
+ int ipos = i+ioff;
+
+ m5[0]=img->m7[0][i];
+ m5[1]=img->m7[1][i];
+ m5[2]=img->m7[2][i];
+ m5[3]=img->m7[3][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[0][i] = iClip1(max_imgpel_value, rshift_rnd_sf((m6[0] + m6[3] + ((long)img->mpr[ joff][ipos] << DQ_BITS)), DQ_BITS));
+ img->m7[1][i] = iClip1(max_imgpel_value, rshift_rnd_sf((m6[1] + m6[2] + ((long)img->mpr[1 + joff][ipos] << DQ_BITS)), DQ_BITS));
+ img->m7[2][i] = iClip1(max_imgpel_value, rshift_rnd_sf((m6[1] - m6[2] + ((long)img->mpr[2 + joff][ipos] << DQ_BITS)), DQ_BITS));
+ img->m7[3][i] = iClip1(max_imgpel_value, rshift_rnd_sf((m6[0] - m6[3] + ((long)img->mpr[3 + joff][ipos] << DQ_BITS)), DQ_BITS));
+ }
+ }
+ else
+ {
+ for (j=0;j<BLOCK_SIZE;j++)
+ for (i=0;i<BLOCK_SIZE ;i++)
+ img->m7[j][i] = iClip1(max_imgpel_value, (img->cof[i0][j0][j][i]+(long)img->mpr[j+joff][i+ioff]));
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * For mapping the q-matrix to the active id and calculate quantisation values
+ *
+ * \param pps
+ * Picture parameter set
+ * \param sps
+ * Sequence parameter set
+ *
+ ************************************************************************
+ */
+void AssignQuantParam(pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps)
+{
+ int i;
+
+ if(!pps->pic_scaling_matrix_present_flag && !sps->seq_scaling_matrix_present_flag)
+ {
+ for(i=0; i<8; i++)
+ qmatrix[i] = (i<6) ? quant_org:quant8_org;
+ }
+ else
+ {
+ if(sps->seq_scaling_matrix_present_flag) // check sps first
+ {
+ for(i=0; i<8; i++)
+ {
+ if(i<6)
+ {
+ if(!sps->seq_scaling_list_present_flag[i]) // fall-back rule A
+ {
+ if((i==0) || (i==3))
+ qmatrix[i] = (i==0) ? quant_intra_default:quant_inter_default;
+ else
+ qmatrix[i] = qmatrix[i-1];
+ }
+ else
+ {
+ if(sps->UseDefaultScalingMatrix4x4Flag[i])
+ qmatrix[i] = (i<3) ? quant_intra_default:quant_inter_default;
+ else
+ qmatrix[i] = sps->ScalingList4x4[i];
+ }
+ }
+ else
+ {
+ if(!sps->seq_scaling_list_present_flag[i] || sps->UseDefaultScalingMatrix8x8Flag[i-6]) // fall-back rule A
+ qmatrix[i] = (i==6) ? quant8_intra_default:quant8_inter_default;
+ else
+ qmatrix[i] = sps->ScalingList8x8[i-6];
+ }
+ }
+ }
+
+ if(pps->pic_scaling_matrix_present_flag) // then check pps
+ {
+ for(i=0; i<8; i++)
+ {
+ if(i<6)
+ {
+ if(!pps->pic_scaling_list_present_flag[i]) // fall-back rule B
+ {
+ if((i==0) || (i==3))
+ {
+ if(!sps->seq_scaling_matrix_present_flag)
+ qmatrix[i] = (i==0) ? quant_intra_default:quant_inter_default;
+ }
+ else
+ qmatrix[i] = qmatrix[i-1];
+ }
+ else
+ {
+ if(pps->UseDefaultScalingMatrix4x4Flag[i])
+ qmatrix[i] = (i<3) ? quant_intra_default:quant_inter_default;
+ else
+ qmatrix[i] = pps->ScalingList4x4[i];
+ }
+ }
+ else
+ {
+ if(!pps->pic_scaling_list_present_flag[i]) // fall-back rule B
+ {
+ if(!sps->seq_scaling_matrix_present_flag)
+ qmatrix[i] = (i==6) ? quant8_intra_default:quant8_inter_default;
+ }
+ else if(pps->UseDefaultScalingMatrix8x8Flag[i-6])
+ qmatrix[i] = (i==6) ? quant8_intra_default:quant8_inter_default;
+ else
+ qmatrix[i] = pps->ScalingList8x8[i-6];
+ }
+ }
+ }
+ }
+
+ CalculateQuantParam();
+ if(pps->transform_8x8_mode_flag)
+ CalculateQuant8Param();
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * For calculating the quantisation values at frame level
+ *
+ ************************************************************************
+ */
+void CalculateQuantParam()
+{
+ int i, j, k, temp;
+
+ for(k=0; k<6; k++)
+ for(j=0; j<4; j++)
+ for(i=0; i<4; i++)
+ {
+ temp = (i<<2)+j;
+ InvLevelScale4x4Luma_Intra[k][i][j] = dequant_coef[k][j][i]*qmatrix[0][temp];
+ InvLevelScale4x4Chroma_Intra[0][k][i][j] = dequant_coef[k][j][i]*qmatrix[1][temp];
+ InvLevelScale4x4Chroma_Intra[1][k][i][j] = dequant_coef[k][j][i]*qmatrix[2][temp];
+
+ InvLevelScale4x4Luma_Inter[k][i][j] = dequant_coef[k][j][i]*qmatrix[3][temp];
+ InvLevelScale4x4Chroma_Inter[0][k][i][j] = dequant_coef[k][j][i]*qmatrix[4][temp];
+ InvLevelScale4x4Chroma_Inter[1][k][i][j] = dequant_coef[k][j][i]*qmatrix[5][temp];
+ }
+}
+
+/*!
+ ***********************************************************************
+ * \brief
+ * Luma DC inverse transform
+ ***********************************************************************
+ */
+void itrans_2(struct img_par *img) //!< image parameters
+{
+ int i,j;
+ int M5[4];
+ int M6[4];
+
+ int qp_per = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)/6;
+ int qp_rem = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)%6;
+
+ // horizontal
+ for (j=0;j<4;j++)
+ {
+ M5[0]=img->cof[0][j][0][0];
+ M5[1]=img->cof[1][j][0][0];
+ M5[2]=img->cof[2][j][0][0];
+ M5[3]=img->cof[3][j][0][0];
+
+ M6[0]=M5[0]+M5[2];
+ M6[1]=M5[0]-M5[2];
+ M6[2]=M5[1]-M5[3];
+ M6[3]=M5[1]+M5[3];
+
+ img->cof[0][j][0][0] = M6[0]+M6[3];
+ img->cof[1][j][0][0] = M6[1]+M6[2];
+ img->cof[2][j][0][0] = M6[1]-M6[2];
+ img->cof[3][j][0][0] = M6[0]-M6[3];
+ }
+
+ // vertical
+ for (i=0;i<4;i++)
+ {
+ M5[0]=img->cof[i][0][0][0];
+ M5[1]=img->cof[i][1][0][0];
+ M5[2]=img->cof[i][2][0][0];
+ M5[3]=img->cof[i][3][0][0];
+
+ M6[0]=M5[0]+M5[2];
+ M6[1]=M5[0]-M5[2];
+ M6[2]=M5[1]-M5[3];
+ M6[3]=M5[1]+M5[3];
+
+ img->cof[i][0][0][0] = rshift_rnd((((M6[0]+M6[3])*InvLevelScale4x4Luma_Intra[qp_rem][0][0]) << qp_per), 6);
+ img->cof[i][1][0][0] = rshift_rnd((((M6[1]+M6[2])*InvLevelScale4x4Luma_Intra[qp_rem][0][0]) << qp_per), 6);
+ img->cof[i][2][0][0] = rshift_rnd((((M6[1]-M6[2])*InvLevelScale4x4Luma_Intra[qp_rem][0][0]) << qp_per), 6);
+ img->cof[i][3][0][0] = rshift_rnd((((M6[0]-M6[3])*InvLevelScale4x4Luma_Intra[qp_rem][0][0]) << qp_per), 6);
+ }
+}
+
+
+void itrans_sp(struct img_par *img, //!< image parameters
+ int ioff, //!< index to 4x4 block
+ int joff, //!<
+ int i0, //!<
+ int j0) //!<
+{
+ int i,j,i1,j1;
+ int m5[4];
+ int m6[4];
+ int predicted_block[BLOCK_SIZE][BLOCK_SIZE],ilev;
+
+ int qp_per = (img->qp-MIN_QP)/6;
+ int qp_rem = (img->qp-MIN_QP)%6;
+ int q_bits = Q_BITS+qp_per;
+
+ int qp_per_sp = (img->qpsp-MIN_QP)/6;
+ int qp_rem_sp = (img->qpsp-MIN_QP)%6;
+ int q_bits_sp = Q_BITS+qp_per_sp;
+ int qp_const2 = (1<<q_bits_sp)/2; //sp_pred
+ if (img->type == SI_SLICE) //ES modified
+ {
+ qp_per = (img->qpsp-MIN_QP)/6;
+ qp_rem = (img->qpsp-MIN_QP)%6;
+ q_bits = Q_BITS+qp_per;
+ }
+
+ for (j=0; j< BLOCK_SIZE; j++)
+ for (i=0; i< BLOCK_SIZE; i++)
+ predicted_block[i][j]=img->mpr[j+joff][i+ioff];
+ 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;
+ }
+
+ for (j=0;j<BLOCK_SIZE;j++)
+ for (i=0;i<BLOCK_SIZE;i++)
+ {
+ // recovering coefficient since they are already dequantized earlier
+ img->cof[i0][j0][j][i]=(img->cof[i0][j0][j][i] >> qp_per) / dequant_coef[qp_rem][i][j];
+ if(img->sp_switch || img->type==SI_SLICE) //M.W. patched for SI
+ {
+ ilev=(iabs(predicted_block[i][j]) * quant_coef[qp_rem_sp][i][j] + qp_const2) >> q_bits_sp; //ES added
+ ilev= isignab(ilev,predicted_block[i][j])+ img->cof[i0][j0][j][i]; //ES added
+ img->cof[i0][j0][j][i] = isignab(iabs(ilev) * dequant_coef[qp_rem_sp][i][j] << qp_per_sp ,ilev) ; //ES added
+ } //ES added
+ else
+ { //ES added
+ ilev=((img->cof[i0][j0][j][i]*dequant_coef[qp_rem][i][j]*A[i][j]<< qp_per) >>6)+predicted_block[i][j] ;
+ img->cof[i0][j0][j][i]=isignab((iabs(ilev) * quant_coef[qp_rem_sp][i][j] + qp_const2) >> q_bits_sp, ilev) * dequant_coef[qp_rem_sp][i][j] << qp_per_sp;
+ }
+ }
+ // horizontal
+ for (j=0;j<BLOCK_SIZE;j++)
+ {
+ for (i=0;i<BLOCK_SIZE;i++)
+ {
+ m5[i]=img->cof[i0][j0][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] =iClip1(img->max_imgpel_value,rshift_rnd_sf((m6[j]+m6[j1]),DQ_BITS));
+ img->m7[j1][i]=iClip1(img->max_imgpel_value,rshift_rnd_sf((m6[j]-m6[j1]),DQ_BITS));
+ }
+ }
+}
+
+/*!
+ ***********************************************************************
+ * \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(struct img_par *img,int block_x,int block_y)
+{
+ int i,j,i1,j1,m5[4],m6[4];
+
+ int predicted_block[BLOCK_SIZE][BLOCK_SIZE];
+ int qp_per = (img->qpsp-MIN_QP)/6;
+ int qp_rem = (img->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]=isignab((iabs(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] =iClip1(img->max_imgpel_value,rshift_rnd_sf((m6[j]+m6[j1]),DQ_BITS));
+ img->m7[j1][i]=iClip1(img->max_imgpel_value,rshift_rnd_sf((m6[j]-m6[j1]),DQ_BITS));
+ }
+ }
+
+ // Decoded block moved to frame memory
+
+ for (j=0; j < BLOCK_SIZE; j++)
+ for (i=0; i < BLOCK_SIZE; i++)
+ dec_picture->imgY[img->pix_y+block_y+j][img->pix_x+block_x+i]=(imgpel) img->m7[j][i];
+
+}
+
+void itrans_sp_chroma(struct img_par *img,int ll)
+{
+ int i,j,i1,j2,ilev,n2,n1,j1,mb_y;
+ int m5[BLOCK_SIZE];
+ int predicted_chroma_block[MB_BLOCK_SIZE/2][MB_BLOCK_SIZE/2],mp1[BLOCK_SIZE];
+ int qp_per,qp_rem,q_bits;
+ int qp_per_sp,qp_rem_sp,q_bits_sp,qp_const2;
+
+ qp_per = ((img->qp<0?img->qp:QP_SCALE_CR[img->qp])-MIN_QP)/6;
+ qp_rem = ((img->qp<0?img->qp:QP_SCALE_CR[img->qp])-MIN_QP)%6;
+ q_bits = Q_BITS+qp_per;
+
+ qp_per_sp = ((img->qpsp<0?img->qpsp:QP_SCALE_CR[img->qpsp])-MIN_QP)/6;
+ qp_rem_sp = ((img->qpsp<0?img->qpsp:QP_SCALE_CR[img->qpsp])-MIN_QP)%6;
+ q_bits_sp = Q_BITS+qp_per_sp;
+ qp_const2=(1<<q_bits_sp)/2; //sp_pred
+
+ if (img->type == SI_SLICE)
+ {
+ qp_per = ((img->qpsp < 0 ? img->qpsp : QP_SCALE_CR[img->qpsp]) - MIN_QP) / 6;
+ qp_rem = ((img->qpsp < 0 ? img->qpsp : QP_SCALE_CR[img->qpsp]) - MIN_QP) % 6;
+ q_bits = Q_BITS + qp_per;
+ }
+
+ for (j=0; j < MB_BLOCK_SIZE/2; j++)
+ for (i=0; i < MB_BLOCK_SIZE/2; i++)
+ {
+ predicted_chroma_block[i][j]=img->mpr[j][i];
+ img->mpr[j][i]=0;
+ }
+ 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.
+ 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]);
+
+ for (n1=0; n1 < 2; n1 ++)
+ for (n2=0; n2 < 2; n2 ++)
+ {
+ if (img->sp_switch || img->type==SI_SLICE) //M.W. patched for SI
+ {
+ //quantization fo predicted block
+ ilev=(iabs (mp1[n1+n2*2]) * quant_coef[qp_rem_sp][0][0] + 2 * qp_const2) >> (q_bits_sp + 1);
+ //addition
+ ilev=img->cof[n1+ll][4+n2][0][0]+isignab(ilev,mp1[n1+n2*2]);
+ //dequantization
+ mp1[n1+n2*2] =ilev*dequant_coef[qp_rem_sp][0][0]<<qp_per_sp;
+ }
+ else
+ {
+ ilev=((img->cof[n1+ll][4+n2][0][0]*dequant_coef[qp_rem][0][0]*A[0][0]<< qp_per) >>5)+mp1[n1+n2*2] ;
+ mp1[n1+n2*2]=isignab((iabs(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;
+ }
+ }
+
+
+ for (n2=0; n2 < 2; n2 ++)
+ for (n1=0; n1 < 2; n1 ++)
+ for (i=0;i< BLOCK_SIZE; i++)
+ for (j=0;j< BLOCK_SIZE; j++)
+ {
+ // recovering coefficient since they are already dequantized earlier
+ img->cof[n1+ll][4+n2][j][i] = (img->cof[n1+ll][4+n2][j][i] >> qp_per) / dequant_coef[qp_rem][i][j];
+
+ if (img->sp_switch || img->type==SI_SLICE) //M.W. patched for SI
+ {
+ //quantization of the predicted block
+ ilev = (iabs(predicted_chroma_block[n1*BLOCK_SIZE+i][n2*BLOCK_SIZE+j]) * quant_coef[qp_rem_sp][i][j] + qp_const2) >> q_bits_sp;
+ //addition of the residual
+ ilev = isignab(ilev,predicted_chroma_block[n1*BLOCK_SIZE+i][n2*BLOCK_SIZE+j]) + img->cof[n1+ll][4+n2][j][i];
+ // Inverse quantization
+ img->cof[n1+ll][4+n2][j][i] = ilev * dequant_coef[qp_rem_sp][i][j] << qp_per_sp ;
+ }
+ else
+ {
+ //dequantization and addition of the predicted block
+ ilev=((img->cof[n1+ll][4+n2][j][i]*dequant_coef[qp_rem][i][j]*A[i][j]<< qp_per) >>6)+predicted_chroma_block[n1*BLOCK_SIZE+i][n2*BLOCK_SIZE+j] ;
+ //quantization and dequantization
+ img->cof[n1+ll][4+n2][j][i] = isignab((iabs(ilev) * quant_coef[qp_rem_sp][i][j] + qp_const2)>> q_bits_sp,ilev)*dequant_coef[qp_rem_sp][i][j]<<qp_per_sp;
+ }
+ }
+ img->cof[0+ll][4][0][0]=(mp1[0]+mp1[1]+mp1[2]+mp1[3])>>1;
+ img->cof[1+ll][4][0][0]=(mp1[0]-mp1[1]+mp1[2]-mp1[3])>>1;
+ img->cof[0+ll][5][0][0]=(mp1[0]+mp1[1]-mp1[2]-mp1[3])>>1;
+ img->cof[1+ll][5][0][0]=(mp1[0]-mp1[1]-mp1[2]+mp1[3])>>1;
+}
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/block.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/block.h:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/block.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,31 @@
+
+/*!
+ ************************************************************************
+ * \file block.h
+ *
+ * \brief
+ * definitions for block decoding functions
+ *
+ * \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_
+
+#include "global.h"
+
+#define DQ_BITS 6
+
+extern const byte QP_SCALE_CR[52] ;
+extern const int dequant_coef[6][4][4];
+extern const unsigned char subblk_offset_x[3][8][4];
+extern const unsigned char subblk_offset_y[3][8][4];
+
+#endif
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/cabac.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/cabac.c:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/cabac.c Sun Feb 4 08:38:31 2007
@@ -0,0 +1,1788 @@
+
+/*!
+ *************************************************************************************
+ * \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 <string.h>
+
+#include "global.h"
+#include "cabac.h"
+#include "memalloc.h"
+#include "elements.h"
+#include "image.h"
+#include "biaridecod.h"
+#include "mb_access.h"
+
+int symbolCount = 0;
+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
+ ***********************************************************************
+ */
+unsigned int unary_bin_decode(DecodingEnvironmentPtr dep_dp,
+ BiContextTypePtr ctx,
+ int ctx_offset);
+
+
+unsigned int unary_bin_max_decode(DecodingEnvironmentPtr dep_dp,
+ BiContextTypePtr ctx,
+ int ctx_offset,
+ unsigned int max_symbol);
+
+unsigned int unary_exp_golomb_level_decode( DecodingEnvironmentPtr dep_dp,
+ BiContextTypePtr ctx);
+
+unsigned int unary_exp_golomb_mv_decode(DecodingEnvironmentPtr dep_dp,
+ BiContextTypePtr ctx,
+ unsigned int max_bin);
+
+
+void CheckAvailabilityOfNeighborsCABAC()
+{
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ PixelPos up, left;
+
+ getNeighbour(img->current_mb_nr, -1, 0, IS_LUMA, &left);
+ getNeighbour(img->current_mb_nr, 0, -1, IS_LUMA, &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;
+}
+
+void cabac_new_slice()
+{
+ last_dquant=0;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocation of contexts models for the motion info
+ * used for arithmetic decoding
+ *
+ ************************************************************************
+ */
+MotionInfoContexts* create_contexts_MotionInfo(void)
+{
+ MotionInfoContexts *deco_ctx;
+
+ deco_ctx = (MotionInfoContexts*) calloc(1, sizeof(MotionInfoContexts) );
+ if( deco_ctx == NULL )
+ no_mem_exit("create_contexts_MotionInfo: deco_ctx");
+
+ return deco_ctx;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocates of contexts models for the texture info
+ * used for arithmetic decoding
+ ************************************************************************
+ */
+TextureInfoContexts* create_contexts_TextureInfo(void)
+{
+ TextureInfoContexts *deco_ctx;
+
+ deco_ctx = (TextureInfoContexts*) calloc(1, sizeof(TextureInfoContexts) );
+ if( deco_ctx == NULL )
+ no_mem_exit("create_contexts_TextureInfo: deco_ctx");
+
+ return deco_ctx;
+}
+
+
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Frees the memory of the contexts models
+ * used for arithmetic decoding of the motion info.
+ ************************************************************************
+ */
+void delete_contexts_MotionInfo(MotionInfoContexts *deco_ctx)
+{
+ if( deco_ctx == NULL )
+ return;
+
+ free( deco_ctx );
+
+ return;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Frees the memory of the contexts models
+ * used for arithmetic decoding of the texture info.
+ ************************************************************************
+ */
+void delete_contexts_TextureInfo(TextureInfoContexts *deco_ctx)
+{
+ if( deco_ctx == NULL )
+ return;
+
+ free( deco_ctx );
+
+ return;
+}
+
+void readFieldModeInfo_CABAC( SyntaxElement *se,
+ struct img_par *img,
+ DecodingEnvironmentPtr dep_dp)
+{
+ int a,b,act_ctx;
+ MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+
+ if (currMB->mbAvailA)
+ a = img->mb_data[currMB->mbAddrA].mb_field;
+ else
+ a = 0;
+ if (currMB->mbAvailB)
+ b = img->mb_data[currMB->mbAddrB].mb_field;
+ else
+ b=0;
+
+ act_ctx = a + b;
+
+ se->value1 = biari_decode_symbol (dep_dp, &ctx->mb_aff_contexts[act_ctx]);
+
+#if TRACE
+ fprintf(p_trace, "@%-6d %-63s (%3d)\n",symbolCount++, se->tracestring, se->value1);
+ fflush(p_trace);
+#endif
+}
+
+
+int check_next_mb_and_get_field_mode_CABAC( SyntaxElement *se,
+ struct img_par *img,
+ DataPartition *act_dp)
+{
+ BiContextTypePtr mb_type_ctx_copy[4];
+ BiContextTypePtr mb_aff_ctx_copy;
+ DecodingEnvironmentPtr dep_dp_copy;
+
+ int length;
+ DecodingEnvironmentPtr dep_dp = &(act_dp->de_cabac);
+
+ int bframe = (img->type==B_SLICE);
+ int skip = 0;
+ int field = 0;
+ int i;
+
+ Macroblock *currMB;
+
+ //get next MB
+ img->current_mb_nr++;
+
+ currMB = &img->mb_data[img->current_mb_nr];
+ currMB->slice_nr = img->current_slice_nr;
+ currMB->mb_field = img->mb_data[img->current_mb_nr-1].mb_field;
+
+ CheckAvailabilityOfNeighbors();
+ CheckAvailabilityOfNeighborsCABAC();
+
+ //create
+ dep_dp_copy = (DecodingEnvironmentPtr) calloc(1, sizeof(DecodingEnvironment) );
+ for (i=0;i<4;i++)
+ mb_type_ctx_copy[i] = (BiContextTypePtr) calloc(NUM_MB_TYPE_CTX, sizeof(BiContextType) );
+ mb_aff_ctx_copy = (BiContextTypePtr) calloc(NUM_MB_AFF_CTX, sizeof(BiContextType) );
+
+ //copy
+ memcpy(dep_dp_copy,dep_dp,sizeof(DecodingEnvironment));
+ length = *(dep_dp_copy->Dcodestrm_len) = *(dep_dp->Dcodestrm_len);
+ for (i=0;i<4;i++)
+ memcpy(mb_type_ctx_copy[i], img->currentSlice->mot_ctx->mb_type_contexts[i],NUM_MB_TYPE_CTX*sizeof(BiContextType) );
+ memcpy(mb_aff_ctx_copy, img->currentSlice->mot_ctx->mb_aff_contexts,NUM_MB_AFF_CTX*sizeof(BiContextType) );
+
+
+ //check_next_mb
+#if TRACE
+ strncpy(se->tracestring, "mb_skip_flag (of following bottom MB)", TRACESTRING_SIZE);
+#endif
+ last_dquant = 0;
+ readMB_skip_flagInfo_CABAC(se,img,dep_dp);
+
+ skip = (bframe)? (se->value1==0 && se->value2==0) : (se->value1==0);
+ if (!skip)
+ {
+#if TRACE
+ strncpy(se->tracestring, "mb_field_decoding_flag (of following bottom MB)", TRACESTRING_SIZE);
+#endif
+ readFieldModeInfo_CABAC( se,img,dep_dp);
+ field = se->value1;
+ img->mb_data[img->current_mb_nr-1].mb_field = field;
+ }
+
+ //reset
+ img->current_mb_nr--;
+
+ memcpy(dep_dp,dep_dp_copy,sizeof(DecodingEnvironment));
+ *(dep_dp->Dcodestrm_len) = length;
+ for (i=0;i<4;i++)
+ memcpy(img->currentSlice->mot_ctx->mb_type_contexts[i],mb_type_ctx_copy[i], NUM_MB_TYPE_CTX*sizeof(BiContextType) );
+ memcpy( img->currentSlice->mot_ctx->mb_aff_contexts,mb_aff_ctx_copy,NUM_MB_AFF_CTX*sizeof(BiContextType) );
+
+ CheckAvailabilityOfNeighborsCABAC();
+
+ //delete
+ free(dep_dp_copy);
+ for (i=0;i<4;i++)
+ free(mb_type_ctx_copy[i]);
+ free(mb_aff_ctx_copy);
+
+ return skip;
+}
+
+
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * This function is used to arithmetically decode the motion
+ * vector data of a B-frame MB.
+ ************************************************************************
+ */
+void readMVD_CABAC( SyntaxElement *se,
+ struct img_par *img,
+ DecodingEnvironmentPtr dep_dp)
+{
+ int i = img->subblock_x;
+ int j = img->subblock_y;
+ int a, b;
+ int act_ctx;
+ int act_sym;
+ 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<<2) - 1, (j<<2), &block_a);
+ getLuma4x4Neighbour(img->current_mb_nr, (i<<2), (j<<2) - 1, &block_b);
+
+ if (block_b.available)
+ {
+ b = iabs(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 = iabs(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;
+ }
+ se->context = act_ctx;
+
+ act_sym = biari_decode_symbol(dep_dp,&ctx->mv_res_contexts[0][act_ctx] );
+
+ if (act_sym != 0)
+ {
+ act_ctx=5*k;
+ act_sym = unary_exp_golomb_mv_decode(dep_dp,ctx->mv_res_contexts[1]+act_ctx,3);
+ act_sym++;
+ mv_sign = biari_decode_symbol_eq_prob(dep_dp);
+
+ if(mv_sign)
+ act_sym = -act_sym;
+ }
+ se->value1 = act_sym;
+
+#if TRACE
+ fprintf(p_trace, "@%-6d %-63s (%3d)\n",symbolCount++, se->tracestring, se->value1);
+ fflush(p_trace);
+#endif
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * This function is used to arithmetically decode the 8x8 block type.
+ ************************************************************************
+ */
+void readB8_typeInfo_CABAC (SyntaxElement *se,
+ struct img_par *img,
+ DecodingEnvironmentPtr dep_dp)
+{
+ int act_sym = 0;
+ int bframe = (img->type==B_SLICE);
+
+ MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx;
+
+
+ if (!bframe)
+ {
+ if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[0][1]))
+ {
+ act_sym = 0;
+ }
+ else
+ {
+ if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[0][3]))
+ {
+ if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[0][4])) act_sym = 2;
+ else act_sym = 3;
+ }
+ else
+ {
+ act_sym = 1;
+ }
+ }
+ }
+ else
+ {
+ if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[1][0]))
+ {
+ if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[1][1]))
+ {
+ if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[1][2]))
+ {
+ if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[1][3]))
+ {
+ act_sym = 10;
+ if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[1][3])) act_sym++;
+ }
+ else
+ {
+ act_sym = 6;
+ if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[1][3])) act_sym+=2;
+ if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[1][3])) act_sym++;
+ }
+ }
+ else
+ {
+ act_sym=2;
+ if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[1][3])) act_sym+=2;
+ if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[1][3])) act_sym+=1;
+ }
+ }
+ else
+ {
+ if (biari_decode_symbol (dep_dp, &ctx->b8_type_contexts[1][3])) act_sym = 1;
+ else act_sym = 0;
+ }
+ act_sym++;
+ }
+ else
+ {
+ act_sym= 0;
+ }
+ }
+ se->value1 = act_sym;
+
+#if TRACE
+ fprintf(p_trace, "@%-6d %-63s (%3d)\n",symbolCount++, se->tracestring, se->value1);
+ fflush(p_trace);
+#endif
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * This function is used to arithmetically decode the macroblock
+ * type info of a given MB.
+ ************************************************************************
+ */
+void readMB_skip_flagInfo_CABAC( SyntaxElement *se,
+ struct img_par *img,
+ DecodingEnvironmentPtr dep_dp)
+{
+ int a, b;
+ int act_ctx;
+ int bframe=(img->type==B_SLICE);
+ MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+
+
+ 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 (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][act_ctx]) == 1)
+ se->value1 = se->value2 = 0;
+ else
+ se->value1 = se->value2 = 1;
+ }
+ 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 (biari_decode_symbol(dep_dp, &ctx->mb_type_contexts[1][act_ctx]) == 1)
+ se->value1 = 0;
+ else
+ se->value1 = 1;
+ }
+
+
+#if TRACE
+ fprintf(p_trace, "@%-6d %-63s (%3d)\n",symbolCount++, se->tracestring, se->value1);
+ fflush(p_trace);
+#endif
+ if (!se->value1)
+ {
+ last_dquant=0;
+ }
+ return;
+}
+
+/*!
+***************************************************************************
+* \brief
+* This function is used to arithmetically decode the macroblock
+* intra_pred_size flag info of a given MB.
+***************************************************************************
+*/
+
+void readMB_transform_size_flag_CABAC( SyntaxElement *se,
+ struct img_par *img,
+ DecodingEnvironmentPtr dep_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];
+
+ if (currMB->mb_available_up == NULL)
+ b = 0;
+ else
+ b = currMB->mb_available_up->luma_transform_size_8x8_flag;
+
+ if (currMB->mb_available_left == NULL)
+ a = 0;
+ else
+ a = currMB->mb_available_left->luma_transform_size_8x8_flag;
+
+ act_ctx = a + b;
+
+
+ act_sym = biari_decode_symbol(dep_dp, ctx->transform_size_contexts + act_ctx );
+ se->value1 = act_sym;
+
+#if TRACE
+ fprintf(p_trace, "@%-6d %-63s (%3d)\n",symbolCount++, se->tracestring, se->value1);
+ fflush(p_trace);
+#endif
+
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * This function is used to arithmetically decode the macroblock
+ * type info of a given MB.
+ ************************************************************************
+ */
+void readMB_typeInfo_CABAC( SyntaxElement *se,
+ struct img_par *img,
+ DecodingEnvironmentPtr dep_dp)
+{
+ int a, b;
+ int act_ctx;
+ int act_sym;
+ int bframe=(img->type==B_SLICE);
+ int mode_sym;
+ int ct = 0;
+ int curr_mb_type;
+
+
+ MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+
+ 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 = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx);
+ se->context = act_ctx; // store context
+
+ if (act_sym==0) // 4x4 Intra
+ {
+ curr_mb_type = act_sym;
+ }
+ else // 16x16 Intra
+ {
+ mode_sym = biari_decode_final(dep_dp);
+ if(mode_sym == 1)
+ {
+ curr_mb_type = 25;
+ }
+ else
+ {
+ act_sym = 1;
+ act_ctx = 4;
+ mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx ); // decoding of AC/no AC
+ act_sym += mode_sym*12;
+ act_ctx = 5;
+ // decoding of cbp: 0,1,2
+ mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx );
+ if (mode_sym!=0)
+ {
+ act_ctx=6;
+ mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx );
+ act_sym+=4;
+ if (mode_sym!=0)
+ act_sym+=4;
+ }
+ // decoding of I pred-mode: 0,1,2,3
+ act_ctx = 7;
+ mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx );
+ act_sym += mode_sym*2;
+ act_ctx = 8;
+ mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx );
+ act_sym += mode_sym;
+ curr_mb_type = act_sym;
+ }
+ }
+ }
+ else if(img->type == SI_SLICE) // SI-frame
+ {
+ // special ctx's for SI4MB
+ if (currMB->mb_available_up == NULL)
+ b = 0;
+ else
+ b = (( (currMB->mb_available_up)->mb_type != SI4MB) ? 1 : 0 );
+ if (currMB->mb_available_left == NULL)
+ a = 0;
+ else
+ a = (( (currMB->mb_available_left)->mb_type != SI4MB) ? 1 : 0 );
+
+ act_ctx = a + b;
+ act_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[1] + act_ctx);
+ se->context = act_ctx; // store context
+
+ if (act_sym==0) // SI 4x4 Intra
+ {
+ curr_mb_type = 0;
+ }
+ else // analog INTRA_IMG
+ {
+ if (currMB->mb_available_up == NULL)
+ b = 0;
+ else
+ b = (( (currMB->mb_available_up)->mb_type != I4MB) ? 1 : 0 );
+ if (currMB->mb_available_left == NULL)
+ a = 0;
+ else
+ a = (( (currMB->mb_available_left)->mb_type != I4MB) ? 1 : 0 );
+
+ act_ctx = a + b;
+ act_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx);
+ se->context = act_ctx; // store context
+
+
+ if (act_sym==0) // 4x4 Intra
+ {
+ curr_mb_type = 1;
+ }
+ else // 16x16 Intra
+ {
+ mode_sym = biari_decode_final(dep_dp);
+ if( mode_sym==1 )
+ {
+ curr_mb_type = 26;
+ }
+ else
+ {
+ act_sym = 2;
+ act_ctx = 4;
+ mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx ); // decoding of AC/no AC
+ act_sym += mode_sym*12;
+ act_ctx = 5;
+ // decoding of cbp: 0,1,2
+ mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx );
+ if (mode_sym!=0)
+ {
+ act_ctx=6;
+ mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx );
+ act_sym+=4;
+ if (mode_sym!=0)
+ act_sym+=4;
+ }
+ // decoding of I pred-mode: 0,1,2,3
+ act_ctx = 7;
+ mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx );
+ act_sym += mode_sym*2;
+ act_ctx = 8;
+ mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx );
+ act_sym += mode_sym;
+ curr_mb_type = act_sym;
+ }
+ }
+ }
+ }
+ else
+ {
+ if (bframe)
+ {
+ ct = 1;
+ 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;
+
+ if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][act_ctx]))
+ {
+ if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][4]))
+ {
+ if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][5]))
+ {
+ act_sym=12;
+ if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=8;
+ if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=4;
+ if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=2;
+
+ if (act_sym==24) act_sym=11;
+ else if (act_sym==26) act_sym=22;
+ else
+ {
+ if (act_sym==22) act_sym=23;
+ if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=1;
+ }
+ }
+ else
+ {
+ act_sym=3;
+ if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=4;
+ if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=2;
+ if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym+=1;
+ }
+ }
+ else
+ {
+ if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][6])) act_sym=2;
+ else act_sym=1;
+ }
+ }
+ else
+ {
+ act_sym = 0;
+ }
+ }
+ else // P-frame
+ {
+ {
+ if (biari_decode_symbol(dep_dp, &ctx->mb_type_contexts[1][4] ))
+ {
+ if (biari_decode_symbol(dep_dp, &ctx->mb_type_contexts[1][7] )) act_sym = 7;
+ else act_sym = 6;
+ }
+ else
+ {
+ if (biari_decode_symbol(dep_dp, &ctx->mb_type_contexts[1][5] ))
+ {
+ if (biari_decode_symbol(dep_dp, &ctx->mb_type_contexts[1][7] )) act_sym = 2;
+ else act_sym = 3;
+ }
+ else
+ {
+ if (biari_decode_symbol(dep_dp, &ctx->mb_type_contexts[1][6] )) act_sym = 4;
+ else act_sym = 1;
+ }
+ }
+ }
+ }
+
+ if (act_sym<=6 || (((img->type == B_SLICE)?1:0) && act_sym<=23))
+ {
+ curr_mb_type = act_sym;
+ }
+ else // additional info for 16x16 Intra-mode
+ {
+ mode_sym = biari_decode_final(dep_dp);
+ if( mode_sym==1 )
+ {
+ if(bframe) // B frame
+ curr_mb_type = 48;
+ else // P frame
+ curr_mb_type = 31;
+ }
+ else
+ {
+ act_ctx = 8;
+ mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[1] + act_ctx ); // decoding of AC/no AC
+ act_sym += mode_sym*12;
+
+ // decoding of cbp: 0,1,2
+ act_ctx = 9;
+ mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[1] + act_ctx );
+ if (mode_sym != 0)
+ {
+ act_sym+=4;
+ mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[1] + act_ctx );
+ if (mode_sym != 0)
+ act_sym+=4;
+ }
+
+ // decoding of I pred-mode: 0,1,2,3
+ act_ctx = 10;
+ mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[1] + act_ctx );
+ act_sym += mode_sym*2;
+ mode_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[1] + act_ctx );
+ act_sym += mode_sym;
+ curr_mb_type = act_sym;
+ }
+ }
+ }
+ se->value1 = curr_mb_type;
+
+// if (curr_mb_type >= 23) printf(" stopx");
+#if TRACE
+ fprintf(p_trace, "@%-6d %-63s (%3d)\n",symbolCount++, se->tracestring, se->value1);
+ fflush(p_trace);
+#endif
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * This function is used to arithmetically decode a pair of
+ * intra prediction modes of a given MB.
+ ************************************************************************
+ */
+void readIntraPredMode_CABAC( SyntaxElement *se,
+ struct img_par *img,
+ DecodingEnvironmentPtr dep_dp)
+{
+ TextureInfoContexts *ctx = img->currentSlice->tex_ctx;
+ int act_sym;
+
+ // use_most_probable_mode
+ act_sym = biari_decode_symbol(dep_dp, ctx->ipr_contexts);
+
+ // remaining_mode_selector
+ if (act_sym == 1)
+ se->value1 = -1;
+ else
+ {
+ se->value1 = 0;
+ se->value1 |= (biari_decode_symbol(dep_dp, ctx->ipr_contexts+1) );
+ se->value1 |= (biari_decode_symbol(dep_dp, ctx->ipr_contexts+1) << 1);
+ se->value1 |= (biari_decode_symbol(dep_dp, ctx->ipr_contexts+1) << 2);
+ }
+
+#if TRACE
+ fprintf(p_trace, "@%-6d %-63s (%3d)\n",symbolCount++, se->tracestring, se->value1);
+ fflush(p_trace);
+#endif
+}
+/*!
+ ************************************************************************
+ * \brief
+ * This function is used to arithmetically decode the reference
+ * parameter of a given MB.
+ ************************************************************************
+ */
+void readRefFrame_CABAC( SyntaxElement *se,
+ struct img_par *img,
+ DecodingEnvironmentPtr dep_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 = dec_picture->ref_idx[se->value2];
+ int b8a, b8b;
+
+ PixelPos block_a, block_b;
+
+ getLuma4x4Neighbour(img->current_mb_nr, (img->subblock_x<<2) - 1, (img->subblock_y<<2), &block_a);
+ getLuma4x4Neighbour(img->current_mb_nr, (img->subblock_x<<2), (img->subblock_y<<2) - 1, &block_b);
+
+ b8a=((block_a.x/2)%2)+2*((block_a.y/2)%2);
+ b8b=((block_b.x/2)%2)+2*((block_b.y/2)%2);
+
+ if (!block_b.available)
+ b=0;
+ else if ( (img->mb_data[block_b.mb_addr].mb_type==IPCM) || IS_DIRECT(&img->mb_data[block_b.mb_addr]) || (img->mb_data[block_b.mb_addr].b8mode[b8b]==0 && img->mb_data[block_b.mb_addr].b8pdir[b8b]==2))
+ 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 ((img->mb_data[block_a.mb_addr].mb_type==IPCM) || IS_DIRECT(&img->mb_data[block_a.mb_addr]) || (img->mb_data[block_a.mb_addr].b8mode[b8a]==0 && img->mb_data[block_a.mb_addr].b8pdir[b8a]==2))
+ 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 = biari_decode_symbol(dep_dp,ctx->ref_no_contexts[addctx] + act_ctx );
+
+ if (act_sym != 0)
+ {
+ act_ctx = 4;
+ act_sym = unary_bin_decode(dep_dp,ctx->ref_no_contexts[addctx]+act_ctx,1);
+ act_sym++;
+ }
+ se->value1 = act_sym;
+
+#if TRACE
+ fprintf(p_trace, "@%-6d %-63s (%3d)\n",symbolCount++, se->tracestring, se->value1);
+// fprintf(p_trace," c: %d :%d \n",ctx->ref_no_contexts[addctx][act_ctx].cum_freq[0],ctx->ref_no_contexts[addctx][act_ctx].cum_freq[1]);
+ fflush(p_trace);
+#endif
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * This function is used to arithmetically decode the delta qp
+ * of a given MB.
+ ************************************************************************
+ */
+void readDquant_CABAC( SyntaxElement *se,
+ struct img_par *img,
+ DecodingEnvironmentPtr dep_dp)
+{
+ MotionInfoContexts *ctx = img->currentSlice->mot_ctx;
+
+ int act_ctx;
+ int act_sym;
+ int dquant;
+
+ act_ctx = ( (last_dquant != 0) ? 1 : 0);
+
+ act_sym = biari_decode_symbol(dep_dp,ctx->delta_qp_contexts + act_ctx );
+ if (act_sym != 0)
+ {
+ act_ctx = 2;
+ act_sym = unary_bin_decode(dep_dp,ctx->delta_qp_contexts+act_ctx,1);
+ act_sym++;
+ }
+
+ dquant = (act_sym+1)/2;
+ if((act_sym & 0x01)==0) // lsb is signed bit
+ dquant = -dquant;
+ se->value1 = dquant;
+
+ last_dquant = dquant;
+
+#if TRACE
+ fprintf(p_trace, "@%-6d %-63s (%3d)\n",symbolCount++, se->tracestring, se->value1);
+ fflush(p_trace);
+#endif
+}
+/*!
+ ************************************************************************
+ * \brief
+ * This function is used to arithmetically decode the coded
+ * block pattern of a given MB.
+ ************************************************************************
+ */
+void readCBP_CABAC(SyntaxElement *se,
+ struct img_par *img,
+ DecodingEnvironmentPtr dep_dp)
+{
+ TextureInfoContexts *ctx = img->currentSlice->tex_ctx;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+
+ int mb_x, mb_y;
+ int a, b;
+ int curr_cbp_ctx, curr_cbp_idx;
+ int cbp = 0;
+ int cbp_bit;
+ int mask;
+ PixelPos block_a;
+
+ // coding of luma part (bit by bit)
+ for (mb_y=0; mb_y < 4; mb_y += 2)
+ {
+ for (mb_x=0; mb_x < 4; mb_x += 2)
+ {
+ if (currMB->b8mode[mb_y+(mb_x/2)]==IBLOCK)
+ curr_cbp_idx = 0;
+ else
+ curr_cbp_idx = 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/2))) == 0) ? 1 : 0);
+ }
+
+ }
+ else
+ b = ( ((cbp & (1<<(mb_x/2))) == 0) ? 1: 0);
+
+ if (mb_x == 0)
+ {
+ getLuma4x4Neighbour(img->current_mb_nr, (mb_x<<2) - 1, (mb_y << 2), &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/2)+1))) == 0) ? 1 : 0);
+ }
+
+ }
+ else
+ a=0;
+ }
+ else
+ a = ( ((cbp & (1<<mb_y)) == 0) ? 1: 0);
+
+ curr_cbp_ctx = a+2*b;
+ mask = (1<<(mb_y+mb_x/2));
+ cbp_bit = biari_decode_symbol(dep_dp, ctx->cbp_contexts[0] + curr_cbp_ctx );
+ if (cbp_bit) cbp += mask;
+ }
+ }
+
+
+ if (dec_picture->chroma_format_idc != YUV400)
+ {
+ // coding of chroma part
+ // CABAC decoding for BinIdx 0
+ 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 = biari_decode_symbol(dep_dp, ctx->cbp_contexts[1] + curr_cbp_ctx );
+
+ // CABAC decoding for BinIdx 1
+ if (cbp_bit) // set the chroma bits
+ {
+ 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 = biari_decode_symbol(dep_dp, ctx->cbp_contexts[2] + curr_cbp_ctx );
+ cbp += (cbp_bit == 1) ? 32 : 16;
+ }
+ }
+
+ se->value1 = cbp;
+
+ if (!cbp)
+ {
+ last_dquant=0;
+ }
+
+#if TRACE
+ fprintf(p_trace, "@%-6d %-63s (%3d)\n",symbolCount++, se->tracestring, se->value1);
+ fflush(p_trace);
+#endif
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * This function is used to arithmetically decode the chroma
+ * intra prediction mode of a given MB.
+ ************************************************************************
+ */ //GB
+void readCIPredMode_CABAC(SyntaxElement *se,
+ struct img_par *img,
+ DecodingEnvironmentPtr dep_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
+ {
+ if( (currMB->mb_available_up)->mb_type==IPCM)
+ b=0;
+ else
+ b = ( ((currMB->mb_available_up)->c_ipred_mode != 0) ? 1 : 0);
+ }
+
+
+ if (currMB->mb_available_left == NULL) a = 0;
+ else
+ {
+ if( (currMB->mb_available_left)->mb_type==IPCM)
+ a=0;
+ else
+ a = ( ((currMB->mb_available_left)->c_ipred_mode != 0) ? 1 : 0);
+ }
+
+
+ act_ctx = a+b;
+
+ act_sym = biari_decode_symbol(dep_dp, ctx->cipr_contexts + act_ctx );
+
+ if (act_sym!=0)
+ act_sym = unary_bin_max_decode(dep_dp,ctx->cipr_contexts+3,0,2)+1;
+
+
+ se->value1 = act_sym;
+
+
+#if TRACE
+ fprintf(p_trace, "@%-6d %-63s (%3d)\n",symbolCount++, se->tracestring, se->value1);
+ fflush(p_trace);
+#endif
+
+}
+
+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
+ * Read CBP4-BIT
+ ************************************************************************
+*/
+int read_and_store_CBP_block_bit (Macroblock *currMB,
+ DecodingEnvironmentPtr dep_dp,
+ struct img_par *img,
+ int type)
+{
+#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 : 35);
+ int default_bit = (img->is_intra_block ? 1 : 0);
+ int upper_bit = default_bit;
+ int left_bit = default_bit;
+ int cbp_bit = 1; // always one for 8x8 mode
+ 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<<2) - 1, (j<<2), &block_a);
+ getLuma4x4Neighbour(img->current_mb_nr, (i<<2), (j<<2) - 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<<2) - 1, (j<<2), &block_a);
+ getChroma4x4Neighbour(img->current_mb_nr, (i<<2), (j<<2) - 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;
+ }
+ }
+
+ if (type!=LUMA_8x8)
+ {
+ //--- get bits from neighbouring blocks ---
+ 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 =====
+ cbp_bit = biari_decode_symbol (dep_dp, img->currentSlice->tex_ctx->bcbp_contexts[type2ctx_bcbp[type]] + ctx);
+ }
+
+ //--- set bits for current block ---
+ 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);
+
+ if (cbp_bit)
+ {
+ if (type==LUMA_8x8)
+ {
+ currMB->cbp_bits |= ((int64)1<< bit );
+ currMB->cbp_bits |= ((int64)1<<(bit+1));
+ currMB->cbp_bits |= ((int64)1<<(bit+4));
+ currMB->cbp_bits |= ((int64)1<<(bit+5));
+ }
+ else if (type==LUMA_8x4)
+ {
+ currMB->cbp_bits |= ((int64)1<< bit );
+ currMB->cbp_bits |= ((int64)1<<(bit+1));
+ }
+ else if (type==LUMA_4x8)
+ {
+ currMB->cbp_bits |= ((int64)1<< bit );
+ currMB->cbp_bits |= ((int64)1<<(bit+4));
+ }
+ else
+ {
+ currMB->cbp_bits |= ((int64)1<<bit);
+ }
+ }
+
+ return cbp_bit;
+}
+
+
+
+
+
+//===== 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
+ * Read Significance MAP
+ ************************************************************************
+ */
+int read_significance_map (Macroblock *currMB,
+ DecodingEnvironmentPtr dep_dp,
+ struct img_par *img,
+ int type,
+ int coeff[])
+{
+ int i, sig;
+ int coeff_ctr = 0;
+ int i0 = 0;
+ int i1 = maxpos[type]-1;
+
+ int fld = ( img->structure!=FRAME || currMB->mb_field );
+ const int **pos2ctx_Map = (fld) ? pos2ctx_map_int : pos2ctx_map;
+ TextureInfoContexts *tex_ctx = img->currentSlice->tex_ctx;
+
+ BiContextTypePtr map_ctx = ( fld ? tex_ctx->fld_map_contexts[type2ctx_map [type]]
+ : tex_ctx-> map_contexts[type2ctx_map [type]] );
+ BiContextTypePtr last_ctx = ( fld ? tex_ctx->fld_last_contexts[type2ctx_last[type]]
+ : tex_ctx-> last_contexts[type2ctx_last[type]] );
+
+ if (!c1isdc[type])
+ {
+ i0++; i1++; coeff--;
+ }
+
+ for (i=i0; i<i1; i++) // if last coeff is reached, it has to be significant
+ {
+ //--- read significance symbol ---
+ sig = biari_decode_symbol (dep_dp, map_ctx + pos2ctx_Map [type][i]);
+
+ if (sig)
+ {
+ coeff[i] = 1;
+ coeff_ctr++;
+ //--- read last coefficient symbol ---
+ if (biari_decode_symbol (dep_dp, last_ctx + pos2ctx_last[type][i]))
+ {
+ for (i++; i<i1+1; i++) coeff[i] = 0;
+ }
+ }
+ else
+ {
+ coeff[i] = 0;
+ }
+ }
+ //--- last coefficient must be significant if no last symbol was received ---
+ if (i<i1+1)
+ {
+ coeff[i] = 1;
+ coeff_ctr++;
+ }
+
+ return coeff_ctr;
+}
+
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Read Levels
+ ************************************************************************
+ */
+void read_significant_coefficients (DecodingEnvironmentPtr dep_dp,
+ struct img_par *img,
+ int type,
+ int coeff[])
+{
+ int i, ctx;
+ int c1 = 1;
+ int c2 = 0;
+
+ for (i=maxpos[type]-1; i>=0; i--)
+ {
+ if (coeff[i]!=0)
+ {
+ ctx = imin (c1,4);
+ coeff[i] += biari_decode_symbol (dep_dp, img->currentSlice->tex_ctx->one_contexts[type2ctx_one[type]] + ctx);
+ if (coeff[i]==2)
+ {
+ ctx = imin (c2, max_c2[type]);
+ coeff[i] += unary_exp_golomb_level_decode (dep_dp, img->currentSlice->tex_ctx->abs_contexts[type2ctx_abs[type]]+ctx);
+ c1=0;
+ c2++;
+ }
+ else if (c1)
+ {
+ c1++;
+ }
+ if (biari_decode_symbol_eq_prob(dep_dp))
+ {
+ coeff[i] *= -1;
+ }
+ }
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Read Block-Transform Coefficients
+ ************************************************************************
+ */
+void readRunLevel_CABAC (SyntaxElement *se,
+ struct img_par *img,
+ DecodingEnvironmentPtr dep_dp)
+{
+ static int coeff[64]; // one more for EOB
+ static int coeff_ctr = -1;
+ static int pos = 0;
+
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+
+ //--- read coefficients for whole block ---
+ if (coeff_ctr < 0)
+ {
+ //===== decode CBP-BIT =====
+ if ((coeff_ctr = read_and_store_CBP_block_bit (currMB, dep_dp, img, se->context) )!=0)
+ {
+ //===== decode significance map =====
+ coeff_ctr = read_significance_map (currMB, dep_dp, img, se->context, coeff);
+
+ //===== decode significant coefficients =====
+ read_significant_coefficients (dep_dp, img, se->context, coeff);
+ }
+ }
+
+ //--- set run and level ---
+ if (coeff_ctr)
+ {
+ //--- set run and level (coefficient) ---
+ for (se->value2=0; coeff[pos]==0; pos++, se->value2++);
+ se->value1=coeff[pos++];
+ }
+ else
+ {
+ //--- set run and level (EOB) ---
+ se->value1 = se->value2 = 0;
+ }
+ //--- decrement coefficient counter and re-set position ---
+ if (coeff_ctr-- == 0) pos=0;
+
+#if TRACE
+ fprintf(p_trace, "@%-6d %-53s %3d %3d\n",symbolCount++, se->tracestring, se->value1,se->value2);
+ fflush(p_trace);
+#endif
+}
+
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * arithmetic decoding
+ ************************************************************************
+ */
+int readSyntaxElement_CABAC(SyntaxElement *se, struct img_par *img, DataPartition *this_dataPart)
+{
+ int curr_len;
+ DecodingEnvironmentPtr dep_dp = &(this_dataPart->de_cabac);
+
+ curr_len = arideco_bits_read(dep_dp);
+
+ // perform the actual decoding by calling the appropriate method
+ se->reading(se, img, dep_dp);
+
+ return (se->len = (arideco_bits_read(dep_dp) - curr_len));
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * decoding of unary binarization using one or 2 distinct
+ * models for the first and all remaining bins; no terminating
+ * "0" for max_symbol
+ ***********************************************************************
+ */
+unsigned int unary_bin_max_decode(DecodingEnvironmentPtr dep_dp,
+ BiContextTypePtr ctx,
+ int ctx_offset,
+ unsigned int max_symbol)
+{
+ unsigned int l;
+ unsigned int symbol;
+ BiContextTypePtr ictx;
+
+ symbol = biari_decode_symbol(dep_dp, ctx );
+
+ if (symbol==0)
+ return 0;
+ else
+ {
+ if (max_symbol == 1)
+ return symbol;
+ symbol=0;
+ ictx=ctx+ctx_offset;
+ do
+ {
+ l=biari_decode_symbol(dep_dp, ictx);
+ symbol++;
+ }
+ while( (l!=0) && (symbol<max_symbol-1) );
+ if ((l!=0) && (symbol==max_symbol-1))
+ symbol++;
+ return symbol;
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * decoding of unary binarization using one or 2 distinct
+ * models for the first and all remaining bins
+ ***********************************************************************
+ */
+unsigned int unary_bin_decode(DecodingEnvironmentPtr dep_dp,
+ BiContextTypePtr ctx,
+ int ctx_offset)
+{
+ unsigned int l;
+ unsigned int symbol;
+ BiContextTypePtr ictx;
+
+ symbol = biari_decode_symbol(dep_dp, ctx );
+
+ if (symbol==0)
+ return 0;
+ else
+ {
+ symbol=0;
+ ictx=ctx+ctx_offset;
+ do
+ {
+ l=biari_decode_symbol(dep_dp, ictx);
+ symbol++;
+ }
+ while( l!=0 );
+ return symbol;
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * finding end of a slice in case this is not the end of a frame
+ *
+ * Unsure whether the "correction" below actually solves an off-by-one
+ * problem or whether it introduces one in some cases :-( Anyway,
+ * with this change the bit stream format works with CABAC again.
+ * StW, 8.7.02
+ ************************************************************************
+ */
+int cabac_startcode_follows(struct img_par *img, int eos_bit)
+{
+ Slice *currSlice = img->currentSlice;
+ int *partMap = assignSE2partition[currSlice->dp_mode];
+ DataPartition *dP;
+ unsigned int bit;
+ DecodingEnvironmentPtr dep_dp;
+
+ dP = &(currSlice->partArr[partMap[SE_MBTYPE]]);
+ dep_dp = &(dP->de_cabac);
+
+ if( eos_bit )
+ {
+ bit = biari_decode_final (dep_dp); //GB
+
+#if TRACE
+ fprintf(p_trace, "@%-6d %-63s (%3d)\n",symbolCount++, "end_of_slice_flag", bit);
+ fflush(p_trace);
+#endif
+ }
+ else
+ {
+ bit = 0;
+ }
+
+ return (bit==1?1:0);
+}
+
+
+
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Exp Golomb binarization and decoding of a symbol
+ * with prob. of 0.5
+ ************************************************************************
+ */
+unsigned int exp_golomb_decode_eq_prob( DecodingEnvironmentPtr dep_dp,
+ int k)
+{
+ unsigned int l;
+ int symbol = 0;
+ int binary_symbol = 0;
+
+ do
+ {
+ l=biari_decode_symbol_eq_prob(dep_dp);
+ if (l==1)
+ {
+ symbol += (1<<k);
+ k++;
+ }
+ }
+ while (l!=0);
+
+ while (k--) //next binary part
+ if (biari_decode_symbol_eq_prob(dep_dp)==1)
+ binary_symbol |= (1<<k);
+
+ return (unsigned int) (symbol+binary_symbol);
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Exp-Golomb decoding for LEVELS
+ ***********************************************************************
+ */
+unsigned int unary_exp_golomb_level_decode( DecodingEnvironmentPtr dep_dp,
+ BiContextTypePtr ctx)
+{
+ unsigned int l,k;
+ unsigned int symbol;
+ unsigned int exp_start = 13;
+
+ symbol = biari_decode_symbol(dep_dp, ctx );
+
+ if (symbol==0)
+ return 0;
+ else
+ {
+ symbol=0;
+ k=1;
+ do
+ {
+ l=biari_decode_symbol(dep_dp, ctx);
+ symbol++;
+ k++;
+ }
+ while((l!=0) && (k!=exp_start));
+ if (l!=0)
+ symbol += exp_golomb_decode_eq_prob(dep_dp,0)+1;
+ return symbol;
+ }
+}
+
+
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Exp-Golomb decoding for Motion Vectors
+ ***********************************************************************
+ */
+unsigned int unary_exp_golomb_mv_decode(DecodingEnvironmentPtr dep_dp,
+ BiContextTypePtr ctx,
+ unsigned int max_bin)
+{
+ unsigned int l,k;
+ unsigned int bin=1;
+ unsigned int symbol;
+ unsigned int exp_start = 8;
+
+ BiContextTypePtr ictx=ctx;
+
+ symbol = biari_decode_symbol(dep_dp, ictx );
+
+ if (symbol==0)
+ return 0;
+ else
+ {
+ symbol=0;
+ k=1;
+
+ ictx++;
+ do
+ {
+ l=biari_decode_symbol(dep_dp, ictx );
+ if ((++bin)==2) ictx++;
+ if (bin==max_bin) ictx++;
+ symbol++;
+ k++;
+ }
+ while((l!=0) && (k!=exp_start));
+ if (l!=0)
+ symbol += exp_golomb_decode_eq_prob(dep_dp,3)+1;
+ return symbol;
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Read one byte from CABAC-partition.
+ * Bitstream->read_len will be modified
+ * (for IPCM CABAC 28/11/2003)
+ *
+ * \author
+ * Dong Wang <Dong.Wang at bristol.ac.uk>
+ ************************************************************************
+*/
+void readIPCMBytes_CABAC(SyntaxElement *sym, Bitstream *currStream)
+{
+ int read_len = currStream->read_len;
+ int code_len = currStream->code_len;
+ byte *buf = currStream->streamBuffer;
+
+ sym->len=8;
+
+ if(read_len<code_len)
+ sym->inf=buf[read_len++];
+
+ sym->value1=sym->inf;
+
+ currStream->read_len=read_len;
+
+#if TRACE
+ tracebits2(sym->tracestring, sym->len, sym->inf);
+#endif
+
+}
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/cabac.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/cabac.h:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/cabac.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,54 @@
+
+/*!
+ ***************************************************************************
+ * \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_
+
+#include "global.h"
+
+MotionInfoContexts* create_contexts_MotionInfo(void);
+TextureInfoContexts* create_contexts_TextureInfo(void);
+void init_contexts_MotionInfo(struct img_par *img, MotionInfoContexts *enco_ctx);
+void init_contexts_TextureInfo(struct img_par *img, TextureInfoContexts *enco_ctx);
+void delete_contexts_MotionInfo(MotionInfoContexts *enco_ctx);
+void delete_contexts_TextureInfo(TextureInfoContexts *enco_ctx);
+
+void cabac_new_slice();
+
+void readMB_typeInfo_CABAC(SyntaxElement *se, struct img_par *img, DecodingEnvironmentPtr dep_dp);
+void readB8_typeInfo_CABAC(SyntaxElement *se, struct img_par *img, DecodingEnvironmentPtr dep_dp);
+void readIntraPredMode_CABAC(SyntaxElement *se, struct img_par *img, DecodingEnvironmentPtr dep_dp);
+void readRefFrame_CABAC(SyntaxElement *se, struct img_par *img, DecodingEnvironmentPtr dep_dp);
+void readMVD_CABAC(SyntaxElement *se, struct img_par *img, DecodingEnvironmentPtr dep_dp);
+void readCBP_CABAC(SyntaxElement *se, struct img_par *img, DecodingEnvironmentPtr dep_dp);
+void readRunLevel_CABAC(SyntaxElement *se, struct img_par *img, DecodingEnvironmentPtr dep_dp);
+void readDquant_CABAC(SyntaxElement *se,struct img_par *img,DecodingEnvironmentPtr dep_dp);
+void readCIPredMode_CABAC(SyntaxElement *se,struct img_par *img,DecodingEnvironmentPtr dep_dp);
+void readMB_skip_flagInfo_CABAC( SyntaxElement *se, struct img_par *img, DecodingEnvironmentPtr dep_dp);
+void readFieldModeInfo_CABAC(SyntaxElement *se, struct img_par *img,DecodingEnvironmentPtr dep_dp);
+
+void readMB_transform_size_flag_CABAC( SyntaxElement *se, struct img_par *img, DecodingEnvironmentPtr dep_dp);
+
+int readSyntaxElement_CABAC(SyntaxElement *se, struct img_par *img, DataPartition *this_dataPart);
+
+int check_next_mb_and_get_field_mode_CABAC(SyntaxElement *se,struct img_par *img,DataPartition *act_dp);
+void CheckAvailabilityOfNeighborsCABAC();
+
+
+#endif // _CABAC_H_
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/context_ini.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/context_ini.c:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/context_ini.c Sun Feb 4 08:38:31 2007
@@ -0,0 +1,74 @@
+
+/*!
+ *************************************************************************************
+ * \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 "defines.h"
+#include "global.h"
+#include "biaridecod.h"
+#include "ctx_tables.h"
+
+
+#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)||(img->type==SI_SLICE)) biari_init_context (img, &(ctx[i][j]), &(tab ## _I[num][i][j][0])); \
+ else biari_init_context (img, &(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)||(img->type==SI_SLICE)) biari_init_context (img, &(ctx[j]), &(tab ## _I[num][0][j][0])); \
+ else biari_init_context (img, &(ctx[j]), &(tab ## _P[num][0][j][0])); \
+ } \
+}
+
+
+void
+init_contexts (struct img_par* img)
+{
+ MotionInfoContexts* mc = img->currentSlice->mot_ctx;
+ TextureInfoContexts* tc = img->currentSlice->tex_ctx;
+ int i, j;
+
+ //printf("%d -", img->model_number);
+
+ //--- 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 (8, 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);
+}
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/context_ini.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/context_ini.h:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/context_ini.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,23 @@
+
+/*!
+ *************************************************************************************
+ * \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 init_contexts (struct img_par* img);
+
+#endif
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/contributors.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/contributors.h:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/contributors.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,208 @@
+
+/*! \file
+ * contributors.h
+ * \brief
+ * List of contributors and copyright information.
+ *
+ * \par Copyright statements
+ \verbatim
+ H.264 JM coder/decoder
+
+ Copyright (C) 2000 by
+ Telenor Satellite 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
+ TICSP, Tampere University of Technology, Finland
+ Munich University of Technology, Institute for Communications Engineering, Germany
+ Videolocus, 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>
+ 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 Satellite 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, Germany
+
+ Guido Heising <heising at hhi.de>
+ Heinrich-Hertz-Institute
+ Einsteinufer 37
+ 10587 Berlin
+ Germany
+
+ Gabi Blaettermann <blaetter at hhi.de>
+ Heinrich-Hertz-Institute
+ Einsteinufer 37
+ 10587 Berlin
+ Germany
+
+ Detlev Marpe <marpe 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
+
+ Viktor Varsa <viktor.varsa at nokia.com>
+ Nokia Inc. / Nokia Research Center
+ 6000 Connection Drive
+ Irving, TX 75039, USA
+
+ Ye-Kui Wang <wyk at ieee.org>
+ Tampere University of Technology
+ Tampere International Center for Signal Processing
+ 33720 Tampere, Finland
+
+ Ari Hourunranta <ari.hourunranta at nokia.com>
+ Nokia Corporation / Nokia Mobile Phones
+ P.O. Box 88
+ 33721 Tampere, Finland
+
+ Yann Le Maguet <yann.lemaguet at philips.com>
+ Philips Research France
+
+ Dong Tian <tian at cs.tut.fi>
+ 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
+
+ Tobias Oelbaum <drehvial at gmx.net>
+ Institute for Communications Engineering
+ Munich University of Technology
+ 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
+
+ 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 <dthoang at yahoo.com>
+ 10533 Roy Butler Dr.
+ Austin, TX 78717
+
+ Eric Viscito <eric at ev-consulting.com>
+ eV Consulting
+ 52 Tracy Ln
+ Shelburne, VT 05482 USA
+
+ 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
+
+ Alexis Michael Tourapis <alexismt at ieee.org><atour at dolby.com>
+ Athanasios Leontaris <aleon at dolby.com>
+ Dolby Laboratories Inc.
+ 3601 West Alameda Ave.
+ Burbank, CA 91505
+
+ Saurav K Bandyopadhyay <saurav at ieee.org>
+ Purvin Pandit <Purvin.Pandit at thomson.net>
+ Zhenyu Wu <Zhenyu.Wu at thomson.net>
+ Thomson Inc.
+ 2 Independence Way
+ Princeton, NJ 08540
+
+
+
+ \endverbatim
+*/
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/ctx_tables.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/ctx_tables.h:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/ctx_tables.h Sun Feb 4 08:38:31 2007
@@ -0,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/ldecod/defines.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/defines.h:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/defines.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,155 @@
+
+/*!
+ **************************************************************************
+ * \file defines.h
+ *
+ * \brief
+ * Headerfile 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
+
+// Dump dbp for debug purposes
+#define DUMP_DPB 0
+//#define PAIR_FIELDS_IN_OUTPUT
+
+//#define MAX_NUM_SLICES 150
+#define MAX_NUM_SLICES 50
+
+//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
+
+
+#define ZEROSNR 0
+
+// CAVLC
+#define LUMA 0
+#define LUMA_INTRA16x16DC 1
+#define LUMA_INTRA16x16AC 2
+
+#define TOTRUN_NUM 15
+#define RUNBEFORE_NUM 7
+
+
+//--- 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 MAX_CODED_FRAME_SIZE 8000000 //!< bytes for one frame
+
+//#define _LEAKYBUCKET_
+
+#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 IS_INTRA(MB) ((MB)->mb_type==I4MB || (MB)->mb_type==I16MB ||(MB)->mb_type==IPCM || (MB)->mb_type==I8MB || (MB)->mb_type==SI4MB)
+#define IS_NEWINTRA(MB) ((MB)->mb_type==I16MB || (MB)->mb_type==IPCM)
+#define IS_OLDINTRA(MB) ((MB)->mb_type==I4MB)
+
+#define IS_INTER(MB) ((MB)->mb_type!=I4MB && (MB)->mb_type!=I16MB && (MB)->mb_type!=I8MB && (MB)->mb_type!=IPCM)
+#define IS_INTERMV(MB) ((MB)->mb_type!=I4MB && (MB)->mb_type!=I16MB && (MB)->mb_type!=I8MB && (MB)->mb_type!=0 && (MB)->mb_type!=IPCM)
+#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 BLOCK_SIZE 4
+#define MB_BLOCK_SIZE 16
+#define MB_BLOCK_PIXELS 256 // MB_BLOCK_SIZE * MB_BLOCK_SIZE
+#define BLOCK_MULTIPLE 4 // (MB_BLOCK_SIZE/BLOCK_SIZE)
+
+#define NO_INTRA_PMODE 9 //!< #intra prediction modes
+/* 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 EOS 1 //!< End Of Sequence
+#define SOP 2 //!< Start Of Picture
+#define SOS 3 //!< Start Of Slice
+
+#define DECODING_OK 0
+#define SEARCH_SYNC 1
+#define PICTURE_DECODED 2
+
+#define MAX_REFERENCE_PICTURES 32 //!< H264 allows 32 fields
+
+#define INVALIDINDEX (-135792468)
+
+#define MVPRED_MEDIAN 0
+#define MVPRED_L 1
+#define MVPRED_U 2
+#define MVPRED_UR 3
+
+#define DECODE_COPY_MB 0
+#define DECODE_MB 1
+//#define DECODE_MB_BFRAME 2
+
+
+//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
+
+#endif
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/elements.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/elements.h:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/elements.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,107 @@
+
+/*!
+ *************************************************************************************
+ * \file elements.h
+ *
+ * \brief
+ * Header file for elements in H.264 streams
+ *
+ * \date
+ * 6.10.2000
+ *
+ * \version
+ * 1.0
+ *
+ * \author
+ * Sebastian Purreiter <sebastian.purreiter at mch.siemens.de> \n
+ * Siemens AG, Information and Communication Mobile \n
+ * P.O.Box 80 17 07 \n
+ * D-81617 Munich, Germany \n
+ *************************************************************************************
+ */
+
+#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 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
+ * SE_DELTA_QUANT_INTER
+ * SE_DELTA_QUANT_INTRA
+ * 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 SE_HEADER 0
+#define SE_PTYPE 1
+#define SE_MBTYPE 2
+#define SE_REFFRAME 3
+#define SE_INTRAPREDMODE 4
+#define SE_MVD 5
+#define SE_CBP_INTRA 6
+#define SE_LUM_DC_INTRA 7
+#define SE_CHR_DC_INTRA 8
+#define SE_LUM_AC_INTRA 9
+#define SE_CHR_AC_INTRA 10
+#define SE_CBP_INTER 11
+#define SE_LUM_DC_INTER 12
+#define SE_CHR_DC_INTER 13
+#define SE_LUM_AC_INTER 14
+#define SE_CHR_AC_INTER 15
+#define SE_DELTA_QUANT_INTER 16
+#define SE_DELTA_QUANT_INTRA 17
+#define SE_BFRAME 18
+#define SE_EOS 19
+#define SE_MAX_ELEMENTS 20
+
+
+#define NO_EC 0 //!< no error concealment necessary
+#define EC_REQ 1 //!< error concealment required
+#define EC_SYNC 2 //!< search and sync on next header element
+
+#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
+ *
+ * We also defined the proposed internet partition mode
+ * of Stephan Wenger here. To select the desired mode
+ * uncomment one of the two following lines. \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.
+ */
+
+
+extern int assignSE2partition[][SE_MAX_ELEMENTS];
+extern int PartitionMode;
+
+#endif
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/erc_api.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/erc_api.c:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/erc_api.c Sun Feb 4 08:38:31 2007
@@ -0,0 +1,382 @@
+
+/*!
+ *************************************************************************************
+ * \file erc_api.c
+ *
+ * \brief
+ * External (still inside video decoder) interface for error concealment module
+ *
+ * \author
+ * - Ari Hourunranta <ari.hourunranta at nokia.com>
+ * - Viktor Varsa <viktor.varsa at nokia.com>
+ * - Ye-Kui Wang <wyk at ieee.org>
+ *
+ *************************************************************************************
+ */
+
+
+#include <stdlib.h>
+
+#include "global.h"
+#include "memalloc.h"
+#include "erc_api.h"
+
+objectBuffer_t *erc_object_list = NULL;
+ercVariables_t *erc_errorVar = NULL;
+frame erc_recfr;
+int erc_mvperMB;
+
+/*!
+ ************************************************************************
+ * \brief
+ * Initinize the error concealment module
+ ************************************************************************
+ */
+void ercInit(int pic_sizex, int pic_sizey, int flag)
+{
+ ercClose(erc_errorVar);
+ erc_object_list = (objectBuffer_t *) calloc((pic_sizex * pic_sizey) >> 6, sizeof(objectBuffer_t));
+ if (erc_object_list == NULL) no_mem_exit("ercInit: erc_object_list");
+
+ // the error concealment instance is allocated
+ erc_errorVar = ercOpen();
+
+ // set error concealment ON
+ ercSetErrorConcealment(erc_errorVar, flag);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocates data structures used in error concealment.
+ *\return
+ * The allocated ercVariables_t is returned.
+ ************************************************************************
+ */
+ercVariables_t *ercOpen( void )
+{
+ ercVariables_t *errorVar = NULL;
+
+ errorVar = (ercVariables_t *)malloc( sizeof(ercVariables_t));
+ if ( errorVar == NULL ) no_mem_exit("ercOpen: errorVar");
+
+ errorVar->nOfMBs = 0;
+ errorVar->segments = NULL;
+ errorVar->currSegment = 0;
+ errorVar->yCondition = NULL;
+ errorVar->uCondition = NULL;
+ errorVar->vCondition = NULL;
+ errorVar->prevFrameYCondition = NULL;
+
+ errorVar->concealment = 1;
+
+ return errorVar;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Resets the variables used in error detection.
+ * Should be called always when starting to decode a new frame.
+ * \param errorVar
+ * Variables for error concealment
+ * \param nOfMBs
+ * Number of macroblocks in a frame
+ * \param numOfSegments
+ * Estimated number of segments (memory reserved)
+ * \param picSizeX
+ * Width of the frame in pixels.
+ ************************************************************************
+ */
+void ercReset( ercVariables_t *errorVar, int nOfMBs, int numOfSegments, int picSizeX )
+{
+ int *tmp = NULL;
+ int i = 0;
+
+ if ( errorVar && errorVar->concealment )
+ {
+ // If frame size has been changed
+ if ( nOfMBs != errorVar->nOfMBs && errorVar->yCondition != NULL )
+ {
+ free( errorVar->yCondition );
+ errorVar->yCondition = NULL;
+ free( errorVar->prevFrameYCondition );
+ errorVar->prevFrameYCondition = NULL;
+ free( errorVar->uCondition );
+ errorVar->uCondition = NULL;
+ free( errorVar->vCondition );
+ errorVar->vCondition = NULL;
+ free( errorVar->segments );
+ errorVar->segments = NULL;
+ }
+
+ // If the structures are uninitialized (first frame, or frame size is changed)
+ if ( errorVar->yCondition == NULL )
+ {
+ errorVar->segments = (ercSegment_t *)malloc( numOfSegments*sizeof(ercSegment_t) );
+ if ( errorVar->segments == NULL ) no_mem_exit("ercReset: errorVar->segments");
+ memset( errorVar->segments, 0, numOfSegments*sizeof(ercSegment_t));
+ errorVar->nOfSegments = numOfSegments;
+
+ errorVar->yCondition = (int *)malloc( 4*nOfMBs*sizeof(int) );
+ if ( errorVar->yCondition == NULL ) no_mem_exit("ercReset: errorVar->yCondition");
+ errorVar->prevFrameYCondition = (int *)malloc( 4*nOfMBs*sizeof(int) );
+ if ( errorVar->prevFrameYCondition == NULL ) no_mem_exit("ercReset: errorVar->prevFrameYCondition");
+ errorVar->uCondition = (int *)malloc( nOfMBs*sizeof(int) );
+ if ( errorVar->uCondition == NULL ) no_mem_exit("ercReset: errorVar->uCondition");
+ errorVar->vCondition = (int *)malloc( nOfMBs*sizeof(int) );
+ if ( errorVar->vCondition == NULL ) no_mem_exit("ercReset: errorVar->vCondition");
+ errorVar->nOfMBs = nOfMBs;
+ }
+ else
+ {
+ // Store the yCondition struct of the previous frame
+ tmp = errorVar->prevFrameYCondition;
+ errorVar->prevFrameYCondition = errorVar->yCondition;
+ errorVar->yCondition = tmp;
+ }
+
+ // Reset tables and parameters
+ memset( errorVar->yCondition, 0, 4*nOfMBs*sizeof(*errorVar->yCondition));
+ memset( errorVar->uCondition, 0, nOfMBs*sizeof(*errorVar->uCondition));
+ memset( errorVar->vCondition, 0, nOfMBs*sizeof(*errorVar->vCondition));
+
+ if (errorVar->nOfSegments != numOfSegments)
+ {
+ free( errorVar->segments );
+ errorVar->segments = NULL;
+ errorVar->segments = (ercSegment_t *)malloc( numOfSegments*sizeof(ercSegment_t) );
+ if ( errorVar->segments == NULL ) no_mem_exit("ercReset: errorVar->segments");
+ errorVar->nOfSegments = numOfSegments;
+ }
+
+ memset( errorVar->segments, 0, errorVar->nOfSegments*sizeof(ercSegment_t));
+
+ for ( i = 0; i < errorVar->nOfSegments; i++ )
+ {
+ errorVar->segments[i].fCorrupted = 1; //! mark segments as corrupted
+ errorVar->segments[i].startMBPos = 0;
+ errorVar->segments[i].endMBPos = nOfMBs - 1;
+ }
+
+ errorVar->currSegment = 0;
+ errorVar->nOfCorruptedSegments = 0;
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Resets the variables used in error detection.
+ * Should be called always when starting to decode a new frame.
+ * \param errorVar
+ * Variables for error concealment
+ ************************************************************************
+ */
+void ercClose( ercVariables_t *errorVar )
+{
+ if ( errorVar != NULL )
+ {
+ if (errorVar->yCondition != NULL)
+ {
+ free( errorVar->segments );
+ free( errorVar->yCondition );
+ free( errorVar->uCondition );
+ free( errorVar->vCondition );
+ free( errorVar->prevFrameYCondition );
+ }
+ free( errorVar );
+ errorVar = NULL;
+ }
+
+ if (erc_object_list)
+ {
+ free(erc_object_list);
+ erc_object_list=NULL;
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Sets error concealment ON/OFF. Can be invoked only between frames, not during a frame
+ * \param errorVar
+ * Variables for error concealment
+ * \param value
+ * New value
+ ************************************************************************
+ */
+void ercSetErrorConcealment( ercVariables_t *errorVar, int value )
+{
+ if ( errorVar != NULL )
+ errorVar->concealment = value;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Creates a new segment in the segment-list, and marks the start MB and bit position.
+ * If the end of the previous segment was not explicitly marked by "ercStopSegment",
+ * also marks the end of the previous segment.
+ * If needed, it reallocates the segment-list for a larger storage place.
+ * \param currMBNum
+ * The MB number where the new slice/segment starts
+ * \param segment
+ * Segment/Slice No. counted by the caller
+ * \param bitPos
+ * Bitstream pointer: number of bits read from the buffer.
+ * \param errorVar
+ * Variables for error detector
+ ************************************************************************
+ */
+void ercStartSegment( int currMBNum, int segment, unsigned int bitPos, ercVariables_t *errorVar )
+{
+ if ( errorVar && errorVar->concealment )
+ {
+ errorVar->currSegmentCorrupted = 0;
+
+ errorVar->segments[ segment ].fCorrupted = 0;
+ errorVar->segments[ segment ].startMBPos = currMBNum;
+
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Marks the end position of a segment.
+ * \param currMBNum
+ * The last MB number of the previous segment
+ * \param segment
+ * Segment/Slice No. counted by the caller
+ * If (segment<0) the internal segment counter is used.
+ * \param bitPos
+ * Bitstream pointer: number of bits read from the buffer.
+ * \param errorVar
+ * Variables for error detector
+ ************************************************************************
+ */
+void ercStopSegment( int currMBNum, int segment, unsigned int bitPos, ercVariables_t *errorVar )
+{
+ if ( errorVar && errorVar->concealment )
+ {
+ errorVar->segments[ segment ].endMBPos = currMBNum; //! Changed TO 12.11.2001
+ errorVar->currSegment++;
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Marks the current segment (the one which has the "currMBNum" MB in it)
+ * as lost: all the blocks of the MBs in the segment as corrupted.
+ * \param picSizeX
+ * Width of the frame in pixels.
+ * \param errorVar
+ * Variables for error detector
+ ************************************************************************
+ */
+void ercMarkCurrSegmentLost(int picSizeX, ercVariables_t *errorVar )
+{
+ int j = 0;
+ int current_segment;
+
+ current_segment = errorVar->currSegment-1;
+ if ( errorVar && errorVar->concealment )
+ {
+ if (errorVar->currSegmentCorrupted == 0)
+ {
+ errorVar->nOfCorruptedSegments++;
+ errorVar->currSegmentCorrupted = 1;
+ }
+
+ for ( j = errorVar->segments[current_segment].startMBPos; j <= errorVar->segments[current_segment].endMBPos; j++ )
+ {
+ errorVar->yCondition[MBNum2YBlock (j, 0, picSizeX)] = ERC_BLOCK_CORRUPTED;
+ errorVar->yCondition[MBNum2YBlock (j, 1, picSizeX)] = ERC_BLOCK_CORRUPTED;
+ errorVar->yCondition[MBNum2YBlock (j, 2, picSizeX)] = ERC_BLOCK_CORRUPTED;
+ errorVar->yCondition[MBNum2YBlock (j, 3, picSizeX)] = ERC_BLOCK_CORRUPTED;
+ errorVar->uCondition[j] = ERC_BLOCK_CORRUPTED;
+ errorVar->vCondition[j] = ERC_BLOCK_CORRUPTED;
+ }
+ errorVar->segments[current_segment].fCorrupted = 1;
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Marks the current segment (the one which has the "currMBNum" MB in it)
+ * as OK: all the blocks of the MBs in the segment as OK.
+ * \param picSizeX
+ * Width of the frame in pixels.
+ * \param errorVar
+ * Variables for error detector
+ ************************************************************************
+ */
+void ercMarkCurrSegmentOK(int picSizeX, ercVariables_t *errorVar )
+{
+ int j = 0;
+ int current_segment;
+
+ current_segment = errorVar->currSegment-1;
+ if ( errorVar && errorVar->concealment )
+ {
+ // mark all the Blocks belonging to the segment as OK */
+ for ( j = errorVar->segments[current_segment].startMBPos; j <= errorVar->segments[current_segment].endMBPos; j++ )
+ {
+ errorVar->yCondition[MBNum2YBlock (j, 0, picSizeX)] = ERC_BLOCK_OK;
+ errorVar->yCondition[MBNum2YBlock (j, 1, picSizeX)] = ERC_BLOCK_OK;
+ errorVar->yCondition[MBNum2YBlock (j, 2, picSizeX)] = ERC_BLOCK_OK;
+ errorVar->yCondition[MBNum2YBlock (j, 3, picSizeX)] = ERC_BLOCK_OK;
+ errorVar->uCondition[j] = ERC_BLOCK_OK;
+ errorVar->vCondition[j] = ERC_BLOCK_OK;
+ }
+ errorVar->segments[current_segment].fCorrupted = 0;
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Marks the Blocks of the given component (YUV) of the current MB as concealed.
+ * \param currMBNum
+ * Selects the segment where this MB number is in.
+ * \param comp
+ * Component to mark (0:Y, 1:U, 2:V, <0:All)
+ * \param picSizeX
+ * Width of the frame in pixels.
+ * \param errorVar
+ * Variables for error detector
+ ************************************************************************
+ */
+void ercMarkCurrMBConcealed( int currMBNum, int comp, int picSizeX, ercVariables_t *errorVar )
+{
+ int setAll = 0;
+
+ if ( errorVar && errorVar->concealment )
+ {
+ if (comp < 0)
+ {
+ setAll = 1;
+ comp = 0;
+ }
+
+ switch (comp)
+ {
+ case 0:
+ errorVar->yCondition[MBNum2YBlock (currMBNum, 0, picSizeX)] = ERC_BLOCK_CONCEALED;
+ errorVar->yCondition[MBNum2YBlock (currMBNum, 1, picSizeX)] = ERC_BLOCK_CONCEALED;
+ errorVar->yCondition[MBNum2YBlock (currMBNum, 2, picSizeX)] = ERC_BLOCK_CONCEALED;
+ errorVar->yCondition[MBNum2YBlock (currMBNum, 3, picSizeX)] = ERC_BLOCK_CONCEALED;
+ if (!setAll)
+ break;
+ case 1:
+ errorVar->uCondition[currMBNum] = ERC_BLOCK_CONCEALED;
+ if (!setAll)
+ break;
+ case 2:
+ errorVar->vCondition[currMBNum] = ERC_BLOCK_CONCEALED;
+ }
+ }
+}
Index: llvm-test/MultiSource/Applications/JM/ldecod/erc_api.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/erc_api.h:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/erc_api.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,166 @@
+
+/*!
+ ************************************************************************
+ * \file erc_api.h
+ *
+ * \brief
+ * External (still inside video decoder) interface for error concealment module
+ *
+ * \author
+ * - Ari Hourunranta <ari.hourunranta at nokia.com>
+ * - Ye-Kui Wang <wyk at ieee.org>
+ * - Jill Boyce <jill.boyce at thomson.net>
+ * - Saurav K Bandyopadhyay <saurav at ieee.org>
+ * - Zhenyu Wu <Zhenyu.Wu at thomson.net
+ * - Purvin Pandit <Purvin.Pandit at thomson.net>
+ *
+ * ************************************************************************
+ */
+
+
+#ifndef _ERC_API_H_
+#define _ERC_API_H_
+
+#include "erc_globals.h"
+
+/*
+* Defines
+*/
+
+/* If the average motion vector of the correctly received macroblocks is less than the
+threshold, concealByCopy is used, otherwise concealByTrial is used. */
+#define MVPERMB_THR 8
+
+/* used to determine the size of the allocated memory for a temporal Region (MB) */
+#define DEF_REGION_SIZE 384 /* 8*8*6 */
+
+#define ERC_BLOCK_OK 3
+#define ERC_BLOCK_CONCEALED 2
+#define ERC_BLOCK_CORRUPTED 1
+#define ERC_BLOCK_EMPTY 0
+
+#define mabs(a) ( (a) < 0 ? -(a) : (a) )
+#define mmax(a,b) ((a) > (b) ? (a) : (b))
+#define mmin(a,b) ((a) < (b) ? (a) : (b))
+
+/*
+* Functions to convert MBNum representation to blockNum
+*/
+
+#define xPosYBlock(currYBlockNum,picSizeX) \
+((currYBlockNum)%((picSizeX)>>3))
+
+#define yPosYBlock(currYBlockNum,picSizeX) \
+((currYBlockNum)/((picSizeX)>>3))
+
+#define xPosMB(currMBNum,picSizeX) \
+((currMBNum)%((picSizeX)>>4))
+
+#define yPosMB(currMBNum,picSizeX) \
+((currMBNum)/((picSizeX)>>4))
+
+#define MBxy2YBlock(currXPos,currYPos,comp,picSizeX) \
+((((currYPos)<<1)+((comp)>>1))*((picSizeX)>>3)+((currXPos)<<1)+((comp)&1))
+
+#define MBNum2YBlock(currMBNum,comp,picSizeX) \
+MBxy2YBlock(xPosMB((currMBNum),(picSizeX)),yPosMB((currMBNum),(picSizeX)),(comp),(picSizeX))
+
+
+/*
+* typedefs
+*/
+
+/* segment data structure */
+typedef struct ercSegment_s
+{
+ int startMBPos;
+ int endMBPos;
+ int fCorrupted;
+} ercSegment_t;
+
+/* Error detector & concealment instance data structure */
+typedef struct ercVariables_s
+{
+ /* Number of macroblocks (size or size/4 of the arrays) */
+ int nOfMBs;
+ /* Number of segments (slices) in frame */
+ int nOfSegments;
+
+ /* Array for conditions of Y blocks */
+ int *yCondition;
+ /* Array for conditions of U blocks */
+ int *uCondition;
+ /* Array for conditions of V blocks */
+ int *vCondition;
+
+ /* Array for Slice level information */
+ ercSegment_t *segments;
+ int currSegment;
+
+ /* Conditions of the MBs of the previous frame */
+ int *prevFrameYCondition;
+
+ /* Flag telling if the current segment was found to be corrupted */
+ int currSegmentCorrupted;
+ /* Counter for corrupted segments per picture */
+ int nOfCorruptedSegments;
+
+ /* State variables for error detector and concealer */
+ int concealment;
+
+} ercVariables_t;
+
+/*
+* External function interface
+*/
+
+void ercInit(int pic_sizex, int pic_sizey, int flag);
+ercVariables_t *ercOpen( void );
+void ercReset( ercVariables_t *errorVar, int nOfMBs, int numOfSegments, int picSizeX );
+void ercClose( ercVariables_t *errorVar );
+void ercSetErrorConcealment( ercVariables_t *errorVar, int value );
+
+void ercStartSegment( int currMBNum, int segment, unsigned int bitPos, ercVariables_t *errorVar );
+void ercStopSegment( int currMBNum, int segment, unsigned int bitPos, ercVariables_t *errorVar );
+void ercMarkCurrSegmentLost(int picSizeX, ercVariables_t *errorVar );
+void ercMarkCurrSegmentOK(int picSizeX, ercVariables_t *errorVar );
+void ercMarkCurrMBConcealed( int currMBNum, int comp, int picSizeX, ercVariables_t *errorVar );
+
+int ercConcealIntraFrame( frame *recfr, int picSizeX, int picSizeY, ercVariables_t *errorVar );
+int ercConcealInterFrame( frame *recfr, objectBuffer_t *object_list,
+ int picSizeX, int picSizeY, ercVariables_t *errorVar, int chroma_format_idc );
+
+
+/* Thomson APIs for concealing entire frame loss */
+
+#include "mbuffer.h"
+#include "output.h"
+
+struct concealment_node {
+ StorablePicture* picture;
+ int missingpocs;
+ struct concealment_node *next;
+};
+
+struct concealment_node * init_node(StorablePicture* , int );
+void print_node( struct concealment_node * );
+void print_list( struct concealment_node * );
+void add_node( struct concealment_node * );
+void delete_node( struct concealment_node * );
+void init_lists_for_non_reference_loss(int , PictureStructure );
+
+void conceal_non_ref_pics(int diff);
+void conceal_lost_frames(ImageParameters *img);
+
+void sliding_window_poc_management(StorablePicture *p);
+
+void write_lost_non_ref_pic(int poc, int p_out);
+void write_lost_ref_after_idr(int pos);
+
+FrameStore *last_out_fs;
+int pocs_in_dpb[100];
+int comp(const void *, const void *);
+
+
+#endif
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/erc_do.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/erc_do.h:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/erc_do.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,44 @@
+
+/*!
+ ************************************************************************
+ * \file erc_do.h
+ *
+ * \brief
+ * Header for the I & P frame error concealment common functions
+ *
+ * \author
+ * - Viktor Varsa <viktor.varsa at nokia.com>
+ * - Ye-Kui Wang <wyk at ieee.org>
+ *
+ ************************************************************************
+ */
+
+#ifndef _ERC_DO_H_
+#define _ERC_DO_H_
+
+
+#include "erc_api.h"
+
+void ercPixConcealIMB(imgpel *currFrame, int row, int column, int predBlocks[], int frameWidth, int mbWidthInBlocks);
+
+int ercCollect8PredBlocks( int predBlocks[], int currRow, int currColumn, int *condition,
+ int maxRow, int maxColumn, int step, byte fNoCornerNeigh );
+int ercCollectColumnBlocks( int predBlocks[], int currRow, int currColumn, int *condition, int maxRow, int maxColumn, int step );
+
+#define isSplitted(object_list,currMBNum) \
+ ((object_list+((currMBNum)<<2))->regionMode >= REGMODE_SPLITTED)
+
+/* this can be used as isBlock(...,INTRA) or isBlock(...,INTER_COPY) */
+#define isBlock(object_list,currMBNum,comp,regMode) \
+ (isSplitted(object_list,currMBNum) ? \
+ ((object_list+((currMBNum)<<2)+(comp))->regionMode == REGMODE_##regMode##_8x8) : \
+ ((object_list+((currMBNum)<<2))->regionMode == REGMODE_##regMode))
+
+/* this can be used as getParam(...,mv) or getParam(...,xMin) or getParam(...,yMin) */
+#define getParam(object_list,currMBNum,comp,param) \
+ (isSplitted(object_list,currMBNum) ? \
+ ((object_list+((currMBNum)<<2)+(comp))->param) : \
+ ((object_list+((currMBNum)<<2))->param))
+
+#endif
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/erc_do_i.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/erc_do_i.c:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/erc_do_i.c Sun Feb 4 08:38:31 2007
@@ -0,0 +1,537 @@
+
+/*!
+ *************************************************************************************
+ * \file
+ * erc_do_i.c
+ *
+ * \brief
+ * Intra (I) frame error concealment algorithms for decoder
+ *
+ * \author
+ * - Ari Hourunranta <ari.hourunranta at nokia.com>
+ * - Viktor Varsa <viktor.varsa at nokia.com>
+ * - Ye-Kui Wang <wyk at ieee.org>
+ *
+ *************************************************************************************
+ */
+
+#include <stdlib.h>
+#include "global.h"
+#include "erc_do.h"
+
+static void concealBlocks( int lastColumn, int lastRow, int comp, frame *recfr, int picSizeX, int *condition );
+static void pixMeanInterpolateBlock( imgpel *src[], imgpel *block, int blockSize, int frameWidth );
+
+/*!
+ ************************************************************************
+ * \brief
+ * The main function for Intra frame concealment.
+ * Calls "concealBlocks" for each color component (Y,U,V) separately
+ * \return
+ * 0, if the concealment was not successful and simple concealment should be used
+ * 1, otherwise (even if none of the blocks were concealed)
+ * \param recfr
+ * Reconstructed frame buffer
+ * \param picSizeX
+ * Width of the frame in pixels
+ * \param picSizeY
+ * Height of the frame in pixels
+ * \param errorVar
+ * Variables for error concealment
+ ************************************************************************
+ */
+int ercConcealIntraFrame( frame *recfr, int picSizeX, int picSizeY, ercVariables_t *errorVar )
+{
+ int lastColumn = 0, lastRow = 0;
+
+ // if concealment is on
+ if ( errorVar && errorVar->concealment )
+ {
+ // if there are segments to be concealed
+ if ( errorVar->nOfCorruptedSegments )
+ {
+ // Y
+ lastRow = (int) (picSizeY>>3);
+ lastColumn = (int) (picSizeX>>3);
+ concealBlocks( lastColumn, lastRow, 0, recfr, picSizeX, errorVar->yCondition );
+
+ // U (dimensions halved compared to Y)
+ lastRow = (int) (picSizeY>>4);
+ lastColumn = (int) (picSizeX>>4);
+ concealBlocks( lastColumn, lastRow, 1, recfr, picSizeX, errorVar->uCondition );
+
+ // V ( dimensions equal to U )
+ concealBlocks( lastColumn, lastRow, 2, recfr, picSizeX, errorVar->vCondition );
+ }
+ return 1;
+ }
+ else
+ return 0;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Conceals the MB at position (row, column) using pixels from predBlocks[]
+ * using pixMeanInterpolateBlock()
+ * \param currFrame
+ * current frame
+ * \param row
+ * y coordinate in blocks
+ * \param column
+ * x coordinate in blocks
+ * \param predBlocks[]
+ * list of neighboring source blocks (numbering 0 to 7, 1 means: use the neighbor)
+ * \param frameWidth
+ * width of frame in pixels
+ * \param mbWidthInBlocks
+ * 2 for Y, 1 for U/V components
+ ************************************************************************
+ */
+void ercPixConcealIMB(imgpel *currFrame, int row, int column, int predBlocks[], int frameWidth, int mbWidthInBlocks)
+{
+ imgpel *src[8]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
+ imgpel *currBlock = NULL;
+
+ // collect the reliable neighboring blocks
+ if (predBlocks[0])
+ src[0] = currFrame + (row-mbWidthInBlocks)*frameWidth*8 + (column+mbWidthInBlocks)*8;
+ if (predBlocks[1])
+ src[1] = currFrame + (row-mbWidthInBlocks)*frameWidth*8 + (column-mbWidthInBlocks)*8;
+ if (predBlocks[2])
+ src[2] = currFrame + (row+mbWidthInBlocks)*frameWidth*8 + (column-mbWidthInBlocks)*8;
+ if (predBlocks[3])
+ src[3] = currFrame + (row+mbWidthInBlocks)*frameWidth*8 + (column+mbWidthInBlocks)*8;
+ if (predBlocks[4])
+ src[4] = currFrame + (row-mbWidthInBlocks)*frameWidth*8 + column*8;
+ if (predBlocks[5])
+ src[5] = currFrame + row*frameWidth*8 + (column-mbWidthInBlocks)*8;
+ if (predBlocks[6])
+ src[6] = currFrame + (row+mbWidthInBlocks)*frameWidth*8 + column*8;
+ if (predBlocks[7])
+ src[7] = currFrame + row*frameWidth*8 + (column+mbWidthInBlocks)*8;
+
+ currBlock = currFrame + row*frameWidth*8 + column*8;
+ pixMeanInterpolateBlock( src, currBlock, mbWidthInBlocks*8, frameWidth );
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * This function checks the neighbors of a Macroblock for usability in
+ * concealment. First the OK macroblocks are marked, and if there is not
+ * enough of them, then the CONCEALED ones as well.
+ * A "1" in the the output array means reliable, a "0" non reliable MB.
+ * The block order in "predBlocks":
+ * 1 4 0
+ * 5 x 7
+ * 2 6 3
+ * i.e., corners first.
+ * \return
+ * Number of useable neighbor macroblocks for concealment.
+ * \param predBlocks[]
+ * Array for indicating the valid neighbor blocks
+ * \param currRow
+ * Current block row in the frame
+ * \param currColumn
+ * Current block column in the frame
+ * \param condition
+ * The block condition (ok, lost) table
+ * \param maxRow
+ * Number of block rows in the frame
+ * \param maxColumn
+ * Number of block columns in the frame
+ * \param step
+ * Number of blocks belonging to a MB, when counting
+ * in vertical/horizontal direction. (Y:2 U,V:1)
+ * \param fNoCornerNeigh
+ * No corner neighbors are considered
+ ************************************************************************
+ */
+int ercCollect8PredBlocks( int predBlocks[], int currRow, int currColumn, int *condition,
+ int maxRow, int maxColumn, int step, byte fNoCornerNeigh )
+{
+ int srcCounter = 0;
+ int srcCountMin = (fNoCornerNeigh ? 2 : 4);
+ int threshold = ERC_BLOCK_OK;
+
+ memset( predBlocks, 0, 8*sizeof(int) );
+
+ // collect the reliable neighboring blocks
+ do
+ {
+ srcCounter = 0;
+ // top
+ if (currRow > 0 && condition[ (currRow-1)*maxColumn + currColumn ] >= threshold )
+ { //ERC_BLOCK_OK (3) or ERC_BLOCK_CONCEALED (2)
+ predBlocks[4] = condition[ (currRow-1)*maxColumn + currColumn ];
+ srcCounter++;
+ }
+ // bottom
+ if ( currRow < (maxRow-step) && condition[ (currRow+step)*maxColumn + currColumn ] >= threshold )
+ {
+ predBlocks[6] = condition[ (currRow+step)*maxColumn + currColumn ];
+ srcCounter++;
+ }
+
+ if ( currColumn > 0 )
+ {
+ // left
+ if ( condition[ currRow*maxColumn + currColumn - 1 ] >= threshold )
+ {
+ predBlocks[5] = condition[ currRow*maxColumn + currColumn - 1 ];
+ srcCounter++;
+ }
+
+ if ( !fNoCornerNeigh )
+ {
+ // top-left
+ if ( currRow > 0 && condition[ (currRow-1)*maxColumn + currColumn - 1 ] >= threshold )
+ {
+ predBlocks[1] = condition[ (currRow-1)*maxColumn + currColumn - 1 ];
+ srcCounter++;
+ }
+ // bottom-left
+ if ( currRow < (maxRow-step) && condition[ (currRow+step)*maxColumn + currColumn - 1 ] >= threshold )
+ {
+ predBlocks[2] = condition[ (currRow+step)*maxColumn + currColumn - 1 ];
+ srcCounter++;
+ }
+ }
+ }
+
+ if ( currColumn < (maxColumn-step) )
+ {
+ // right
+ if ( condition[ currRow*maxColumn+currColumn + step ] >= threshold )
+ {
+ predBlocks[7] = condition[ currRow*maxColumn+currColumn + step ];
+ srcCounter++;
+ }
+
+ if ( !fNoCornerNeigh )
+ {
+ // top-right
+ if ( currRow > 0 && condition[ (currRow-1)*maxColumn + currColumn + step ] >= threshold )
+ {
+ predBlocks[0] = condition[ (currRow-1)*maxColumn + currColumn + step ];
+ srcCounter++;
+ }
+ // bottom-right
+ if ( currRow < (maxRow-step) && condition[ (currRow+step)*maxColumn + currColumn + step ] >= threshold )
+ {
+ predBlocks[3] = condition[ (currRow+step)*maxColumn + currColumn + step ];
+ srcCounter++;
+ }
+ }
+ }
+ // prepare for the next round
+ threshold--;
+ if (threshold < ERC_BLOCK_CONCEALED)
+ break;
+ } while ( srcCounter < srcCountMin);
+
+ return srcCounter;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * collects prediction blocks only from the current column
+ * \return
+ * Number of usable neighbour Macroblocks for concealment.
+ * \param predBlocks[]
+ * Array for indicating the valid neighbor blocks
+ * \param currRow
+ * Current block row in the frame
+ * \param currColumn
+ * Current block column in the frame
+ * \param condition
+ * The block condition (ok, lost) table
+ * \param maxRow
+ * Number of block rows in the frame
+ * \param maxColumn
+ * Number of block columns in the frame
+ * \param step
+ * Number of blocks belonging to a MB, when counting
+ * in vertical/horizontal direction. (Y:2 U,V:1)
+ ************************************************************************
+ */
+int ercCollectColumnBlocks( int predBlocks[], int currRow, int currColumn, int *condition, int maxRow, int maxColumn, int step )
+{
+ int srcCounter = 0, threshold = ERC_BLOCK_CORRUPTED;
+
+ memset( predBlocks, 0, 8*sizeof(int) );
+
+ // in this case, row > 0 and row < 17
+ if ( condition[ (currRow-1)*maxColumn + currColumn ] > threshold )
+ {
+ predBlocks[4] = 1;
+ srcCounter++;
+ }
+ if ( condition[ (currRow+step)*maxColumn + currColumn ] > threshold )
+ {
+ predBlocks[6] = 1;
+ srcCounter++;
+ }
+
+ return srcCounter;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Core for the Intra blocks concealment.
+ * It is called for each color component (Y,U,V) separately
+ * Finds the corrupted blocks and calls pixel interpolation functions
+ * to correct them, one block at a time.
+ * Scanning is done vertically and each corrupted column is corrected
+ * bi-directionally, i.e., first block, last block, first block+1, last block -1 ...
+ * \param lastColumn
+ * Number of block columns in the frame
+ * \param lastRow
+ * Number of block rows in the frame
+ * \param comp
+ * color component
+ * \param recfr
+ * Reconstructed frame buffer
+ * \param picSizeX
+ * Width of the frame in pixels
+ * \param condition
+ * The block condition (ok, lost) table
+ ************************************************************************
+ */
+static void concealBlocks( int lastColumn, int lastRow, int comp, frame *recfr, int picSizeX, int *condition )
+{
+ int row, column, srcCounter = 0, thr = ERC_BLOCK_CORRUPTED,
+ lastCorruptedRow = -1, firstCorruptedRow = -1, currRow = 0,
+ areaHeight = 0, i = 0, smoothColumn = 0;
+ int predBlocks[8], step = 1;
+
+ // in the Y component do the concealment MB-wise (not block-wise):
+ // this is useful if only whole MBs can be damaged or lost
+ if ( comp == 0 )
+ step = 2;
+ else
+ step = 1;
+
+ for ( column = 0; column < lastColumn; column += step )
+ {
+ for ( row = 0; row < lastRow; row += step )
+ {
+ if ( condition[row*lastColumn+column] <= thr )
+ {
+ firstCorruptedRow = row;
+ // find the last row which has corrupted blocks (in same continuous area)
+ for ( lastCorruptedRow = row+step; lastCorruptedRow < lastRow; lastCorruptedRow += step )
+ {
+ // check blocks in the current column
+ if ( condition[ lastCorruptedRow*lastColumn + column ] > thr )
+ {
+ // current one is already OK, so the last was the previous one
+ lastCorruptedRow -= step;
+ break;
+ }
+ }
+ if ( lastCorruptedRow >= lastRow )
+ {
+ // correct only from above
+ lastCorruptedRow = lastRow-step;
+ for ( currRow = firstCorruptedRow; currRow < lastRow; currRow += step )
+ {
+ srcCounter = ercCollect8PredBlocks( predBlocks, currRow, column, condition, lastRow, lastColumn, step, 1 );
+
+ switch( comp )
+ {
+ case 0 :
+ ercPixConcealIMB( recfr->yptr, currRow, column, predBlocks, picSizeX, 2 );
+ break;
+ case 1 :
+ ercPixConcealIMB( recfr->uptr, currRow, column, predBlocks, (picSizeX>>1), 1 );
+ break;
+ case 2 :
+ ercPixConcealIMB( recfr->vptr, currRow, column, predBlocks, (picSizeX>>1), 1 );
+ break;
+ }
+
+ if ( comp == 0 )
+ {
+ condition[ currRow*lastColumn+column] = ERC_BLOCK_CONCEALED;
+ condition[ currRow*lastColumn+column + 1] = ERC_BLOCK_CONCEALED;
+ condition[ currRow*lastColumn+column + lastColumn] = ERC_BLOCK_CONCEALED;
+ condition[ currRow*lastColumn+column + lastColumn + 1] = ERC_BLOCK_CONCEALED;
+ }
+ else
+ {
+ condition[ currRow*lastColumn+column] = ERC_BLOCK_CONCEALED;
+ }
+
+ }
+ row = lastRow;
+ }
+ else if ( firstCorruptedRow == 0 )
+ {
+ // correct only from below
+ for ( currRow = lastCorruptedRow; currRow >= 0; currRow -= step )
+ {
+ srcCounter = ercCollect8PredBlocks( predBlocks, currRow, column, condition, lastRow, lastColumn, step, 1 );
+
+ switch( comp )
+ {
+ case 0 :
+ ercPixConcealIMB( recfr->yptr, currRow, column, predBlocks, picSizeX, 2 );
+ break;
+ case 1 :
+ ercPixConcealIMB( recfr->uptr, currRow, column, predBlocks, (picSizeX>>1), 1 );
+ break;
+ case 2 :
+ ercPixConcealIMB( recfr->vptr, currRow, column, predBlocks, (picSizeX>>1), 1 );
+ break;
+ }
+
+ if ( comp == 0 )
+ {
+ condition[ currRow*lastColumn+column] = ERC_BLOCK_CONCEALED;
+ condition[ currRow*lastColumn+column + 1] = ERC_BLOCK_CONCEALED;
+ condition[ currRow*lastColumn+column + lastColumn] = ERC_BLOCK_CONCEALED;
+ condition[ currRow*lastColumn+column + lastColumn + 1] = ERC_BLOCK_CONCEALED;
+ }
+ else
+ {
+ condition[ currRow*lastColumn+column] = ERC_BLOCK_CONCEALED;
+ }
+
+ }
+
+ row = lastCorruptedRow+step;
+ }
+ else
+ {
+ // correct bi-directionally
+
+ row = lastCorruptedRow+step;
+ areaHeight = lastCorruptedRow-firstCorruptedRow+step;
+
+ // Conceal the corrupted area switching between the up and the bottom rows
+ for ( i = 0; i < areaHeight; i += step )
+ {
+ if ( i % 2 )
+ {
+ currRow = lastCorruptedRow;
+ lastCorruptedRow -= step;
+ }
+ else
+ {
+ currRow = firstCorruptedRow;
+ firstCorruptedRow += step;
+ }
+
+ if (smoothColumn > 0)
+ {
+ srcCounter = ercCollectColumnBlocks( predBlocks, currRow, column, condition, lastRow, lastColumn, step );
+ }
+ else
+ {
+ srcCounter = ercCollect8PredBlocks( predBlocks, currRow, column, condition, lastRow, lastColumn, step, 1 );
+ }
+
+ switch( comp )
+ {
+ case 0 :
+ ercPixConcealIMB( recfr->yptr, currRow, column, predBlocks, picSizeX, 2 );
+ break;
+
+ case 1 :
+ ercPixConcealIMB( recfr->uptr, currRow, column, predBlocks, (picSizeX>>1), 1 );
+ break;
+
+ case 2 :
+ ercPixConcealIMB( recfr->vptr, currRow, column, predBlocks, (picSizeX>>1), 1 );
+ break;
+ }
+
+ if ( comp == 0 )
+ {
+ condition[ currRow*lastColumn+column] = ERC_BLOCK_CONCEALED;
+ condition[ currRow*lastColumn+column + 1] = ERC_BLOCK_CONCEALED;
+ condition[ currRow*lastColumn+column + lastColumn] = ERC_BLOCK_CONCEALED;
+ condition[ currRow*lastColumn+column + lastColumn + 1] = ERC_BLOCK_CONCEALED;
+ }
+ else
+ {
+ condition[ currRow*lastColumn+column ] = ERC_BLOCK_CONCEALED;
+ }
+ }
+ }
+
+ lastCorruptedRow = -1;
+ firstCorruptedRow = -1;
+
+ }
+ }
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Does the actual pixel based interpolation for block[]
+ * using weighted average
+ * \param src[]
+ * pointers to neighboring source blocks
+ * \param block
+ * destination block
+ * \param blockSize
+ * 16 for Y, 8 for U/V components
+ * \param frameWidth
+ * Width of the frame in pixels
+ ************************************************************************
+ */
+static void pixMeanInterpolateBlock( imgpel *src[], imgpel *block, int blockSize, int frameWidth )
+{
+ int row, column, k, tmp, srcCounter = 0, weight = 0, bmax = blockSize - 1;
+
+ k = 0;
+ for ( row = 0; row < blockSize; row++ )
+ {
+ for ( column = 0; column < blockSize; column++ )
+ {
+ tmp = 0;
+ srcCounter = 0;
+ // above
+ if ( src[4] != NULL )
+ {
+ weight = blockSize-row;
+ tmp += weight * (*(src[4]+bmax*frameWidth+column));
+ srcCounter += weight;
+ }
+ // left
+ if ( src[5] != NULL )
+ {
+ weight = blockSize-column;
+ tmp += weight * (*(src[5]+row*frameWidth+bmax));
+ srcCounter += weight;
+ }
+ // below
+ if ( src[6] != NULL )
+ {
+ weight = row+1;
+ tmp += weight * (*(src[6]+column));
+ srcCounter += weight;
+ }
+ // right
+ if ( src[7] != NULL )
+ {
+ weight = column+1;
+ tmp += weight * (*(src[7]+row*frameWidth));
+ srcCounter += weight;
+ }
+
+ if ( srcCounter > 0 )
+ block[ k + column ] = (byte)(tmp/srcCounter);
+ else
+ block[ k + column ] = blockSize == 8 ? img->dc_pred_value_chroma : img->dc_pred_value_luma;
+ }
+ k += frameWidth;
+ }
+}
Index: llvm-test/MultiSource/Applications/JM/ldecod/erc_do_p.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/erc_do_p.c:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/erc_do_p.c Sun Feb 4 08:38:31 2007
@@ -0,0 +1,1826 @@
+
+/*!
+ *************************************************************************************
+ * \file
+ * erc_do_p.c
+ *
+ * \brief
+ * Inter (P) frame error concealment algorithms for decoder
+ *
+ * \author
+ * - Viktor Varsa <viktor.varsa at nokia.com>
+ * - Ye-Kui Wang <wyk at ieee.org>
+ * - Jill Boyce <jill.boyce at thomson.net>
+ * - Saurav K Bandyopadhyay <saurav at ieee.org>
+ * - Zhenyu Wu <Zhenyu.Wu at thomson.net
+ * - Purvin Pandit <Purvin.Pandit at thomson.net>
+ *
+ *************************************************************************************
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include "mbuffer.h"
+#include "global.h"
+#include "memalloc.h"
+#include "erc_do.h"
+#include "image.h"
+
+extern int erc_mvperMB;
+struct img_par *erc_img;
+
+// picture error concealment
+// concealment_head points to first node in list, concealment_end points to
+// last node in list. Initialize both to NULL, meaning no nodes in list yet
+struct concealment_node *concealment_head = NULL;
+struct concealment_node *concealment_end = NULL;
+
+// static function declarations
+static int concealByCopy(frame *recfr, int currMBNum, objectBuffer_t *object_list, int picSizeX);
+static int concealByTrial(frame *recfr, imgpel *predMB,
+ int currMBNum, objectBuffer_t *object_list, int predBlocks[],
+ int picSizeX, int picSizeY, int *yCondition);
+static int edgeDistortion (int predBlocks[], int currYBlockNum, imgpel *predMB,
+ imgpel *recY, int picSizeX, int regionSize);
+static void copyBetweenFrames (frame *recfr, int currYBlockNum, int picSizeX, int regionSize);
+static void buildPredRegionYUV(struct img_par *img, int *mv, int x, int y, imgpel *predMB);
+
+// picture error concealment
+static void buildPredblockRegionYUV(struct img_par *img, int *mv,
+ int x, int y, imgpel *predMB, int list);
+static void CopyImgData(imgpel **inputY, imgpel ***inputUV, imgpel **outputY,
+ imgpel ***outputUV, int img_width, int img_height);
+
+
+static void copyPredMB (int currYBlockNum, imgpel *predMB, frame *recfr,
+ int picSizeX, int regionSize);
+
+extern const unsigned char subblk_offset_y[3][8][4];
+extern const unsigned char subblk_offset_x[3][8][4];
+static int uv_div[2][4] = {{0, 1, 1, 0}, {0, 1, 0, 0}}; //[x/y][yuv_format]
+
+/*!
+ ************************************************************************
+ * \brief
+ * The main function for Inter (P) frame concealment.
+ * \return
+ * 0, if the concealment was not successful and simple concealment should be used
+ * 1, otherwise (even if none of the blocks were concealed)
+ * \param recfr
+ * Reconstructed frame buffer
+ * \param object_list
+ * Motion info for all MBs in the frame
+ * \param picSizeX
+ * Width of the frame in pixels
+ * \param picSizeY
+ * Height of the frame in pixels
+ * \param errorVar
+ * Variables for error concealment
+ * \param chroma_format_idc
+ * Chroma format IDC
+ ************************************************************************
+ */
+int ercConcealInterFrame(frame *recfr, objectBuffer_t *object_list,
+ int picSizeX, int picSizeY, ercVariables_t *errorVar, int chroma_format_idc )
+{
+ int lastColumn = 0, lastRow = 0, predBlocks[8];
+ int lastCorruptedRow = -1, firstCorruptedRow = -1, currRow = 0,
+ row, column, columnInd, areaHeight = 0, i = 0;
+ imgpel *predMB;
+
+ /* if concealment is on */
+ if ( errorVar && errorVar->concealment )
+ {
+ /* if there are segments to be concealed */
+ if ( errorVar->nOfCorruptedSegments )
+ {
+ if (chroma_format_idc != YUV400)
+ predMB = (imgpel *) malloc ( (256 + (img->mb_cr_size_x*img->mb_cr_size_y)*2) * sizeof (imgpel));
+ else
+ predMB = (imgpel *) malloc(256 * sizeof (imgpel));
+
+ if ( predMB == NULL ) no_mem_exit("ercConcealInterFrame: predMB");
+
+ lastRow = (int) (picSizeY>>4);
+ lastColumn = (int) (picSizeX>>4);
+
+ for ( columnInd = 0; columnInd < lastColumn; columnInd ++)
+ {
+
+ column = ((columnInd%2) ? (lastColumn - columnInd/2 -1) : (columnInd/2));
+
+ for ( row = 0; row < lastRow; row++)
+ {
+
+ if ( errorVar->yCondition[MBxy2YBlock(column, row, 0, picSizeX)] <= ERC_BLOCK_CORRUPTED )
+ { // ERC_BLOCK_CORRUPTED (1) or ERC_BLOCK_EMPTY (0)
+ firstCorruptedRow = row;
+ /* find the last row which has corrupted blocks (in same continuous area) */
+ for ( lastCorruptedRow = row+1; lastCorruptedRow < lastRow; lastCorruptedRow++)
+ {
+ /* check blocks in the current column */
+ if (errorVar->yCondition[MBxy2YBlock(column, lastCorruptedRow, 0, picSizeX)] > ERC_BLOCK_CORRUPTED)
+ {
+ /* current one is already OK, so the last was the previous one */
+ lastCorruptedRow --;
+ break;
+ }
+ }
+ if ( lastCorruptedRow >= lastRow )
+ {
+ /* correct only from above */
+ lastCorruptedRow = lastRow-1;
+ for ( currRow = firstCorruptedRow; currRow < lastRow; currRow++ )
+ {
+
+ ercCollect8PredBlocks (predBlocks, (currRow<<1), (column<<1),
+ errorVar->yCondition, (lastRow<<1), (lastColumn<<1), 2, 0);
+
+ if(erc_mvperMB >= MVPERMB_THR)
+ concealByTrial(recfr, predMB,
+ currRow*lastColumn+column, object_list, predBlocks,
+ picSizeX, picSizeY,
+ errorVar->yCondition);
+ else
+ concealByCopy(recfr, currRow*lastColumn+column,
+ object_list, picSizeX);
+
+ ercMarkCurrMBConcealed (currRow*lastColumn+column, -1, picSizeX, errorVar);
+ }
+ row = lastRow;
+ }
+ else if ( firstCorruptedRow == 0 )
+ {
+ /* correct only from below */
+ for ( currRow = lastCorruptedRow; currRow >= 0; currRow-- )
+ {
+
+ ercCollect8PredBlocks (predBlocks, (currRow<<1), (column<<1),
+ errorVar->yCondition, (lastRow<<1), (lastColumn<<1), 2, 0);
+
+ if(erc_mvperMB >= MVPERMB_THR)
+ concealByTrial(recfr, predMB,
+ currRow*lastColumn+column, object_list, predBlocks,
+ picSizeX, picSizeY,
+ errorVar->yCondition);
+ else
+ concealByCopy(recfr, currRow*lastColumn+column,
+ object_list, picSizeX);
+
+ ercMarkCurrMBConcealed (currRow*lastColumn+column, -1, picSizeX, errorVar);
+ }
+
+ row = lastCorruptedRow+1;
+ }
+ else
+ {
+ /* correct bi-directionally */
+
+ row = lastCorruptedRow+1;
+
+ areaHeight = lastCorruptedRow-firstCorruptedRow+1;
+
+ /*
+ * Conceal the corrupted area switching between the up and the bottom rows
+ */
+ for ( i = 0; i < areaHeight; i++)
+ {
+ if ( i % 2 )
+ {
+ currRow = lastCorruptedRow;
+ lastCorruptedRow --;
+ }
+ else
+ {
+ currRow = firstCorruptedRow;
+ firstCorruptedRow ++;
+ }
+
+ ercCollect8PredBlocks (predBlocks, (currRow<<1), (column<<1),
+ errorVar->yCondition, (lastRow<<1), (lastColumn<<1), 2, 0);
+
+ if(erc_mvperMB >= MVPERMB_THR)
+ concealByTrial(recfr, predMB,
+ currRow*lastColumn+column, object_list, predBlocks,
+ picSizeX, picSizeY,
+ errorVar->yCondition);
+ else
+ concealByCopy(recfr, currRow*lastColumn+column,
+ object_list, picSizeX);
+
+ ercMarkCurrMBConcealed (currRow*lastColumn+column, -1, picSizeX, errorVar);
+
+ }
+ }
+ lastCorruptedRow = -1;
+ firstCorruptedRow = -1;
+ }
+ }
+ }
+
+ free(predMB);
+ }
+ return 1;
+ }
+ else
+ return 0;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * It conceals a given MB by simply copying the pixel area from the reference image
+ * that is at the same location as the macroblock in the current image. This correcponds
+ * to COPY MBs.
+ * \return
+ * Always zero (0).
+ * \param recfr
+ * Reconstructed frame buffer
+ * \param currMBNum
+ * current MB index
+ * \param object_list
+ * Motion info for all MBs in the frame
+ * \param picSizeX
+ * Width of the frame in pixels
+ ************************************************************************
+ */
+static int concealByCopy(frame *recfr, int currMBNum,
+ objectBuffer_t *object_list, int picSizeX)
+{
+ objectBuffer_t *currRegion;
+
+ currRegion = object_list+(currMBNum<<2);
+ currRegion->regionMode = REGMODE_INTER_COPY;
+
+ currRegion->xMin = (xPosMB(currMBNum,picSizeX)<<4);
+ currRegion->yMin = (yPosMB(currMBNum,picSizeX)<<4);
+
+ copyBetweenFrames (recfr, MBNum2YBlock(currMBNum,0,picSizeX), picSizeX, 16);
+
+ return 0;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Copies the co-located pixel values from the reference to the current frame.
+ * Used by concealByCopy
+ * \param recfr
+ * Reconstructed frame buffer
+ * \param currYBlockNum
+ * index of the block (8x8) in the Y plane
+ * \param picSizeX
+ * Width of the frame in pixels
+ * \param regionSize
+ * can be 16 or 8 to tell the dimension of the region to copy
+ ************************************************************************
+ */
+static void copyBetweenFrames (frame *recfr, int currYBlockNum, int picSizeX, int regionSize)
+{
+ int j, k, location, xmin, ymin;
+ StorablePicture* refPic = listX[0][0];
+
+ /* set the position of the region to be copied */
+ xmin = (xPosYBlock(currYBlockNum,picSizeX)<<3);
+ ymin = (yPosYBlock(currYBlockNum,picSizeX)<<3);
+
+ for (j = ymin; j < ymin + regionSize; j++)
+ for (k = xmin; k < xmin + regionSize; k++)
+ {
+ location = j * picSizeX + k;
+//th recfr->yptr[location] = dec_picture->imgY[j][k];
+ recfr->yptr[location] = refPic->imgY[j][k];
+ }
+
+ for (j = ymin >> uv_div[1][dec_picture->chroma_format_idc]; j < (ymin + regionSize) >> uv_div[1][dec_picture->chroma_format_idc]; j++)
+ for (k = xmin >> uv_div[0][dec_picture->chroma_format_idc]; k < (xmin + regionSize) >> uv_div[0][dec_picture->chroma_format_idc]; k++)
+ {
+// location = j * picSizeX / 2 + k;
+ location = ((j * picSizeX) >> uv_div[0][dec_picture->chroma_format_idc]) + k;
+
+//th recfr->uptr[location] = dec_picture->imgUV[0][j][k];
+//th recfr->vptr[location] = dec_picture->imgUV[1][j][k];
+ recfr->uptr[location] = refPic->imgUV[0][j][k];
+ recfr->vptr[location] = refPic->imgUV[1][j][k];
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * It conceals a given MB by using the motion vectors of one reliable neighbor. That MV of a
+ * neighbor is selected wich gives the lowest pixel difference at the edges of the MB
+ * (see function edgeDistortion). This corresponds to a spatial smoothness criteria.
+ * \return
+ * Always zero (0).
+ * \param recfr
+ * Reconstructed frame buffer
+ * \param predMB
+ * memory area for storing temporary pixel values for a macroblock
+ * the Y,U,V planes are concatenated y = predMB, u = predMB+256, v = predMB+320
+ * \param currMBNum
+ * current MB index
+ * \param object_list
+ * array of region structures storing region mode and mv for each region
+ * \param predBlocks
+ * status array of the neighboring blocks (if they are OK, concealed or lost)
+ * \param picSizeX
+ * Width of the frame in pixels
+ * \param picSizeY
+ * Height of the frame in pixels
+ * \param yCondition
+ * array for conditions of Y blocks from ercVariables_t
+ ************************************************************************
+ */
+static int concealByTrial(frame *recfr, imgpel *predMB,
+ int currMBNum, objectBuffer_t *object_list, int predBlocks[],
+ int picSizeX, int picSizeY, int *yCondition)
+{
+ int predMBNum = 0, numMBPerLine,
+ compSplit1 = 0, compSplit2 = 0, compLeft = 1, comp = 0, compPred, order = 1,
+ fInterNeighborExists, numIntraNeighbours,
+ fZeroMotionChecked, predSplitted = 0,
+ threshold = ERC_BLOCK_OK,
+ minDist, currDist, i, k, bestDir;
+ int regionSize;
+ objectBuffer_t *currRegion;
+ int mvBest[3] , mvPred[3], *mvptr;
+
+ numMBPerLine = (int) (picSizeX>>4);
+
+ comp = 0;
+ regionSize = 16;
+
+ do
+ { /* 4 blocks loop */
+
+ currRegion = object_list+(currMBNum<<2)+comp;
+
+ /* set the position of the region to be concealed */
+
+ currRegion->xMin = (xPosYBlock(MBNum2YBlock(currMBNum,comp,picSizeX),picSizeX)<<3);
+ currRegion->yMin = (yPosYBlock(MBNum2YBlock(currMBNum,comp,picSizeX),picSizeX)<<3);
+
+ do
+ { /* reliability loop */
+
+ minDist = 0;
+ fInterNeighborExists = 0;
+ numIntraNeighbours = 0;
+ fZeroMotionChecked = 0;
+
+ /* loop the 4 neighbours */
+ for (i = 4; i < 8; i++)
+ {
+
+ /* if reliable, try it */
+ if (predBlocks[i] >= threshold)
+ {
+ switch (i)
+ {
+ case 4:
+ predMBNum = currMBNum-numMBPerLine;
+ compSplit1 = 2;
+ compSplit2 = 3;
+ break;
+
+ case 5:
+ predMBNum = currMBNum-1;
+ compSplit1 = 1;
+ compSplit2 = 3;
+ break;
+
+ case 6:
+ predMBNum = currMBNum+numMBPerLine;
+ compSplit1 = 0;
+ compSplit2 = 1;
+ break;
+
+ case 7:
+ predMBNum = currMBNum+1;
+ compSplit1 = 0;
+ compSplit2 = 2;
+ break;
+ }
+
+ /* try the concealment with the Motion Info of the current neighbour
+ only try if the neighbour is not Intra */
+ if (isBlock(object_list,predMBNum,compSplit1,INTRA) ||
+ isBlock(object_list,predMBNum,compSplit2,INTRA))
+ {
+ numIntraNeighbours++;
+ }
+ else
+ {
+ /* if neighbour MB is splitted, try both neighbour blocks */
+ for (predSplitted = isSplitted(object_list, predMBNum),
+ compPred = compSplit1;
+ predSplitted >= 0;
+ compPred = compSplit2,
+ predSplitted -= ((compSplit1 == compSplit2) ? 2 : 1))
+ {
+
+ /* if Zero Motion Block, do the copying. This option is tried only once */
+ if (isBlock(object_list, predMBNum, compPred, INTER_COPY))
+ {
+
+ if (fZeroMotionChecked)
+ {
+ continue;
+ }
+ else
+ {
+ fZeroMotionChecked = 1;
+
+ mvPred[0] = mvPred[1] = 0;
+ mvPred[2] = 0;
+
+ buildPredRegionYUV(erc_img, mvPred, currRegion->xMin, currRegion->yMin, predMB);
+ }
+ }
+ /* build motion using the neighbour's Motion Parameters */
+ else if (isBlock(object_list,predMBNum,compPred,INTRA))
+ {
+ continue;
+ }
+ else
+ {
+ mvptr = getParam(object_list, predMBNum, compPred, mv);
+
+ mvPred[0] = mvptr[0];
+ mvPred[1] = mvptr[1];
+ mvPred[2] = mvptr[2];
+
+ buildPredRegionYUV(erc_img, mvPred, currRegion->xMin, currRegion->yMin, predMB);
+ }
+
+ /* measure absolute boundary pixel difference */
+ currDist = edgeDistortion(predBlocks,
+ MBNum2YBlock(currMBNum,comp,picSizeX),
+ predMB, recfr->yptr, picSizeX, regionSize);
+
+ /* if so far best -> store the pixels as the best concealment */
+ if (currDist < minDist || !fInterNeighborExists)
+ {
+
+ minDist = currDist;
+ bestDir = i;
+
+ for (k=0;k<3;k++)
+ mvBest[k] = mvPred[k];
+
+ currRegion->regionMode =
+ (isBlock(object_list, predMBNum, compPred, INTER_COPY)) ?
+ ((regionSize == 16) ? REGMODE_INTER_COPY : REGMODE_INTER_COPY_8x8) :
+ ((regionSize == 16) ? REGMODE_INTER_PRED : REGMODE_INTER_PRED_8x8);
+
+ copyPredMB(MBNum2YBlock(currMBNum,comp,picSizeX), predMB, recfr,
+ picSizeX, regionSize);
+ }
+
+ fInterNeighborExists = 1;
+ }
+ }
+ }
+ }
+
+ threshold--;
+
+ } while ((threshold >= ERC_BLOCK_CONCEALED) && (fInterNeighborExists == 0));
+
+ /* always try zero motion */
+ if (!fZeroMotionChecked)
+ {
+ mvPred[0] = mvPred[1] = 0;
+ mvPred[2] = 0;
+
+ buildPredRegionYUV(erc_img, mvPred, currRegion->xMin, currRegion->yMin, predMB);
+
+ currDist = edgeDistortion(predBlocks,
+ MBNum2YBlock(currMBNum,comp,picSizeX),
+ predMB, recfr->yptr, picSizeX, regionSize);
+
+ if (currDist < minDist || !fInterNeighborExists)
+ {
+
+ minDist = currDist;
+ for (k=0;k<3;k++)
+ mvBest[k] = mvPred[k];
+
+ currRegion->regionMode =
+ ((regionSize == 16) ? REGMODE_INTER_COPY : REGMODE_INTER_COPY_8x8);
+
+ copyPredMB(MBNum2YBlock(currMBNum,comp,picSizeX), predMB, recfr,
+ picSizeX, regionSize);
+ }
+ }
+
+ for (i=0; i<3; i++)
+ currRegion->mv[i] = mvBest[i];
+
+ yCondition[MBNum2YBlock(currMBNum,comp,picSizeX)] = ERC_BLOCK_CONCEALED;
+ comp = (comp+order+4)%4;
+ compLeft--;
+
+ } while (compLeft);
+
+ return 0;
+}
+
+/*!
+************************************************************************
+* \brief
+* Builds the motion prediction pixels from the given location (in 1/4 pixel units)
+* of the reference frame. It not only copies the pixel values but builds the interpolation
+* when the pixel positions to be copied from is not full pixel (any 1/4 pixel position).
+* It copies the resulting pixel vlaues into predMB.
+* \param img
+* The pointer of img_par struture of current frame
+* \param mv
+* The pointer of the predicted MV of the current (being concealed) MB
+* \param x
+* The x-coordinate of the above-left corner pixel of the current MB
+* \param y
+* The y-coordinate of the above-left corner pixel of the current MB
+* \param predMB
+* memory area for storing temporary pixel values for a macroblock
+* the Y,U,V planes are concatenated y = predMB, u = predMB+256, v = predMB+320
+************************************************************************
+*/
+static void buildPredRegionYUV(struct img_par *img, int *mv, int x, int y, imgpel *predMB)
+{
+ int tmp_block[BLOCK_SIZE][BLOCK_SIZE];
+ int i=0,j=0,ii=0,jj=0,i1=0,j1=0,j4=0,i4=0;
+ int jf=0;
+ int uv;
+ int vec1_x=0,vec1_y=0;
+ int ioff,joff;
+ imgpel *pMB = predMB;
+
+ int ii0,jj0,ii1,jj1,if1,jf1,if0,jf0;
+ int mv_mul;
+
+ //FRExt
+ int f1_x, f1_y, f2_x, f2_y, f3, f4, ifx;
+ int b8, b4;
+ int yuv = dec_picture->chroma_format_idc - 1;
+
+ int ref_frame = imax (mv[2], 0); // !!KS: quick fix, we sometimes seem to get negative ref_pic here, so restrict to zero an above
+
+ /* Update coordinates of the current concealed macroblock */
+ img->mb_x = x/MB_BLOCK_SIZE;
+ img->mb_y = y/MB_BLOCK_SIZE;
+ img->block_y = img->mb_y * BLOCK_SIZE;
+ img->pix_c_y = img->mb_y * img->mb_cr_size_y;
+ img->block_x = img->mb_x * BLOCK_SIZE;
+ img->pix_c_x = img->mb_x * img->mb_cr_size_x;
+
+ mv_mul=4;
+
+ // luma *******************************************************
+
+ for(j=0;j<MB_BLOCK_SIZE/BLOCK_SIZE;j++)
+ {
+ joff=j*4;
+ j4=img->block_y+j;
+ for(i=0;i<MB_BLOCK_SIZE/BLOCK_SIZE;i++)
+ {
+ ioff=i*4;
+ i4=img->block_x+i;
+
+ vec1_x = i4*4*mv_mul + mv[0];
+ vec1_y = j4*4*mv_mul + mv[1];
+
+ get_block(ref_frame, listX[0], vec1_x,vec1_y,img,tmp_block);
+
+ for(ii=0;ii<BLOCK_SIZE;ii++)
+ for(jj=0;jj<MB_BLOCK_SIZE/BLOCK_SIZE;jj++)
+ img->mpr[jj+joff][ii+ioff]=tmp_block[jj][ii];
+ }
+ }
+
+
+ for (j = 0; j < 16; j++)
+ {
+ for (i = 0; i < 16; i++)
+ {
+ pMB[j*16+i] = img->mpr[j][i];
+ }
+ }
+ pMB += 256;
+
+ if (dec_picture->chroma_format_idc != YUV400)
+ {
+ // chroma *******************************************************
+ f1_x = 64/img->mb_cr_size_x;
+ f2_x=f1_x-1;
+
+ f1_y = 64/img->mb_cr_size_y;
+ f2_y=f1_y-1;
+
+ f3=f1_x*f1_y;
+ f4=f3>>1;
+
+ for(uv=0;uv<2;uv++)
+ {
+ for (b8=0;b8<(img->num_blk8x8_uv/2);b8++)
+ {
+ for(b4=0;b4<4;b4++)
+ {
+ joff = subblk_offset_y[yuv][b8][b4];
+ j4=img->pix_c_y+joff;
+ ioff = subblk_offset_x[yuv][b8][b4];
+ i4=img->pix_c_x+ioff;
+
+ for(jj=0;jj<4;jj++)
+ {
+ jf=(j4+jj)/(img->mb_cr_size_y/4); // jf = Subblock_y-coordinate
+ for(ii=0;ii<4;ii++)
+ {
+ ifx=(i4+ii)/(img->mb_cr_size_x/4); // ifx = Subblock_x-coordinate
+
+ i1=(i4+ii)*f1_x + mv[0];
+ j1=(j4+jj)*f1_y + mv[1];
+
+ ii0=iClip3 (0, dec_picture->size_x_cr-1, i1/f1_x);
+ jj0=iClip3 (0, dec_picture->size_y_cr-1, j1/f1_y);
+ ii1=iClip3 (0, dec_picture->size_x_cr-1, ((i1+f2_x)/f1_x));
+ jj1=iClip3 (0, dec_picture->size_y_cr-1, ((j1+f2_y)/f1_y));
+
+ if1=(i1 & f2_x);
+ jf1=(j1 & f2_y);
+ if0=f1_x-if1;
+ jf0=f1_y-jf1;
+
+ img->mpr[jj+joff][ii+ioff]=(if0*jf0*listX[0][ref_frame]->imgUV[uv][jj0][ii0]+
+ if1*jf0*listX[0][ref_frame]->imgUV[uv][jj0][ii1]+
+ if0*jf1*listX[0][ref_frame]->imgUV[uv][jj1][ii0]+
+ if1*jf1*listX[0][ref_frame]->imgUV[uv][jj1][ii1]+f4)/f3;
+ }
+ }
+ }
+ }
+
+ for (j = 0; j < 8; j++)
+ {
+ for (i = 0; i < 8; i++)
+ {
+ pMB[j*8+i] = img->mpr[j][i];
+ }
+ }
+ pMB += 64;
+
+ }
+ }
+}
+/*!
+ ************************************************************************
+ * \brief
+ * Copies pixel values between a YUV frame and the temporary pixel value storage place. This is
+ * used to save some pixel values temporarily before overwriting it, or to copy back to a given
+ * location in a frame the saved pixel values.
+ * \param currYBlockNum
+ * index of the block (8x8) in the Y plane
+ * \param predMB
+ * memory area where the temporary pixel values are stored
+ * the Y,U,V planes are concatenated y = predMB, u = predMB+256, v = predMB+320
+ * \param recfr
+ * pointer to a YUV frame
+ * \param picSizeX
+ * picture width in pixels
+ * \param regionSize
+ * can be 16 or 8 to tell the dimension of the region to copy
+ ************************************************************************
+ */
+static void copyPredMB (int currYBlockNum, imgpel *predMB, frame *recfr,
+ int picSizeX, int regionSize)
+{
+
+ int j, k, xmin, ymin, xmax, ymax;
+ int locationTmp, locationPred;
+ int uv_x = uv_div[0][dec_picture->chroma_format_idc];
+ int uv_y = uv_div[1][dec_picture->chroma_format_idc];
+
+ xmin = (xPosYBlock(currYBlockNum,picSizeX)<<3);
+ ymin = (yPosYBlock(currYBlockNum,picSizeX)<<3);
+ xmax = xmin + regionSize -1;
+ ymax = ymin + regionSize -1;
+
+ for (j = ymin; j <= ymax; j++)
+ {
+ for (k = xmin; k <= xmax; k++)
+ {
+ locationPred = j * picSizeX + k;
+ locationTmp = (j-ymin) * 16 + (k-xmin);
+ dec_picture->imgY[j][k] = predMB[locationTmp];
+ }
+ }
+
+ if (dec_picture->chroma_format_idc != YUV400)
+ {
+ for (j = (ymin>>uv_y); j <= (ymax>>uv_y); j++)
+ {
+ for (k = (xmin>>uv_x); k <= (xmax>>uv_x); k++)
+ {
+ locationPred = ((j * picSizeX) >> uv_x) + k;
+ locationTmp = (j-(ymin>>uv_y)) * img->mb_cr_size_x + (k-(xmin>>1)) + 256;
+ dec_picture->imgUV[0][j][k] = predMB[locationTmp];
+
+ locationTmp += 64;
+
+ dec_picture->imgUV[1][j][k] = predMB[locationTmp];
+ }
+ }
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Calculates a weighted pixel difference between edge Y pixels of the macroblock stored in predMB
+ * and the pixels in the given Y plane of a frame (recY) that would become neighbor pixels if
+ * predMB was placed at currYBlockNum block position into the frame. This "edge distortion" value
+ * is used to determine how well the given macroblock in predMB would fit into the frame when
+ * considering spatial smoothness. If there are correctly received neighbor blocks (status stored
+ * in predBlocks) only they are used in calculating the edge distorion; otherwise also the already
+ * concealed neighbor blocks can also be used.
+ * \return
+ * The calculated weighted pixel difference at the edges of the MB.
+ * \param predBlocks
+ * status array of the neighboring blocks (if they are OK, concealed or lost)
+ * \param currYBlockNum
+ * index of the block (8x8) in the Y plane
+ * \param predMB
+ * memory area where the temporary pixel values are stored
+ * the Y,U,V planes are concatenated y = predMB, u = predMB+256, v = predMB+320
+ * \param recY
+ * pointer to a Y plane of a YUV frame
+ * \param picSizeX
+ * picture width in pixels
+ * \param regionSize
+ * can be 16 or 8 to tell the dimension of the region to copy
+ ************************************************************************
+ */
+static int edgeDistortion (int predBlocks[], int currYBlockNum, imgpel *predMB,
+ imgpel *recY, int picSizeX, int regionSize)
+{
+ int i, j, distortion, numOfPredBlocks, threshold = ERC_BLOCK_OK;
+ imgpel *currBlock = NULL, *neighbor = NULL;
+ int currBlockOffset = 0;
+
+ currBlock = recY + (yPosYBlock(currYBlockNum,picSizeX)<<3)*picSizeX + (xPosYBlock(currYBlockNum,picSizeX)<<3);
+
+ do
+ {
+
+ distortion = 0; numOfPredBlocks = 0;
+
+ // loop the 4 neighbors
+ for (j = 4; j < 8; j++)
+ {
+ /* if reliable, count boundary pixel difference */
+ if (predBlocks[j] >= threshold)
+ {
+
+ switch (j)
+ {
+ case 4:
+ neighbor = currBlock - picSizeX;
+ for ( i = 0; i < regionSize; i++ )
+ {
+ distortion += mabs((int)(predMB[i] - neighbor[i]));
+ }
+ break;
+ case 5:
+ neighbor = currBlock - 1;
+ for ( i = 0; i < regionSize; i++ )
+ {
+ distortion += mabs((int)(predMB[i*16] - neighbor[i*picSizeX]));
+ }
+ break;
+ case 6:
+ neighbor = currBlock + regionSize*picSizeX;
+ currBlockOffset = (regionSize-1)*16;
+ for ( i = 0; i < regionSize; i++ )
+ {
+ distortion += mabs((int)(predMB[i+currBlockOffset] - neighbor[i]));
+ }
+ break;
+ case 7:
+ neighbor = currBlock + regionSize;
+ currBlockOffset = regionSize-1;
+ for ( i = 0; i < regionSize; i++ )
+ {
+ distortion += mabs((int)(predMB[i*16+currBlockOffset] - neighbor[i*picSizeX]));
+ }
+ break;
+ }
+
+ numOfPredBlocks++;
+ }
+ }
+
+ threshold--;
+ if (threshold < ERC_BLOCK_CONCEALED)
+ break;
+ } while (numOfPredBlocks == 0);
+
+ if(numOfPredBlocks == 0)
+ {
+ return 0;
+ // assert (numOfPredBlocks != 0); !!!KS hmm, trying to continue...
+ }
+ return (distortion/numOfPredBlocks);
+}
+
+// picture error concealment below
+
+/*!
+************************************************************************
+* \brief
+* The motion prediction pixels are calculated from the given location (in
+* 1/4 pixel units) of the referenced frame. It copies the sub block from the
+* corresponding reference to the frame to be concealed.
+*
+*************************************************************************
+*/
+static void buildPredblockRegionYUV(struct img_par *img, int *mv,
+ int x, int y, imgpel *predMB, int list)
+{
+ int tmp_block[BLOCK_SIZE][BLOCK_SIZE];
+ int i=0,j=0,ii=0,jj=0,i1=0,j1=0,j4=0,i4=0;
+ int jf=0;
+ int uv;
+ int vec1_x=0,vec1_y=0;
+ int ioff,joff;
+ imgpel *pMB = predMB;
+
+ int ii0,jj0,ii1,jj1,if1,jf1,if0,jf0;
+ int mv_mul;
+
+ //FRExt
+ int f1_x, f1_y, f2_x, f2_y, f3, f4, ifx;
+ int yuv = dec_picture->chroma_format_idc - 1;
+
+ int ref_frame = mv[2];
+
+ /* Update coordinates of the current concealed macroblock */
+
+ img->mb_x = x/BLOCK_SIZE;
+ img->mb_y = y/BLOCK_SIZE;
+ img->block_y = img->mb_y * BLOCK_SIZE;
+ img->pix_c_y = img->mb_y * img->mb_cr_size_y/4;
+ img->block_x = img->mb_x * BLOCK_SIZE;
+ img->pix_c_x = img->mb_x * img->mb_cr_size_x/4;
+
+ mv_mul=4;
+
+ // luma *******************************************************
+
+ vec1_x = x*mv_mul + mv[0];
+ vec1_y = y*mv_mul + mv[1];
+
+ get_block(ref_frame, listX[list], vec1_x,vec1_y,img,tmp_block);
+
+ for(jj=0;jj<MB_BLOCK_SIZE/BLOCK_SIZE;jj++)
+ for(ii=0;ii<BLOCK_SIZE;ii++)
+ img->mpr[jj][ii]=tmp_block[jj][ii];
+
+
+ for (j = 0; j < 4; j++)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ pMB[j*4+i] = img->mpr[j][i];
+ }
+ }
+ pMB += 16;
+
+ if (dec_picture->chroma_format_idc != YUV400)
+ {
+ // chroma *******************************************************
+ f1_x = 64/(img->mb_cr_size_x);
+ f2_x=f1_x-1;
+
+ f1_y = 64/(img->mb_cr_size_y);
+ f2_y=f1_y-1;
+
+ f3=f1_x*f1_y;
+ f4=f3>>1;
+
+ for(uv=0;uv<2;uv++)
+ {
+ joff = subblk_offset_y[yuv][0][0];
+ j4=img->pix_c_y+joff;
+ ioff = subblk_offset_x[yuv][0][0];
+ i4=img->pix_c_x+ioff;
+
+ for(jj=0;jj<2;jj++)
+ {
+ jf=(j4+jj)/(img->mb_cr_size_y/4); // jf = Subblock_y-coordinate
+ for(ii=0;ii<2;ii++)
+ {
+ ifx=(i4+ii)/(img->mb_cr_size_x/4); // ifx = Subblock_x-coordinate
+
+ i1=(i4+ii)*f1_x + mv[0];
+ j1=(j4+jj)*f1_y + mv[1];
+
+ ii0=iClip3 (0, dec_picture->size_x_cr-1, i1/f1_x);
+ jj0=iClip3 (0, dec_picture->size_y_cr-1, j1/f1_y);
+ ii1=iClip3 (0, dec_picture->size_x_cr-1, ((i1+f2_x)/f1_x));
+ jj1=iClip3 (0, dec_picture->size_y_cr-1, ((j1+f2_y)/f1_y));
+
+ if1=(i1 & f2_x);
+ jf1=(j1 & f2_y);
+ if0=f1_x-if1;
+ jf0=f1_y-jf1;
+
+ img->mpr[jj][ii]=(if0*jf0*listX[list][ref_frame]->imgUV[uv][jj0][ii0]+
+ if1*jf0*listX[list][ref_frame]->imgUV[uv][jj0][ii1]+
+ if0*jf1*listX[list][ref_frame]->imgUV[uv][jj1][ii0]+
+ if1*jf1*listX[list][ref_frame]->imgUV[uv][jj1][ii1]+f4)/f3;
+ }
+ }
+
+ for (j = 0; j < 2; j++)
+ {
+ for (i = 0; i < 2; i++)
+ {
+ pMB[j*2+i] = img->mpr[j][i];
+ }
+ }
+ pMB += 4;
+
+ }
+ }
+}
+
+/*!
+************************************************************************
+* \brief
+* compares two stored pictures by picture number for qsort in descending order
+*
+************************************************************************
+*/
+static int compare_pic_by_pic_num_desc( const void *arg1, const void *arg2 )
+{
+ if ( (*(StorablePicture**)arg1)->pic_num < (*(StorablePicture**)arg2)->pic_num)
+ return 1;
+ if ( (*(StorablePicture**)arg1)->pic_num > (*(StorablePicture**)arg2)->pic_num)
+ return -1;
+ else
+ return 0;
+}
+
+/*!
+************************************************************************
+* \brief
+* compares two stored pictures by picture number for qsort in descending order
+*
+************************************************************************
+*/
+static int compare_pic_by_lt_pic_num_asc( const void *arg1, const void *arg2 )
+{
+ if ( (*(StorablePicture**)arg1)->long_term_pic_num < (*(StorablePicture**)arg2)->long_term_pic_num)
+ return -1;
+ if ( (*(StorablePicture**)arg1)->long_term_pic_num > (*(StorablePicture**)arg2)->long_term_pic_num)
+ return 1;
+ else
+ return 0;
+}
+
+/*!
+************************************************************************
+* \brief
+* compares two stored pictures by poc for qsort in ascending order
+*
+************************************************************************
+*/
+static int compare_pic_by_poc_asc( const void *arg1, const void *arg2 )
+{
+ if ( (*(StorablePicture**)arg1)->poc < (*(StorablePicture**)arg2)->poc)
+ return -1;
+ if ( (*(StorablePicture**)arg1)->poc > (*(StorablePicture**)arg2)->poc)
+ return 1;
+ else
+ return 0;
+}
+
+
+/*!
+************************************************************************
+* \brief
+* compares two stored pictures by poc for qsort in descending order
+*
+************************************************************************
+*/
+static int compare_pic_by_poc_desc( const void *arg1, const void *arg2 )
+{
+ if ( (*(StorablePicture**)arg1)->poc < (*(StorablePicture**)arg2)->poc)
+ return 1;
+ if ( (*(StorablePicture**)arg1)->poc > (*(StorablePicture**)arg2)->poc)
+ return -1;
+ else
+ return 0;
+}
+
+/*!
+************************************************************************
+* \brief
+* Copy image data from one array to another array
+************************************************************************
+*/
+
+static
+void CopyImgData(imgpel **inputY, imgpel ***inputUV, imgpel **outputY,
+ imgpel ***outputUV, int img_width, int img_height)
+{
+ int x, y;
+
+ for (y=0; y<img_height; y++)
+ for (x=0; x<img_width; x++)
+ outputY[y][x] = inputY[y][x];
+
+ for (y=0; y<img_height/2; y++)
+ for (x=0; x<img_width/2; x++)
+ {
+ outputUV[0][y][x] = inputUV[0][y][x];
+ outputUV[1][y][x] = inputUV[1][y][x];
+ }
+}
+
+/*!
+************************************************************************
+* \brief
+* Copies the last reference frame for concealing reference frame loss.
+************************************************************************
+*/
+
+static StorablePicture *
+get_last_ref_pic_from_dpb()
+{
+ int used_size = dpb.used_size - 1;
+ int i;
+
+ for(i = used_size; i >= 0; i--)
+ {
+ if (dpb.fs[i]->is_used==3)
+ {
+ if (((dpb.fs[i]->frame->used_for_reference) &&
+ (!dpb.fs[i]->frame->is_long_term)) /*|| ((dpb.fs[i]->frame->used_for_reference==0)
+ && (dpb.fs[i]->frame->slice_type == P_SLICE))*/ )
+ {
+ return dpb.fs[i]->frame;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/*!
+************************************************************************
+* \brief
+* Conceals the lost reference or non reference frame by either frame copy
+* or motion vector copy concealment.
+*
+************************************************************************
+*/
+
+static void copy_to_conceal(StorablePicture *src, StorablePicture *dst, ImageParameters *img)
+{
+ int i=0;
+ int mv[3];
+ int multiplier;
+ imgpel *predMB, *storeYUV;
+ int j, y, x, mb_height, mb_width, ii=0, jj=0;
+ int uv;
+ int mm, nn;
+ int scale = 1;
+ // struct inp_par *test;
+
+ img->current_mb_nr = 0;
+
+ dst->PicSizeInMbs = src->PicSizeInMbs;
+
+ dst->slice_type = src->slice_type = img->conceal_slice_type;
+
+ dst->idr_flag = 0; //since we do not want to clears the ref list
+
+ dst->no_output_of_prior_pics_flag = src->no_output_of_prior_pics_flag;
+ dst->long_term_reference_flag = src->long_term_reference_flag;
+ dst->adaptive_ref_pic_buffering_flag = src->adaptive_ref_pic_buffering_flag = 0;
+ dst->chroma_format_idc = src->chroma_format_idc;
+ dst->frame_mbs_only_flag = src->frame_mbs_only_flag;
+ dst->frame_cropping_flag = src->frame_cropping_flag;
+ dst->frame_cropping_rect_left_offset = src->frame_cropping_rect_left_offset;
+ dst->frame_cropping_rect_right_offset = src->frame_cropping_rect_right_offset;
+ dst->frame_cropping_rect_bottom_offset = src->frame_cropping_rect_bottom_offset;
+ dst->frame_cropping_rect_top_offset = src->frame_cropping_rect_top_offset;
+ dst->qp = src->qp;
+ dst->slice_qp_delta = src->slice_qp_delta;
+
+ dec_picture = src;
+
+ // Conceals the missing frame by frame copy concealment
+ if (img->conceal_mode==1)
+ {
+ // We need these initializations for using deblocking filter for frame copy
+ // concealment as well.
+ dst->PicWidthInMbs = src->PicWidthInMbs;
+ dst->PicSizeInMbs = src->PicSizeInMbs;
+
+ CopyImgData(src->imgY, src->imgUV,
+ dst->imgY, dst->imgUV,
+ img->width, img->height);
+
+ }
+
+ // Conceals the missing frame by motion vector copy concealment
+ if (img->conceal_mode==2)
+ {
+ if (dec_picture->chroma_format_idc != YUV400)
+ {
+ storeYUV = (imgpel *) malloc ( (16 + (img->mb_cr_size_x*img->mb_cr_size_y)*2/16) * sizeof (imgpel));
+ }
+ else
+ {
+ storeYUV = (imgpel *) malloc (16 * sizeof (imgpel));
+ }
+
+ erc_img = img;
+
+ dst->PicWidthInMbs = src->PicWidthInMbs;
+ dst->PicSizeInMbs = src->PicSizeInMbs;
+ mb_width = dst->PicWidthInMbs;
+ mb_height = (dst->PicSizeInMbs)/(dst->PicWidthInMbs);
+ scale = (img->conceal_slice_type == B_SLICE) ? 2 : 1;
+
+ if(img->conceal_slice_type == B_SLICE)
+ init_lists_for_non_reference_loss(dst->slice_type, img->currentSlice->structure);
+ else
+ init_lists(dst->slice_type, img->currentSlice->structure);
+
+ multiplier = BLOCK_SIZE;
+
+ for(i=0;i<mb_height*4;i++)
+ {
+ mm = i*BLOCK_SIZE;
+ for(j=0;j<mb_width*4;j++)
+ {
+ nn = j*BLOCK_SIZE;
+
+ mv[0] = src->mv[LIST_0][i][j][0] / scale;
+ mv[1] = src->mv[LIST_0][i][j][1] / scale;
+ mv[2] = src->ref_idx[LIST_0][i][j];
+
+
+ if(mv[2]<0)
+ mv[2]=0;
+
+ dst->mv[LIST_0][i][j][0] = mv[0];
+ dst->mv[LIST_0][i][j][1] = mv[1];
+ dst->ref_idx[LIST_0][i][j] = mv[2];
+
+ x = (j)*multiplier;
+ y = (i)*multiplier;
+
+ if ((mm%16==0) && (nn%16==0))
+ img->current_mb_nr++;
+
+ buildPredblockRegionYUV(erc_img, mv, x, y, storeYUV, LIST_0);
+
+ predMB = storeYUV;
+
+ for(ii=0;ii<multiplier;ii++)
+ {
+ for(jj=0;jj<multiplier;jj++)
+ {
+ dst->imgY[i*multiplier+ii][j*multiplier+jj] = predMB[ii*(multiplier)+jj];
+ }
+ }
+
+ predMB = predMB + (multiplier*multiplier);
+
+ if (dec_picture->chroma_format_idc != YUV400)
+ {
+
+ for(uv=0;uv<2;uv++)
+ {
+ for(ii=0;ii< (multiplier/2);ii++)
+ {
+ for(jj=0;jj< (multiplier/2);jj++)
+ {
+ dst->imgUV[uv][i*multiplier/2 +ii][j*multiplier/2 +jj] = predMB[ii*(multiplier/2)+jj];
+ }
+ }
+ predMB = predMB + (multiplier*multiplier/4);
+ }
+ }
+ }
+ }
+ free(storeYUV);
+ }
+}
+
+/*!
+************************************************************************
+* \brief
+* Uses the previous reference pic for concealment of reference frames
+*
+************************************************************************
+*/
+
+static void
+copy_prev_pic_to_concealed_pic(StorablePicture *picture, ImageParameters *img)
+{
+
+ StorablePicture *ref_pic;
+ /* get the last ref pic in dpb */
+ ref_pic = get_last_ref_pic_from_dpb();
+
+ assert(ref_pic != NULL);
+
+ /* copy all the struc from this to current concealment pic */
+ img->conceal_slice_type = P_SLICE;
+ copy_to_conceal(ref_pic, picture, img);
+}
+
+
+/*!
+************************************************************************
+* \brief
+* This function conceals a missing reference frame. The routine is called
+* based on the difference in frame number. It conceals an IDR frame loss
+* based on the sudden decrease in frame number.
+*
+************************************************************************
+*/
+
+void conceal_lost_frames(ImageParameters *img)
+{
+ int CurrFrameNum;
+ int UnusedShortTermFrameNum;
+ StorablePicture *picture = NULL;
+ int tmp1 = img->delta_pic_order_cnt[0];
+ int tmp2 = img->delta_pic_order_cnt[1];
+ int i;
+
+ img->delta_pic_order_cnt[0] = img->delta_pic_order_cnt[1] = 0;
+
+ // printf("A gap in frame number is found, try to fill it.\n");
+
+ if(img->IDR_concealment_flag == 1)
+ {
+ // Conceals an IDR frame loss. Uses the reference frame in the previous
+ // GOP for concealment.
+ UnusedShortTermFrameNum = 0;
+ img->last_ref_pic_poc = -img->poc_gap;
+ img->earlier_missing_poc = 0;
+ }
+ else
+ UnusedShortTermFrameNum = (img->pre_frame_num + 1) % img->MaxFrameNum;
+
+ CurrFrameNum = img->frame_num;
+
+ while (CurrFrameNum != UnusedShortTermFrameNum)
+ {
+ picture = alloc_storable_picture (FRAME, img->width, img->height, img->width_cr, img->height_cr);
+
+ picture->coded_frame = 1;
+ picture->pic_num = UnusedShortTermFrameNum;
+ picture->frame_num = UnusedShortTermFrameNum;
+ picture->non_existing = 0;
+ picture->is_output = 0;
+ picture->used_for_reference = 1;
+ picture->concealed_pic = 1;
+
+ picture->adaptive_ref_pic_buffering_flag = 0;
+
+ img->frame_num = UnusedShortTermFrameNum;
+
+ picture->top_poc=img->last_ref_pic_poc + img->ref_poc_gap;
+ picture->bottom_poc=picture->top_poc;
+ picture->frame_poc=picture->top_poc;
+ picture->poc=picture->top_poc;
+ img->last_ref_pic_poc = picture->poc;
+
+ copy_prev_pic_to_concealed_pic(picture, img);
+
+ //if (UnusedShortTermFrameNum == 0)
+ if(img->IDR_concealment_flag == 1)
+ {
+ picture->slice_type = I_SLICE;
+ picture->idr_flag = 1;
+ flush_dpb();
+ picture->top_poc= 0;
+ picture->bottom_poc=picture->top_poc;
+ picture->frame_poc=picture->top_poc;
+ picture->poc=picture->top_poc;
+ img->last_ref_pic_poc = picture->poc;
+ }
+
+ store_picture_in_dpb(picture);
+
+ picture=NULL;
+
+ img->pre_frame_num = UnusedShortTermFrameNum;
+ UnusedShortTermFrameNum = (UnusedShortTermFrameNum + 1) % img->MaxFrameNum;
+
+ // update reference flags and set current flag.
+ for(i=16;i>0;i--)
+ {
+ ref_flag[i] = ref_flag[i-1];
+ }
+ ref_flag[0] = 0;
+ }
+ img->delta_pic_order_cnt[0] = tmp1;
+ img->delta_pic_order_cnt[1] = tmp2;
+ img->frame_num = CurrFrameNum;
+}
+
+/*!
+************************************************************************
+* \brief
+* Updates the reference list for motion vector copy concealment for non-
+* reference frame loss.
+*
+************************************************************************
+*/
+
+void update_ref_list_for_concealment()
+{
+ unsigned i, j;
+ for (i=0, j=0; i<dpb.used_size; i++)
+ {
+ if (dpb.fs[i]->concealment_reference)
+ {
+ dpb.fs_ref[j++]=dpb.fs[i];
+ }
+ }
+
+ dpb.ref_frames_in_buffer = active_pps->num_ref_idx_l0_active_minus1;
+}
+
+/*!
+************************************************************************
+* \brief
+* Initialize the list based on the B frame or non reference 'p' frame
+* to be concealed. The function initialize listX[0] and list 1 depending
+* on current picture type
+*
+************************************************************************
+*/
+void init_lists_for_non_reference_loss(int currSliceType, PictureStructure currPicStructure)
+{
+ unsigned i;
+ int j;
+ int MaxFrameNum = 1 << (active_sps->log2_max_frame_num_minus4 + 4);
+ int diff;
+
+ int list0idx = 0;
+ int list0idx_1 = 0;
+
+ StorablePicture *tmp_s;
+
+ if (currPicStructure == FRAME)
+ {
+ for(i=0;i<dpb.ref_frames_in_buffer; i++)
+ {
+ if(dpb.fs[i]->concealment_reference == 1)
+ {
+ if(dpb.fs[i]->frame_num > img->frame_to_conceal)
+ dpb.fs_ref[i]->frame_num_wrap = dpb.fs[i]->frame_num - MaxFrameNum;
+ else
+ dpb.fs_ref[i]->frame_num_wrap = dpb.fs[i]->frame_num;
+ dpb.fs_ref[i]->frame->pic_num = dpb.fs_ref[i]->frame_num_wrap;
+ }
+ }
+ }
+
+ if (currSliceType == P_SLICE)
+ {
+ // Calculate FrameNumWrap and PicNum
+ if (currPicStructure == FRAME)
+ {
+ for(i=0;i<dpb.used_size; i++)
+ {
+ if(dpb.fs[i]->concealment_reference == 1)
+ {
+ listX[0][list0idx++] = dpb.fs[i]->frame;
+ }
+ }
+ // order list 0 by PicNum
+ qsort((void *)listX[0], list0idx, sizeof(StorablePicture*), compare_pic_by_pic_num_desc);
+ listXsize[0] = list0idx;
+ }
+ }
+
+ if (currSliceType == B_SLICE)
+ {
+ if (currPicStructure == FRAME)
+ {
+ // for(i=0;i<dpb.ref_frames_in_buffer; i++)
+ for(i=0;i<dpb.used_size; i++)
+ {
+ if(dpb.fs[i]->concealment_reference == 1)
+ {
+ if(img->earlier_missing_poc > dpb.fs[i]->frame->poc)
+ listX[0][list0idx++] = dpb.fs[i]->frame;
+ }
+ }
+
+ qsort((void *)listX[0], list0idx, sizeof(StorablePicture*), compare_pic_by_poc_desc);
+ list0idx_1 = list0idx;
+
+ // for(i=0;i<dpb.ref_frames_in_buffer; i++)
+ for(i=0;i<dpb.used_size; i++)
+ {
+ if(dpb.fs[i]->concealment_reference == 1)
+ {
+ if(img->earlier_missing_poc < dpb.fs[i]->frame->poc)
+ listX[0][list0idx++] = dpb.fs[i]->frame;
+ }
+ }
+
+ qsort((void *)&listX[0][list0idx_1], list0idx-list0idx_1, sizeof(StorablePicture*), compare_pic_by_poc_asc);
+
+ for (j=0; j<list0idx_1; j++)
+ {
+ listX[1][list0idx-list0idx_1+j]=listX[0][j];
+ }
+ for (j=list0idx_1; j<list0idx; j++)
+ {
+ listX[1][j-list0idx_1]=listX[0][j];
+ }
+
+ listXsize[0] = listXsize[1] = list0idx;
+
+ qsort((void *)&listX[0][listXsize[0]], list0idx-listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
+ qsort((void *)&listX[1][listXsize[0]], list0idx-listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
+ listXsize[0] = listXsize[1] = list0idx;
+ }
+ }
+
+ if ((listXsize[0] == listXsize[1]) && (listXsize[0] > 1))
+ {
+ // check if lists are identical, if yes swap first two elements of listX[1]
+ diff=0;
+ for (j = 0; j< listXsize[0]; j++)
+ {
+ if (listX[0][j]!=listX[1][j])
+ diff=1;
+ }
+ if (!diff)
+ {
+ tmp_s = listX[1][0];
+ listX[1][0]=listX[1][1];
+ listX[1][1]=tmp_s;
+ }
+ }
+
+
+ // set max size
+ listXsize[0] = imin (listXsize[0], (int)active_sps->num_ref_frames);
+ listXsize[1] = imin (listXsize[1], (int)active_sps->num_ref_frames);
+
+ listXsize[1] = 0;
+ // set the unused list entries to NULL
+ for (i=listXsize[0]; i< (MAX_LIST_SIZE) ; i++)
+ {
+ listX[0][i] = NULL;
+ }
+ for (i=listXsize[1]; i< (MAX_LIST_SIZE) ; i++)
+ {
+ listX[1][i] = NULL;
+ }
+}
+
+
+/*!
+************************************************************************
+* \brief
+* Get from the dpb the picture corresponding to a POC. The POC varies
+* depending on whether it is a frame copy or motion vector copy concealment.
+* The frame corresponding to the POC is returned.
+*
+************************************************************************
+*/
+
+StorablePicture *get_pic_from_dpb(int missingpoc, unsigned int *pos)
+{
+ int used_size = dpb.used_size - 1;
+ int i, concealfrom = 0;
+
+ if(img->conceal_mode == 1)
+ concealfrom = missingpoc - img->poc_gap;
+ else if (img->conceal_mode == 2)
+ concealfrom = missingpoc + img->poc_gap;
+
+ for(i = used_size; i >= 0; i--)
+ {
+ if(dpb.fs[i]->poc == concealfrom)
+ {
+ *pos = i;
+ return dpb.fs[i]->frame;
+ }
+ }
+
+ return NULL;
+}
+
+/*!
+************************************************************************
+* \brief
+* Function to sort the POC and find the lowest number in the POC list
+* Compare the integers
+*
+************************************************************************
+*/
+
+int comp(const void *i, const void *j)
+{
+ return *(int *)i - *(int *)j;
+}
+
+/*!
+************************************************************************
+* \brief
+* Initialises a node, allocates memory for the node, and returns
+* a pointer to the new node.
+*
+************************************************************************
+*/
+
+struct concealment_node * init_node( StorablePicture* picture, int missingpoc )
+{
+ struct concealment_node *ptr;
+
+ ptr = (struct concealment_node *) calloc( 1, sizeof(struct concealment_node ) );
+
+ if( ptr == NULL )
+ return (struct concealment_node *) NULL;
+ else {
+ ptr->picture = picture;
+ ptr->missingpocs = missingpoc;
+ ptr->next = NULL;
+ return ptr;
+ }
+}
+
+/*!
+************************************************************************
+* \brief
+* Prints the details of a node
+*
+************************************************************************
+*/
+
+void print_node( struct concealment_node *ptr )
+{
+ printf("Missing POC=%d\n", ptr->missingpocs );
+}
+
+
+/*!
+************************************************************************
+* \brief
+* Prints all nodes from the current address passed to it.
+*
+************************************************************************
+*/
+
+void print_list( struct concealment_node *ptr )
+{
+ while( ptr != NULL )
+ {
+ print_node( ptr );
+ ptr = ptr->next;
+ }
+}
+
+/*!
+************************************************************************
+* \brief
+* Adds a node to the end of the list.
+*
+************************************************************************
+*/
+
+
+void add_node( struct concealment_node *concealment_new )
+{
+ if( concealment_head == NULL )
+ {
+ concealment_end = concealment_head = concealment_new;
+ return;
+ }
+ concealment_end->next = concealment_new;
+ concealment_end = concealment_new;
+}
+
+
+/*!
+************************************************************************
+* \brief
+* Deletes the specified node pointed to by 'ptr' from the list
+*
+************************************************************************
+*/
+
+
+void delete_node( struct concealment_node *ptr )
+{
+ // We only need to delete the first node in the linked list
+ if( ptr == concealment_head ) {
+ concealment_head = concealment_head->next;
+ if( concealment_end == ptr )
+ concealment_end = concealment_end->next;
+ free(ptr);
+ }
+}
+
+/*!
+************************************************************************
+* \brief
+* Deletes all nodes from the place specified by ptr
+*
+************************************************************************
+*/
+
+void delete_list( struct concealment_node *ptr )
+{
+ struct concealment_node *temp;
+
+ if( concealment_head == NULL ) return;
+
+ if( ptr == concealment_head ) {
+ concealment_head = NULL;
+ concealment_end = NULL;
+ }
+ else
+ {
+ temp = concealment_head;
+
+ while( temp->next != ptr )
+ temp = temp->next;
+ concealment_end = temp;
+ }
+
+ while( ptr != NULL ) {
+ temp = ptr->next;
+ free( ptr );
+ ptr = temp;
+ }
+}
+
+/*!
+************************************************************************
+* \brief
+* Stores the missing non reference frames in the concealment buffer. The
+* detection is based on the POC difference in the sorted POC array. A missing
+* non reference frame is detected when the dpb is full. A singly linked list
+* is maintained for storing the missing non reference frames.
+*
+************************************************************************
+*/
+
+void conceal_non_ref_pics(int diff)
+{
+ int missingpoc = 0;
+ unsigned int i, pos;
+ StorablePicture *conceal_from_picture = NULL;
+ StorablePicture *conceal_to_picture = NULL;
+ struct concealment_node *concealment_ptr = NULL;
+ int temp_used_size = dpb.used_size;
+
+ if(dpb.used_size == 0 )
+ return;
+
+ qsort(pocs_in_dpb, dpb.size, sizeof(int), comp);
+
+ for(i=0;i<dpb.size-diff;i++)
+ {
+ dpb.used_size = dpb.size;
+ if((pocs_in_dpb[i+1]-pocs_in_dpb[i])>img->poc_gap)
+ {
+ conceal_to_picture = alloc_storable_picture (FRAME, img->width, img->height, img->width_cr, img->height_cr);
+
+ missingpoc = pocs_in_dpb[i] + img->poc_gap;
+ // Diagnostics
+ // printf("\n missingpoc = %d\n",missingpoc);
+
+ if(missingpoc > img->earlier_missing_poc)
+ {
+ img->earlier_missing_poc = missingpoc;
+ conceal_to_picture->top_poc= missingpoc;
+ conceal_to_picture->bottom_poc=missingpoc;
+ conceal_to_picture->frame_poc=missingpoc;
+ conceal_to_picture->poc=missingpoc;
+ conceal_from_picture = get_pic_from_dpb(missingpoc, &pos);
+
+ assert(conceal_from_picture != NULL);
+
+ dpb.used_size = pos+1;
+
+ img->frame_to_conceal = conceal_from_picture->frame_num + 1;
+
+ update_ref_list_for_concealment();
+ img->conceal_slice_type = B_SLICE;
+ copy_to_conceal(conceal_from_picture, conceal_to_picture, img);
+ concealment_ptr = init_node( conceal_to_picture, missingpoc );
+ add_node(concealment_ptr);
+ // Diagnostics
+ // print_node(concealment_ptr);
+ }
+ }
+ }
+
+ //restore the original value
+ //dpb.used_size = dpb.size;
+ dpb.used_size = temp_used_size;
+}
+
+/*!
+************************************************************************
+* \brief
+* Perform Sliding window decoded reference picture marking process. It
+* maintains the POC s stored in the dpb at a specific instance.
+*
+************************************************************************
+*/
+
+void sliding_window_poc_management(StorablePicture *p)
+{
+ unsigned int i;
+
+ if (dpb.used_size == dpb.size)
+ {
+ for(i=0;i<dpb.size-1; i++)
+ pocs_in_dpb[i] = pocs_in_dpb[i+1];
+ }
+
+// pocs_in_dpb[dpb.used_size-1] = p->poc;
+}
+
+
+/*!
+************************************************************************
+* \brief
+* Outputs the non reference frames. The POCs in the concealment buffer are
+* sorted in ascending order and outputted when the lowest POC in the
+* concealment buffer is lower than the lowest in the dpb. The linked list
+* entry corresponding to the outputted POC is immediately deleted.
+*
+************************************************************************
+*/
+
+void write_lost_non_ref_pic(int poc, int p_out)
+{
+ FrameStore concealment_fs;
+ if(poc > 0)
+ {
+ if((poc - dpb.last_output_poc) > img->poc_gap)
+ {
+
+ concealment_fs.frame = concealment_head->picture;
+ concealment_fs.is_output = 0;
+ concealment_fs.is_reference = 0;
+ concealment_fs.is_used = 3;
+
+ write_stored_frame(&concealment_fs, p_out);
+ delete_node(concealment_head);
+ }
+ }
+}
+
+/*!
+************************************************************************
+* \brief
+* Conceals frame loss immediately after the IDR. This special case produces
+* the same result for either frame copy or motion vector copy concealment.
+*
+************************************************************************
+*/
+
+void write_lost_ref_after_idr(int pos)
+{
+ int temp = 1;
+
+ if(last_out_fs->frame == NULL)
+ {
+ last_out_fs->frame = alloc_storable_picture (FRAME, img->width, img->height,
+ img->width_cr, img->height_cr);
+ last_out_fs->is_used = 3;
+ }
+
+ if(img->conceal_mode == 2)
+ {
+ temp = 2;
+ img->conceal_mode = 1;
+ }
+ copy_to_conceal(dpb.fs[pos]->frame, last_out_fs->frame, img);
+
+ img->conceal_mode = temp;
+}
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/erc_globals.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/erc_globals.h:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/erc_globals.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,52 @@
+
+/*!
+ ************************************************************************
+ * \file erc_globals.h
+ *
+ * \brief
+ * global header file for error concealment module
+ *
+ * \author
+ * - Viktor Varsa <viktor.varsa at nokia.com>
+ * - Ye-Kui Wang <wyk at ieee.org>
+ ************************************************************************
+ */
+
+#ifndef _ERC_GLOBALS_H_
+#define _ERC_GLOBALS_H_
+
+#include <string.h>
+#include "defines.h"
+
+/* "block" means an 8x8 pixel area */
+
+/* Region modes */
+#define REGMODE_INTER_COPY 0 //!< Copy region
+#define REGMODE_INTER_PRED 1 //!< Inter region with motion vectors
+#define REGMODE_INTRA 2 //!< Intra region
+#define REGMODE_SPLITTED 3 //!< Any region mode higher than this indicates that the region
+ //!< is splitted which means 8x8 block
+#define REGMODE_INTER_COPY_8x8 4
+#define REGMODE_INTER_PRED_8x8 5
+#define REGMODE_INTRA_8x8 6
+
+//! YUV pixel domain image arrays for a video frame
+typedef struct
+{
+ imgpel *yptr;
+ imgpel *uptr;
+ imgpel *vptr;
+} frame;
+
+//! region structure stores information about a region that is needed for concealment
+typedef struct
+{
+ byte regionMode; //!< region mode as above
+ int xMin; //!< X coordinate of the pixel position of the top-left corner of the region
+ int yMin; //!< Y coordinate of the pixel position of the top-left corner of the region
+ int mv[3]; //!< motion vectors in 1/4 pixel units: mvx = mv[0], mvy = mv[1],
+ //!< and ref_frame = mv[2]
+} objectBuffer_t;
+
+#endif
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/errorconcealment.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/errorconcealment.c:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/errorconcealment.c Sun Feb 4 08:38:31 2007
@@ -0,0 +1,242 @@
+
+/*!
+ ***********************************************************************
+ * \file errorconcealment.c
+ *
+ * \brief
+ * Implements error concealment scheme for H.264 decoder
+ *
+ * \date
+ * 6.10.2000
+ *
+ * \version
+ * 1.0
+ *
+ * \note
+ * This simple error concealment implemented in this decoder uses
+ * the existing dependencies of syntax elements.
+ * In case that an element is detected as false this elements and all
+ * dependend elements are marked as elements to conceal in the ec_flag[]
+ * array. If the decoder requests a new element by the function
+ * readSyntaxElement_xxxx() this array is checked first if an error concealment has
+ * to be applied on this element.
+ * In case that an error occured a concealed element is given to the
+ * decoding function in macroblock().
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Sebastian Purreiter <sebastian.purreiter at mch.siemens.de>
+ ***********************************************************************
+ */
+
+#include "contributors.h"
+#include "global.h"
+#include "elements.h"
+
+static int ec_flag[SE_MAX_ELEMENTS]; //!< array to set errorconcealment
+/*
+static char SEtypes[][25] =
+{
+ "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"
+};
+*/
+
+/*!
+ ***********************************************************************
+ * \brief
+ * set concealment for all elements in same partition
+ * and dependend syntax elements
+ * \return
+ * EC_REQ, elements of same type or depending type need error concealment. \n
+ * EX_SYNC sync on next header
+ ***********************************************************************
+ */
+int set_ec_flag(
+ int se) //!< type of syntax element to conceal
+{
+
+ /*
+ if (ec_flag[se] == NO_EC)
+ printf("Error concealment on element %s\n",SEtypes[se]);
+ */
+ switch (se)
+ {
+ case SE_HEADER :
+ ec_flag[SE_HEADER] = EC_REQ;
+ case SE_PTYPE :
+ ec_flag[SE_PTYPE] = EC_REQ;
+ case SE_MBTYPE :
+ ec_flag[SE_MBTYPE] = EC_REQ;
+
+ case SE_REFFRAME :
+ ec_flag[SE_REFFRAME] = EC_REQ;
+ ec_flag[SE_MVD] = EC_REQ; // set all motion vectors to zero length
+ se = SE_CBP_INTER; // conceal also Inter texture elements
+ break;
+
+ case SE_INTRAPREDMODE :
+ ec_flag[SE_INTRAPREDMODE] = EC_REQ;
+ se = SE_CBP_INTRA; // conceal also Intra texture elements
+ break;
+ case SE_MVD :
+ ec_flag[SE_MVD] = EC_REQ;
+ se = SE_CBP_INTER; // conceal also Inter texture elements
+ break;
+
+ default:
+ break;
+ }
+
+ switch (se)
+ {
+ case SE_CBP_INTRA :
+ ec_flag[SE_CBP_INTRA] = EC_REQ;
+ case SE_LUM_DC_INTRA :
+ ec_flag[SE_LUM_DC_INTRA] = EC_REQ;
+ case SE_CHR_DC_INTRA :
+ ec_flag[SE_CHR_DC_INTRA] = EC_REQ;
+ case SE_LUM_AC_INTRA :
+ ec_flag[SE_LUM_AC_INTRA] = EC_REQ;
+ case SE_CHR_AC_INTRA :
+ ec_flag[SE_CHR_AC_INTRA] = EC_REQ;
+ break;
+
+ case SE_CBP_INTER :
+ ec_flag[SE_CBP_INTER] = EC_REQ;
+ case SE_LUM_DC_INTER :
+ ec_flag[SE_LUM_DC_INTER] = EC_REQ;
+ case SE_CHR_DC_INTER :
+ ec_flag[SE_CHR_DC_INTER] = EC_REQ;
+ case SE_LUM_AC_INTER :
+ ec_flag[SE_LUM_AC_INTER] = EC_REQ;
+ case SE_CHR_AC_INTER :
+ ec_flag[SE_CHR_AC_INTER] = EC_REQ;
+ break;
+ case SE_DELTA_QUANT_INTER :
+ ec_flag[SE_DELTA_QUANT_INTER] = EC_REQ;
+ break;
+ case SE_DELTA_QUANT_INTRA :
+ ec_flag[SE_DELTA_QUANT_INTRA] = EC_REQ;
+ break;
+ default:
+ break;
+
+ }
+ return EC_REQ;
+}
+
+/*!
+ ***********************************************************************
+ * \brief
+ * resets EC_Flags called at the start of each slice
+ *
+ ***********************************************************************
+ */
+void reset_ec_flags()
+{
+ int i;
+ for (i=0; i<SE_MAX_ELEMENTS; i++)
+ ec_flag[i] = NO_EC;
+}
+
+
+/*!
+ ***********************************************************************
+ * \brief
+ * get error concealed element in dependence of syntax
+ * element se. \n
+ * This function implements the error concealment.
+ * \return
+ * NO_EC if no error concealment required \n
+ * EC_REQ if element requires error concealment
+ ***********************************************************************
+ */
+int get_concealed_element(SyntaxElement *sym)
+{
+ if (ec_flag[sym->type] == NO_EC)
+ return NO_EC;
+/*
+#if TRACE
+ printf("TRACE: get concealed element for %s!!!\n", SEtypes[sym->type]);
+#endif
+*/
+ switch (sym->type)
+ {
+ case SE_HEADER :
+ sym->len = 31;
+ sym->inf = 0; // Picture Header
+ break;
+
+ case SE_PTYPE : // inter_img_1
+ case SE_MBTYPE : // set COPY_MB
+ case SE_REFFRAME :
+ sym->len = 1;
+ sym->inf = 0;
+ break;
+
+ case SE_INTRAPREDMODE :
+ case SE_MVD :
+ sym->len = 1;
+ sym->inf = 0; // set vector to zero length
+ break;
+
+ case SE_CBP_INTRA :
+ sym->len = 5;
+ sym->inf = 0; // codenumber 3 <=> no CBP information for INTRA images
+ break;
+
+ case SE_LUM_DC_INTRA :
+ case SE_CHR_DC_INTRA :
+ case SE_LUM_AC_INTRA :
+ case SE_CHR_AC_INTRA :
+ sym->len = 1;
+ sym->inf = 0; // return EOB
+ break;
+
+ case SE_CBP_INTER :
+ sym->len = 1;
+ sym->inf = 0; // codenumber 1 <=> no CBP information for INTER images
+ break;
+
+ case SE_LUM_DC_INTER :
+ case SE_CHR_DC_INTER :
+ case SE_LUM_AC_INTER :
+ case SE_CHR_AC_INTER :
+ sym->len = 1;
+ sym->inf = 0; // return EOB
+ break;
+
+ case SE_DELTA_QUANT_INTER:
+ sym->len = 1;
+ sym->inf = 0;
+ break;
+ case SE_DELTA_QUANT_INTRA:
+ sym->len = 1;
+ sym->inf = 0;
+ break;
+ default:
+ break;
+ }
+
+ return EC_REQ;
+}
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/errorconcealment.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/errorconcealment.h:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/errorconcealment.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,21 @@
+
+
+/*!
+ ****************************************************************************
+ * \file errorconcealment.h
+ *
+ * \brief
+ * Header file for errorconcealment.c
+ *
+ ****************************************************************************
+ */
+
+#ifndef _ERRORCONCEALMENT_H_
+#define _ERRORCONCEALMENT_H_
+
+int set_ec_flag(int se);
+void reset_ec_flags();
+int get_concealed_element(SyntaxElement *sym);
+
+#endif
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/filehandle.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/filehandle.c:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/filehandle.c Sun Feb 4 08:38:31 2007
@@ -0,0 +1,165 @@
+
+/*!
+ **************************************************************************************
+ * \file
+ * filehandle.c
+ * \brief
+ * Trace file handling and standard error handling function.
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Karsten Suehring <suehring at hhi.de>
+ ***************************************************************************************
+ */
+
+#include <stdlib.h>
+
+#include "contributors.h"
+#include "global.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);
+}
+
+#if TRACE
+
+static int bitcounter = 0;
+
+/*!
+ ************************************************************************
+ * \brief
+ * Tracing bitpatterns for symbols
+ * A code word has the following format: 0 Xn...0 X2 0 X1 0 X0 1
+ ************************************************************************
+ */
+void tracebits(
+ const char *trace_str, //!< tracing information, char array describing the symbol
+ int len, //!< length of syntax element in bits
+ int info, //!< infoword of syntax element
+ int value1)
+{
+
+ int i, chars;
+ // int outint = 1;
+
+
+ if(len>=34)
+ {
+ snprintf(errortext, ET_SIZE, "Length argument to put too long for trace to work");
+ error (errortext, 600);
+ }
+
+ putc('@', p_trace);
+ chars = fprintf(p_trace, "%i", bitcounter);
+ while(chars++ < 5)
+ putc(' ',p_trace);
+
+ chars += fprintf(p_trace, " %s", trace_str);
+ while(chars++ < 55)
+ putc(' ',p_trace);
+
+ // Align bitpattern
+ if(len<15)
+ {
+ for(i=0 ; i<15-len ; i++)
+ fputc(' ', p_trace);
+ }
+
+ // Print bitpattern
+ for(i=0 ; i<len/2 ; i++)
+ {
+ fputc('0', p_trace);
+ }
+ // put 1
+ fprintf(p_trace, "1");
+
+ // Print bitpattern
+ for(i=0 ; i<len/2 ; i++)
+ {
+ if (0x01 & ( info >> ((len/2-i)-1)))
+ fputc('1', p_trace);
+ else
+ fputc('0', p_trace);
+ }
+
+ fprintf(p_trace, " (%3d) \n", value1);
+ bitcounter += len;
+
+ fflush (p_trace);
+
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Tracing bitpatterns
+ ************************************************************************
+ */
+void tracebits2(
+ const char *trace_str, //!< tracing information, char array describing the symbol
+ int len, //!< length of syntax element in bits
+ int info)
+{
+
+ int i, chars;
+ // int outint = 1;
+
+ if(len>=45)
+ {
+ snprintf(errortext, ET_SIZE, "Length argument to put too long for trace to work");
+ error (errortext, 600);
+ }
+
+ putc('@', p_trace);
+ chars = fprintf(p_trace, "%i", bitcounter);
+ while(chars++ < 5)
+ putc(' ',p_trace);
+ chars += fprintf(p_trace, " %s", trace_str);
+ while(chars++ < 55)
+ putc(' ',p_trace);
+
+ // Align bitpattern
+ if(len<15)
+ for(i=0 ; i<15-len ; i++)
+ fputc(' ', p_trace);
+
+
+ bitcounter += len;
+ while (len >= 32)
+ {
+ for(i=0 ; i<8 ; i++)
+ {
+ fputc('0', p_trace);
+ }
+ len -= 8;
+
+ }
+ // Print bitpattern
+ for(i=0 ; i<len ; i++)
+ {
+ if (0x01 & ( info >> (len-i-1)))
+ fputc('1', p_trace);
+ else
+ fputc('0', p_trace);
+ }
+
+ fprintf(p_trace, " (%3d) \n", info);
+
+ fflush (p_trace);
+}
+#endif
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/fmo.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/fmo.c:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/fmo.c Sun Feb 4 08:38:31 2007
@@ -0,0 +1,551 @@
+
+/*!
+ *****************************************************************************
+ *
+ * \file fmo.c
+ *
+ * \brief
+ * Support for Flexible Macroblock Ordering (FMO)
+ *
+ * \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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+
+#include "global.h"
+#include "elements.h"
+#include "defines.h"
+#include "header.h"
+#include "fmo.h"
+
+//#define PRINT_FMO_MAPS
+
+int *MbToSliceGroupMap = NULL;
+int *MapUnitToSliceGroupMap = NULL;
+
+static int NumberOfSliceGroups; // the number of slice groups -1 (0 == scan order, 7 == maximum)
+
+static void FmoGenerateType0MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
+static void FmoGenerateType1MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
+static void FmoGenerateType2MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
+static void FmoGenerateType3MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
+static void FmoGenerateType4MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
+static void FmoGenerateType5MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
+static void FmoGenerateType6MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits );
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Generates MapUnitToSliceGroupMap
+ * Has to be called every time a new Picture Parameter Set is used
+ *
+ * \param pps
+ * Picture Parameter set to be used for map generation
+ * \param sps
+ * Sequence Parameter set to be used for map generation
+ *
+ ************************************************************************
+ */
+static int FmoGenerateMapUnitToSliceGroupMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps)
+{
+ unsigned int NumSliceGroupMapUnits;
+
+ NumSliceGroupMapUnits = (sps->pic_height_in_map_units_minus1+1)* (sps->pic_width_in_mbs_minus1+1);
+
+ if (pps->slice_group_map_type == 6)
+ {
+ if ((pps->num_slice_group_map_units_minus1+1) != NumSliceGroupMapUnits)
+ {
+ error ("wrong pps->num_slice_group_map_units_minus1 for used SPS and FMO type 6", 500);
+ }
+ }
+
+ // allocate memory for MapUnitToSliceGroupMap
+ if (MapUnitToSliceGroupMap)
+ free (MapUnitToSliceGroupMap);
+ if ((MapUnitToSliceGroupMap = malloc ((NumSliceGroupMapUnits) * sizeof (int))) == NULL)
+ {
+ printf ("cannot allocated %d bytes for MapUnitToSliceGroupMap, exit\n", (int) ( (pps->num_slice_group_map_units_minus1+1) * sizeof (int)));
+ exit (-1);
+ }
+
+ if (pps->num_slice_groups_minus1 == 0) // only one slice group
+ {
+ memset (MapUnitToSliceGroupMap, 0, NumSliceGroupMapUnits * sizeof (int));
+ return 0;
+ }
+
+ switch (pps->slice_group_map_type)
+ {
+ case 0:
+ FmoGenerateType0MapUnitMap (pps, sps, NumSliceGroupMapUnits);
+ break;
+ case 1:
+ FmoGenerateType1MapUnitMap (pps, sps, NumSliceGroupMapUnits);
+ break;
+ case 2:
+ FmoGenerateType2MapUnitMap (pps, sps, NumSliceGroupMapUnits);
+ break;
+ case 3:
+ FmoGenerateType3MapUnitMap (pps, sps, NumSliceGroupMapUnits);
+ break;
+ case 4:
+ FmoGenerateType4MapUnitMap (pps, sps, NumSliceGroupMapUnits);
+ break;
+ case 5:
+ FmoGenerateType5MapUnitMap (pps, sps, NumSliceGroupMapUnits);
+ break;
+ case 6:
+ FmoGenerateType6MapUnitMap (pps, sps, NumSliceGroupMapUnits);
+ break;
+ default:
+ printf ("Illegal slice_group_map_type %d , exit \n", pps->slice_group_map_type);
+ exit (-1);
+ }
+ return 0;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Generates MbToSliceGroupMap from MapUnitToSliceGroupMap
+ *
+ * \param pps
+ * Picture Parameter set to be used for map generation
+ * \param sps
+ * Sequence Parameter set to be used for map generation
+ *
+ ************************************************************************
+ */
+static int FmoGenerateMbToSliceGroupMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps)
+{
+ unsigned i;
+
+ // allocate memory for MbToSliceGroupMap
+ if (MbToSliceGroupMap)
+ free (MbToSliceGroupMap);
+
+ if ((MbToSliceGroupMap = malloc ((img->PicSizeInMbs) * sizeof (int))) == NULL)
+ {
+ printf ("cannot allocate %d bytes for MbToSliceGroupMap, exit\n", (int) ((img->PicSizeInMbs) * sizeof (int)));
+ exit (-1);
+ }
+
+
+ if ((sps->frame_mbs_only_flag)|| img->field_pic_flag)
+ {
+ for (i=0; i<img->PicSizeInMbs; i++)
+ {
+ MbToSliceGroupMap[i] = MapUnitToSliceGroupMap[i];
+ }
+ }
+ else
+ if (sps->mb_adaptive_frame_field_flag && (!img->field_pic_flag))
+ {
+ for (i=0; i<img->PicSizeInMbs; i++)
+ {
+ MbToSliceGroupMap[i] = MapUnitToSliceGroupMap[i/2];
+ }
+ }
+ else
+ {
+ for (i=0; i<img->PicSizeInMbs; i++)
+ {
+ MbToSliceGroupMap[i] = MapUnitToSliceGroupMap[(i/(2*img->PicWidthInMbs))*img->PicWidthInMbs+(i%img->PicWidthInMbs)];
+ }
+ }
+ return 0;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * FMO initialization: Generates MapUnitToSliceGroupMap and MbToSliceGroupMap.
+ *
+ * \param pps
+ * Picture Parameter set to be used for map generation
+ * \param sps
+ * Sequence Parameter set to be used for map generation
+ ************************************************************************
+ */
+int FmoInit(pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps)
+{
+#ifdef PRINT_FMO_MAPS
+ unsigned i,j;
+#endif
+
+ FmoGenerateMapUnitToSliceGroupMap(pps, sps);
+ FmoGenerateMbToSliceGroupMap(pps, sps);
+
+ NumberOfSliceGroups = pps->num_slice_groups_minus1+1;
+
+#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("%c",48+MapUnitToSliceGroupMap[i+j*img->PicWidthInMbs]);
+ }
+ printf("\n");
+ }
+ printf("\n");
+ printf("FMO Map (Mb):\n");
+
+ for (j=0; j<img->PicHeightInMbs; j++)
+ {
+ for (i=0; i<img->PicWidthInMbs; i++)
+ {
+ printf("%c",48+MbToSliceGroupMap[i+j*img->PicWidthInMbs]);
+ }
+ printf("\n");
+ }
+ printf("\n");
+
+#endif
+
+ return 0;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Free memory allocated by FMO functions
+ ************************************************************************
+ */
+int FmoFinit()
+{
+ if (MbToSliceGroupMap)
+ {
+ free (MbToSliceGroupMap);
+ MbToSliceGroupMap = NULL;
+ }
+ if (MapUnitToSliceGroupMap)
+ {
+ free (MapUnitToSliceGroupMap);
+ MapUnitToSliceGroupMap = NULL;
+ }
+ return 0;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * FmoGetNumberOfSliceGroup()
+ *
+ * \par Input:
+ * None
+ ************************************************************************
+ */
+int FmoGetNumberOfSliceGroup()
+{
+ return NumberOfSliceGroups;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * FmoGetLastMBOfPicture()
+ * returns the macroblock number of the last MB in a picture. This
+ * mb happens to be the last macroblock of the picture if there is only
+ * one slice group
+ *
+ * \par Input:
+ * None
+ ************************************************************************
+ */
+int FmoGetLastMBOfPicture()
+{
+ return FmoGetLastMBInSliceGroup (FmoGetNumberOfSliceGroup()-1);
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * FmoGetLastMBInSliceGroup: Returns MB number of last MB in SG
+ *
+ * \par Input:
+ * SliceGroupID (0 to 7)
+ ************************************************************************
+ */
+
+int FmoGetLastMBInSliceGroup (int SliceGroup)
+{
+ int i;
+
+ for (i=img->PicSizeInMbs-1; i>=0; i--)
+ if (FmoGetSliceGroupId (i) == SliceGroup)
+ return i;
+ return -1;
+
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Returns SliceGroupID for a given MB
+ *
+ * \param mb
+ * Macroblock number (in scan order)
+ ************************************************************************
+ */
+int FmoGetSliceGroupId (int mb)
+{
+ assert (mb < (int)img->PicSizeInMbs);
+ assert (MbToSliceGroupMap != NULL);
+ return MbToSliceGroupMap[mb];
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * FmoGetNextMBBr: Returns the MB-Nr (in scan order) of the next
+ * MB in the (scattered) Slice, -1 if the slice is finished
+ *
+ * \param CurrentMbNr
+ * number of the current macroblock
+ ************************************************************************
+ */
+int FmoGetNextMBNr (int CurrentMbNr)
+{
+ int SliceGroup = FmoGetSliceGroupId (CurrentMbNr);
+
+ while (++CurrentMbNr<(int)img->PicSizeInMbs && MbToSliceGroupMap [CurrentMbNr] != SliceGroup)
+ ;
+
+ if (CurrentMbNr >= (int)img->PicSizeInMbs)
+ return -1; // No further MB in this slice (could be end of picture)
+ else
+ return CurrentMbNr;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Generate interleaved slice group map type MapUnit map (type 0)
+ *
+ ************************************************************************
+ */
+static void FmoGenerateType0MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
+{
+ 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)
+ *
+ ************************************************************************
+ */
+static void FmoGenerateType1MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
+{
+ 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)
+ *
+ ************************************************************************
+ */
+static void FmoGenerateType2MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
+{
+ 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)
+ *
+ ************************************************************************
+ */
+static void FmoGenerateType3MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
+{
+ unsigned i, k;
+ int leftBound, topBound, rightBound, bottomBound;
+ int x, y, xDir, yDir;
+ int mapUnitVacant;
+
+ unsigned mapUnitsInSliceGroup0 = imin((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 = imax( leftBound - 1, 0 );
+ x = leftBound;
+ xDir = 0;
+ yDir = 2 * pps->slice_group_change_direction_flag - 1;
+ }
+ else
+ if( xDir == 1 && x == rightBound )
+ {
+ rightBound = imin( 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 = imax( topBound - 1, 0 );
+ y = topBound;
+ xDir = 1 - 2 * pps->slice_group_change_direction_flag;
+ yDir = 0;
+ }
+ else
+ if( yDir == 1 && y == bottomBound )
+ {
+ bottomBound = imin( 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)
+ *
+ ************************************************************************
+ */
+static void FmoGenerateType4MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
+{
+
+ unsigned mapUnitsInSliceGroup0 = imin((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)
+ *
+ ************************************************************************
+ */
+static void FmoGenerateType5MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
+{
+
+ unsigned mapUnitsInSliceGroup0 = imin((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 ] = pps->slice_group_change_direction_flag;
+ else
+ MapUnitToSliceGroupMap[ i * img->PicWidthInMbs + j ] = 1 - pps->slice_group_change_direction_flag;
+
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Generate explicit slice group map type MapUnit map (type 6)
+ *
+ ************************************************************************
+ */
+static void FmoGenerateType6MapUnitMap (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps, unsigned PicSizeInMapUnits )
+{
+ unsigned i;
+ for (i=0; i<PicSizeInMapUnits; i++)
+ {
+ MapUnitToSliceGroupMap[i] = pps->slice_group_id[i];
+ }
+}
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/fmo.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/fmo.h:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/fmo.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,30 @@
+
+/*!
+ ***************************************************************************
+ *
+ * \file fmo.h
+ *
+ * \brief
+ * Support for Flexilble Macroblock Ordering (FMO)
+ *
+ * \date
+ * 19 June, 2002
+ *
+ * \author
+ * Stephan Wenger stewe at cs.tu-berlin.de
+ **************************************************************************/
+
+#ifndef _FMO_H_
+#define _FMO_H_
+
+
+int FmoInit (pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps);
+int FmoFinit ();
+
+int FmoGetNumberOfSliceGroup();
+int FmoGetLastMBOfPicture();
+int FmoGetLastMBInSliceGroup(int SliceGroup);
+int FmoGetSliceGroupId (int mb);
+int FmoGetNextMBNr (int CurrentMbNr);
+
+#endif
Index: llvm-test/MultiSource/Applications/JM/ldecod/global.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/global.h:1.4
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/global.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,804 @@
+
+/*!
+ ************************************************************************
+ * \file
+ * global.h
+ * \brief
+ * global definitions for H.264 decoder.
+ * \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 <stdarg.h>
+
+#include <time.h>
+#include <sys/timeb.h>
+#include "win32.h"
+#include "defines.h"
+#include "ifunctions.h"
+#include "parsetcommon.h"
+
+
+typedef unsigned char byte; //!< 8 bit unsigned
+typedef unsigned short imgpel; //!< Pixel type definition (16 bit for FRExt)
+//typedef unsigned char imgpel; //!< Pixel type definition (8 bit without FRExt)
+
+pic_parameter_set_rbsp_t *active_pps;
+seq_parameter_set_rbsp_t *active_sps;
+
+// global picture format dependent buffers, memory allocation in decod.c
+imgpel **imgY_ref; //!< reference frame find snr
+imgpel ***imgUV_ref;
+
+int **PicPos;
+int ReMapRef[20];
+// B pictures
+int Bframe_ctr;
+int frame_no;
+
+int g_nFrame;
+
+// For MB level frame/field coding
+int TopFieldForSkip_Y[16][16];
+int TopFieldForSkip_UV[2][16][16];
+
+int InvLevelScale4x4Luma_Intra[6][4][4];
+int InvLevelScale4x4Chroma_Intra[2][6][4][4];
+
+int InvLevelScale4x4Luma_Inter[6][4][4];
+int InvLevelScale4x4Chroma_Inter[2][6][4][4];
+
+int InvLevelScale8x8Luma_Intra[6][8][8];
+
+int InvLevelScale8x8Luma_Inter[6][8][8];
+
+int *qmatrix[8];
+
+#define ET_SIZE 300 //!< size of error text buffer
+char errortext[ET_SIZE]; //!< buffer for error message for exit with error()
+
+/***********************************************************************
+ * T y p e d e f i n i t i o n s f o r T M L
+ ***********************************************************************
+ */
+
+//! 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, //!< Current TML description
+ PAR_OF_RTP //!< RTP Packet Output format
+} PAR_OF_TYPE;
+
+
+//! 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, this MUST be the last one!
+} SE_type; // substituting the definitions in element.h
+
+
+typedef enum {
+ INTER_MB,
+ INTRA_MB_4x4,
+ INTRA_MB_16x16
+} IntraInterDecision;
+
+typedef enum {
+ BITS_TOTAL_MB,
+ BITS_HEADER_MB,
+ BITS_INTER_MB,
+ BITS_CBP_MB,
+ BITS_COEFF_Y_MB,
+ BITS_COEFF_UV_MB,
+ MAX_BITCOUNTER_MB
+} BitCountType;
+
+typedef enum {
+ NO_SLICES,
+ FIXED_MB,
+ FIXED_RATE,
+ CALLBACK,
+ FMO
+} SliceMode;
+
+
+typedef enum {
+ UVLC,
+ CABAC
+} SymbolMode;
+
+typedef enum {
+ LIST_0=0,
+ LIST_1=1
+} Lists;
+
+
+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;
+
+typedef enum
+{
+ IS_LUMA = 0,
+ IS_CHROMA = 1
+} Component_Type;
+
+
+/***********************************************************************
+ * 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 Dlow, Drange;
+ unsigned int Dvalue;
+ unsigned int Dbuffer;
+ int Dbits_to_go;
+ byte *Dcodestrm;
+ int *Dcodestrm_len;
+} DecodingEnvironment;
+
+typedef DecodingEnvironment *DecodingEnvironmentPtr;
+
+//! struct for context management
+typedef struct
+{
+ unsigned short state; // index into state-table CP
+ unsigned char MPS; // Least Probable Symbol 0/1 CP
+} 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 [4][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 *******************
+
+/***********************************************************************
+ * N e w D a t a t y p e s f o r T M L
+ ***********************************************************************
+ */
+
+struct img_par;
+struct inp_par;
+struct stat_par;
+
+/*! 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 UVLC to syntaxElement
+ void (*mapping)(int len, int info, int *value1, int *value2);
+ //! used for CABAC: refers to actual coding method of each individual syntax element type
+ void (*reading)(struct syntaxelement *, struct img_par *, DecodingEnvironmentPtr);
+
+} SyntaxElement;
+
+//! Macroblock
+typedef struct macroblock
+{
+ int qp; //!< QP luma
+ int qpc[2]; //!< QP chroma
+
+ int slice_nr;
+ int delta_quant; //!< for rate control
+
+ struct macroblock *mb_available_up; //!< pointer to neighboring MB (CABAC)
+ struct macroblock *mb_available_left; //!< pointer to neighboring MB (CABAC)
+
+ // some storage of macroblock syntax elements for global access
+ int mb_type;
+ int mvd[2][BLOCK_MULTIPLE][BLOCK_MULTIPLE][2]; //!< indices correspond to [forw,backw][block_y][block_x][x,y]
+ int cbp;
+ int64 cbp_blk ;
+ int64 cbp_bits;
+
+ int is_skip;
+
+ int i16mode;
+ char b8mode[4];
+ char b8pdir[4];
+ int ei_flag;
+
+ int LFDisableIdc;
+ int LFAlphaC0Offset;
+ int LFBetaOffset;
+
+ int c_ipred_mode; //!< chroma intra prediction mode
+ int mb_field;
+
+ int skip_flag;
+
+ int mbAddrA, mbAddrB, mbAddrC, mbAddrD;
+ int mbAvailA, mbAvailB, mbAvailC, mbAvailD;
+
+ int luma_transform_size_8x8_flag;
+ int NoMbPartLessThan8x8Flag;
+} Macroblock;
+
+//! Bitstream
+typedef struct
+{
+ // CABAC Decoding
+ int read_len; //!< actual position in the codebuffer, CABAC only
+ int code_len; //!< overall codebuffer length, CABAC only
+ // UVLC Decoding
+ int frame_bitoffset; //!< actual position in the codebuffer, bit-oriented, UVLC only
+ int bitstream_length; //!< over codebuffer lnegth, byte oriented, UVLC only
+ // ErrorConcealment
+ byte *streamBuffer; //!< actual codebuffer for read bytes
+ int ei_flag; //!< error indication, 0: no error, else unspecified error
+} Bitstream;
+
+//! DataPartition
+typedef struct datapartition
+{
+
+ Bitstream *bitstream;
+ DecodingEnvironment de_cabac;
+
+ int (*readSyntaxElement)(SyntaxElement *, struct img_par *, struct datapartition *);
+ /*!< virtual function;
+ actual method depends on chosen data partition and
+ entropy coding method */
+} DataPartition;
+
+//! Slice
+typedef struct
+{
+ int ei_flag; //!< 0 if the partArr[0] contains valid information
+ int qp;
+ int slice_qp_delta;
+ int picture_type; //!< picture type
+ PictureStructure structure; //!< Identify picture structure type
+ int start_mb_nr; //!< MUST be set by NAL even in case of ei_flag == 1
+ int max_part_nr;
+ int dp_mode; //!< data partioning mode
+ int next_header;
+// int last_mb_nr; //!< only valid when entropy coding == CABAC
+ 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
+
+ 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;
+
+ int (*readSlice)(struct img_par *, struct inp_par *);
+
+ int LFDisableIdc; //!< Disable loop filter on slice
+ int LFAlphaC0Offset; //!< Alpha and C0 offset for filtering slice
+ int LFBetaOffset; //!< Beta offset for filtering slice
+
+ int pic_parameter_set_id; //!<the ID of the picture parameter set the slice is reffering to
+
+} Slice;
+
+//****************************** ~DM ***********************************
+
+// image parameters
+typedef struct img_par
+{
+ int number; //!< frame number
+ unsigned int current_mb_nr; // bitstream order
+ unsigned int num_dec_mb;
+ int current_slice_nr;
+ int *intra_block;
+ int tr; //!< temporal reference, 8 bit, wrapps at 255
+ int qp; //!< quant for the current frame
+ int qpsp; //!< quant for SP-picture predicted frame
+ int sp_switch; //!< 1 for switching sp, 0 for normal sp
+ int direct_spatial_mv_pred_flag; //!< 1 for Spatial Direct, 0 for Temporal
+ int type; //!< image type INTER/INTRA
+ int width;
+ int height;
+ int width_cr; //!< width chroma
+ int width_cr_m1; //!< width chroma
+ int height_cr; //!< height chroma
+ int mb_y;
+ int mb_x;
+ int block_y;
+ int pix_y;
+ int pix_x;
+ int pix_c_y;
+ int block_x;
+ int pix_c_x;
+
+ int allrefzero;
+ imgpel mpr[16][16]; //!< predicted block
+ int mvscale[6][MAX_REFERENCE_PICTURES];
+ int m7[16][16]; //!< final 4x4 block. Extended to 16x16 for ABT
+ int cof[4][12][4][4]; //!< correction coefficients from predicted
+ int cofu[16];
+ byte **ipredmode; //!< prediction type [90][74]
+ int *quad;
+ int ***nz_coeff;
+ int **siblock;
+ int cod_counter; //!< Current count of number of skipped macroblocks in a row
+
+ int newframe;
+
+ int structure; //!< Identify picture structure type
+ int pstruct_next_P;
+
+ // B pictures
+ Slice *currentSlice; //!< pointer to current Slice data struct
+ Macroblock *mb_data; //!< array containing all MBs of a whole frame
+ int subblock_x;
+ int subblock_y;
+ int is_intra_block;
+ int is_v_block;
+
+ // For MB level frame/field coding
+ int MbaffFrameFlag;
+
+ // for signalling to the neighbour logic that this is a deblocker call
+ int DeblockCall;
+
+ DecRefPicMarking_t *dec_ref_pic_marking_buffer; //!< stores the memory management control operations
+
+ int num_ref_idx_l0_active; //!< number of forward reference
+ int num_ref_idx_l1_active; //!< number of backward reference
+
+ int slice_group_change_cycle;
+
+ int redundant_pic_cnt;
+
+ int explicit_B_prediction;
+
+ unsigned int pre_frame_num; //!< store the frame_num in the last decoded slice. For detecting gap in frame_num.
+
+ // End JVT-D101
+ // POC200301: from unsigned int to int
+ int toppoc; //poc for this top field // POC200301
+ int bottompoc; //poc of bottom field of frame
+ int framepoc; //poc of this frame // POC200301
+ unsigned int frame_num; //frame_num for this frame
+ unsigned int field_pic_flag;
+ unsigned int bottom_field_flag;
+
+ //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[3];
+
+ // ////////////////////////
+ // for POC mode 0:
+ signed int PrevPicOrderCntMsb;
+ unsigned int PrevPicOrderCntLsb;
+ signed int PicOrderCntMsb;
+
+ // for POC mode 1:
+ unsigned int AbsFrameNum;
+ signed int ExpectedPicOrderCnt, PicOrderCntCycleCnt, FrameNumInPicOrderCntCycle;
+ unsigned int PreviousFrameNum, FrameNumOffset;
+ int ExpectedDeltaPerPicOrderCntCycle;
+ int PreviousPOC, ThisPOC;
+ int PreviousFrameNumOffset;
+ // /////////////////////////
+
+ //weighted prediction
+ unsigned int luma_log2_weight_denom;
+ unsigned int chroma_log2_weight_denom;
+ int ***wp_weight; // weight in [list][index][component] order
+ int ***wp_offset; // offset in [list][index][component] order
+ int ****wbp_weight; //weight in [list][fw_index][bw_index][component] order
+ int wp_round_luma;
+ int wp_round_chroma;
+ unsigned int apply_weights;
+
+ int idr_flag;
+ int nal_reference_idc; //!< nal_reference_idc from NAL unit
+
+ int idr_pic_id;
+
+ int MaxFrameNum;
+
+ unsigned int PicWidthInMbs;
+ unsigned int PicHeightInMapUnits;
+ unsigned int FrameHeightInMbs;
+ unsigned int PicHeightInMbs;
+ unsigned int PicSizeInMbs;
+ unsigned int FrameSizeInMbs;
+ unsigned int oldFrameSizeInMbs;
+
+ int no_output_of_prior_pics_flag;
+ int long_term_reference_flag;
+ int adaptive_ref_pic_buffering_flag;
+
+ int last_has_mmco_5;
+ int last_pic_bottom_field;
+
+ int model_number;
+
+ // Fidelity Range Extensions Stuff
+ int pic_unit_bitsize_on_disk;
+ int bitdepth_luma;
+ int bitdepth_chroma;
+ int bitdepth_luma_qp_scale;
+ int bitdepth_chroma_qp_scale;
+ unsigned int dc_pred_value_luma; //!< luma value for DC prediction (depends on luma pel bit depth)
+ unsigned int dc_pred_value_chroma; //!< chroma value for DC prediction (depends on chroma pel bit depth)
+ int max_imgpel_value; //!< max value that one luma picture element (pixel) can take (depends on pic_unit_bitdepth)
+ int max_imgpel_value_uv; //!< max value that one chroma picture element (pixel) can take (depends on pic_unit_bitdepth)
+ int Transform8x8Mode;
+ int profile_idc;
+ int yuv_format;
+ int lossless_qpprime_flag;
+ int num_blk8x8_uv;
+ int num_cdc_coeff;
+ int mb_cr_size_x;
+ int mb_cr_size_y;
+ int mb_cr_size_x_blk;
+ int mb_cr_size_y_blk;
+ int mb_size[3][2]; //!< component macroblock dimensions
+ int mb_size_blk[3][2]; //!< component macroblock dimensions
+
+ int idr_psnr_number;
+ int psnr_number;
+
+ time_t ltime_start; // for time measurement
+ time_t ltime_end; // for time measurement
+
+#ifdef WIN32
+ struct _timeb tstruct_start;
+ struct _timeb tstruct_end;
+#else
+ struct timeb tstruct_start;
+ struct timeb tstruct_end;
+#endif
+
+ // picture error concealment
+ int last_ref_pic_poc;
+ int ref_poc_gap;
+ int poc_gap;
+ int conceal_mode;
+ int earlier_missing_poc;
+ unsigned int frame_to_conceal;
+ int IDR_concealment_flag;
+ int conceal_slice_type;
+
+ // random access point decoding
+ int recovery_point;
+ int recovery_point_found;
+ int recovery_frame_cnt;
+ int recovery_frame_num;
+ int recovery_poc;
+
+} ImageParameters;
+
+extern ImageParameters *img;
+extern struct snr_par *snr;
+
+// signal to noise ratio parameters
+struct snr_par
+{
+ int frame_ctr;
+ 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_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
+};
+
+time_t tot_time;
+
+// input parameters from configuration file
+struct inp_par
+{
+ char infile[100]; //!< H.264 inputfile
+ char outfile[100]; //!< Decoded YUV 4:2:0 output
+ char reffile[100]; //!< Optional YUV 4:2:0 reference file for SNR measurement
+ int FileFormat; //!< File format of the Input file, PAR_OF_ANNEXB or PAR_OF_RTP
+ int ref_offset;
+ int poc_scale;
+ int write_uv;
+ int silent;
+
+#ifdef _LEAKYBUCKET_
+ unsigned long R_decoder; //!< Decoder Rate in HRD Model
+ unsigned long B_decoder; //!< Decoder Buffer size in HRD model
+ unsigned long F_decoder; //!< Decoder Initial buffer fullness in HRD model
+ char LeakyBucketParamFile[100]; //!< LeakyBucketParamFile
+#endif
+
+ // picture error concealment
+ int conceal_mode;
+ int ref_poc_gap;
+ int poc_gap;
+
+};
+
+extern struct inp_par *input;
+
+typedef struct pix_pos
+{
+ int available;
+ int mb_addr;
+ int x;
+ int y;
+ int pos_x;
+ int pos_y;
+} PixelPos;
+
+typedef struct old_slice_par
+{
+ unsigned field_pic_flag;
+ unsigned bottom_field_flag;
+ unsigned frame_num;
+ int nal_ref_idc;
+ unsigned pic_oder_cnt_lsb;
+ int delta_pic_oder_cnt_bottom;
+ int delta_pic_order_cnt[2];
+ int idr_flag;
+ int idr_pic_id;
+ int pps_id;
+} OldSliceParams;
+
+extern OldSliceParams old_slice;
+
+// files
+int p_out; //!< file descriptor to output YUV file
+//FILE *p_out2; //!< pointer to debug output YUV file
+int p_ref; //!< pointer to input original reference YUV file file
+
+FILE *p_log; //!< SNR file
+
+#if TRACE
+FILE *p_trace;
+#endif
+
+// Redundant slices
+unsigned int previous_frame_num; //!< frame number of previous slice
+int ref_flag[17]; //!< 0: i-th previous frame is incorrect
+ //!< non-zero: i-th previous frame is correct
+int Is_primary_correct; //!< if primary frame is correct, 0: incorrect
+int Is_redundant_correct; //!< if redundant frame is correct, 0:incorrect
+int redundant_slice_ref_idx; //!< reference index of redundant slice
+void Error_tracking(void);
+
+// prototypes
+void init_conf(struct inp_par *inp, char *config_filename);
+void report(struct inp_par *inp, struct img_par *img, struct snr_par *snr);
+void init(struct img_par *img);
+
+void malloc_slice(struct inp_par *inp, struct img_par *img);
+void free_slice(struct inp_par *inp, struct img_par *img);
+
+int decode_one_frame(struct img_par *img,struct inp_par *inp, struct snr_par *snr);
+void init_picture(struct img_par *img, struct inp_par *inp);
+void exit_picture();
+
+int read_new_slice();
+void decode_one_slice(struct img_par *img,struct inp_par *inp);
+
+void start_macroblock(struct img_par *img,int CurrentMBInScanOrder);
+int read_one_macroblock(struct img_par *img,struct inp_par *inp);
+void read_ipred_modes(struct img_par *img,struct inp_par *inp);
+int decode_one_macroblock(struct img_par *img,struct inp_par *inp);
+Boolean exit_macroblock(struct img_par *img,struct inp_par *inp, int eos_bit);
+void decode_ipcm_mb(struct img_par *img);
+
+
+void readMotionInfoFromNAL (struct img_par *img,struct inp_par *inp);
+void readCBPandCoeffsFromNAL(struct img_par *img,struct inp_par *inp);
+void readIPCMcoeffsFromNAL(struct img_par *img, struct inp_par *inp, struct datapartition *dP);
+
+void readLumaCoeff8x8_CABAC (struct img_par *img,struct inp_par *inp, int b8);
+void itrans8x8(struct img_par *img, int ioff, int joff);
+
+void copyblock_sp(struct img_par *img,int block_x,int block_y);
+void itrans_sp_chroma(struct img_par *img,int ll);
+void itrans(struct img_par *img,int ioff,int joff,int i0,int j0, int chroma);
+void itrans_sp(struct img_par *img,int ioff,int joff,int i0,int j0);
+int intrapred(struct img_par *img,int ioff,int joff,int i4,int j4);
+void itrans_2(struct img_par *img);
+int intrapred_luma_16x16(struct img_par *img,int predmode);
+void intrapred_chroma(struct img_par *img, int uv);
+
+// SLICE function pointers
+int (*nal_startcode_follows) (struct img_par*, int );
+
+// NAL functions TML/CABAC bitstream
+int uvlc_startcode_follows(struct img_par *img, int dummy);
+int cabac_startcode_follows(struct img_par *img, int eos_bit);
+void free_Partition(Bitstream *currStream);
+
+// ErrorConcealment
+void reset_ec_flags();
+
+void error(char *text, int code);
+int is_new_picture();
+void init_old_slice();
+
+// dynamic mem allocation
+int init_global_buffers();
+void free_global_buffers();
+
+void frame_postprocessing(struct img_par *img, struct inp_par *inp);
+void field_postprocessing(struct img_par *img, struct inp_par *inp);
+int bottom_field_picture(struct img_par *img,struct inp_par *inp);
+void decode_slice(struct img_par *img,struct inp_par *inp, int current_header);
+
+int RBSPtoSODB(byte *streamBuffer, int last_byte_pos);
+int EBSPtoRBSP(byte *streamBuffer, int end_bytepos, int begin_bytepos);
+
+// For MB level frame/field coding
+void init_super_macroblock(struct img_par *img,struct inp_par *inp);
+void exit_super_macroblock(struct img_par *img,struct inp_par *inp);
+int decode_super_macroblock(struct img_par *img,struct inp_par *inp);
+void decode_one_Copy_topMB(struct img_par *img,struct inp_par *inp);
+
+void SetOneRefMV(struct img_par* img);
+int peekSyntaxElement_UVLC(SyntaxElement *sym, struct img_par *img, struct datapartition *dP);
+
+void fill_wp_params(struct img_par *img);
+
+void reset_wp_params(struct img_par *img);
+
+void FreePartition (DataPartition *dp, int n);
+DataPartition *AllocPartition();
+
+void tracebits2(const char *trace_str, int len, int info);
+
+void init_decoding_engine_IPCM(struct img_par *img);
+void readIPCMBytes_CABAC(SyntaxElement *sym, Bitstream *currStream);
+
+unsigned CeilLog2( unsigned uiVal);
+
+// For Q-matrix
+void AssignQuantParam(pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps);
+void CalculateQuantParam(void);
+void CalculateQuant8Param(void);
+
+#endif
+
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/header.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/header.c:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/header.c Sun Feb 4 08:38:31 2007
@@ -0,0 +1,802 @@
+
+/*!
+ *************************************************************************************
+ * \file header.c
+ *
+ * \brief
+ * H.264 Slice headers
+ *
+ *************************************************************************************
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "global.h"
+#include "elements.h"
+#include "defines.h"
+#include "fmo.h"
+#include "vlc.h"
+#include "mbuffer.h"
+#include "header.h"
+
+#include "ctx_tables.h"
+
+extern StorablePicture *dec_picture;
+
+#if TRACE
+#define SYMTRACESTRING(s) strncpy(sym.tracestring,s,TRACESTRING_SIZE)
+#else
+#define SYMTRACESTRING(s) // to nothing
+#endif
+
+extern int UsedBits;
+
+static void ref_pic_list_reordering();
+static void pred_weight_table();
+
+
+/*!
+ ************************************************************************
+ * \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
+ * read the first part of the header (only the pic_parameter_set_id)
+ * \return
+ * Length of the first part of the slice header (in bits)
+ ************************************************************************
+ */
+int FirstPartOfSliceHeader()
+{
+ Slice *currSlice = img->currentSlice;
+ int dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER];
+ DataPartition *partition = &(currSlice->partArr[dP_nr]);
+ Bitstream *currStream = partition->bitstream;
+ int tmp;
+
+ UsedBits= partition->bitstream->frame_bitoffset; // was hardcoded to 31 for previous start-code. This is better.
+
+ // Get first_mb_in_slice
+ currSlice->start_mb_nr = ue_v ("SH: first_mb_in_slice", currStream);
+
+ tmp = ue_v ("SH: slice_type", currStream);
+
+ if (tmp>4) tmp -=5;
+
+ img->type = currSlice->picture_type = (SliceType) tmp;
+
+ currSlice->pic_parameter_set_id = ue_v ("SH: pic_parameter_set_id", currStream);
+
+ return UsedBits;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * read the scond part of the header (without the pic_parameter_set_id
+ * \return
+ * Length of the second part of the Slice header in bits
+ ************************************************************************
+ */
+int RestOfSliceHeader()
+{
+ Slice *currSlice = img->currentSlice;
+ int dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER];
+ DataPartition *partition = &(currSlice->partArr[dP_nr]);
+ Bitstream *currStream = partition->bitstream;
+
+ int val, len;
+
+ img->frame_num = u_v (active_sps->log2_max_frame_num_minus4 + 4, "SH: frame_num", currStream);
+
+ /* Tian Dong: frame_num gap processing, if found */
+ if (img->idr_flag)
+ {
+ img->pre_frame_num = img->frame_num;
+ // picture error concealment
+ img->last_ref_pic_poc = 0;
+ assert(img->frame_num == 0);
+ }
+
+ if (active_sps->frame_mbs_only_flag)
+ {
+ img->structure = FRAME;
+ img->field_pic_flag=0;
+ }
+ else
+ {
+ // field_pic_flag u(1)
+ img->field_pic_flag = u_1("SH: field_pic_flag", currStream);
+ if (img->field_pic_flag)
+ {
+ // bottom_field_flag u(1)
+ img->bottom_field_flag = u_1("SH: bottom_field_flag", currStream);
+
+ img->structure = img->bottom_field_flag ? BOTTOM_FIELD : TOP_FIELD;
+ }
+ else
+ {
+ img->structure = FRAME;
+ img->bottom_field_flag=0;
+ }
+ }
+
+ currSlice->structure = (PictureStructure) img->structure;
+
+ img->MbaffFrameFlag=(active_sps->mb_adaptive_frame_field_flag && (img->field_pic_flag==0));
+
+ if (img->structure == FRAME ) assert (img->field_pic_flag == 0);
+ if (img->structure == TOP_FIELD ) assert (img->field_pic_flag == 1 && img->bottom_field_flag == 0);
+ if (img->structure == BOTTOM_FIELD) assert (img->field_pic_flag == 1 && img->bottom_field_flag == 1);
+
+ if (img->idr_flag)
+ {
+ img->idr_pic_id = ue_v("SH: idr_pic_id", currStream);
+ }
+
+ if (active_sps->pic_order_cnt_type == 0)
+ {
+ img->pic_order_cnt_lsb = u_v(active_sps->log2_max_pic_order_cnt_lsb_minus4 + 4, "SH: pic_order_cnt_lsb", currStream);
+ if( active_pps->pic_order_present_flag == 1 && !img->field_pic_flag )
+ img->delta_pic_order_cnt_bottom = se_v("SH: delta_pic_order_cnt_bottom", currStream);
+ else
+ img->delta_pic_order_cnt_bottom = 0;
+ }
+ if( active_sps->pic_order_cnt_type == 1 && !active_sps->delta_pic_order_always_zero_flag )
+ {
+ img->delta_pic_order_cnt[ 0 ] = se_v("SH: delta_pic_order_cnt[0]", currStream);
+ if( active_pps->pic_order_present_flag == 1 && !img->field_pic_flag )
+ img->delta_pic_order_cnt[ 1 ] = se_v("SH: delta_pic_order_cnt[1]", currStream);
+ }else
+ {
+ if (active_sps->pic_order_cnt_type == 1)
+ {
+ img->delta_pic_order_cnt[ 0 ] = 0;
+ img->delta_pic_order_cnt[ 1 ] = 0;
+ }
+ }
+
+ //! redundant_pic_cnt is missing here
+ if (active_pps->redundant_pic_cnt_present_flag)
+ {
+ img->redundant_pic_cnt = ue_v ("SH: redundant_pic_cnt", currStream);
+ }
+
+ if(img->type==B_SLICE)
+ {
+ img->direct_spatial_mv_pred_flag = u_1 ("SH: direct_spatial_mv_pred_flag", currStream);
+ }
+
+ 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;
+
+ if(img->type==P_SLICE || img->type == SP_SLICE || img->type==B_SLICE)
+ {
+ val = u_1 ("SH: num_ref_idx_override_flag", currStream);
+ if (val)
+ {
+ img->num_ref_idx_l0_active = 1 + ue_v ("SH: num_ref_idx_l0_active_minus1", currStream);
+
+ if(img->type==B_SLICE)
+ {
+ img->num_ref_idx_l1_active = 1 + ue_v ("SH: num_ref_idx_l1_active_minus1", currStream);
+ }
+ }
+ }
+ if (img->type!=B_SLICE)
+ {
+ img->num_ref_idx_l1_active = 0;
+ }
+
+ ref_pic_list_reordering();
+
+ img->apply_weights = ((active_pps->weighted_pred_flag && (currSlice->picture_type == P_SLICE || currSlice->picture_type == SP_SLICE) )
+ || ((active_pps->weighted_bipred_idc > 0 ) && (currSlice->picture_type == B_SLICE)));
+
+ if ((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))||
+ (active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE)))
+ {
+ pred_weight_table();
+ }
+
+ if (img->nal_reference_idc)
+ dec_ref_pic_marking(currStream);
+
+ if (active_pps->entropy_coding_mode_flag && img->type!=I_SLICE && img->type!=SI_SLICE)
+ {
+ img->model_number = ue_v("SH: cabac_init_idc", currStream);
+ }
+ else
+ {
+ img->model_number = 0;
+ }
+
+ val = se_v("SH: slice_qp_delta", currStream);
+ currSlice->qp = img->qp = 26 + active_pps->pic_init_qp_minus26 + val;
+ if ((img->qp < -img->bitdepth_luma_qp_scale) || (img->qp > 51))
+ error ("slice_qp_delta makes slice_qp_y out of range", 500);
+
+
+ currSlice->slice_qp_delta = val;
+
+ if(img->type==SP_SLICE || img->type == SI_SLICE)
+ {
+ if(img->type==SP_SLICE)
+ {
+ img->sp_switch = u_1 ("SH: sp_for_switch_flag", currStream);
+ }
+ val = se_v("SH: slice_qs_delta", currStream);
+ img->qpsp = 26 + active_pps->pic_init_qs_minus26 + val;
+ if ((img->qpsp < 0) || (img->qpsp > 51))
+ error ("slice_qs_delta makes slice_qs_y out of range", 500);
+ }
+
+ if (active_pps->deblocking_filter_control_present_flag)
+ {
+ currSlice->LFDisableIdc = ue_v ("SH: disable_deblocking_filter_idc", currStream);
+
+ if (currSlice->LFDisableIdc!=1)
+ {
+ currSlice->LFAlphaC0Offset = 2 * se_v("SH: slice_alpha_c0_offset_div2", currStream);
+ currSlice->LFBetaOffset = 2 * se_v("SH: slice_beta_offset_div2", currStream);
+ }
+ else
+ {
+ currSlice->LFAlphaC0Offset = currSlice->LFBetaOffset = 0;
+ }
+ }
+ else
+ {
+ currSlice->LFDisableIdc = currSlice->LFAlphaC0Offset = currSlice->LFBetaOffset = 0;
+ }
+
+ if (active_pps->num_slice_groups_minus1>0 && active_pps->slice_group_map_type>=3 &&
+ active_pps->slice_group_map_type<=5)
+ {
+ len = (active_sps->pic_height_in_map_units_minus1+1)*(active_sps->pic_width_in_mbs_minus1+1)/
+ (active_pps->slice_group_change_rate_minus1+1);
+ if (((active_sps->pic_height_in_map_units_minus1+1)*(active_sps->pic_width_in_mbs_minus1+1))%
+ (active_pps->slice_group_change_rate_minus1+1))
+ len +=1;
+
+ len = CeilLog2(len+1);
+
+ img->slice_group_change_cycle = u_v (len, "SH: slice_group_change_cycle", currStream);
+ }
+ img->PicHeightInMbs = img->FrameHeightInMbs / ( 1 + img->field_pic_flag );
+ img->PicSizeInMbs = img->PicWidthInMbs * img->PicHeightInMbs;
+ img->FrameSizeInMbs = img->PicWidthInMbs * img->FrameHeightInMbs;
+
+ return UsedBits;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * read the reference picture reordering information
+ ************************************************************************
+ */
+static void ref_pic_list_reordering()
+{
+ Slice *currSlice = img->currentSlice;
+ int dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER];
+ DataPartition *partition = &(currSlice->partArr[dP_nr]);
+ Bitstream *currStream = partition->bitstream;
+ int i, val;
+
+ alloc_ref_pic_list_reordering_buffer(currSlice);
+
+ if (img->type!=I_SLICE && img->type!=SI_SLICE)
+ {
+ val = currSlice->ref_pic_list_reordering_flag_l0 = u_1 ("SH: ref_pic_list_reordering_flag_l0", currStream);
+
+ if (val)
+ {
+ i=0;
+ do
+ {
+ val = currSlice->reordering_of_pic_nums_idc_l0[i] = ue_v("SH: reordering_of_pic_nums_idc_l0", currStream);
+ if (val==0 || val==1)
+ {
+ currSlice->abs_diff_pic_num_minus1_l0[i] = ue_v("SH: abs_diff_pic_num_minus1_l0", currStream);
+ }
+ else
+ {
+ if (val==2)
+ {
+ currSlice->long_term_pic_idx_l0[i] = ue_v("SH: long_term_pic_idx_l0", currStream);
+ }
+ }
+ i++;
+ // assert (i>img->num_ref_idx_l0_active);
+ } while (val != 3);
+ }
+ }
+
+ if (img->type==B_SLICE)
+ {
+ val = currSlice->ref_pic_list_reordering_flag_l1 = u_1 ("SH: ref_pic_list_reordering_flag_l1", currStream);
+
+ if (val)
+ {
+ i=0;
+ do
+ {
+ val = currSlice->reordering_of_pic_nums_idc_l1[i] = ue_v("SH: reordering_of_pic_nums_idc_l1", currStream);
+ if (val==0 || val==1)
+ {
+ currSlice->abs_diff_pic_num_minus1_l1[i] = ue_v("SH: abs_diff_pic_num_minus1_l1", currStream);
+ }
+ else
+ {
+ if (val==2)
+ {
+ currSlice->long_term_pic_idx_l1[i] = ue_v("SH: long_term_pic_idx_l1", currStream);
+ }
+ }
+ i++;
+ // assert (i>img->num_ref_idx_l1_active);
+ } while (val != 3);
+ }
+ }
+
+ // set reference index of redundant slices.
+ if(img->redundant_pic_cnt)
+ {
+ redundant_slice_ref_idx = currSlice->abs_diff_pic_num_minus1_l0[0] + 1;
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * read the weighted prediction tables
+ ************************************************************************
+ */
+static void pred_weight_table()
+{
+ Slice *currSlice = img->currentSlice;
+ int dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER];
+ DataPartition *partition = &(currSlice->partArr[dP_nr]);
+ Bitstream *currStream = partition->bitstream;
+ int luma_weight_flag_l0, luma_weight_flag_l1, chroma_weight_flag_l0, chroma_weight_flag_l1;
+ int i,j;
+
+ img->luma_log2_weight_denom = ue_v ("SH: luma_log2_weight_denom", currStream);
+ img->wp_round_luma = img->luma_log2_weight_denom ? 1<<(img->luma_log2_weight_denom - 1): 0;
+
+ if ( 0 != active_sps->chroma_format_idc)
+ {
+ img->chroma_log2_weight_denom = ue_v ("SH: chroma_log2_weight_denom", currStream);
+ img->wp_round_chroma = img->chroma_log2_weight_denom ? 1<<(img->chroma_log2_weight_denom - 1): 0;
+ }
+
+ reset_wp_params(img);
+
+ for (i=0; i<img->num_ref_idx_l0_active; i++)
+ {
+ luma_weight_flag_l0 = u_1("SH: luma_weight_flag_l0", currStream);
+
+ if (luma_weight_flag_l0)
+ {
+ img->wp_weight[0][i][0] = se_v ("SH: luma_weight_l0", currStream);
+ img->wp_offset[0][i][0] = se_v ("SH: luma_offset_l0", currStream);
+ }
+ else
+ {
+ img->wp_weight[0][i][0] = 1<<img->luma_log2_weight_denom;
+ img->wp_offset[0][i][0] = 0;
+ }
+
+ if (active_sps->chroma_format_idc != 0)
+ {
+ chroma_weight_flag_l0 = u_1 ("SH: chroma_weight_flag_l0", currStream);
+
+ for (j=1; j<3; j++)
+ {
+ if (chroma_weight_flag_l0)
+ {
+ img->wp_weight[0][i][j] = se_v("SH: chroma_weight_l0", currStream);
+ img->wp_offset[0][i][j] = se_v("SH: chroma_offset_l0", currStream);
+ }
+ else
+ {
+ img->wp_weight[0][i][j] = 1<<img->chroma_log2_weight_denom;
+ img->wp_offset[0][i][j] = 0;
+ }
+ }
+ }
+ }
+ if ((img->type == B_SLICE) && active_pps->weighted_bipred_idc == 1)
+ {
+ for (i=0; i<img->num_ref_idx_l1_active; i++)
+ {
+ luma_weight_flag_l1 = u_1("SH: luma_weight_flag_l1", currStream);
+
+ if (luma_weight_flag_l1)
+ {
+ img->wp_weight[1][i][0] = se_v ("SH: luma_weight_l1", currStream);
+ img->wp_offset[1][i][0] = se_v ("SH: luma_offset_l1", currStream);
+ }
+ else
+ {
+ img->wp_weight[1][i][0] = 1<<img->luma_log2_weight_denom;
+ img->wp_offset[1][i][0] = 0;
+ }
+
+ if (active_sps->chroma_format_idc != 0)
+ {
+ chroma_weight_flag_l1 = u_1 ("SH: chroma_weight_flag_l1", currStream);
+
+ for (j=1; j<3; j++)
+ {
+ if (chroma_weight_flag_l1)
+ {
+ img->wp_weight[1][i][j] = se_v("SH: chroma_weight_l1", currStream);
+ img->wp_offset[1][i][j] = se_v("SH: chroma_offset_l1", currStream);
+ }
+ else
+ {
+ img->wp_weight[1][i][j] = 1<<img->chroma_log2_weight_denom;
+ img->wp_offset[1][i][j] = 0;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * read the memory control operations
+ ************************************************************************
+ */
+void dec_ref_pic_marking(Bitstream *currStream)
+{
+ int val;
+
+ DecRefPicMarking_t *tmp_drpm,*tmp_drpm2;
+
+ // free old buffer content
+ while (img->dec_ref_pic_marking_buffer)
+ {
+ tmp_drpm=img->dec_ref_pic_marking_buffer;
+
+ img->dec_ref_pic_marking_buffer=tmp_drpm->Next;
+ free (tmp_drpm);
+ }
+
+ if (img->idr_flag)
+ {
+ img->no_output_of_prior_pics_flag = u_1("SH: no_output_of_prior_pics_flag", currStream);
+ img->long_term_reference_flag = u_1("SH: long_term_reference_flag", currStream);
+ }
+ else
+ {
+ img->adaptive_ref_pic_buffering_flag = u_1("SH: adaptive_ref_pic_buffering_flag", currStream);
+ if (img->adaptive_ref_pic_buffering_flag)
+ {
+ // read Memory Management Control Operation
+ do
+ {
+ tmp_drpm=(DecRefPicMarking_t*)calloc (1,sizeof (DecRefPicMarking_t));
+ tmp_drpm->Next=NULL;
+
+ val = tmp_drpm->memory_management_control_operation = ue_v("SH: memory_management_control_operation", currStream);
+
+ if ((val==1)||(val==3))
+ {
+ tmp_drpm->difference_of_pic_nums_minus1 = ue_v("SH: difference_of_pic_nums_minus1", currStream);
+ }
+ if (val==2)
+ {
+ tmp_drpm->long_term_pic_num = ue_v("SH: long_term_pic_num", currStream);
+ }
+
+ if ((val==3)||(val==6))
+ {
+ tmp_drpm->long_term_frame_idx = ue_v("SH: long_term_frame_idx", currStream);
+ }
+ if (val==4)
+ {
+ tmp_drpm->max_long_term_frame_idx_plus1 = ue_v("SH: max_long_term_pic_idx_plus1", currStream);
+ }
+
+ // add command
+ if (img->dec_ref_pic_marking_buffer==NULL)
+ {
+ img->dec_ref_pic_marking_buffer=tmp_drpm;
+ }
+ else
+ {
+ tmp_drpm2=img->dec_ref_pic_marking_buffer;
+ while (tmp_drpm2->Next!=NULL) tmp_drpm2=tmp_drpm2->Next;
+ tmp_drpm2->Next=tmp_drpm;
+ }
+
+ }while (val != 0);
+
+ }
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * To calculate the poc values
+ * based upon JVT-F100d2
+ * POC200301: Until Jan 2003, this function will calculate the correct POC
+ * values, but the management of POCs in buffered pictures may need more work.
+ * \return
+ * none
+ ************************************************************************
+ */
+void decode_poc(struct img_par *img)
+{
+ int i;
+ // for POC mode 0:
+ unsigned int MaxPicOrderCntLsb = (1<<(active_sps->log2_max_pic_order_cnt_lsb_minus4+4));
+
+ switch ( active_sps->pic_order_cnt_type )
+ {
+ case 0: // POC MODE 0
+ // 1st
+ if(img->idr_flag)
+ {
+ img->PrevPicOrderCntMsb = 0;
+ img->PrevPicOrderCntLsb = 0;
+ }
+ else
+ {
+ if (img->last_has_mmco_5)
+ {
+ if (img->last_pic_bottom_field)
+ {
+ img->PrevPicOrderCntMsb = 0;
+ img->PrevPicOrderCntLsb = 0;
+ }
+ else
+ {
+ img->PrevPicOrderCntMsb = 0;
+ img->PrevPicOrderCntLsb = img->toppoc;
+ }
+ }
+ }
+ // Calculate the MSBs of current picture
+ if( img->pic_order_cnt_lsb < img->PrevPicOrderCntLsb &&
+ ( img->PrevPicOrderCntLsb - img->pic_order_cnt_lsb ) >= ( MaxPicOrderCntLsb / 2 ) )
+ img->PicOrderCntMsb = img->PrevPicOrderCntMsb + MaxPicOrderCntLsb;
+ else if ( img->pic_order_cnt_lsb > img->PrevPicOrderCntLsb &&
+ ( img->pic_order_cnt_lsb - img->PrevPicOrderCntLsb ) > ( MaxPicOrderCntLsb / 2 ) )
+ img->PicOrderCntMsb = img->PrevPicOrderCntMsb - MaxPicOrderCntLsb;
+ else
+ img->PicOrderCntMsb = img->PrevPicOrderCntMsb;
+
+ // 2nd
+
+ if(img->field_pic_flag==0)
+ { //frame pix
+ img->toppoc = img->PicOrderCntMsb + img->pic_order_cnt_lsb;
+ img->bottompoc = img->toppoc + img->delta_pic_order_cnt_bottom;
+ img->ThisPOC = img->framepoc = (img->toppoc < img->bottompoc)? img->toppoc : img->bottompoc; // POC200301
+ }
+ else if (img->bottom_field_flag==0)
+ { //top field
+ img->ThisPOC= img->toppoc = img->PicOrderCntMsb + img->pic_order_cnt_lsb;
+ }
+ else
+ { //bottom field
+ img->ThisPOC= img->bottompoc = img->PicOrderCntMsb + img->pic_order_cnt_lsb;
+ }
+ img->framepoc=img->ThisPOC;
+
+ if ( img->frame_num!=img->PreviousFrameNum)
+ img->PreviousFrameNum=img->frame_num;
+
+ if(img->nal_reference_idc)
+ {
+ img->PrevPicOrderCntLsb = img->pic_order_cnt_lsb;
+ img->PrevPicOrderCntMsb = img->PicOrderCntMsb;
+ }
+
+ break;
+
+ case 1: // POC MODE 1
+ // 1st
+ if(img->idr_flag)
+ {
+ img->FrameNumOffset=0; // first pix of IDRGOP,
+ img->delta_pic_order_cnt[0]=0; //ignore first delta
+ if(img->frame_num)
+ error("frame_num not equal to zero in IDR picture", -1020);
+ }
+ else
+ {
+ if (img->last_has_mmco_5)
+ {
+ img->PreviousFrameNumOffset = 0;
+ img->PreviousFrameNum = 0;
+ }
+ if (img->frame_num<img->PreviousFrameNum)
+ { //not first pix of IDRGOP
+ img->FrameNumOffset = img->PreviousFrameNumOffset + img->MaxFrameNum;
+ }
+ else
+ {
+ img->FrameNumOffset = img->PreviousFrameNumOffset;
+ }
+ }
+
+ // 2nd
+ if(active_sps->num_ref_frames_in_pic_order_cnt_cycle)
+ img->AbsFrameNum = img->FrameNumOffset+img->frame_num;
+ else
+ img->AbsFrameNum=0;
+ if( (!img->nal_reference_idc) && img->AbsFrameNum>0)
+ img->AbsFrameNum--;
+
+ // 3rd
+ img->ExpectedDeltaPerPicOrderCntCycle=0;
+
+ if(active_sps->num_ref_frames_in_pic_order_cnt_cycle)
+ for(i=0;i<(int) active_sps->num_ref_frames_in_pic_order_cnt_cycle;i++)
+ img->ExpectedDeltaPerPicOrderCntCycle += active_sps->offset_for_ref_frame[i];
+
+ if(img->AbsFrameNum)
+ {
+ img->PicOrderCntCycleCnt = (img->AbsFrameNum-1)/active_sps->num_ref_frames_in_pic_order_cnt_cycle;
+ img->FrameNumInPicOrderCntCycle = (img->AbsFrameNum-1)%active_sps->num_ref_frames_in_pic_order_cnt_cycle;
+ img->ExpectedPicOrderCnt = img->PicOrderCntCycleCnt*img->ExpectedDeltaPerPicOrderCntCycle;
+ for(i=0;i<=(int)img->FrameNumInPicOrderCntCycle;i++)
+ img->ExpectedPicOrderCnt += active_sps->offset_for_ref_frame[i];
+ }
+ else
+ img->ExpectedPicOrderCnt=0;
+
+ if(!img->nal_reference_idc)
+ img->ExpectedPicOrderCnt += active_sps->offset_for_non_ref_pic;
+
+ if(img->field_pic_flag==0)
+ { //frame pix
+ img->toppoc = img->ExpectedPicOrderCnt + img->delta_pic_order_cnt[0];
+ img->bottompoc = img->toppoc + active_sps->offset_for_top_to_bottom_field + img->delta_pic_order_cnt[1];
+ img->ThisPOC = img->framepoc = (img->toppoc < img->bottompoc)? img->toppoc : img->bottompoc; // POC200301
+ }
+ else if (img->bottom_field_flag==0)
+ { //top field
+ img->ThisPOC = img->toppoc = img->ExpectedPicOrderCnt + img->delta_pic_order_cnt[0];
+ }
+ else
+ { //bottom field
+ img->ThisPOC = img->bottompoc = img->ExpectedPicOrderCnt + active_sps->offset_for_top_to_bottom_field + img->delta_pic_order_cnt[0];
+ }
+ img->framepoc=img->ThisPOC;
+
+ img->PreviousFrameNum=img->frame_num;
+ img->PreviousFrameNumOffset=img->FrameNumOffset;
+
+ break;
+
+
+ case 2: // POC MODE 2
+ if(img->idr_flag) // IDR picture
+ {
+ img->FrameNumOffset=0; // first pix of IDRGOP,
+ img->ThisPOC = img->framepoc = img->toppoc = img->bottompoc = 0;
+ if(img->frame_num)
+ error("frame_num not equal to zero in IDR picture", -1020);
+ }
+ else
+ {
+ if (img->last_has_mmco_5)
+ {
+ img->PreviousFrameNum = 0;
+ img->PreviousFrameNumOffset = 0;
+ }
+ if (img->frame_num<img->PreviousFrameNum)
+ img->FrameNumOffset = img->PreviousFrameNumOffset + img->MaxFrameNum;
+ else
+ img->FrameNumOffset = img->PreviousFrameNumOffset;
+
+
+ img->AbsFrameNum = img->FrameNumOffset+img->frame_num;
+ if(!img->nal_reference_idc)
+ img->ThisPOC = (2*img->AbsFrameNum - 1);
+ else
+ img->ThisPOC = (2*img->AbsFrameNum);
+
+ if (img->field_pic_flag==0)
+ img->toppoc = img->bottompoc = img->framepoc = img->ThisPOC;
+ else if (img->bottom_field_flag==0)
+ img->toppoc = img->framepoc = img->ThisPOC;
+ else img->bottompoc = img->framepoc = img->ThisPOC;
+ }
+
+ img->PreviousFrameNum=img->frame_num;
+ img->PreviousFrameNumOffset=img->FrameNumOffset;
+ break;
+
+
+ default:
+ //error must occurs
+ assert( 1==0 );
+ break;
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * A little helper for the debugging of POC code
+ * \return
+ * none
+ ************************************************************************
+ */
+int dumppoc(struct img_par *img) {
+ printf ("\nPOC locals...\n");
+ printf ("toppoc %d\n", img->toppoc);
+ printf ("bottompoc %d\n", img->bottompoc);
+ printf ("frame_num %d\n", img->frame_num);
+ printf ("field_pic_flag %d\n", img->field_pic_flag);
+ printf ("bottom_field_flag %d\n", img->bottom_field_flag);
+ printf ("POC SPS\n");
+ printf ("log2_max_frame_num_minus4 %d\n", active_sps->log2_max_frame_num_minus4); // POC200301
+ printf ("log2_max_pic_order_cnt_lsb_minus4 %d\n", active_sps->log2_max_pic_order_cnt_lsb_minus4);
+ printf ("pic_order_cnt_type %d\n", active_sps->pic_order_cnt_type);
+ printf ("num_ref_frames_in_pic_order_cnt_cycle %d\n", active_sps->num_ref_frames_in_pic_order_cnt_cycle);
+ printf ("delta_pic_order_always_zero_flag %d\n", active_sps->delta_pic_order_always_zero_flag);
+ printf ("offset_for_non_ref_pic %d\n", active_sps->offset_for_non_ref_pic);
+ printf ("offset_for_top_to_bottom_field %d\n", active_sps->offset_for_top_to_bottom_field);
+ printf ("offset_for_ref_frame[0] %d\n", active_sps->offset_for_ref_frame[0]);
+ printf ("offset_for_ref_frame[1] %d\n", active_sps->offset_for_ref_frame[1]);
+ printf ("POC in SLice Header\n");
+ printf ("pic_order_present_flag %d\n", active_pps->pic_order_present_flag);
+ printf ("delta_pic_order_cnt[0] %d\n", img->delta_pic_order_cnt[0]);
+ printf ("delta_pic_order_cnt[1] %d\n", img->delta_pic_order_cnt[1]);
+ printf ("delta_pic_order_cnt[2] %d\n", img->delta_pic_order_cnt[2]);
+ printf ("idr_flag %d\n", img->idr_flag);
+ printf ("MaxFrameNum %d\n", img->MaxFrameNum);
+
+ return 0;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * return the poc of img as per (8-1) JVT-F100d2
+ * POC200301
+ ************************************************************************
+ */
+int picture_order(struct img_par *img)
+{
+ if (img->field_pic_flag==0) // is a frame
+ return img->framepoc;
+ else if (img->bottom_field_flag==0) // top field
+ return img->toppoc;
+ else // bottom field
+ return img->bottompoc;
+}
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/header.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/header.h:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/header.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,23 @@
+
+/*!
+ *************************************************************************************
+ * \file header.h
+ *
+ * \brief
+ * Prototypes for header.c
+ *************************************************************************************
+ */
+
+#ifndef _HEADER_H_
+#define _HEADER_H_
+
+int FirstPartOfSliceHeader();
+int RestOfSliceHeader();
+
+void dec_ref_pic_marking(Bitstream *currStream);
+
+void decode_poc(struct img_par *img);
+int dumppoc(struct img_par *img);
+
+#endif
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/ifunctions.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/ldecod/ifunctions.h:1.1
*** /dev/null Sun Feb 4 08:38:52 2007
--- llvm-test/MultiSource/Applications/JM/ldecod/ifunctions.h Sun Feb 4 08:38:31 2007
***************
*** 0 ****
--- 1,121 ----
+
+ /*!
+ ************************************************************************
+ * \file
+ * ifunctions.h
+ *
+ * \brief
+ * define some inline functions that are used within the encoder.
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Karsten Sühring <suehring at hhi.de>
+ * - Alexis Tourapis <alexismt at ieee.org>
+ *
+ ************************************************************************
+ */
+
+ #ifndef _IFUNCTIONS_H_
+ #define _IFUNCTIONS_H_
+
+ static inline int imin(int a, int b)
+ {
+ return ((a) < (b)) ? (a) : (b);
+ }
+
+ static inline int imax(int a, int b)
+ {
+ return ((a) > (b)) ? (a) : (b);
+ }
+
+ static inline double dmin(double a, double b)
+ {
+ return ((a) < (b)) ? (a) : (b);
+ }
+
+ static inline double dmax(double a, double b)
+ {
+ return ((a) > (b)) ? (a) : (b);
+ }
+
+ static inline int64 i64min(int64 a, int64 b)
+ {
+ return ((a) < (b)) ? (a) : (b);
+ }
+
+ static inline int64 i64max(int64 a, int64 b)
+ {
+ return ((a) > (b)) ? (a) : (b);
+ }
+
+ static inline int iabs(int x)
+ {
+ return ((x) < 0) ? -(x) : (x);
+ }
+
+ static inline double dabs(double x)
+ {
+ return ((x) < 0) ? -(x) : (x);
+ }
+
+ static inline int isign(int x)
+ {
+ return ((x) < 0) ? -1 : 1;
+ }
+
+ static inline int isignab(int a, int b)
+ {
+ return ((b) < 0) ? -iabs(a) : iabs(a);
+ }
+
+ static inline int rshift_rnd(int x, int a)
+ {
+ return (a > 0) ? ((x + (1 << (a-1) )) >> a) : (x << (-a));
+ }
+
+ static inline unsigned int rshift_rnd_us(unsigned int x, unsigned int a)
+ {
+ return (a > 0) ? ((x + (1 << (a-1))) >> a) : x;
+ }
+
+ static inline int rshift_rnd_sf(int x, int a)
+ {
+ return ((x + (1 << (a-1) )) >> a);
+ }
+
+ static inline unsigned int rshift_rnd_us_sf(unsigned int x, unsigned int a)
+ {
+ return ((x + (1 << (a-1))) >> a);
+ }
+
+ static inline int iClip1(int high, int x)
+ {
+ x = imax(x, 0);
+ x = imin(x, high);
+
+ return x;
+ }
+
+ static inline int iClip3(int low, int high, int x)
+ {
+ x = imax(x, low);
+ x = imin(x, high);
+
+ return x;
+ }
+
+ static inline double dClip3(double low, double high, double x)
+ {
+ x = dmax(x, low);
+ x = dmin(x, high);
+
+ return x;
+ }
+
+ static inline int RSD(int x)
+ {
+ return ((x&2)?(x|1):(x&(~1)));
+ }
+
+ #endif
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/image.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/image.c:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/image.c Sun Feb 4 08:38:31 2007
@@ -0,0 +1,2059 @@
+
+/*!
+ ***********************************************************************
+ * \file image.c
+ *
+ * \brief
+ * Decode a 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>
+ * - Thomas Wedi <wedi at tnt.uni-hannover.de>
+ * - Gabi Blaettermann <blaetter at hhi.de>
+ * - Ye-Kui Wang <wyk at ieee.org>
+ * - Antti Hallapuro <antti.hallapuro at nokia.com>
+ * - Alexis Tourapis <alexismt at ieee.org>
+ * - Jill Boyce <jill.boyce at thomson.net>
+ * - Saurav K Bandyopadhyay <saurav at ieee.org>
+ * - Zhenyu Wu <Zhenyu.Wu at thomson.net
+ * - Purvin Pandit <Purvin.Pandit at thomson.net>
+ *
+ ***********************************************************************
+ */
+
+#include "contributors.h"
+
+#include <math.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#ifdef WIN32
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+#include "global.h"
+#include "errorconcealment.h"
+#include "image.h"
+#include "mbuffer.h"
+#include "fmo.h"
+#include "nalu.h"
+#include "parsetcommon.h"
+#include "parset.h"
+#include "header.h"
+#include "rtp.h"
+#include "sei.h"
+#include "output.h"
+#include "biaridecod.h"
+#include "mb_access.h"
+#include "memalloc.h"
+#include "annexb.h"
+
+#include "context_ini.h"
+#include "cabac.h"
+#include "loopfilter.h"
+
+#include "vlc.h"
+
+#include "erc_api.h"
+extern objectBuffer_t *erc_object_list;
+extern ercVariables_t *erc_errorVar;
+extern frame erc_recfr;
+extern int erc_mvperMB;
+extern struct img_par *erc_img;
+
+//extern FILE *p_out2;
+
+extern StorablePicture **listX[6];
+extern ColocatedParams *Co_located;
+
+extern StorablePicture *no_reference_picture;
+int non_conforming_stream;
+
+StorablePicture *dec_picture;
+
+OldSliceParams old_slice;
+
+void MbAffPostProc()
+{
+ imgpel temp[16][32];
+
+ imgpel ** imgY = dec_picture->imgY;
+ imgpel ***imgUV = dec_picture->imgUV;
+
+ int i, x, y, x0, y0, uv;
+ for (i=0; i<(int)dec_picture->PicSizeInMbs; i+=2)
+ {
+ if (dec_picture->mb_field[i])
+ {
+ get_mb_pos(i, &x0, &y0, IS_LUMA);
+ for (y=0; y<(2*MB_BLOCK_SIZE);y++)
+ for (x=0; x<MB_BLOCK_SIZE; x++)
+ temp[x][y] = imgY[y0+y][x0+x];
+
+ for (y=0; y<MB_BLOCK_SIZE;y++)
+ for (x=0; x<MB_BLOCK_SIZE; x++)
+ {
+ imgY[y0+(2*y)][x0+x] = temp[x][y];
+ imgY[y0+(2*y+1)][x0+x] = temp[x][y+MB_BLOCK_SIZE];
+ }
+
+ if (dec_picture->chroma_format_idc != YUV400)
+ {
+ 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++)
+ for (x=0; x<img->mb_cr_size_x; x++)
+ temp[x][y] = imgUV[uv][y0+y][x0+x];
+
+ for (y=0; y<img->mb_cr_size_y;y++)
+ for (x=0; x<img->mb_cr_size_x; x++)
+ {
+ imgUV[uv][y0+(2*y)][x0+x] = temp[x][y];
+ imgUV[uv][y0+(2*y+1)][x0+x] = temp[x][y+img->mb_cr_size_y];
+ }
+ }
+ }
+ }
+ }
+}
+
+/*!
+ ***********************************************************************
+ * \brief
+ * decodes one I- or P-frame
+ *
+ ***********************************************************************
+ */
+
+int decode_one_frame(struct img_par *img,struct inp_par *inp, struct snr_par *snr)
+{
+ int current_header;
+ Slice *currSlice = img->currentSlice;
+ int i;
+
+ img->current_slice_nr = 0;
+ img->current_mb_nr = -4711; // initialized to an impossible value for debugging -- correct value is taken from slice header
+ currSlice->next_header = -8888; // initialized to an impossible value for debugging -- correct value is taken from slice header
+ img->num_dec_mb = 0;
+ img->newframe = 1;
+
+ while ((currSlice->next_header != EOS && currSlice->next_header != SOP))
+ {
+ current_header = read_new_slice();
+
+ // error tracking of primary and redundant slices.
+ Error_tracking();
+
+ // If primary and redundant are received and primary is correct, discard the redundant
+ // else, primary slice will be replaced with redundant slice.
+ if(img->frame_num == previous_frame_num && img->redundant_pic_cnt !=0
+ && Is_primary_correct !=0 && current_header != EOS)
+ {
+ continue;
+ }
+
+ // update reference flags and set current ref_flag
+ if(!(img->redundant_pic_cnt != 0 && previous_frame_num == img->frame_num))
+ {
+ for(i=16;i>0;i--)
+ {
+ ref_flag[i] = ref_flag[i-1];
+ }
+ }
+ ref_flag[0] = img->redundant_pic_cnt==0 ? Is_primary_correct : Is_redundant_correct;
+ previous_frame_num = img->frame_num;
+
+ if (current_header == EOS)
+ {
+ exit_picture();
+ return EOS;
+ }
+
+ decode_slice(img, inp, current_header);
+
+ img->newframe = 0;
+ img->current_slice_nr++;
+ }
+
+ exit_picture();
+
+ return (SOP);
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Convert file read buffer to source picture structure
+ * \param imgX
+ * Pointer to image plane
+ * \param buf
+ * Buffer for file output
+ * \param size_x
+ * horizontal image size in pixel
+ * \param size_y
+ * vertical image size in pixel
+ * \param symbol_size_in_bytes
+ * number of bytes used per pel
+ ************************************************************************
+ */
+void buf2img (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes)
+{
+ 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][0], 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
+ if (symbol_size_in_bytes == 1)
+ {
+ for (j=0; j < size_y; j++)
+ {
+ for (i=0; i < size_x; i++)
+ {
+ imgX[j][i]=*(buf++);
+ }
+ }
+ }
+ else
+ {
+ for (j=0; j < size_y; j++)
+ {
+ int jpos = j*size_x;
+ for (i=0; i < size_x; i++)
+ {
+ imgX[j][i]=0;
+ memcpy(&(imgX[j][i]), buf +((i+jpos)*symbol_size_in_bytes), symbol_size_in_bytes);
+ }
+ }
+ }
+
+ }
+ }
+}
+
+
+/*!
+************************************************************************
+* \brief
+* Find PSNR for all three components.Compare decoded frame with
+* the original sequence. Read inp->jumpd frames to reflect frame skipping.
+************************************************************************
+*/
+void find_snr(
+ struct snr_par *snr, //!< pointer to snr parameters
+ StorablePicture *p, //!< picture to be compared
+ int p_ref) //!< open reference YUV file
+{
+ static const int SubWidthC [4]= { 1, 2, 2, 1};
+ static const int SubHeightC [4]= { 1, 2, 1, 1};
+ int crop_left, crop_right, crop_top, crop_bottom;
+
+ int i,j;
+ int64 diff_y,diff_u,diff_v;
+ int uv;
+ int64 status;
+ int symbol_size_in_bytes = img->pic_unit_bitsize_on_disk/8;
+ int size_x, size_y;
+ int size_x_cr, size_y_cr;
+ int64 framesize_in_bytes;
+ 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;
+ Boolean rgb_output = (Boolean) (active_sps->vui_seq_parameters.matrix_coefficients==0);
+ unsigned char *buf;
+
+ // picture error concealment
+ char yuv_types[4][6]= {"4:0:0","4:2:0","4:2:2","4:4:4"};
+
+ // calculate frame number
+ int psnrPOC = active_sps->mb_adaptive_frame_field_flag ? p->poc /(input->poc_scale) : p->poc/(input->poc_scale);
+
+ // cropping for luma
+ if (p->frame_cropping_flag)
+ {
+ crop_left = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_left_offset;
+ crop_right = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_right_offset;
+ crop_top = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
+ crop_bottom = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
+ }
+ else
+ {
+ crop_left = crop_right = crop_top = crop_bottom = 0;
+ }
+
+ size_x = p->size_x - crop_left - crop_right;
+ size_y = p->size_y - crop_top - crop_bottom;
+
+ // cropping for chroma
+ if (p->frame_cropping_flag)
+ {
+ crop_left = p->frame_cropping_rect_left_offset;
+ crop_right = p->frame_cropping_rect_right_offset;
+ crop_top = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
+ crop_bottom = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
+ }
+ else
+ {
+ crop_left = crop_right = crop_top = crop_bottom = 0;
+ }
+
+ if ((p->chroma_format_idc==YUV400) && input->write_uv)
+ {
+ size_x_cr = p->size_x/2;
+ size_y_cr = p->size_y/2;
+ }
+ else
+ {
+ size_x_cr = p->size_x_cr - crop_left - crop_right;
+ size_y_cr = p->size_y_cr - crop_top - crop_bottom;
+ }
+
+ framesize_in_bytes = (((int64)size_y*size_x) + ((int64)size_y_cr*size_x_cr)*2) * symbol_size_in_bytes;
+
+ if (psnrPOC==0 && img->psnr_number)
+ img->idr_psnr_number = img->number*img->ref_poc_gap/(input->poc_scale);
+
+ img->psnr_number=imax(img->psnr_number,img->idr_psnr_number+psnrPOC);
+
+ frame_no = img->idr_psnr_number+psnrPOC;
+
+ // KS: this buffer should actually be allocated only once, but this is still much faster than the previous version
+ buf = malloc ( size_y * size_x * symbol_size_in_bytes );
+
+ if (NULL == buf)
+ {
+ no_mem_exit("find_snr: buf");
+ }
+
+ status = lseek (p_ref, framesize_in_bytes * frame_no, SEEK_SET);
+ if (status == -1)
+ {
+ fprintf(stderr, "Error in seeking frame number: %d\n", frame_no);
+ free (buf);
+ return;
+ }
+
+ if(rgb_output)
+ lseek (p_ref, framesize_in_bytes/3, SEEK_CUR);
+
+ read(p_ref, buf, size_y * size_x * symbol_size_in_bytes);
+ buf2img(imgY_ref, buf, size_x, size_y, symbol_size_in_bytes);
+
+ if (p->chroma_format_idc != YUV400)
+ {
+ for (uv=0; uv < 2; uv++)
+ {
+ if(rgb_output && uv==1)
+ lseek (p_ref, -framesize_in_bytes, SEEK_CUR);
+
+ read(p_ref, buf, size_y_cr * size_x_cr*symbol_size_in_bytes);
+ buf2img(imgUV_ref[uv], buf, size_x_cr, size_y_cr, symbol_size_in_bytes);
+ }
+ }
+
+ if(rgb_output)
+ lseek (p_ref, framesize_in_bytes*2/3, SEEK_CUR);
+
+ free (buf);
+
+ img->quad[0]=0;
+ diff_y=0;
+ for (j=0; j < size_y; ++j)
+ {
+ for (i=0; i < size_x; ++i)
+ {
+ diff_y += img->quad[p->imgY[j][i]-imgY_ref[j][i]];
+ }
+ }
+
+ // Chroma
+ diff_u=0;
+ diff_v=0;
+
+ if (p->chroma_format_idc != YUV400)
+ {
+ for (j=0; j < size_y_cr; ++j)
+ {
+ for (i=0; i < size_x_cr; ++i)
+ {
+ diff_u += img->quad[imgUV_ref[0][j][i]-p->imgUV[0][j][i]];
+ diff_v += img->quad[imgUV_ref[1][j][i]-p->imgUV[1][j][i]];
+ }
+ }
+ }
+
+#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)(size_x)*(size_y) / diff_y))); // luma snr for current frame
+ else
+ snr->snr_y=0.0;
+ if (diff_u != 0)
+ snr->snr_u=(float)(10*log10(max_pix_value_sqd_uv*(double)((double)(size_x_cr)*(size_y_cr) / (diff_u)))); // chroma snr for current frame
+ else
+ snr->snr_u=0.0;
+ if (diff_v != 0)
+ snr->snr_v=(float)(10*log10(max_pix_value_sqd_uv*(double)((double)(size_x_cr)*(size_y_cr) / (diff_v)))); // chroma snr for current frame
+ else
+ snr->snr_v=0;
+
+ if (img->number == 0) // first
+ {
+ snr->snr_ya=snr->snr_y1=snr->snr_y; // keep luma snr for first frame
+ snr->snr_ua=snr->snr_u1=snr->snr_u; // keep chroma snr for first frame
+ snr->snr_va=snr->snr_v1=snr->snr_v; // keep chroma snr for first frame
+
+ }
+ else
+ {
+ snr->snr_ya=(float)(snr->snr_ya*(snr->frame_ctr)+snr->snr_y)/(snr->frame_ctr+1); // average snr chroma for all frames
+ snr->snr_ua=(float)(snr->snr_ua*(snr->frame_ctr)+snr->snr_u)/(snr->frame_ctr+1); // average snr luma for all frames
+ snr->snr_va=(float)(snr->snr_va*(snr->frame_ctr)+snr->snr_v)/(snr->frame_ctr+1); // average snr luma for all frames
+ }
+
+ // picture error concealment
+ if(p->concealed_pic)
+ {
+ fprintf(stdout,"%04d(P) %8d %5d %5d %7.4f %7.4f %7.4f %s %5d\n",
+ frame_no, p->frame_poc, p->pic_num, p->qp,
+ snr->snr_y, snr->snr_u, snr->snr_v, yuv_types[p->chroma_format_idc], 0);
+
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpolation of 1/4 subpixel
+ ************************************************************************
+ */
+void get_block(int ref_frame, StorablePicture **list, int x_pos, int y_pos, struct img_par *img, int block[BLOCK_SIZE][BLOCK_SIZE])
+{
+
+ int dx, dy;
+ int i, j;
+ int maxold_x,maxold_y;
+ int result;
+ int pres_x, pres_y;
+
+ int tmp_res[9][9];
+ static const int COEF[6] = { 1, -5, 20, 20, -5, 1 };
+ StorablePicture *curr_ref = list[ref_frame];
+ static imgpel **cur_imgY, *cur_lineY;
+ static int jpos_m2, jpos_m1, jpos, jpos_p1, jpos_p2, jpos_p3;
+ static int ipos_m2, ipos_m1, ipos, ipos_p1, ipos_p2, ipos_p3;
+
+ if (curr_ref == no_reference_picture && img->framepoc < img->recovery_poc)
+ {
+ printf("list[ref_frame] is equal to 'no reference picture' before RAP\n");
+
+ /* fill the block with sample value 128 */
+ for (j = 0; j < BLOCK_SIZE; j++)
+ for (i = 0; i < BLOCK_SIZE; i++)
+ block[j][i] = 128;
+ return;
+ }
+ cur_imgY = curr_ref->imgY;
+ dx = x_pos&3;
+ dy = y_pos&3;
+ x_pos = (x_pos-dx)>>2;
+ y_pos = (y_pos-dy)>>2;
+
+ maxold_x = dec_picture->size_x_m1;
+ maxold_y = dec_picture->size_y_m1;
+
+ if (dec_picture->mb_field[img->current_mb_nr])
+ maxold_y = (dec_picture->size_y >> 1) - 1;
+
+ if (dx == 0 && dy == 0)
+ { /* fullpel position */
+ for (j = 0; j < BLOCK_SIZE; j++)
+ {
+ cur_lineY = cur_imgY[iClip3(0,maxold_y,y_pos+j)];
+
+ block[j][0] = cur_lineY[iClip3(0,maxold_x,x_pos )];
+ block[j][1] = cur_lineY[iClip3(0,maxold_x,x_pos+1)];
+ block[j][2] = cur_lineY[iClip3(0,maxold_x,x_pos+2)];
+ block[j][3] = cur_lineY[iClip3(0,maxold_x,x_pos+3)];
+ }
+ }
+ else
+ { /* other positions */
+
+ if (dy == 0)
+ { /* No vertical interpolation */
+
+ for (i = 0; i < BLOCK_SIZE; i++)
+ {
+ ipos_m2 = iClip3(0, maxold_x, x_pos + i - 2);
+ ipos_m1 = iClip3(0, maxold_x, x_pos + i - 1);
+ ipos = iClip3(0, maxold_x, x_pos + i );
+ ipos_p1 = iClip3(0, maxold_x, x_pos + i + 1);
+ ipos_p2 = iClip3(0, maxold_x, x_pos + i + 2);
+ ipos_p3 = iClip3(0, maxold_x, x_pos + i + 3);
+
+ for (j = 0; j < BLOCK_SIZE; j++)
+ {
+ cur_lineY = cur_imgY[iClip3(0,maxold_y,y_pos+j)];
+
+ result = (cur_lineY[ipos_m2] + cur_lineY[ipos_p3]) * COEF[0];
+ result += (cur_lineY[ipos_m1] + cur_lineY[ipos_p2]) * COEF[1];
+ result += (cur_lineY[ipos ] + cur_lineY[ipos_p1]) * COEF[2];
+
+ block[j][i] = iClip1(img->max_imgpel_value, ((result+16)>>5));
+ }
+ }
+
+ if ((dx&1) == 1)
+ {
+ for (j = 0; j < BLOCK_SIZE; j++)
+ {
+ cur_lineY = cur_imgY[iClip3(0,maxold_y,y_pos+j)];
+ block[j][0] = (block[j][0] + cur_lineY[iClip3(0,maxold_x,x_pos +(dx>>1))] + 1 )>>1;
+ block[j][1] = (block[j][1] + cur_lineY[iClip3(0,maxold_x,x_pos+1+(dx>>1))] + 1 )>>1;
+ block[j][2] = (block[j][2] + cur_lineY[iClip3(0,maxold_x,x_pos+2+(dx>>1))] + 1 )>>1;
+ block[j][3] = (block[j][3] + cur_lineY[iClip3(0,maxold_x,x_pos+3+(dx>>1))] + 1 )>>1;
+ }
+ }
+ }
+ else if (dx == 0)
+ { /* No horizontal interpolation */
+
+ for (j = 0; j < BLOCK_SIZE; j++)
+ {
+ jpos_m2 = iClip3(0, maxold_y, y_pos + j - 2);
+ jpos_m1 = iClip3(0, maxold_y, y_pos + j - 1);
+ jpos = iClip3(0, maxold_y, y_pos + j );
+ jpos_p1 = iClip3(0, maxold_y, y_pos + j + 1);
+ jpos_p2 = iClip3(0, maxold_y, y_pos + j + 2);
+ jpos_p3 = iClip3(0, maxold_y, y_pos + j + 3);
+ for (i = 0; i < BLOCK_SIZE; i++)
+ {
+ pres_x = iClip3(0,maxold_x,x_pos+i);
+
+ result = (cur_imgY[jpos_m2][pres_x] + cur_imgY[jpos_p3][pres_x]) * COEF[0];
+ result += (cur_imgY[jpos_m1][pres_x] + cur_imgY[jpos_p2][pres_x]) * COEF[1];
+ result += (cur_imgY[jpos ][pres_x] + cur_imgY[jpos_p1][pres_x]) * COEF[2];
+ block[j][i] = iClip1(img->max_imgpel_value, ((result+16)>>5));
+ }
+ }
+
+ if ((dy&1) == 1)
+ {
+ for (j = 0; j < BLOCK_SIZE; j++)
+ {
+ cur_lineY = cur_imgY[iClip3(0,maxold_y,y_pos+j+(dy>>1))];
+ block[j][0] = (block[j][0] + cur_lineY[iClip3(0,maxold_x,x_pos )] + 1 )>>1;
+ block[j][1] = (block[j][1] + cur_lineY[iClip3(0,maxold_x,x_pos+1)] + 1 )>>1;
+ block[j][2] = (block[j][2] + cur_lineY[iClip3(0,maxold_x,x_pos+2)] + 1 )>>1;
+ block[j][3] = (block[j][3] + cur_lineY[iClip3(0,maxold_x,x_pos+3)] + 1 )>>1;
+ }
+ }
+ }
+ else if (dx == 2)
+ { /* Vertical & horizontal interpolation */
+
+ for (i = 0; i < BLOCK_SIZE; i++)
+ {
+ ipos_m2 = iClip3(0, maxold_x, x_pos + i - 2);
+ ipos_m1 = iClip3(0, maxold_x, x_pos + i - 1);
+ ipos = iClip3(0, maxold_x, x_pos + i );
+ ipos_p1 = iClip3(0, maxold_x, x_pos + i + 1);
+ ipos_p2 = iClip3(0, maxold_x, x_pos + i + 2);
+ ipos_p3 = iClip3(0, maxold_x, x_pos + i + 3);
+
+ for (j = 0; j < BLOCK_SIZE + 5; j++)
+ {
+ cur_lineY = cur_imgY[iClip3(0,maxold_y,y_pos + j - 2)];
+
+ tmp_res[j][i] = (cur_lineY[ipos_m2] + cur_lineY[ipos_p3]) * COEF[0];
+ tmp_res[j][i] += (cur_lineY[ipos_m1] + cur_lineY[ipos_p2]) * COEF[1];
+ tmp_res[j][i] += (cur_lineY[ipos ] + cur_lineY[ipos_p1]) * COEF[2];
+ }
+ }
+
+ for (j = 0; j < BLOCK_SIZE; j++)
+ {
+ jpos_m2 = j ;
+ jpos_m1 = j + 1;
+ jpos = j + 2;
+ jpos_p1 = j + 3;
+ jpos_p2 = j + 4;
+ jpos_p3 = j + 5;
+
+ for (i = 0; i < BLOCK_SIZE; i++)
+ {
+ result = (tmp_res[jpos_m2][i] + tmp_res[jpos_p3][i]) * COEF[0];
+ result += (tmp_res[jpos_m1][i] + tmp_res[jpos_p2][i]) * COEF[1];
+ result += (tmp_res[jpos ][i] + tmp_res[jpos_p1][i]) * COEF[2];
+
+ block[j][i] = iClip1(img->max_imgpel_value, ((result+512)>>10));
+ }
+ }
+
+ if ((dy&1) == 1)
+ {
+ for (j = 0; j < BLOCK_SIZE; j++)
+ {
+ pres_y = j+2+(dy>>1);
+
+ block[j][0] = (block[j][0] + iClip1(img->max_imgpel_value, ((tmp_res[pres_y][0]+16)>>5)) +1 )>>1;
+ block[j][1] = (block[j][1] + iClip1(img->max_imgpel_value, ((tmp_res[pres_y][1]+16)>>5)) +1 )>>1;
+ block[j][2] = (block[j][2] + iClip1(img->max_imgpel_value, ((tmp_res[pres_y][2]+16)>>5)) +1 )>>1;
+ block[j][3] = (block[j][3] + iClip1(img->max_imgpel_value, ((tmp_res[pres_y][3]+16)>>5)) +1 )>>1;
+ }
+ }
+ }
+ else if (dy == 2)
+ { /* Horizontal & vertical interpolation */
+
+ for (j = 0; j < BLOCK_SIZE; j++)
+ {
+ jpos_m2 = iClip3(0, maxold_y, y_pos + j - 2);
+ jpos_m1 = iClip3(0, maxold_y, y_pos + j - 1);
+ jpos = iClip3(0, maxold_y, y_pos + j );
+ jpos_p1 = iClip3(0, maxold_y, y_pos + j + 1);
+ jpos_p2 = iClip3(0, maxold_y, y_pos + j + 2);
+ jpos_p3 = iClip3(0, maxold_y, y_pos + j + 3);
+ for (i = 0; i < BLOCK_SIZE+5; i++)
+ {
+ pres_x = iClip3(0,maxold_x,x_pos+i - 2);
+ tmp_res[j][i] = (cur_imgY[jpos_m2][pres_x] + cur_imgY[jpos_p3][pres_x])*COEF[0];
+ tmp_res[j][i] += (cur_imgY[jpos_m1][pres_x] + cur_imgY[jpos_p2][pres_x])*COEF[1];
+ tmp_res[j][i] += (cur_imgY[jpos ][pres_x] + cur_imgY[jpos_p1][pres_x])*COEF[2];
+ }
+ }
+
+ for (j = 0; j < BLOCK_SIZE; j++)
+ {
+ for (i = 0; i < BLOCK_SIZE; i++)
+ {
+ result = (tmp_res[j][i ] + tmp_res[j][i + 5]) * COEF[0];
+ result += (tmp_res[j][i + 1] + tmp_res[j][i + 4]) * COEF[1];
+ result += (tmp_res[j][i + 2] + tmp_res[j][i + 3]) * COEF[2];
+ block[j][i] = iClip1(img->max_imgpel_value, ((result+512)>>10));
+ }
+ }
+
+ if ((dx&1) == 1)
+ {
+ for (j = 0; j < BLOCK_SIZE; j++)
+ {
+ block[j][0] = (block[j][0] + iClip1(img->max_imgpel_value, ((tmp_res[j][2+(dx>>1)]+16)>>5))+1)>>1;
+ block[j][1] = (block[j][1] + iClip1(img->max_imgpel_value, ((tmp_res[j][3+(dx>>1)]+16)>>5))+1)>>1;
+ block[j][2] = (block[j][2] + iClip1(img->max_imgpel_value, ((tmp_res[j][4+(dx>>1)]+16)>>5))+1)>>1;
+ block[j][3] = (block[j][3] + iClip1(img->max_imgpel_value, ((tmp_res[j][5+(dx>>1)]+16)>>5))+1)>>1;
+ }
+ }
+ }
+ else
+ { /* Diagonal interpolation */
+
+ for (i = 0; i < BLOCK_SIZE; i++)
+ {
+ ipos_m2 = iClip3(0, maxold_x, x_pos + i - 2);
+ ipos_m1 = iClip3(0, maxold_x, x_pos + i - 1);
+ ipos = iClip3(0, maxold_x, x_pos + i );
+ ipos_p1 = iClip3(0, maxold_x, x_pos + i + 1);
+ ipos_p2 = iClip3(0, maxold_x, x_pos + i + 2);
+ ipos_p3 = iClip3(0, maxold_x, x_pos + i + 3);
+
+ for (j = 0; j < BLOCK_SIZE; j++)
+ {
+ cur_lineY = cur_imgY[iClip3(0,maxold_y,(dy == 1 ? y_pos+j : y_pos+j+1))];
+
+ result = (cur_lineY[ipos_m2] + cur_lineY[ipos_p3]) * COEF[0];
+ result += (cur_lineY[ipos_m1] + cur_lineY[ipos_p2]) * COEF[1];
+ result += (cur_lineY[ipos ] + cur_lineY[ipos_p1]) * COEF[2];
+
+ block[j][i] = iClip1(img->max_imgpel_value, ((result+16)>>5));
+ }
+ }
+
+ for (j = 0; j < BLOCK_SIZE; j++)
+ {
+ jpos_m2 = iClip3(0, maxold_y, y_pos + j - 2);
+ jpos_m1 = iClip3(0, maxold_y, y_pos + j - 1);
+ jpos = iClip3(0, maxold_y, y_pos + j );
+ jpos_p1 = iClip3(0, maxold_y, y_pos + j + 1);
+ jpos_p2 = iClip3(0, maxold_y, y_pos + j + 2);
+ jpos_p3 = iClip3(0, maxold_y, y_pos + j + 3);
+ for (i = 0; i < BLOCK_SIZE; i++)
+ {
+ pres_x = dx == 1 ? x_pos+i : x_pos+i+1;
+ pres_x = iClip3(0,maxold_x,pres_x);
+
+ result = (cur_imgY[jpos_m2][pres_x] + cur_imgY[jpos_p3][pres_x]) * COEF[0];
+ result += (cur_imgY[jpos_m1][pres_x] + cur_imgY[jpos_p2][pres_x]) * COEF[1];
+ result += (cur_imgY[jpos ][pres_x] + cur_imgY[jpos_p1][pres_x]) * COEF[2];
+
+ block[j][i] = (block[j][i] + iClip1(img->max_imgpel_value, ((result+16)>>5)) +1 ) >>1;
+ }
+ }
+
+ }
+ }
+}
+
+
+void reorder_lists(int currSliceType, Slice * currSlice)
+{
+
+ if ((currSliceType != I_SLICE)&&(currSliceType != SI_SLICE))
+ {
+ if (currSlice->ref_pic_list_reordering_flag_l0)
+ {
+ reorder_ref_pic_list(listX[0], &listXsize[0],
+ img->num_ref_idx_l0_active - 1,
+ currSlice->reordering_of_pic_nums_idc_l0,
+ currSlice->abs_diff_pic_num_minus1_l0,
+ currSlice->long_term_pic_idx_l0);
+ }
+ if (no_reference_picture == listX[0][img->num_ref_idx_l0_active-1])
+ {
+ if (non_conforming_stream)
+ printf("RefPicList0[ num_ref_idx_l0_active_minus1 ] is equal to 'no reference picture'\n");
+ else
+ error("RefPicList0[ num_ref_idx_l0_active_minus1 ] is equal to 'no reference picture', invalid bitstream",500);
+ }
+ // that's a definition
+ listXsize[0] = img->num_ref_idx_l0_active;
+ }
+ if (currSliceType == B_SLICE)
+ {
+ if (currSlice->ref_pic_list_reordering_flag_l1)
+ {
+ reorder_ref_pic_list(listX[1], &listXsize[1],
+ img->num_ref_idx_l1_active - 1,
+ currSlice->reordering_of_pic_nums_idc_l1,
+ currSlice->abs_diff_pic_num_minus1_l1,
+ currSlice->long_term_pic_idx_l1);
+ }
+ if (no_reference_picture == listX[1][img->num_ref_idx_l1_active-1])
+ {
+ if (non_conforming_stream)
+ printf("RefPicList1[ num_ref_idx_l1_active_minus1 ] is equal to 'no reference picture'\n");
+ else
+ error("RefPicList1[ num_ref_idx_l1_active_minus1 ] is equal to 'no reference picture', invalid bitstream",500);
+ }
+ // that's a definition
+ listXsize[1] = img->num_ref_idx_l1_active;
+ }
+
+ free_ref_pic_list_reordering_buffer(currSlice);
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * initialize ref_pic_num array
+ ************************************************************************
+ */
+void set_ref_pic_num()
+{
+ int i,j;
+
+ int slice_id=img->current_slice_nr;
+
+ for (i=0;i<listXsize[LIST_0];i++)
+ {
+ dec_picture->ref_pic_num [slice_id][LIST_0][i]=listX[LIST_0][i]->poc * 2 + ((listX[LIST_0][i]->structure==BOTTOM_FIELD)?1:0) ;
+ dec_picture->frm_ref_pic_num [slice_id][LIST_0][i]=listX[LIST_0][i]->frame_poc * 2;
+ dec_picture->top_ref_pic_num [slice_id][LIST_0][i]=listX[LIST_0][i]->top_poc * 2;
+ dec_picture->bottom_ref_pic_num [slice_id][LIST_0][i]=listX[LIST_0][i]->bottom_poc * 2 + 1;
+ //printf("POCS %d %d %d %d ",listX[LIST_0][i]->frame_poc,listX[LIST_0][i]->bottom_poc,listX[LIST_0][i]->top_poc,listX[LIST_0][i]->poc);
+ //printf("refid %d %d %d %d\n",(int) dec_picture->frm_ref_pic_num[LIST_0][i],(int) dec_picture->top_ref_pic_num[LIST_0][i],(int) dec_picture->bottom_ref_pic_num[LIST_0][i],(int) dec_picture->ref_pic_num[LIST_0][i]);
+ }
+
+ for (i=0;i<listXsize[LIST_1];i++)
+ {
+ dec_picture->ref_pic_num [slice_id][LIST_1][i]=listX[LIST_1][i]->poc *2 + ((listX[LIST_1][i]->structure==BOTTOM_FIELD)?1:0);
+ dec_picture->frm_ref_pic_num [slice_id][LIST_1][i]=listX[LIST_1][i]->frame_poc * 2;
+ dec_picture->top_ref_pic_num [slice_id][LIST_1][i]=listX[LIST_1][i]->top_poc * 2;
+ dec_picture->bottom_ref_pic_num [slice_id][LIST_1][i]=listX[LIST_1][i]->bottom_poc * 2 + 1;
+ }
+
+ if (!active_sps->frame_mbs_only_flag)
+ {
+ if (img->structure==FRAME)
+ for (j=2;j<6;j++)
+ for (i=0;i<listXsize[j];i++)
+ {
+ dec_picture->ref_pic_num [slice_id][j][i] = listX[j][i]->poc * 2 + ((listX[j][i]->structure==BOTTOM_FIELD)?1:0);
+ dec_picture->frm_ref_pic_num [slice_id][j][i] = listX[j][i]->frame_poc * 2 ;
+ dec_picture->top_ref_pic_num [slice_id][j][i] = listX[j][i]->top_poc * 2 ;
+ dec_picture->bottom_ref_pic_num [slice_id][j][i] = listX[j][i]->bottom_poc * 2 + 1;
+ }
+ }
+
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Reads new slice from bit_stream
+ ************************************************************************
+ */
+int read_new_slice()
+{
+ NALU_t *nalu = AllocNALU(MAX_CODED_FRAME_SIZE);
+ int current_header = 0;
+ int ret;
+ int BitsUsedByHeader;
+ Slice *currSlice = img->currentSlice;
+ Bitstream *currStream;
+
+ int slice_id_a, slice_id_b, slice_id_c;
+ int redundant_pic_cnt_b, redundant_pic_cnt_c;
+ long ftell_position;
+
+ while (1)
+ {
+ ftell_position = ftell(bits);
+
+ if (input->FileFormat == PAR_OF_ANNEXB)
+ ret=GetAnnexbNALU (nalu);
+ else
+ ret=GetRTPNALU (nalu);
+
+ //In some cases, zero_byte shall be present. If current NALU is a VCL NALU, we can't tell
+ //whether it is the first VCL NALU at this point, so only non-VCL NAL unit is checked here.
+ CheckZeroByteNonVCL(nalu, &ret);
+
+ NALUtoRBSP(nalu);
+
+ if (ret < 0)
+ printf ("Error while getting the NALU in file format %s, exit\n", input->FileFormat==PAR_OF_ANNEXB?"Annex B":"RTP");
+ if (ret == 0)
+ {
+ FreeNALU(nalu);
+ return EOS;
+ }
+
+ // Got a NALU
+ if (nalu->forbidden_bit)
+ {
+ printf ("Found NALU w/ forbidden_bit set, bit error? Let's try...\n");
+ }
+
+ switch (nalu->nal_unit_type)
+ {
+ case NALU_TYPE_SLICE:
+ case NALU_TYPE_IDR:
+
+ if (img->recovery_point || nalu->nal_unit_type == NALU_TYPE_IDR)
+ {
+ if (img->recovery_point_found == 0)
+ {
+ if (nalu->nal_unit_type != NALU_TYPE_IDR)
+ {
+ printf("Warning: Decoding does not start with an IDR picture.\n");
+ non_conforming_stream = 1;
+ }
+ else
+ non_conforming_stream = 0;
+ }
+ img->recovery_point_found = 1;
+ }
+
+ if (img->recovery_point_found == 0)
+ break;
+
+ img->idr_flag = (nalu->nal_unit_type == NALU_TYPE_IDR);
+ img->nal_reference_idc = nalu->nal_reference_idc;
+ currSlice->dp_mode = PAR_DP_1;
+ currSlice->max_part_nr = 1;
+ currSlice->ei_flag = 0;
+ currStream = currSlice->partArr[0].bitstream;
+ currStream->ei_flag = 0;
+ currStream->frame_bitoffset = currStream->read_len = 0;
+ memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1);
+ currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1);
+
+ // Some syntax of the Slice Header depends on the parameter set, which depends on
+ // the parameter set ID of the SLice header. Hence, read the pic_parameter_set_id
+ // of the slice header first, then setup the active parameter sets, and then read
+ // the rest of the slice header
+ BitsUsedByHeader = FirstPartOfSliceHeader();
+ UseParameterSet (currSlice->pic_parameter_set_id);
+ BitsUsedByHeader+= RestOfSliceHeader ();
+
+ FmoInit (active_pps, active_sps);
+
+ AssignQuantParam (active_pps, active_sps);
+
+ // if primary slice is replaced with redundant slice, set the correct image type
+ if(img->redundant_pic_cnt && Is_primary_correct==0 && Is_redundant_correct)
+ {
+ dec_picture->slice_type=img->type;
+ }
+
+ if(is_new_picture())
+ {
+ init_picture(img, input);
+
+ current_header = SOP;
+ //check zero_byte if it is also the first NAL unit in the access unit
+ CheckZeroByteVCL(nalu, &ret);
+ }
+ else
+ current_header = SOS;
+
+ init_lists(img->type, img->currentSlice->structure);
+ reorder_lists (img->type, img->currentSlice);
+
+ if (img->structure==FRAME)
+ {
+ init_mbaff_lists();
+ }
+
+/* if (img->frame_num==1) // write a reference list
+ {
+ count ++;
+ if (count==1)
+ for (i=0; i<listXsize[0]; i++)
+ write_picture(listX[0][i], p_out2);
+ }
+*/
+
+ // From here on, active_sps, active_pps and the slice header are valid
+ if (img->MbaffFrameFlag)
+ img->current_mb_nr = currSlice->start_mb_nr << 1;
+ else
+ img->current_mb_nr = currSlice->start_mb_nr;
+
+ if (active_pps->entropy_coding_mode_flag)
+ {
+ int ByteStartPosition = currStream->frame_bitoffset/8;
+ if (currStream->frame_bitoffset%8 != 0)
+ {
+ ByteStartPosition++;
+ }
+ arideco_start_decoding (&currSlice->partArr[0].de_cabac, currStream->streamBuffer, ByteStartPosition, &currStream->read_len, img->type);
+ }
+// printf ("read_new_slice: returning %s\n", current_header == SOP?"SOP":"SOS");
+ FreeNALU(nalu);
+ img->recovery_point = 0;
+ return current_header;
+ break;
+ case NALU_TYPE_DPA:
+ // read DP_A
+ img->idr_flag = (nalu->nal_unit_type == NALU_TYPE_IDR);
+ if (img->idr_flag)
+ {
+ printf ("Data partiton A cannot have idr_flag set, trying anyway \n");
+ }
+ img->nal_reference_idc = nalu->nal_reference_idc;
+ currSlice->dp_mode = PAR_DP_3;
+ currSlice->max_part_nr = 3;
+ currSlice->ei_flag = 0;
+ currStream = currSlice->partArr[0].bitstream;
+ currStream->ei_flag = 0;
+ currStream->frame_bitoffset = currStream->read_len = 0;
+ memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1);
+ currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1);
+
+ BitsUsedByHeader = FirstPartOfSliceHeader();
+ UseParameterSet (currSlice->pic_parameter_set_id);
+ BitsUsedByHeader += RestOfSliceHeader ();
+
+ FmoInit (active_pps, active_sps);
+
+ if(is_new_picture())
+ {
+ init_picture(img, input);
+ current_header = SOP;
+ CheckZeroByteVCL(nalu, &ret);
+ }
+ else
+ current_header = SOS;
+
+ init_lists(img->type, img->currentSlice->structure);
+ reorder_lists (img->type, img->currentSlice);
+
+ if (img->structure==FRAME)
+ {
+ init_mbaff_lists();
+ }
+
+ // From here on, active_sps, active_pps and the slice header are valid
+ if (img->MbaffFrameFlag)
+ img->current_mb_nr = currSlice->start_mb_nr << 1;
+ else
+ img->current_mb_nr = currSlice->start_mb_nr;
+
+ // Now I need to read the slice ID, which depends on the value of
+ // redundant_pic_cnt_present_flag
+
+ slice_id_a = ue_v("NALU: DP_A slice_id", currStream);
+
+ if (active_pps->entropy_coding_mode_flag)
+ error ("received data partition with CABAC, this is not allowed", 500);
+
+ // continue with reading next DP
+ ftell_position = ftell(bits);
+ if (input->FileFormat == PAR_OF_ANNEXB)
+ ret=GetAnnexbNALU (nalu);
+ else
+ ret=GetRTPNALU (nalu);
+
+ CheckZeroByteNonVCL(nalu, &ret);
+ NALUtoRBSP(nalu);
+
+ if (ret < 0)
+ printf ("Error while getting the NALU in file format %s, exit\n", input->FileFormat==PAR_OF_ANNEXB?"Annex B":"RTP");
+ if (ret == 0)
+ {
+ FreeNALU(nalu);
+ return current_header;
+ }
+
+ if ( NALU_TYPE_DPB == nalu->nal_unit_type)
+ {
+ // we got a DPB
+ currStream = currSlice->partArr[1].bitstream;
+ currStream->ei_flag = 0;
+ currStream->frame_bitoffset = currStream->read_len = 0;
+
+ memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1);
+ currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1);
+
+ slice_id_b = ue_v("NALU: DP_B slice_id", currStream);
+
+ if (slice_id_b != slice_id_a)
+ {
+ printf ("got a data partition B which does not match DP_A\n");
+ // KS: needs error handling !!!
+ }
+
+ if (active_pps->redundant_pic_cnt_present_flag)
+ redundant_pic_cnt_b = ue_v("NALU: DP_B redudant_pic_cnt", currStream);
+ else
+ redundant_pic_cnt_b = 0;
+
+ // we're finished with DP_B, so let's continue with next DP
+ ftell_position = ftell(bits);
+ if (input->FileFormat == PAR_OF_ANNEXB)
+ ret=GetAnnexbNALU (nalu);
+ else
+ ret=GetRTPNALU (nalu);
+
+ CheckZeroByteNonVCL(nalu, &ret);
+ NALUtoRBSP(nalu);
+
+ if (ret < 0)
+ printf ("Error while getting the NALU in file format %s, exit\n", input->FileFormat==PAR_OF_ANNEXB?"Annex B":"RTP");
+ if (ret == 0)
+ {
+ FreeNALU(nalu);
+ return current_header;
+ }
+ }
+
+ // check if we got DP_C
+ if ( NALU_TYPE_DPC == nalu->nal_unit_type)
+ {
+ currStream = currSlice->partArr[2].bitstream;
+ currStream->ei_flag = 0;
+ currStream->frame_bitoffset = currStream->read_len = 0;
+
+ memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1);
+ currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1);
+
+ slice_id_c = ue_v("NALU: DP_C slice_id", currStream);
+ if (slice_id_c != slice_id_a)
+ {
+ printf ("got a data partition C which does not match DP_A\n");
+ // KS: needs error handling !!!
+ }
+
+ if (active_pps->redundant_pic_cnt_present_flag)
+ redundant_pic_cnt_c = ue_v("NALU:SLICE_C redudand_pic_cnt", currStream);
+ else
+ redundant_pic_cnt_c = 0;
+ }
+
+ // check if we read anything else than the expected partitions
+ if ((nalu->nal_unit_type != NALU_TYPE_DPB) && (nalu->nal_unit_type != NALU_TYPE_DPC))
+ {
+ // reset bitstream position and read again in next call
+ fseek(bits, ftell_position, SEEK_SET);
+ }
+
+ FreeNALU(nalu);
+ return current_header;
+
+ break;
+ case NALU_TYPE_DPB:
+ printf ("found data partition B without matching DP A, discarding\n");
+ break;
+ case NALU_TYPE_DPC:
+ printf ("found data partition C without matching DP A, discarding\n");
+ break;
+ case NALU_TYPE_SEI:
+ printf ("read_new_slice: Found NALU_TYPE_SEI, len %d\n", nalu->len);
+ InterpretSEIMessage(nalu->buf,nalu->len,img);
+ break;
+ case NALU_TYPE_PPS:
+ ProcessPPS(nalu);
+ break;
+ case NALU_TYPE_SPS:
+ ProcessSPS(nalu);
+ break;
+ case NALU_TYPE_AUD:
+// printf ("read_new_slice: Found 'Access Unit Delimiter' NAL unit, len %d, ignored\n", nalu->len);
+ break;
+ case NALU_TYPE_EOSEQ:
+// printf ("read_new_slice: Found 'End of Sequence' NAL unit, len %d, ignored\n", nalu->len);
+ break;
+ case NALU_TYPE_EOSTREAM:
+// printf ("read_new_slice: Found 'End of Stream' NAL unit, len %d, ignored\n", nalu->len);
+ break;
+ case NALU_TYPE_FILL:
+ printf ("read_new_slice: Found NALU_TYPE_FILL, len %d\n", nalu->len);
+ printf ("Skipping these filling bits, proceeding w/ next NALU\n");
+ break;
+ default:
+ printf ("Found NALU type %d, len %d undefined, ignore NALU, moving on\n", nalu->nal_unit_type, nalu->len);
+ }
+ }
+ FreeNALU(nalu);
+
+ return current_header;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Initializes the parameters for a new picture
+ ************************************************************************
+ */
+void init_picture(struct img_par *img, struct inp_par *inp)
+{
+ int i,k,l;
+ Slice *currSlice = img->currentSlice;
+
+ if (dec_picture)
+ {
+ // this may only happen on slice loss
+ exit_picture();
+ }
+ if (img->recovery_point)
+ img->recovery_frame_num = (img->frame_num + img->recovery_frame_cnt) % img->MaxFrameNum;
+
+ if (img->idr_flag)
+ img->recovery_frame_num = img->frame_num;
+
+ if (img->recovery_point == 0 &&
+ img->frame_num != img->pre_frame_num &&
+ img->frame_num != (img->pre_frame_num + 1) % img->MaxFrameNum)
+ {
+ if (active_sps->gaps_in_frame_num_value_allowed_flag == 0)
+ {
+ // picture error concealment
+ if(inp->conceal_mode !=0)
+ {
+ if((img->frame_num) < ((img->pre_frame_num + 1) % img->MaxFrameNum))
+ {
+ /* Conceal lost IDR frames and any frames immediately
+ following the IDR. Use frame copy for these since
+ lists cannot be formed correctly for motion copy*/
+ img->conceal_mode = 1;
+ img->IDR_concealment_flag = 1;
+ conceal_lost_frames(img);
+ //reset to original concealment mode for future drops
+ img->conceal_mode = inp->conceal_mode;
+ }
+ else
+ {
+ //reset to original concealment mode for future drops
+ img->conceal_mode = inp->conceal_mode;
+
+ img->IDR_concealment_flag = 0;
+ conceal_lost_frames(img);
+ }
+ }
+ else
+ { /* Advanced Error Concealment would be called here to combat unintentional loss of pictures. */
+ error("An unintentional loss of pictures occurs! Exit\n", 100);
+ }
+ }
+ if(img->conceal_mode == 0)
+ fill_frame_num_gap(img);
+ }
+
+ if(img->nal_reference_idc)
+ {
+ img->pre_frame_num = img->frame_num;
+ }
+
+ //img->num_dec_mb = 0;
+
+ //calculate POC
+ decode_poc(img);
+
+ if (img->recovery_frame_num == img->frame_num &&
+ img->recovery_poc == 0x7fffffff)
+ img->recovery_poc = img->framepoc;
+
+ if(img->nal_reference_idc)
+ img->last_ref_pic_poc = img->framepoc;
+
+ // dumppoc (img);
+
+ if (img->structure==FRAME ||img->structure==TOP_FIELD)
+ {
+#ifdef WIN32
+ _ftime (&(img->tstruct_start)); // start time ms
+#else
+ ftime (&(img->tstruct_start)); // start time ms
+#endif
+ time( &(img->ltime_start)); // start time s
+ }
+
+ dec_picture = alloc_storable_picture ((PictureStructure) img->structure, img->width, img->height, img->width_cr, img->height_cr);
+ dec_picture->top_poc=img->toppoc;
+ dec_picture->bottom_poc=img->bottompoc;
+ dec_picture->frame_poc=img->framepoc;
+ dec_picture->qp=img->qp;
+ dec_picture->slice_qp_delta=currSlice->slice_qp_delta;
+ dec_picture->chroma_qp_offset[0] = active_pps->chroma_qp_index_offset;
+ dec_picture->chroma_qp_offset[1] = active_pps->second_chroma_qp_index_offset;
+
+ // reset all variables of the error concealment instance before decoding of every frame.
+ // here the third parameter should, if perfectly, be equal to the number of slices per frame.
+ // using little value is ok, the code will allocate more memory if the slice number is larger
+ ercReset(erc_errorVar, img->PicSizeInMbs, img->PicSizeInMbs, dec_picture->size_x);
+ erc_mvperMB = 0;
+
+ switch (img->structure )
+ {
+ case TOP_FIELD:
+ {
+ dec_picture->poc=img->toppoc;
+ img->number *= 2;
+ break;
+ }
+ case BOTTOM_FIELD:
+ {
+ dec_picture->poc=img->bottompoc;
+ img->number = img->number * 2 + 1;
+ break;
+ }
+ case FRAME:
+ {
+ dec_picture->poc=img->framepoc;
+ break;
+ }
+ default:
+ error("img->structure not initialized", 235);
+ }
+
+ img->current_slice_nr=0;
+
+ if (img->type > SI_SLICE)
+ {
+ set_ec_flag(SE_PTYPE);
+ img->type = P_SLICE; // concealed element
+ }
+
+ // CAVLC init
+ for (i=0;i < (int)img->PicSizeInMbs; i++)
+ for (k=0;k<4;k++)
+ for (l=0;l<(4 + img->num_blk8x8_uv);l++)
+ img->nz_coeff[i][k][l]=-1; // CAVLC
+
+ if(active_pps->constrained_intra_pred_flag)
+ {
+ for (i=0; i<(int)img->PicSizeInMbs; i++)
+ {
+ img->intra_block[i] = 1;
+ }
+ }
+
+ // Set the slice_nr member of each MB to -1, to ensure correct when packet loss occurs
+ // TO set Macroblock Map (mark all MBs as 'have to be concealed')
+ for(i=0; i<(int)img->PicSizeInMbs; i++)
+ {
+ img->mb_data[i].slice_nr = -1;
+ img->mb_data[i].ei_flag = 1;
+ }
+
+ 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->pix_c_x = 0; // define horizontal positions
+
+ dec_picture->slice_type = img->type;
+ dec_picture->used_for_reference = (img->nal_reference_idc != 0);
+ dec_picture->idr_flag = img->idr_flag;
+ dec_picture->no_output_of_prior_pics_flag = img->no_output_of_prior_pics_flag;
+ dec_picture->long_term_reference_flag = img->long_term_reference_flag;
+ dec_picture->adaptive_ref_pic_buffering_flag = img->adaptive_ref_pic_buffering_flag;
+
+ dec_picture->dec_ref_pic_marking_buffer = img->dec_ref_pic_marking_buffer;
+ img->dec_ref_pic_marking_buffer = NULL;
+
+ dec_picture->MbaffFrameFlag = img->MbaffFrameFlag;
+ dec_picture->PicWidthInMbs = img->PicWidthInMbs;
+
+ get_mb_block_pos = dec_picture->MbaffFrameFlag ? get_mb_block_pos_mbaff : get_mb_block_pos_normal;
+ getNeighbour = dec_picture->MbaffFrameFlag ? getAffNeighbour : getNonAffNeighbour;
+
+
+
+ dec_picture->pic_num = img->frame_num;
+ dec_picture->frame_num = img->frame_num;
+
+ dec_picture->recovery_frame = (img->frame_num == img->recovery_frame_num);
+
+ dec_picture->coded_frame = (img->structure==FRAME);
+
+ dec_picture->chroma_format_idc = active_sps->chroma_format_idc;
+
+ dec_picture->frame_mbs_only_flag = active_sps->frame_mbs_only_flag;
+ dec_picture->frame_cropping_flag = active_sps->frame_cropping_flag;
+
+ if (dec_picture->frame_cropping_flag)
+ {
+ dec_picture->frame_cropping_rect_left_offset = active_sps->frame_cropping_rect_left_offset;
+ dec_picture->frame_cropping_rect_right_offset = active_sps->frame_cropping_rect_right_offset;
+ dec_picture->frame_cropping_rect_top_offset = active_sps->frame_cropping_rect_top_offset;
+ dec_picture->frame_cropping_rect_bottom_offset = active_sps->frame_cropping_rect_bottom_offset;
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * finish decoding of a picture, conceal errors and store it
+ * into the DPB
+ ************************************************************************
+ */
+void exit_picture()
+{
+ char yuv_types[4][6]= {"4:0:0","4:2:0","4:2:2","4:4:4"};
+ int ercStartMB;
+ int ercSegment;
+ frame recfr;
+ unsigned int i;
+ int structure, frame_poc, slice_type, refpic, qp, pic_num, chroma_format_idc;
+
+ char yuvFormat[10];
+
+ // return if the last picture has already been finished
+ if (dec_picture==NULL)
+ {
+ return;
+ }
+
+ //deblocking for frame or field
+ DeblockPicture( img, dec_picture );
+
+ if (dec_picture->MbaffFrameFlag)
+ MbAffPostProc();
+
+ recfr.yptr = &dec_picture->imgY[0][0];
+ if (dec_picture->chroma_format_idc != YUV400)
+ {
+ recfr.uptr = &dec_picture->imgUV[0][0][0];
+ recfr.vptr = &dec_picture->imgUV[1][0][0];
+ }
+
+ //! this is always true at the beginning of a picture
+ ercStartMB = 0;
+ ercSegment = 0;
+
+ //! mark the start of the first segment
+ if (!dec_picture->MbaffFrameFlag)
+ {
+ ercStartSegment(0, ercSegment, 0 , erc_errorVar);
+ //! generate the segments according to the macroblock map
+ for(i = 1; i<dec_picture->PicSizeInMbs; i++)
+ {
+ if(img->mb_data[i].ei_flag != img->mb_data[i-1].ei_flag)
+ {
+ ercStopSegment(i-1, ercSegment, 0, erc_errorVar); //! stop current segment
+
+ //! mark current segment as lost or OK
+ if(img->mb_data[i-1].ei_flag)
+ ercMarkCurrSegmentLost(dec_picture->size_x, erc_errorVar);
+ else
+ ercMarkCurrSegmentOK(dec_picture->size_x, erc_errorVar);
+
+ ercSegment++; //! next segment
+ ercStartSegment(i, ercSegment, 0 , erc_errorVar); //! start new segment
+ ercStartMB = i;//! save start MB for this segment
+ }
+ }
+ //! mark end of the last segment
+ ercStopSegment(dec_picture->PicSizeInMbs-1, ercSegment, 0, erc_errorVar);
+ if(img->mb_data[i-1].ei_flag)
+ ercMarkCurrSegmentLost(dec_picture->size_x, erc_errorVar);
+ else
+ ercMarkCurrSegmentOK(dec_picture->size_x, erc_errorVar);
+
+ //! call the right error concealment function depending on the frame type.
+ erc_mvperMB /= dec_picture->PicSizeInMbs;
+
+ erc_img = img;
+ if(dec_picture->slice_type == I_SLICE || dec_picture->slice_type == SI_SLICE) // I-frame
+ ercConcealIntraFrame(&recfr, dec_picture->size_x, dec_picture->size_y, erc_errorVar);
+ else
+ ercConcealInterFrame(&recfr, erc_object_list, dec_picture->size_x, dec_picture->size_y, erc_errorVar, dec_picture->chroma_format_idc);
+ }
+
+ if (img->structure == FRAME) // buffer mgt. for frame mode
+ frame_postprocessing(img, input);
+ else
+ field_postprocessing(img, input); // reset all interlaced variables
+
+ structure = dec_picture->structure;
+ slice_type = dec_picture->slice_type;
+ frame_poc = dec_picture->frame_poc;
+ refpic = dec_picture->used_for_reference;
+ qp = dec_picture->qp;
+ pic_num = dec_picture->pic_num;
+
+ chroma_format_idc= dec_picture->chroma_format_idc;
+
+ store_picture_in_dpb(dec_picture);
+ dec_picture=NULL;
+
+ if (img->last_has_mmco_5)
+ {
+ img->pre_frame_num = 0;
+ }
+
+ if ((structure==FRAME)||structure==BOTTOM_FIELD)
+ {
+
+#ifdef WIN32
+ _ftime (&(img->tstruct_end)); // start time ms
+#else
+ ftime (&(img->tstruct_end)); // start time ms
+#endif
+
+ time( &(img->ltime_end)); // start time s
+
+
+ sprintf(yuvFormat,"%s", yuv_types[chroma_format_idc]);
+
+ if (input->silent == FALSE)
+ {
+ if(slice_type == I_SLICE) // I picture
+ fprintf(stdout,"%04d(I) %8d %5d %5d %7.4f %7.4f %7.4f %s %5d\n",
+ frame_no, frame_poc, pic_num, qp, snr->snr_y, snr->snr_u, snr->snr_v, yuvFormat, 0);
+ else if(slice_type == P_SLICE) // P pictures
+ fprintf(stdout,"%04d(P) %8d %5d %5d %7.4f %7.4f %7.4f %s %5d\n",
+ frame_no, frame_poc, pic_num, qp, snr->snr_y, snr->snr_u, snr->snr_v, yuvFormat, 0);
+ else if(slice_type == SP_SLICE) // SP pictures
+ fprintf(stdout,"%04d(SP) %8d %5d %5d %7.4f %7.4f %7.4f %s %5d\n",
+ frame_no, frame_poc, pic_num, qp, snr->snr_y, snr->snr_u, snr->snr_v, yuvFormat, 0);
+ else if (slice_type == SI_SLICE)
+ fprintf(stdout,"%04d(SI) %8d %5d %5d %7.4f %7.4f %7.4f %s %5d\n",
+ frame_no, frame_poc, pic_num, qp, snr->snr_y, snr->snr_u, snr->snr_v, yuvFormat, 0);
+ else if(refpic) // stored B pictures
+ fprintf(stdout,"%04d(RB) %8d %5d %5d %7.4f %7.4f %7.4f %s %5d\n",
+ frame_no, frame_poc, pic_num, qp, snr->snr_y, snr->snr_u, snr->snr_v, yuvFormat, 0);
+ else // B pictures
+ fprintf(stdout,"%04d(B) %8d %5d %5d %7.4f %7.4f %7.4f %s %5d\n",
+ frame_no, frame_poc, pic_num, qp, snr->snr_y, snr->snr_u, snr->snr_v, yuvFormat, 0);
+ }
+ else
+ fprintf(stdout,"Completed Decoding frame %05d.\r",snr->frame_ctr);
+
+ fflush(stdout);
+
+ if(slice_type == I_SLICE || slice_type == SI_SLICE || slice_type == P_SLICE || refpic) // I or P pictures
+ img->number++;
+ else
+ Bframe_ctr++; // B pictures
+ snr->frame_ctr++;
+
+ g_nFrame++;
+ }
+
+ img->current_mb_nr = -4712; // impossible value for debugging, StW
+ img->current_slice_nr = 0;
+
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * write the encoding mode and motion vectors of current
+ * MB to the buffer of the error concealment module.
+ ************************************************************************
+ */
+
+void ercWriteMBMODEandMV(struct img_par *img,struct inp_par *inp)
+{
+ extern objectBuffer_t *erc_object_list;
+ int i, ii, jj, currMBNum = img->current_mb_nr;
+ int mbx = xPosMB(currMBNum,dec_picture->size_x), mby = yPosMB(currMBNum,dec_picture->size_x);
+ objectBuffer_t *currRegion, *pRegion;
+ Macroblock *currMB = &img->mb_data[currMBNum];
+ short*** mv;
+
+ currRegion = erc_object_list + (currMBNum<<2);
+
+ if(img->type != B_SLICE) //non-B frame
+ {
+ for (i=0; i<4; i++)
+ {
+ pRegion = currRegion + i;
+ pRegion->regionMode = (currMB->mb_type ==I16MB ? REGMODE_INTRA :
+ currMB->b8mode[i]==IBLOCK ? REGMODE_INTRA_8x8 :
+ currMB->b8mode[i]==0 ? REGMODE_INTER_COPY :
+ currMB->b8mode[i]==1 ? REGMODE_INTER_PRED : REGMODE_INTER_PRED_8x8);
+ if (currMB->b8mode[i]==0 || currMB->b8mode[i]==IBLOCK) // INTRA OR COPY
+ {
+ pRegion->mv[0] = 0;
+ pRegion->mv[1] = 0;
+ pRegion->mv[2] = 0;
+ }
+ else
+ {
+ ii = 4*mbx + (i%2)*2;// + BLOCK_SIZE;
+ jj = 4*mby + (i/2)*2;
+ if (currMB->b8mode[i]>=5 && currMB->b8mode[i]<=7) // SMALL BLOCKS
+ {
+ pRegion->mv[0] = (dec_picture->mv[LIST_0][jj][ii][0] + dec_picture->mv[LIST_0][jj][ii+1][0] + dec_picture->mv[LIST_0][jj+1][ii][0] + dec_picture->mv[LIST_0][jj+1][ii+1][0] + 2)/4;
+ pRegion->mv[1] = (dec_picture->mv[LIST_0][jj][ii][1] + dec_picture->mv[LIST_0][jj][ii+1][1] + dec_picture->mv[LIST_0][jj+1][ii][1] + dec_picture->mv[LIST_0][jj+1][ii+1][1] + 2)/4;
+ }
+ else // 16x16, 16x8, 8x16, 8x8
+ {
+ pRegion->mv[0] = dec_picture->mv[LIST_0][jj][ii][0];
+ pRegion->mv[1] = dec_picture->mv[LIST_0][jj][ii][1];
+// pRegion->mv[0] = dec_picture->mv[LIST_0][4*mby+(i/2)*2][4*mbx+(i%2)*2+BLOCK_SIZE][0];
+// pRegion->mv[1] = dec_picture->mv[LIST_0][4*mby+(i/2)*2][4*mbx+(i%2)*2+BLOCK_SIZE][1];
+ }
+ erc_mvperMB += mabs(pRegion->mv[0]) + mabs(pRegion->mv[1]);
+ pRegion->mv[2] = dec_picture->ref_idx[LIST_0][jj][ii];
+ }
+ }
+ }
+ else //B-frame
+ {
+ for (i=0; i<4; i++)
+ {
+ ii = 4*mbx + (i%2)*2;// + BLOCK_SIZE;
+ jj = 4*mby + (i/2)*2;
+ pRegion = currRegion + i;
+ pRegion->regionMode = (currMB->mb_type ==I16MB ? REGMODE_INTRA :
+ currMB->b8mode[i]==IBLOCK ? REGMODE_INTRA_8x8 : REGMODE_INTER_PRED_8x8);
+ if (currMB->mb_type==I16MB || currMB->b8mode[i]==IBLOCK) // INTRA
+ {
+ pRegion->mv[0] = 0;
+ pRegion->mv[1] = 0;
+ pRegion->mv[2] = 0;
+ }
+ else
+ {
+ int idx = (dec_picture->ref_idx[0][jj][ii]<0)?1:0;
+// int idx = (currMB->b8mode[i]==0 && currMB->b8pdir[i]==2 ? LIST_0 : currMB->b8pdir[i]==1 ? LIST_1 : LIST_0);
+// int idx = currMB->b8pdir[i]==0 ? LIST_0 : LIST_1;
+ mv = dec_picture->mv[idx];
+ pRegion->mv[0] = (mv[jj][ii][0] + mv[jj][ii+1][0] + mv[jj+1][ii][0] + mv[jj+1][ii+1][0] + 2)/4;
+ pRegion->mv[1] = (mv[jj][ii][1] + mv[jj][ii+1][1] + mv[jj+1][ii][1] + mv[jj+1][ii+1][1] + 2)/4;
+ erc_mvperMB += mabs(pRegion->mv[0]) + mabs(pRegion->mv[1]);
+
+ pRegion->mv[2] = (dec_picture->ref_idx[idx][jj][ii]);
+/*
+ if (currMB->b8pdir[i]==0 || (currMB->b8pdir[i]==2 && currMB->b8mode[i]!=0)) // forward or bidirect
+ {
+ pRegion->mv[2] = (dec_picture->ref_idx[LIST_0][jj][ii]);
+ ///???? is it right, not only "img->fw_refFrArr[jj][ii-4]"
+ }
+ else
+ {
+ pRegion->mv[2] = (dec_picture->ref_idx[LIST_1][jj][ii]);
+// pRegion->mv[2] = 0;
+ }
+ */
+ }
+ }
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * set defaults for old_slice
+ * NAL unit of a picture"
+ ************************************************************************
+ */
+void init_old_slice()
+{
+ old_slice.field_pic_flag = 0;
+
+ old_slice.pps_id = INT_MAX;
+
+ old_slice.frame_num = INT_MAX;
+
+ old_slice.nal_ref_idc = INT_MAX;
+
+ old_slice.idr_flag = 0;
+
+ old_slice.pic_oder_cnt_lsb = UINT_MAX;
+ old_slice.delta_pic_oder_cnt_bottom = INT_MAX;
+
+ old_slice.delta_pic_order_cnt[0] = INT_MAX;
+ old_slice.delta_pic_order_cnt[1] = INT_MAX;
+
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * save slice parameters that are needed for checking of "first VCL
+ * NAL unit of a picture"
+ ************************************************************************
+ */
+void exit_slice()
+{
+
+ old_slice.pps_id = img->currentSlice->pic_parameter_set_id;
+
+ old_slice.frame_num = img->frame_num;
+
+ old_slice.field_pic_flag = img->field_pic_flag;
+
+ if(img->field_pic_flag)
+ {
+ old_slice.bottom_field_flag = img->bottom_field_flag;
+ }
+
+ old_slice.nal_ref_idc = img->nal_reference_idc;
+
+ old_slice.idr_flag = img->idr_flag;
+ if (img->idr_flag)
+ {
+ old_slice.idr_pic_id = img->idr_pic_id;
+ }
+
+ if (active_sps->pic_order_cnt_type == 0)
+ {
+ old_slice.pic_oder_cnt_lsb = img->pic_order_cnt_lsb;
+ old_slice.delta_pic_oder_cnt_bottom = img->delta_pic_order_cnt_bottom;
+ }
+
+ if (active_sps->pic_order_cnt_type == 1)
+ {
+ old_slice.delta_pic_order_cnt[0] = img->delta_pic_order_cnt[0];
+ old_slice.delta_pic_order_cnt[1] = img->delta_pic_order_cnt[1];
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * detect if current slice is "first VCL NAL unit of a picture"
+ ************************************************************************
+ */
+int is_new_picture()
+{
+ int result=0;
+
+ result |= (NULL==dec_picture);
+
+ result |= (old_slice.pps_id != img->currentSlice->pic_parameter_set_id);
+
+ result |= (old_slice.frame_num != img->frame_num);
+
+ result |= (old_slice.field_pic_flag != img->field_pic_flag);
+
+ if(img->field_pic_flag && old_slice.field_pic_flag)
+ {
+ result |= (old_slice.bottom_field_flag != img->bottom_field_flag);
+ }
+
+ result |= (old_slice.nal_ref_idc != img->nal_reference_idc) && ((old_slice.nal_ref_idc == 0) || (img->nal_reference_idc == 0));
+
+ result |= ( old_slice.idr_flag != img->idr_flag);
+
+ if (img->idr_flag && old_slice.idr_flag)
+ {
+ result |= (old_slice.idr_pic_id != img->idr_pic_id);
+ }
+
+ if (active_sps->pic_order_cnt_type == 0)
+ {
+ result |= (old_slice.pic_oder_cnt_lsb != img->pic_order_cnt_lsb);
+ result |= (old_slice.delta_pic_oder_cnt_bottom != img->delta_pic_order_cnt_bottom);
+ }
+
+ if (active_sps->pic_order_cnt_type == 1)
+ {
+ result |= (old_slice.delta_pic_order_cnt[0] != img->delta_pic_order_cnt[0]);
+ result |= (old_slice.delta_pic_order_cnt[1] != img->delta_pic_order_cnt[1]);
+ }
+
+ return result;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * decodes one slice
+ ************************************************************************
+ */
+void decode_one_slice(struct img_par *img,struct inp_par *inp)
+{
+
+ Boolean end_of_slice = FALSE;
+ int read_flag;
+ img->cod_counter=-1;
+
+ set_ref_pic_num();
+
+ if (img->type == B_SLICE)
+ compute_colocated(Co_located, listX);
+
+ //reset_ec_flags();
+
+ while (end_of_slice == FALSE) // loop over macroblocks
+ {
+
+#if TRACE
+ fprintf(p_trace,"\n*********** POC: %i (I/P) MB: %i Slice: %i Type %d **********\n", img->ThisPOC, img->current_mb_nr, img->current_slice_nr, img->type);
+#endif
+
+ // Initializes the current macroblock
+ start_macroblock(img, img->current_mb_nr);
+ // Get the syntax elements from the NAL
+ read_flag = read_one_macroblock(img,inp);
+ decode_one_macroblock(img,inp);
+
+ if(img->MbaffFrameFlag && dec_picture->mb_field[img->current_mb_nr])
+ {
+ img->num_ref_idx_l0_active >>= 1;
+ img->num_ref_idx_l1_active >>= 1;
+ }
+
+ ercWriteMBMODEandMV(img,inp);
+
+ end_of_slice=exit_macroblock(img,inp,(!img->MbaffFrameFlag||img->current_mb_nr%2));
+ }
+
+ exit_slice();
+ //reset_ec_flags();
+
+}
+
+
+void decode_slice(struct img_par *img,struct inp_par *inp, int current_header)
+{
+ Slice *currSlice = img->currentSlice;
+
+ if (active_pps->entropy_coding_mode_flag)
+ {
+ init_contexts (img);
+ cabac_new_slice();
+ }
+
+ if ( (active_pps->weighted_bipred_idc > 0 && (img->type == B_SLICE)) || (active_pps->weighted_pred_flag && img->type !=I_SLICE))
+ fill_wp_params(img);
+
+ //printf("frame picture %d %d %d\n",img->structure,img->ThisPOC,img->direct_spatial_mv_pred_flag);
+
+
+ // decode main slice information
+ if ((current_header == SOP || current_header == SOS) && currSlice->ei_flag == 0)
+ decode_one_slice(img,inp);
+
+ // setMB-Nr in case this slice was lost
+// if(currSlice->ei_flag)
+// img->current_mb_nr = currSlice->last_mb_nr + 1;
+
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Prepare field and frame buffer after frame decoding
+ ************************************************************************
+ */
+void frame_postprocessing(struct img_par *img, struct inp_par *inp)
+{
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Prepare field and frame buffer after field decoding
+ ************************************************************************
+ */
+void field_postprocessing(struct img_par *img, struct inp_par *inp)
+{
+ img->number /= 2;
+}
+
+
+
+void reset_wp_params(struct img_par *img)
+{
+ int i,comp;
+ int log_weight_denom;
+
+ for (i=0; i<MAX_REFERENCE_PICTURES; i++)
+ {
+ for (comp=0; comp<3; comp++)
+ {
+ log_weight_denom = (comp == 0) ? img->luma_log2_weight_denom : img->chroma_log2_weight_denom;
+ img->wp_weight[0][i][comp] = 1<<log_weight_denom;
+ img->wp_weight[1][i][comp] = 1<<log_weight_denom;
+ }
+ }
+}
+
+
+void fill_wp_params(struct img_par *img)
+{
+ int i, j, k;
+ int comp;
+ int log_weight_denom;
+ int tb, td;
+ int bframe = (img->type==B_SLICE);
+ int max_bwd_ref, max_fwd_ref;
+ int tx,DistScaleFactor;
+
+ max_fwd_ref = img->num_ref_idx_l0_active;
+ max_bwd_ref = img->num_ref_idx_l1_active;
+
+ if (active_pps->weighted_bipred_idc == 2 && bframe)
+ {
+ img->luma_log2_weight_denom = 5;
+ img->chroma_log2_weight_denom = 5;
+ img->wp_round_luma = 16;
+ img->wp_round_chroma = 16;
+
+ for (i=0; i<MAX_REFERENCE_PICTURES; i++)
+ {
+ for (comp=0; comp<3; comp++)
+ {
+ log_weight_denom = (comp == 0) ? img->luma_log2_weight_denom : img->chroma_log2_weight_denom;
+ img->wp_weight[0][i][comp] = 1<<log_weight_denom;
+ img->wp_weight[1][i][comp] = 1<<log_weight_denom;
+ img->wp_offset[0][i][comp] = 0;
+ img->wp_offset[1][i][comp] = 0;
+ }
+ }
+ }
+
+ if (bframe)
+ {
+ for (i=0; i<max_fwd_ref; i++)
+ {
+ for (j=0; j<max_bwd_ref; j++)
+ {
+ for (comp = 0; comp<3; comp++)
+ {
+ log_weight_denom = (comp == 0) ? img->luma_log2_weight_denom : img->chroma_log2_weight_denom;
+ if (active_pps->weighted_bipred_idc == 1)
+ {
+ img->wbp_weight[0][i][j][comp] = img->wp_weight[0][i][comp];
+ img->wbp_weight[1][i][j][comp] = img->wp_weight[1][j][comp];
+ }
+ else if (active_pps->weighted_bipred_idc == 2)
+ {
+ td = iClip3(-128,127,listX[LIST_1][j]->poc - listX[LIST_0][i]->poc);
+ if (td == 0 || listX[LIST_1][j]->is_long_term || listX[LIST_0][i]->is_long_term)
+ {
+ img->wbp_weight[0][i][j][comp] = 32;
+ img->wbp_weight[1][i][j][comp] = 32;
+ }
+ else
+ {
+ tb = iClip3(-128,127,img->ThisPOC - listX[LIST_0][i]->poc);
+
+ tx = (16384 + iabs(td/2))/td;
+ DistScaleFactor = iClip3(-1024, 1023, (tx*tb + 32 )>>6);
+
+ img->wbp_weight[1][i][j][comp] = DistScaleFactor >> 2;
+ img->wbp_weight[0][i][j][comp] = 64 - img->wbp_weight[1][i][j][comp];
+ if (img->wbp_weight[1][i][j][comp] < -64 || img->wbp_weight[1][i][j][comp] > 128)
+ {
+ img->wbp_weight[0][i][j][comp] = 32;
+ img->wbp_weight[1][i][j][comp] = 32;
+ img->wp_offset[0][i][comp] = 0;
+ img->wp_offset[1][j][comp] = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (bframe && img->MbaffFrameFlag)
+ {
+ for (i=0; i<2*max_fwd_ref; i++)
+ {
+ for (j=0; j<2*max_bwd_ref; j++)
+ {
+ for (comp = 0; comp<3; comp++)
+ {
+ for (k=2; k<6; k+=2)
+ {
+ img->wp_offset[k+0][i][comp] = img->wp_offset[0][i/2][comp];
+ img->wp_offset[k+1][j][comp] = img->wp_offset[1][j/2][comp];
+
+ log_weight_denom = (comp == 0) ? img->luma_log2_weight_denom : img->chroma_log2_weight_denom;
+ if (active_pps->weighted_bipred_idc == 1)
+ {
+ img->wbp_weight[k+0][i][j][comp] = img->wp_weight[0][i/2][comp];
+ img->wbp_weight[k+1][i][j][comp] = img->wp_weight[1][j/2][comp];
+ }
+ else if (active_pps->weighted_bipred_idc == 2)
+ {
+ td = iClip3(-128,127,listX[k+LIST_1][j]->poc - listX[k+LIST_0][i]->poc);
+ if (td == 0 || listX[k+LIST_1][j]->is_long_term || listX[k+LIST_0][i]->is_long_term)
+ {
+ img->wbp_weight[k+0][i][j][comp] = 32;
+ img->wbp_weight[k+1][i][j][comp] = 32;
+ }
+ else
+ {
+ tb = iClip3(-128,127,((k==2)?img->toppoc:img->bottompoc) - listX[k+LIST_0][i]->poc);
+
+ tx = (16384 + iabs(td/2))/td;
+ DistScaleFactor = iClip3(-1024, 1023, (tx*tb + 32 )>>6);
+
+ img->wbp_weight[k+1][i][j][comp] = DistScaleFactor >> 2;
+ img->wbp_weight[k+0][i][j][comp] = 64 - img->wbp_weight[k+1][i][j][comp];
+ if (img->wbp_weight[k+1][i][j][comp] < -64 || img->wbp_weight[k+1][i][j][comp] > 128)
+ {
+ img->wbp_weight[k+1][i][j][comp] = 32;
+ img->wbp_weight[k+0][i][j][comp] = 32;
+ img->wp_offset[k+0][i][comp] = 0;
+ img->wp_offset[k+1][j][comp] = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Error tracking: if current frame is lost or any reference frame of
+ * current frame is lost, current frame is incorrect.
+ ************************************************************************
+ */
+void Error_tracking()
+{
+ int i;
+
+ if(img->redundant_pic_cnt == 0)
+ {
+ Is_primary_correct = Is_redundant_correct = 1;
+ }
+
+ if(img->redundant_pic_cnt == 0 && img->type != I_SLICE)
+ {
+ for(i=0;i<img->num_ref_idx_l0_active;i++)
+ {
+ if(ref_flag[i] == 0) // any reference of primary slice is incorrect
+ {
+ Is_primary_correct = 0; // primary slice is incorrect
+ }
+ }
+ }
+ else if(img->redundant_pic_cnt != 0 && img->type != I_SLICE)
+ {
+ if(ref_flag[redundant_slice_ref_idx] == 0) // reference of redundant slice is incorrect
+ {
+ Is_redundant_correct = 0; // redundant slice is incorrect
+ }
+ }
+}
Index: llvm-test/MultiSource/Applications/JM/ldecod/image.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/image.h:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/image.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,24 @@
+
+/*!
+ ************************************************************************
+ * \file image.h
+ *
+ * \brief
+ * prototypes for image.c
+ *
+ ************************************************************************
+ */
+
+#ifndef _IMAGE_H_
+#define _IMAGE_H_
+
+#include "mbuffer.h"
+
+extern StorablePicture *dec_picture;
+
+void find_snr(struct snr_par *snr, StorablePicture *p, int p_ref);
+void get_block(int ref_frame, StorablePicture **list, int x_pos, int y_pos, struct img_par *img, int block[BLOCK_SIZE][BLOCK_SIZE]);
+int picture_order(struct img_par *img);
+
+#endif
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/ldecod.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/ldecod.c:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/ldecod.c Sun Feb 4 08:38:31 2007
@@ -0,0 +1,999 @@
+
+/*!
+ ***********************************************************************
+ * \mainpage
+ * This is the H.264/AVC decoder reference software. For detailed documentation
+ * see the comments in each file.
+ *
+ * \author
+ * The main contributors are listed in contributors.h
+ *
+ * \version
+ * JM 12.1 (FRExt)
+ *
+ * \note
+ * tags are used for document system "doxygen"
+ * available at http://www.doxygen.org
+ */
+/*!
+ * \file
+ * ldecod.c
+ * \brief
+ * H.264/AVC reference decoder project main()
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Inge Lille-Langøy <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>
+ * - Sebastian Purreiter <sebastian.purreiter at mch.siemens.de>
+ * - Byeong-Moon Jeon <jeonbm at lge.com>
+ * - Gabi Blaettermann <blaetter at hhi.de>
+ * - Ye-Kui Wang <wyk at ieee.org>
+ * - Valeri George <george at hhi.de>
+ * - Karsten Suehring <suehring at hhi.de>
+ *
+ ***********************************************************************
+ */
+
+#include "contributors.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <sys/timeb.h>
+
+#if defined WIN32
+ #include <io.h>
+#else
+ #include <unistd.h>
+#endif
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+#include <assert.h>
+
+#include "global.h"
+#include "rtp.h"
+#include "memalloc.h"
+#include "mbuffer.h"
+#include "leaky_bucket.h"
+#include "fmo.h"
+#include "annexb.h"
+#include "output.h"
+#include "cabac.h"
+#include "parset.h"
+
+#include "erc_api.h"
+
+#define JM "12 (FRExt)"
+#define VERSION "12.1"
+#define EXT_VERSION "(FRExt)"
+
+#define LOGFILE "log.dec"
+#define DATADECFILE "dataDec.txt"
+#define TRACEFILE "trace_dec.txt"
+
+extern objectBuffer_t *erc_object_list;
+extern ercVariables_t *erc_errorVar;
+extern ColocatedParams *Co_located;
+
+// I have started to move the inp and img structures into global variables.
+// They are declared in the following lines. Since inp is defined in conio.h
+// and cannot be overridden globally, it is defined here as input
+//
+// Everywhere, input-> and img-> can now be used either globally or with
+// the local override through the formal parameter mechanism
+
+extern FILE* bits;
+extern StorablePicture* dec_picture;
+
+struct inp_par *input; //!< input parameters from input configuration file
+struct snr_par *snr; //!< statistics
+struct img_par *img; //!< image parameters
+
+int global_init_done = 0;
+
+/*!
+ ***********************************************************************
+ * \brief
+ * print help message and exit
+ ***********************************************************************
+ */
+void JMDecHelpExit ()
+{
+ fprintf( stderr, "\n ldecod [-h] {[defdec.cfg] | {[-p pocScale][-i bitstream.264]...[-o output.yuv] [-r reference.yuv] [-uv]}}\n\n"
+ "## Parameters\n\n"
+
+ "## Options\n"
+ " -h : prints function usage\n"
+ " : parse <defdec.cfg> for decoder operation.\n"
+ " -i : Input file name. \n"
+ " -o : Output file name. If not specified default output is set as test_dec.yuv\n\n"
+ " -r : Reference file name. If not specified default output is set as test_rec.yuv\n\n"
+ " -p : Poc Scale. \n"
+ " -uv : write chroma components for monochrome streams(4:2:0)\n\n"
+
+ "## Supported video file formats\n"
+ " Input : .264 -> H.264 bitstream files. \n"
+ " Output: .yuv -> RAW file. Format depends on bitstream information. \n\n"
+
+ "## Examples of usage:\n"
+ " ldecod\n"
+ " ldecod -h\n"
+ " ldecod default.cfg\n"
+ " ldecod -i bitstream.264 -o output.yuv -r reference.yuv\n");
+
+ exit(-1);
+}
+
+
+void Configure(int ac, char *av[])
+{
+ int CLcount;
+ char *config_filename=NULL;
+ CLcount = 1;
+
+
+ strcpy(input->infile,"test.264"); //! set default bitstream name
+ strcpy(input->outfile,"test_dec.yuv"); //! set default output file name
+ strcpy(input->reffile,"test_rec.yuv"); //! set default reference file name
+ input->FileFormat = PAR_OF_ANNEXB;
+ input->ref_offset=0;
+ input->poc_scale=2;
+ input->silent = FALSE;
+
+#ifdef _LEAKYBUCKET_
+ input->R_decoder=500000; //! Decoder rate
+ input->B_decoder=104000; //! Decoder buffer size
+ input->F_decoder=73000; //! Decoder initial delay
+ strcpy(input->LeakyBucketParamFile,"leakybucketparam.cfg"); // file where Leaky Bucket params (computed by encoder) are stored
+#endif
+
+ if (ac==2)
+ {
+ if (0 == strncmp (av[1], "-h", 2))
+ {
+ JMDecHelpExit();
+ }
+ else if (0 == strncmp (av[1], "-s", 2))
+ {
+ input->silent = TRUE;
+ }
+ else
+ {
+ config_filename=av[1];
+ init_conf(input, av[1]);
+ }
+ CLcount=2;
+ }
+
+ if (ac>=3)
+ {
+ if (0 == strncmp (av[1], "-i", 2))
+ {
+ strcpy(input->infile,av[2]);
+ CLcount = 3;
+ }
+ if (0 == strncmp (av[1], "-h", 2))
+ {
+ JMDecHelpExit();
+ }
+ if (0 == strncmp (av[1], "-s", 2))
+ {
+ input->silent = TRUE;
+ }
+ }
+
+ // Parse the command line
+
+ while (CLcount < ac)
+ {
+ if (0 == strncmp (av[CLcount], "-h", 2))
+ {
+ JMDecHelpExit();
+ }
+
+ if (0 == strncmp (av[CLcount], "-s", 2))
+ {
+ input->silent = TRUE;
+ CLcount ++;
+ }
+
+ if (0 == strncmp (av[CLcount], "-i", 2)) //! Input file
+ {
+ strcpy(input->infile,av[CLcount+1]);
+ CLcount += 2;
+ }
+ else if (0 == strncmp (av[CLcount], "-o", 2)) //! Output File
+ {
+ strcpy(input->outfile,av[CLcount+1]);
+ CLcount += 2;
+ }
+ else if (0 == strncmp (av[CLcount], "-r", 2)) //! Reference File
+ {
+ strcpy(input->reffile,av[CLcount+1]);
+ CLcount += 2;
+ }
+ else if (0 == strncmp (av[CLcount], "-p", 2)) //! Poc Scale
+ {
+ sscanf (av[CLcount+1], "%d", &input->poc_scale);
+ CLcount += 2;
+ }
+ else if (0 == strncmp (av[CLcount], "-uv", 3)) //! indicate UV writing for 4:0:0
+ {
+ input->write_uv = 1;
+ CLcount ++;
+ }
+ else
+ {
+ //config_filename=av[CLcount];
+ //init_conf(input, config_filename);
+ snprintf(errortext, ET_SIZE, "Invalid syntax. Use ldecod -h for proper usage");
+ error(errortext, 300);
+ }
+ }
+
+
+#if TRACE
+ if ((p_trace=fopen(TRACEFILE,"w"))==0) // append new statistic at the end
+ {
+ snprintf(errortext, ET_SIZE, "Error open file %s!",TRACEFILE);
+ error(errortext,500);
+ }
+#endif
+
+
+ if ((p_out=open(input->outfile, OPENFLAGS_WRITE, OPEN_PERMISSIONS))==-1)
+ {
+ snprintf(errortext, ET_SIZE, "Error open file %s ",input->outfile);
+ error(errortext,500);
+ }
+/* if ((p_out2=fopen("out.yuv","wb"))==0)
+ {
+ snprintf(errortext, ET_SIZE, "Error open file %s ",input->outfile);
+ error(errortext,500);
+ }*/
+
+
+ fprintf(stdout,"----------------------------- JM %s %s -----------------------------\n", VERSION, EXT_VERSION);
+ fprintf(stdout," Decoder config file : %s \n",config_filename);
+ fprintf(stdout,"--------------------------------------------------------------------------\n");
+ fprintf(stdout," Input H.264 bitstream : %s \n",input->infile);
+ fprintf(stdout," Output decoded YUV : %s \n",input->outfile);
+ fprintf(stdout," Output status file : %s \n",LOGFILE);
+ if ((p_ref=open(input->reffile,OPENFLAGS_READ))==-1)
+ {
+ fprintf(stdout," Input reference file : %s does not exist \n",input->reffile);
+ fprintf(stdout," SNR values are not available\n");
+ }
+ else
+ fprintf(stdout," Input reference file : %s \n",input->reffile);
+
+ fprintf(stdout,"--------------------------------------------------------------------------\n");
+#ifdef _LEAKYBUCKET_
+ fprintf(stdout," Rate_decoder : %8ld \n",input->R_decoder);
+ fprintf(stdout," B_decoder : %8ld \n",input->B_decoder);
+ fprintf(stdout," F_decoder : %8ld \n",input->F_decoder);
+ fprintf(stdout," LeakyBucketParamFile: %s \n",input->LeakyBucketParamFile); // Leaky Bucket Param file
+ calc_buffer(input);
+ fprintf(stdout,"--------------------------------------------------------------------------\n");
+#endif
+ fprintf(stdout,"POC must = frame# or field# for SNRs to be correct\n");
+ fprintf(stdout,"--------------------------------------------------------------------------\n");
+ fprintf(stdout," Frame POC Pic# QP SnrY SnrU SnrV Y:U:V Time(ms)\n");
+ fprintf(stdout,"--------------------------------------------------------------------------\n");
+
+}
+
+/*!
+ ***********************************************************************
+ * \brief
+ * main function for TML decoder
+ ***********************************************************************
+ */
+int main(int argc, char **argv)
+{
+ int i;
+
+ // allocate memory for the structures
+ if ((input = (struct inp_par *)calloc(1, sizeof(struct inp_par)))==NULL) no_mem_exit("main: input");
+ if ((snr = (struct snr_par *)calloc(1, sizeof(struct snr_par)))==NULL) no_mem_exit("main: snr");
+ if ((img = (struct img_par *)calloc(1, sizeof(struct img_par)))==NULL) no_mem_exit("main: img");
+
+
+ Configure (argc, argv);
+
+ init_old_slice();
+
+ switch (input->FileFormat)
+ {
+ case 0:
+ OpenBitstreamFile (input->infile);
+ break;
+ case 1:
+ OpenRTPFile (input->infile);
+ break;
+ default:
+ printf ("Unsupported file format %d, exit\n", input->FileFormat);
+ }
+
+ // Allocate Slice data struct
+ malloc_slice(input,img);
+
+ init(img);
+
+ dec_picture = NULL;
+
+ dpb.init_done = 0;
+ g_nFrame = 0;
+
+ init_out_buffer();
+
+ img->idr_psnr_number=input->ref_offset;
+ img->psnr_number=0;
+
+ img->number=0;
+ img->type = I_SLICE;
+ img->dec_ref_pic_marking_buffer = NULL;
+
+ // B pictures
+ Bframe_ctr=snr->frame_ctr=0;
+
+ // time for total decoding session
+ tot_time = 0;
+
+ // reference flag initialization
+ for(i=0;i<17;i++)
+ {
+ ref_flag[i]=1;
+ }
+
+ while (decode_one_frame(img, input, snr) != EOS)
+ ;
+
+ report(input, img, snr);
+ free_slice(input,img);
+ FmoFinit();
+ free_global_buffers();
+
+ flush_dpb();
+
+#ifdef PAIR_FIELDS_IN_OUTPUT
+ flush_pending_output(p_out);
+#endif
+
+ CloseBitstreamFile();
+
+ close(p_out);
+// fclose(p_out2);
+ if (p_ref!=-1)
+ close(p_ref);
+#if TRACE
+ fclose(p_trace);
+#endif
+
+ ercClose(erc_errorVar);
+
+ CleanUpPPS();
+
+ free_dpb();
+ uninit_out_buffer();
+ free_colocated(Co_located);
+ free (input);
+ free (snr);
+ free (img);
+
+ //while( !kbhit() );
+ return 0;
+}
+
+
+/*!
+ ***********************************************************************
+ * \brief
+ * Initilize some arrays
+ ***********************************************************************
+ */
+void init(struct img_par *img) //!< image parameters
+{
+ img->oldFrameSizeInMbs = -1;
+
+ imgY_ref = NULL;
+ imgUV_ref = NULL;
+
+ img->recovery_point = 0;
+ img->recovery_point_found = 0;
+ img->recovery_poc = 0x7fffffff; /* set to a max value */
+}
+
+/*!
+ ***********************************************************************
+ * \brief
+ * Initialize FREXT variables
+ ***********************************************************************
+ */
+void init_frext(struct img_par *img) //!< image parameters
+{
+ //pel bitdepth init
+ img->bitdepth_luma_qp_scale = 6*(img->bitdepth_luma - 8);
+ if(img->bitdepth_luma > img->bitdepth_chroma || active_sps->chroma_format_idc == YUV400)
+ img->pic_unit_bitsize_on_disk = (img->bitdepth_luma > 8)? 16:8;
+ else
+ img->pic_unit_bitsize_on_disk = (img->bitdepth_chroma > 8)? 16:8;
+ img->dc_pred_value_luma = 1<<(img->bitdepth_luma - 1);
+ img->max_imgpel_value = (1<<img->bitdepth_luma) - 1;
+ img->mb_size[0][0] = img->mb_size[0][1] = MB_BLOCK_SIZE;
+
+ if (active_sps->chroma_format_idc != YUV400)
+ {
+ //for chrominance part
+ img->bitdepth_chroma_qp_scale = 6*(img->bitdepth_chroma - 8);
+ img->dc_pred_value_chroma = 1<<(img->bitdepth_chroma - 1);
+ img->max_imgpel_value_uv = (1<<img->bitdepth_chroma) - 1;
+ img->num_blk8x8_uv = (1<<active_sps->chroma_format_idc)&(~(0x1));
+ img->num_cdc_coeff = img->num_blk8x8_uv<<1;
+ img->mb_size[1][0] = img->mb_size[2][0] = img->mb_cr_size_x = (active_sps->chroma_format_idc==YUV420 || active_sps->chroma_format_idc==YUV422)? 8:16;
+ img->mb_size[1][1] = img->mb_size[2][1] = img->mb_cr_size_y = (active_sps->chroma_format_idc==YUV444 || active_sps->chroma_format_idc==YUV422)? 16:8;
+ }
+ else
+ {
+ img->bitdepth_chroma_qp_scale = 0;
+ img->max_imgpel_value_uv = 0;
+ img->num_blk8x8_uv = 0;
+ img->num_cdc_coeff = 0;
+ img->mb_size[1][0] = img->mb_size[2][0] = img->mb_cr_size_x = 0;
+ img->mb_size[1][1] = img->mb_size[2][1] = img->mb_cr_size_y = 0;
+ }
+ img->mb_size_blk[0][0] = img->mb_size_blk[0][1] = img->mb_size[0][0] >> 2;
+ img->mb_size_blk[1][0] = img->mb_size_blk[2][0] = img->mb_size[1][0] >> 2;
+ img->mb_size_blk[1][1] = img->mb_size_blk[2][1] = img->mb_size[1][1] >> 2;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Read input from configuration file
+ *
+ * \par Input:
+ * Name of configuration filename
+ *
+ * \par Output
+ * none
+ ************************************************************************
+ */
+void init_conf(struct inp_par *inp, char *config_filename)
+{
+ FILE *fd;
+ int NAL_mode;
+
+ // picture error concealment
+ long int temp;
+ char tempval[100];
+
+ // read the decoder configuration file
+ if((fd=fopen(config_filename,"r")) == NULL)
+ {
+ snprintf(errortext, ET_SIZE, "Error: Control file %s not found\n",config_filename);
+ error(errortext, 300);
+ }
+
+ fscanf(fd,"%s",inp->infile); // H.264 compressed input bitstream
+ fscanf(fd,"%*[^\n]");
+
+ fscanf(fd,"%s",inp->outfile); // RAW (YUV/RGB) output file
+ fscanf(fd,"%*[^\n]");
+
+ fscanf(fd,"%s",inp->reffile); // reference file
+ fscanf(fd,"%*[^\n]");
+
+ fscanf(fd,"%d",&(inp->write_uv)); // write UV in YUV 4:0:0 mode
+ fscanf(fd,"%*[^\n]");
+
+ fscanf(fd,"%d",&(NAL_mode)); // NAL mode
+ fscanf(fd,"%*[^\n]");
+
+ switch(NAL_mode)
+ {
+ case 0:
+ inp->FileFormat = PAR_OF_ANNEXB;
+ break;
+ case 1:
+ inp->FileFormat = PAR_OF_RTP;
+ break;
+ default:
+ snprintf(errortext, ET_SIZE, "NAL mode %i is not supported", NAL_mode);
+ error(errortext,400);
+ }
+
+ fscanf(fd,"%d,",&inp->ref_offset); // offset used for SNR computation
+ fscanf(fd,"%*[^\n]");
+
+ fscanf(fd,"%d,",&inp->poc_scale); // offset used for SNR computation
+ fscanf(fd,"%*[^\n]");
+
+
+ if (inp->poc_scale < 1 || inp->poc_scale > 10)
+ {
+ snprintf(errortext, ET_SIZE, "Poc Scale is %d. It has to be within range 1 to 10",inp->poc_scale);
+ error(errortext,1);
+ }
+
+ inp->write_uv=1;
+
+ // picture error concealment
+ img->conceal_mode = inp->conceal_mode = 0;
+ img->ref_poc_gap = inp->ref_poc_gap = 2;
+ img->poc_gap = inp->poc_gap = 2;
+
+#ifdef _LEAKYBUCKET_
+ fscanf(fd,"%ld,",&inp->R_decoder); // Decoder rate
+ fscanf(fd, "%*[^\n]");
+ fscanf(fd,"%ld,",&inp->B_decoder); // Decoder buffer size
+ fscanf(fd, "%*[^\n]");
+ fscanf(fd,"%ld,",&inp->F_decoder); // Decoder initial delay
+ fscanf(fd, "%*[^\n]");
+ fscanf(fd,"%s",inp->LeakyBucketParamFile); // file where Leaky Bucket params (computed by encoder) are stored
+ fscanf(fd,"%*[^\n]");
+#endif
+
+ /* since error concealment parameters are added at the end of
+ decoder conf file we need to read the leakybucket params to get to
+ those parameters */
+#ifndef _LEAKYBUCKET_
+ fscanf(fd,"%ld,",&temp);
+ fscanf(fd, "%*[^\n]");
+ fscanf(fd,"%ld,",&temp);
+ fscanf(fd, "%*[^\n]");
+ fscanf(fd,"%ld,",&temp);
+ fscanf(fd, "%*[^\n]");
+ fscanf(fd,"%s",tempval);
+ fscanf(fd,"%*[^\n]");
+#endif
+
+ fscanf(fd,"%d",&inp->conceal_mode); // Mode of Error Concealment
+ fscanf(fd,"%*[^\n]");
+ img->conceal_mode = inp->conceal_mode;
+ fscanf(fd,"%d",&inp->ref_poc_gap); // POC gap depending on pattern
+ fscanf(fd,"%*[^\n]");
+ img->ref_poc_gap = inp->ref_poc_gap;
+ fscanf(fd,"%d",&inp->poc_gap); // POC gap between consecutive frames in display order
+ fscanf(fd,"%*[^\n]");
+ img->poc_gap = inp->poc_gap;
+ fscanf(fd,"%d,",&inp->silent); // use silent decode mode
+ fscanf(fd,"%*[^\n]");
+
+ fclose (fd);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Reports the gathered information to appropriate outputs
+ *
+ * \par Input:
+ * struct inp_par *inp,
+ * struct img_par *img,
+ * struct snr_par *stat
+ *
+ * \par Output:
+ * None
+ ************************************************************************
+ */
+void report(struct inp_par *inp, struct img_par *img, struct snr_par *snr)
+{
+ #define OUTSTRING_SIZE 255
+ char string[OUTSTRING_SIZE];
+ FILE *p_log;
+ char yuv_formats[4][4]= { {"400"}, {"420"}, {"422"}, {"444"} };
+
+#ifndef WIN32
+ time_t now;
+ struct tm *l_time;
+#else
+ char timebuf[128];
+#endif
+
+ if (input->silent == FALSE)
+ {
+ fprintf(stdout,"-------------------- Average SNR all frames ------------------------------\n");
+ 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,"--------------------------------------------------------------------------\n");
+ fprintf(stdout," Exit JM %s decoder, ver %s ",JM, VERSION);
+ fprintf(stdout,"\n");
+ }
+ else
+ {
+ fprintf(stdout,"\n----------------------- Decoding Completed -------------------------------\n");
+ fprintf(stdout,"--------------------------------------------------------------------------\n");
+ fprintf(stdout," Exit JM %s decoder, ver %s ",JM, VERSION);
+ fprintf(stdout,"\n");
+ }
+
+ // write to log file
+
+ snprintf(string, OUTSTRING_SIZE, "%s", LOGFILE);
+ if ((p_log=fopen(string,"r"))==0) // check if file exist
+ {
+ if ((p_log=fopen(string,"a"))==0)
+ {
+ snprintf(errortext, ET_SIZE, "Error open file %s for appending",string);
+ error(errortext, 500);
+ }
+ else // Create header to new file
+ {
+ fprintf(p_log," -------------------------------------------------------------------------------------------------------------------\n");
+ fprintf(p_log,"| Decoder statistics. This file is made first time, later runs are appended |\n");
+ fprintf(p_log," ------------------------------------------------------------------------------------------------------------------- \n");
+ fprintf(p_log,"| ver | Date | Time | Sequence |#Img| Format | YUV |Coding|SNRY 1|SNRU 1|SNRV 1|SNRY N|SNRU N|SNRV N|\n");
+ fprintf(p_log," -------------------------------------------------------------------------------------------------------------------\n");
+ }
+ }
+ else
+ {
+ fclose(p_log);
+ p_log=fopen(string,"a"); // File exist,just open for appending
+ }
+
+ 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
+
+ fprintf(p_log,"%20.20s|",inp->infile);
+
+ fprintf(p_log,"%3d |",img->number);
+ fprintf(p_log,"%4dx%-4d|", img->width, img->height);
+ fprintf(p_log," %s |", &(yuv_formats[img->yuv_format][0]));
+
+ if (active_pps)
+ {
+ if (active_pps->entropy_coding_mode_flag == UVLC)
+ fprintf(p_log," CAVLC|");
+ else
+ fprintf(p_log," CABAC|");
+ }
+
+
+ fprintf(p_log,"%6.3f|",snr->snr_y1);
+ fprintf(p_log,"%6.3f|",snr->snr_u1);
+ fprintf(p_log,"%6.3f|",snr->snr_v1);
+ fprintf(p_log,"%6.3f|",snr->snr_ya);
+ fprintf(p_log,"%6.3f|",snr->snr_ua);
+ fprintf(p_log,"%6.3f|\n",snr->snr_va);
+
+ fclose(p_log);
+
+ snprintf(string, OUTSTRING_SIZE,"%s", DATADECFILE);
+ p_log=fopen(string,"a");
+
+ if(Bframe_ctr != 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\n",
+ img->number, 0, img->qp,
+ snr->snr_y1,
+ snr->snr_u1,
+ snr->snr_v1,
+ 0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0,
+ snr->snr_ya,
+ snr->snr_ua,
+ snr->snr_va,
+ 0);
+ }
+ else
+ {
+ 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\n",
+ img->number, 0, img->qp,
+ snr->snr_y1,
+ snr->snr_u1,
+ snr->snr_v1,
+ 0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0,
+ snr->snr_ya,
+ snr->snr_ua,
+ snr->snr_va,
+ 0);
+ }
+ fclose(p_log);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocates a stand-alone partition structure. Structure should
+ * be freed by FreePartition();
+ * data structures
+ *
+ * \par Input:
+ * n: number of partitions in the array
+ * \par return
+ * pointer to DataPartition Structure, zero-initialized
+ ************************************************************************
+ */
+
+DataPartition *AllocPartition(int n)
+{
+ DataPartition *partArr, *dataPart;
+ int i;
+
+ partArr = (DataPartition *) calloc(n, sizeof(DataPartition));
+ if (partArr == NULL)
+ {
+ snprintf(errortext, ET_SIZE, "AllocPartition: Memory allocation for Data Partition failed");
+ error(errortext, 100);
+ }
+
+ for (i=0; i<n; i++) // loop over all data partitions
+ {
+ dataPart = &(partArr[i]);
+ dataPart->bitstream = (Bitstream *) calloc(1, sizeof(Bitstream));
+ if (dataPart->bitstream == NULL)
+ {
+ snprintf(errortext, ET_SIZE, "AllocPartition: Memory allocation for Bitstream failed");
+ error(errortext, 100);
+ }
+ dataPart->bitstream->streamBuffer = (byte *) calloc(MAX_CODED_FRAME_SIZE, sizeof(byte));
+ if (dataPart->bitstream->streamBuffer == NULL)
+ {
+ snprintf(errortext, ET_SIZE, "AllocPartition: Memory allocation for streamBuffer failed");
+ error(errortext, 100);
+ }
+ }
+ return partArr;
+}
+
+
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Frees a partition structure (array).
+ *
+ * \par Input:
+ * Partition to be freed, size of partition Array (Number of Partitions)
+ *
+ * \par return
+ * None
+ *
+ * \note
+ * n must be the same as for the corresponding call of AllocPartition
+ ************************************************************************
+ */
+
+
+void FreePartition (DataPartition *dp, int n)
+{
+ int i;
+
+ assert (dp != NULL);
+ assert (dp->bitstream != NULL);
+ assert (dp->bitstream->streamBuffer != NULL);
+ for (i=0; i<n; i++)
+ {
+ free (dp[i].bitstream->streamBuffer);
+ free (dp[i].bitstream);
+ }
+ free (dp);
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocates the slice structure along with its dependent
+ * data structures
+ *
+ * \par Input:
+ * Input Parameters struct inp_par *inp, struct img_par *img
+ ************************************************************************
+ */
+void malloc_slice(struct inp_par *inp, struct img_par *img)
+{
+ Slice *currSlice;
+
+ img->currentSlice = (Slice *) calloc(1, sizeof(Slice));
+ if ( (currSlice = img->currentSlice) == NULL)
+ {
+ snprintf(errortext, ET_SIZE, "Memory allocation for Slice datastruct in NAL-mode %d failed", inp->FileFormat);
+ error(errortext,100);
+ }
+// img->currentSlice->rmpni_buffer=NULL;
+ //! you don't know whether we do CABAC hre, hence initialize CABAC anyway
+ // if (inp->symbol_mode == CABAC)
+ if (1)
+ {
+ // create all context models
+ currSlice->mot_ctx = create_contexts_MotionInfo();
+ currSlice->tex_ctx = create_contexts_TextureInfo();
+ }
+ currSlice->max_part_nr = 3; //! assume data partitioning (worst case) for the following mallocs()
+ currSlice->partArr = AllocPartition(currSlice->max_part_nr);
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Memory frees of the Slice structure and of its dependent
+ * data structures
+ *
+ * \par Input:
+ * Input Parameters struct inp_par *inp, struct img_par *img
+ ************************************************************************
+ */
+void free_slice(struct inp_par *inp, struct img_par *img)
+{
+ Slice *currSlice = img->currentSlice;
+
+ FreePartition (currSlice->partArr, 3);
+// if (inp->symbol_mode == CABAC)
+ if (1)
+ {
+ // delete all context models
+ delete_contexts_MotionInfo(currSlice->mot_ctx);
+ delete_contexts_TextureInfo(currSlice->tex_ctx);
+ }
+ free(img->currentSlice);
+
+ currSlice = NULL;
+}
+
+/*!
+ ************************************************************************
+ * \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, Image Parameters struct img_par *img
+ *
+ * \par Output:
+ * Number of allocated bytes
+ ***********************************************************************
+ */
+int init_global_buffers()
+{
+ int memory_size=0;
+ int quad_range, i;
+
+ if (global_init_done)
+ {
+ free_global_buffers();
+ }
+
+ // allocate memory for reference frame in find_snr
+ memory_size += get_mem2Dpel(&imgY_ref, img->height, img->width);
+
+ if (active_sps->chroma_format_idc != YUV400)
+ memory_size += get_mem3Dpel(&imgUV_ref, 2, img->height_cr, img->width_cr);
+ else
+ imgUV_ref=NULL;
+
+ // allocate memory in structure img
+ if(((img->mb_data) = (Macroblock *) calloc(img->FrameSizeInMbs, sizeof(Macroblock))) == NULL)
+ no_mem_exit("init_global_buffers: img->mb_data");
+
+ if(((img->intra_block) = (int*)calloc(img->FrameSizeInMbs, sizeof(int))) == NULL)
+ no_mem_exit("init_global_buffers: img->intra_block");
+
+ memory_size += get_mem2Dint(&PicPos,img->FrameSizeInMbs + 1,2); //! Helper array to access macroblock positions. We add 1 to also consider last MB.
+
+ for (i = 0; i < (int) img->FrameSizeInMbs + 1;i++)
+ {
+ PicPos[i][0] = (i % img->PicWidthInMbs);
+ PicPos[i][1] = (i / img->PicWidthInMbs);
+ }
+
+ memory_size += get_mem2D(&(img->ipredmode), 4*img->FrameHeightInMbs, 4*img->PicWidthInMbs);
+
+ memory_size += get_mem3Dint(&(img->wp_weight), 2, MAX_REFERENCE_PICTURES, 3);
+ memory_size += get_mem3Dint(&(img->wp_offset), 6, MAX_REFERENCE_PICTURES, 3);
+ memory_size += get_mem4Dint(&(img->wbp_weight), 6, MAX_REFERENCE_PICTURES, MAX_REFERENCE_PICTURES, 3);
+
+ // CAVLC mem
+ memory_size += get_mem3Dint(&(img->nz_coeff), img->FrameSizeInMbs, 4, 4 + img->num_blk8x8_uv);
+
+ memory_size += get_mem2Dint(&(img->siblock), img->FrameHeightInMbs, img->PicWidthInMbs);
+
+ if(img->max_imgpel_value > img->max_imgpel_value_uv || active_sps->chroma_format_idc == YUV400)
+ quad_range = (img->max_imgpel_value + 1) * 2;
+ else
+ quad_range = (img->max_imgpel_value_uv + 1) * 2;
+
+ if ((img->quad = (int*)calloc (quad_range, sizeof(int))) == NULL)
+ no_mem_exit ("init_img: img->quad");
+
+ img->quad+=quad_range/2;
+ for (i=0; i < quad_range/2; ++i)
+ {
+ img->quad[i]=img->quad[-i]=i*i;
+ }
+
+ global_init_done = 1;
+
+ img->oldFrameSizeInMbs = img->FrameSizeInMbs;
+
+ return (memory_size);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Free allocated memory of frame size related global buffers
+ * buffers are defined in global.h, allocated memory is allocated in
+ * int init_global_buffers()
+ *
+ * \par Input:
+ * Input Parameters struct inp_par *inp, Image Parameters struct img_par *img
+ *
+ * \par Output:
+ * none
+ *
+ ************************************************************************
+ */
+void free_global_buffers()
+{
+ free_mem2Dpel (imgY_ref);
+ if (imgUV_ref)
+ free_mem3Dpel (imgUV_ref,2);
+
+ // CAVLC free mem
+ free_mem3Dint(img->nz_coeff, img->oldFrameSizeInMbs);
+
+ free_mem2Dint(img->siblock);
+
+ // free mem, allocated for structure img
+ if (img->mb_data != NULL)
+ free(img->mb_data);
+
+ free_mem2Dint(PicPos);
+
+ free (img->intra_block);
+ free_mem2D(img->ipredmode);
+
+ free_mem3Dint(img->wp_weight, 2);
+ free_mem3Dint(img->wp_offset, 6);
+ free_mem4Dint(img->wbp_weight, 6, MAX_REFERENCE_PICTURES);
+
+ 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));
+
+ global_init_done = 0;
+
+}
+
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/leaky_bucket.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/leaky_bucket.c:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/leaky_bucket.c Sun Feb 4 08:38:31 2007
@@ -0,0 +1,138 @@
+
+/*!
+ ************************************************************************
+ * \file leaky_bucket.c
+ *
+ * \brief
+ * Calculate if decoder leaky bucket parameters meets HRD constraints specified by encoder.
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Shankar Regunathan <shanre at microsoft.com>
+ ************************************************************************
+ */
+
+#include "contributors.h"
+#include "global.h"
+#include "stdlib.h"
+
+#ifdef _LEAKYBUCKET_
+/*!
+ ***********************************************************************
+ * \brief
+ * Function to get unsigned long word from a file.
+ * \param fp
+ * Filepointer
+ * \return
+ * unsigned long double word
+ * \par SideEffects
+ * None.
+ * \par Notes
+ * File should be opened to read in binary format.
+ * \author
+ * Shankar Regunathan shanre at microsoft.com
+ * \date
+ * December 06, 2001.
+ ***********************************************************************
+ */
+/* gets unsigned double stored in Big Endian Order */
+unsigned long GetBigDoubleWord(FILE *fp)
+{
+ register unsigned long dw;
+ dw = (unsigned long) (fgetc(fp) & 0xFF);
+ dw = ((unsigned long) (fgetc(fp) & 0xFF)) | (dw << 0x08);
+ dw = ((unsigned long) (fgetc(fp) & 0xFF)) | (dw << 0x08);
+ dw = ((unsigned long) (fgetc(fp) & 0xFF)) | (dw << 0x08);
+ return(dw);
+}
+
+/*!
+ ***********************************************************************
+ * \brief
+ * Calculates if decoder leaky bucket parameters meets HRD constraints specified by encoder.
+ * \param inp
+ * Structure which contains decoder leaky bucket parameters.
+ * \return
+ * None
+ * \par SideEffects
+ * None.
+ * \par Notes
+ * Failure if LeakyBucketParam file is missing or if it does not have
+ * the correct number of entries.
+ * \author
+ * Shankar Regunathan shanre at microsoft.com
+ * \date
+ * December 06, 2001.
+ ***********************************************************************
+ */
+
+/* Main Routine to verify HRD compliance */
+void calc_buffer(struct inp_par *inp)
+{
+ unsigned long NumberLeakyBuckets, *Rmin, *Bmin, *Fmin;
+ float B_interp, F_interp;
+ unsigned long iBucket;
+ float dnr, frac1, frac2;
+ unsigned long R_decoder, B_decoder, F_decoder;
+ FILE *outf;
+
+ if ((outf=fopen(inp->LeakyBucketParamFile,"rb"))==NULL)
+ {
+ snprintf(errortext, ET_SIZE, "Error open file %s \n",inp->LeakyBucketParamFile);
+ error(errortext,1);
+ }
+
+ NumberLeakyBuckets = GetBigDoubleWord(outf);
+ printf(" Number Leaky Buckets: %8ld \n\n", NumberLeakyBuckets);
+ Rmin = calloc(sizeof(unsigned long), NumberLeakyBuckets);
+ Bmin = calloc(sizeof(unsigned long), NumberLeakyBuckets);
+ Fmin = calloc(sizeof(unsigned long), NumberLeakyBuckets);
+
+ for(iBucket =0; iBucket < NumberLeakyBuckets; iBucket++)
+ {
+ Rmin[iBucket] = GetBigDoubleWord(outf);
+ Bmin[iBucket] = GetBigDoubleWord(outf);
+ Fmin[iBucket] = GetBigDoubleWord(outf);
+ printf(" %8ld %8ld %8ld \n", Rmin[iBucket], Bmin[iBucket], Fmin[iBucket]);
+ }
+ fclose(outf);
+
+ R_decoder = inp->R_decoder;
+ F_decoder = inp->F_decoder;
+ B_decoder = inp->B_decoder;
+
+ for( iBucket =0; iBucket < NumberLeakyBuckets; iBucket++)
+ {
+ if(R_decoder < Rmin[iBucket])
+ break;
+ }
+
+ printf("\n");
+ if(iBucket > 0 ) {
+ if(iBucket < NumberLeakyBuckets) {
+ dnr = (float) (Rmin[iBucket] - Rmin[iBucket-1]);
+ frac1 = (float) (R_decoder - Rmin[iBucket-1]);
+ frac2 = (float) (Rmin[iBucket] - R_decoder);
+ B_interp = (float) (Bmin[iBucket] * frac1 + Bmin[iBucket-1] * frac2) /dnr;
+ F_interp = (float) (Fmin[iBucket] * frac1 + Fmin[iBucket-1] * frac2) /dnr;
+ }
+ else {
+ B_interp = (float) Bmin[iBucket-1];
+ F_interp = (float) Fmin[iBucket-1];
+ }
+ printf(" Min.buffer %8.2f Decoder buffer size %ld \n Minimum Delay %8.2f DecoderDelay %ld \n", B_interp, B_decoder, F_interp, F_decoder);
+ if(B_decoder > B_interp && F_decoder > F_interp)
+ printf(" HRD Compliant \n");
+ else
+ printf(" HRD Non Compliant \n");
+ }
+ else { // (iBucket = 0)
+ printf(" Decoder Rate is too small; HRD cannot be verified \n");
+ }
+
+ free(Rmin);
+ free(Bmin);
+ free(Fmin);
+ return;
+}
+#endif
Index: llvm-test/MultiSource/Applications/JM/ldecod/leaky_bucket.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/leaky_bucket.h:1.3
--- /dev/null Sun Feb 4 08:38:52 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/leaky_bucket.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,26 @@
+
+/*!
+ *************************************************************************************
+ * \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_
+
+#include "global.h"
+
+#ifdef _LEAKYBUCKET_
+// Leaky Bucket functions
+unsigned long GetBigDoubleWord(FILE *fp);
+void calc_buffer(struct inp_par *inp);
+#endif
+
+#endif
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/loopFilter.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/loopFilter.c:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/loopFilter.c Sun Feb 4 08:38:31 2007
@@ -0,0 +1,476 @@
+
+/*!
+ *************************************************************************************
+ * \file loopFilter.c
+ *
+ * \brief
+ * Filter to reduce blocking artifacts on a macroblock level.
+ * The filter strength 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 <string.h>
+#include <assert.h>
+#include "global.h"
+#include "image.h"
+#include "mb_access.h"
+#include "loopfilter.h"
+
+byte mixedModeEdgeFlag, fieldModeFilteringFlag;
+
+/*********************************************************************************************************/
+
+
+// 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
+
+static const 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} ;
+static const 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} ;
+static const 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}
+} ;
+
+static const 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],struct img_par *img,int MbQAddr,int dir,int edge, int mvlimit,StorablePicture *p);
+void EdgeLoop(imgpel** Img, byte Strength[16],struct img_par *img, int MbQAddr, int AlphaC0Offset, int BetaOffset, int dir, int edge, int width, int yuv, int uv, StorablePicture *p);
+void DeblockMb(ImageParameters *img, StorablePicture *p, int MbQAddr) ;
+
+/*!
+ *****************************************************************************************
+ * \brief
+ * Filter all macroblocks in order of increasing macroblock address.
+ *****************************************************************************************
+ */
+void DeblockPicture(ImageParameters *img, StorablePicture *p)
+{
+ unsigned i;
+
+ for (i=0; i<p->PicSizeInMbs; i++)
+ {
+ DeblockMb( img, p, i ) ;
+ }
+}
+
+
+/*!
+ *****************************************************************************************
+ * \brief
+ * Deblocking filter for one macroblock.
+ *****************************************************************************************
+ */
+
+void DeblockMb(ImageParameters *img, StorablePicture *p, 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;
+ imgpel **imgY = p->imgY;
+ imgpel ***imgUV = p->imgUV;
+
+ int edge_cr;
+
+ img->DeblockCall = 1;
+ get_mb_pos (MbQAddr, &mb_x, &mb_y, IS_LUMA);
+
+ 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 (p->MbaffFrameFlag && mb_y==16 && MbQ->mb_field)
+ filterTopMbEdgeFlag = 0;
+
+ fieldModeMbFlag = (p->structure!=FRAME) || (p->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 (p->MbaffFrameFlag && !MbQ->mb_field && (MbQAddr & 0x01))
+ 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][p->chroma_format_idc];
+
+ GetStrength(Strength,img,MbQAddr,dir,edge, mvlimit, p); // Strength for 4 blks in 1 stripe
+ StrengthSum = Strength[0];
+ for (i = 1; i < 16; i++)
+ {
+ if (StrengthSum) break;
+ 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, p->size_x, 0, 0, p) ;
+ if( (imgUV != NULL) && (edge_cr >= 0))
+ {
+ EdgeLoop( imgUV[0], Strength, img, MbQAddr, MbQ->LFAlphaC0Offset, MbQ->LFBetaOffset, dir, edge_cr, p->size_x_cr, 1, 0, p) ;
+ EdgeLoop( imgUV[1], Strength, img, MbQAddr, MbQ->LFAlphaC0Offset, MbQ->LFBetaOffset, dir, edge_cr, p->size_x_cr, 1, 1, p) ;
+ }
+ }
+
+ 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, p); // 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, p->size_x, 0, 0, p) ;
+ if( (imgUV != NULL) && (edge_cr >= 0))
+ {
+ EdgeLoop( imgUV[0], Strength, img, MbQAddr, MbQ->LFAlphaC0Offset, MbQ->LFBetaOffset, dir, 4, p->size_x_cr, 1, 0, p) ;
+ EdgeLoop( imgUV[1], Strength, img, MbQAddr, MbQ->LFAlphaC0Offset, MbQ->LFBetaOffset, dir, 4, p->size_x_cr, 1, 1, p) ;
+ }
+ }
+ 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)
+ *********************************************************************************************
+ */
+
+#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],struct img_par *img,int MbQAddr,int dir,int edge, int mvlimit, StorablePicture *p)
+{
+ int blkP, blkQ, idx;
+ int blk_x, blk_x2, blk_y, blk_y2 ;
+ short ***list0_mv = p->mv[LIST_0];
+ short ***list1_mv = p->mv[LIST_1];
+ char **list0_refIdxArr = p->ref_idx[LIST_0];
+ char **list1_refIdxArr = p->ref_idx[LIST_1];
+ int64 **list0_refPicIdArr = p->ref_pic_id[LIST_0];
+ int64 **list1_refPicIdArr = p->ref_pic_id[LIST_1];
+ int64 ref_p0,ref_p1,ref_q0,ref_q1;
+ int xQ, xP, yQ, yP;
+ int mb_x, mb_y;
+ Macroblock *MbQ, *MbP;
+ PixelPos pixP;
+ int dir_m1 = (1 - dir);
+
+ 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 - dir_m1, yQ - dir, IS_LUMA, &pixP);
+ xP = pixP.x;
+ yP = pixP.y;
+ MbP = &(img->mb_data[pixP.mb_addr]);
+ mixedModeEdgeFlag = (byte) (MbQ->mb_field != MbP->mb_field);
+
+ blkQ = ((yQ>>2)<<2) + (xQ>>2);
+ blkP = ((yP>>2)<<2) + (xP>>2);
+
+ if ((p->slice_type==SP_SLICE)||(p->slice_type==SI_SLICE) )
+ {
+ Strength[idx] = (edge == 0 && (((!p->MbaffFrameFlag && (p->structure==FRAME)) ||
+ (p->MbaffFrameFlag && !MbP->mb_field && !MbQ->mb_field)) ||
+ ((p->MbaffFrameFlag || (p->structure != FRAME)) && !dir))) ? 4 : 3;
+ }
+ else
+ {
+ // Start with Strength=3. or Strength=4 for Mb-edge
+ Strength[idx] = (edge == 0 && (((!p->MbaffFrameFlag && (p->structure==FRAME)) ||
+ (p->MbaffFrameFlag && !MbP->mb_field && !MbQ->mb_field)) ||
+ ((p->MbaffFrameFlag || (p->structure!=FRAME)) && !dir))) ? 4 : 3;
+
+ if( !(MbP->mb_type==I4MB || MbP->mb_type==I16MB || MbP->mb_type==I8MB || MbP->mb_type==IPCM)
+ && !(MbQ->mb_type==I4MB || MbQ->mb_type==I16MB || MbQ->mb_type==I8MB || MbQ->mb_type==IPCM) )
+ {
+ if( ((MbQ->cbp_blk & ((int64)1 << blkQ )) != 0) || ((MbP->cbp_blk & ((int64)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;
+ {
+ 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] = (byte) (
+ (iabs( list0_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
+ (iabs( list0_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit) |
+ (iabs( list1_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
+ (iabs( list1_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit));
+ }
+ else
+ {
+ Strength[idx] = (byte) (
+ (iabs( list0_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
+ (iabs( list0_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit) |
+ (iabs( list1_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
+ (iabs( 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] = (byte) (
+ ((iabs( list0_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
+ (iabs( list0_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit ) |
+ (iabs( list1_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
+ (iabs( list1_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit))
+ &&
+ ((iabs( list0_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
+ (iabs( list0_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit) |
+ (iabs( list1_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
+ (iabs( list1_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit)));
+ }
+ }
+ else
+ {
+ Strength[idx] = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/*!
+ *****************************************************************************************
+ * \brief
+ * Filters one edge of 16 (luma) or 8 (chroma) pel
+ *****************************************************************************************
+ */
+void EdgeLoop(imgpel** Img, byte Strength[16],struct img_par *img, int MbQAddr, int AlphaC0Offset, int BetaOffset,
+ int dir, int edge, int width, int yuv, int uv, StorablePicture *p)
+{
+ 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 ;
+ const 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;
+ static const 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][p->chroma_format_idc] : 16 ;
+
+ for( pel=0 ; pel<PelNum ; pel++ )
+ {
+ xQ = dir ? pel : edge << 2;
+ yQ = dir ? (edge < 4 ? edge << 2 : 1) : pel;
+ getNeighbour(MbQAddr, xQ, yQ, yuv, &pixQ);
+ getNeighbour(MbQAddr, xQ - (1 - dir), yQ - dir, yuv, &pixP);
+ xP = pixP.x;
+ yP = pixP.y;
+ MbQ = &(img->mb_data[MbQAddr]);
+ MbP = &(img->mb_data[pixP.mb_addr]);
+ fieldModeFilteringFlag = (byte) (MbQ->mb_field || MbP->mb_field);
+ StrengthIdx = (yuv&&(PelNum==8)) ? ((MbQ->mb_field && !MbP->mb_field) ? pel<<1 :((pel>>1)<<2)+(pel&0x01)) : 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 ? (MbP->qpc[uv] + MbQ->qpc[uv] + 1) >> 1 : (MbP->qp + MbQ->qp + 1) >> 1;
+
+ indexA = iClip3(0, MAX_QP, QP + AlphaC0Offset);
+ indexB = iClip3(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]) != 0)
+ {
+ AbsDelta = iabs( Delta = R0 - L0 ) ;
+
+ if( AbsDelta < Alpha )
+ {
+ C0 = ClipTab[ Strng ] * bitdepth_scale;
+ if( ((iabs( R0 - R1) - Beta ) & (iabs(L0 - L1) - Beta )) < 0 )
+ {
+ if( !yuv)
+ {
+ aq = (iabs( R0 - R2) - Beta ) < 0 ;
+ ap = (iabs( L0 - L2) - Beta ) < 0 ;
+ }
+
+ RL0 = L0 + R0 ;
+
+ if(Strng == 4 ) // INTRA strong filtering
+ {
+ if( yuv) // Chroma
+ {
+ SrcPtrQ[0] = (imgpel) (((R1 << 1) + R0 + L1 + 2) >> 2);
+ SrcPtrP[0] = (imgpel) (((L1 << 1) + L0 + R1 + 2) >> 2);
+ }
+ else // Luma
+ {
+ small_gap = (AbsDelta < ((Alpha >> 2) + 2));
+
+ aq &= small_gap;
+ ap &= small_gap;
+
+ SrcPtrQ[0] = (imgpel) (aq ? ( L1 + ((R1 + RL0) << 1) + R2 + 4) >> 3 : ((R1 << 1) + R0 + L1 + 2) >> 2) ;
+ SrcPtrP[0] = (imgpel) (ap ? ( R1 + ((L1 + RL0) << 1) + L2 + 4) >> 3 : ((L1 << 1) + L0 + R1 + 2) >> 2) ;
+
+ SrcPtrQ[ incQ] = (imgpel) (aq ? ( R2 + R0 + R1 + L0 + 2) >> 2 : R1);
+ SrcPtrP[-incP] = (imgpel) (ap ? ( L2 + L1 + L0 + R0 + 2) >> 2 : L1);
+
+ SrcPtrQ[ incQ*2] = (imgpel) (aq ? (((R3 + R2) <<1) + R2 + R1 + RL0 + 4) >> 3 : R2);
+ SrcPtrP[-incP*2] = (imgpel) (ap ? (((L3 + L2) <<1) + L2 + L1 + RL0 + 4) >> 3 : L2);
+ }
+ }
+ else // normal filtering
+ {
+ c0 = yuv? (C0+1):(C0 + ap + aq) ;
+ dif = iClip3( -c0, c0, ( (Delta << 2) + (L1 - R1) + 4) >> 3 ) ;
+ if(!yuv)
+ {
+ SrcPtrP[0] = (imgpel) iClip3(0, img->max_imgpel_value, L0 + dif) ;
+ SrcPtrQ[0] = (imgpel) iClip3(0, img->max_imgpel_value, R0 - dif) ;
+ if( ap )
+ SrcPtrP[-incP] += iClip3( -C0, C0, ( L2 + ((RL0 + 1) >> 1) - (L1<<1)) >> 1 ) ;
+ if( aq )
+ SrcPtrQ[ incQ] += iClip3( -C0, C0, ( R2 + ((RL0 + 1) >> 1) - (R1<<1)) >> 1 ) ;
+ }
+ else
+ {
+ SrcPtrP[0] = (imgpel) iClip3(0, img->max_imgpel_value_uv, L0 + dif) ;
+ SrcPtrQ[0] = (imgpel) iClip3(0, img->max_imgpel_value_uv, R0 - dif) ;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/loopfilter.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/loopfilter.h:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/loopfilter.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,18 @@
+/*!
+ ************************************************************************
+ * \file
+ * loopfilter.h
+ * \brief
+ * external loop filter interface
+ ************************************************************************
+ */
+
+#ifndef _LOOPFILTER_H_
+#define _LOOPFILTER_H_
+
+#include "global.h"
+#include "mbuffer.h"
+
+void DeblockPicture(struct img_par *img, StorablePicture *p) ;
+
+#endif //_LOOPFILTER_H_
Index: llvm-test/MultiSource/Applications/JM/ldecod/macroblock.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/macroblock.c:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/macroblock.c Sun Feb 4 08:38:31 2007
@@ -0,0 +1,4938 @@
+
+/*!
+ ***********************************************************************
+ * \file macroblock.c
+ *
+ * \brief
+ * Decode a Macroblock
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Inge Lille-Langøy <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>
+ * - Thomas Wedi <wedi at tnt.uni-hannover.de>
+ * - Detlev Marpe <marpe at hhi.de>
+ * - Gabi Blaettermann <blaetter at hhi.de>
+ * - Ye-Kui Wang <wyk at ieee.org>
+ * - Lowell Winger <lwinger at lsil.com>
+ ***********************************************************************
+*/
+
+#include "contributors.h"
+
+#include <math.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include "global.h"
+#include "mbuffer.h"
+#include "elements.h"
+#include "errorconcealment.h"
+#include "macroblock.h"
+#include "fmo.h"
+#include "cabac.h"
+#include "vlc.h"
+#include "image.h"
+#include "mb_access.h"
+#include "biaridecod.h"
+
+#include "transform8x8.h"
+
+#if TRACE
+#define TRACE_STRING(s) strncpy(currSE.tracestring, s, TRACESTRING_SIZE)
+#else
+#define TRACE_STRING(s) // do nothing
+#endif
+
+extern int last_dquant;
+extern ColocatedParams *Co_located;
+
+
+static void SetMotionVectorPredictor (struct img_par *img,
+ short pmv[2],
+ char ref_frame,
+ byte list,
+ char ***refPic,
+ short ****tmp_mv,
+ int block_x,
+ int block_y,
+ int blockshape_x,
+ int blockshape_y);
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * initializes the current macroblock
+ ************************************************************************
+ */
+void start_macroblock(struct img_par *img,int CurrentMBInScanOrder)
+{
+ int l,j;
+ Macroblock *currMB; // intialization code deleted, see below, StW
+
+ assert (img->current_mb_nr < img->PicSizeInMbs);
+
+ currMB = &img->mb_data[img->current_mb_nr];
+
+ /* Update coordinates of the current macroblock */
+ if (img->MbaffFrameFlag)
+ {
+ img->mb_x = (img->current_mb_nr)%((2*img->width)/MB_BLOCK_SIZE);
+ img->mb_y = 2*((img->current_mb_nr)/((2*img->width)/MB_BLOCK_SIZE));
+
+ if (img->mb_x & 0x01)
+ {
+ img->mb_y++;
+ }
+
+ img->mb_x /= 2;
+ }
+ else
+ {
+ img->mb_x = PicPos[img->current_mb_nr][0];
+ img->mb_y = PicPos[img->current_mb_nr][1];
+ }
+
+ /* Define vertical positions */
+ img->block_y = img->mb_y * BLOCK_SIZE; /* luma block position */
+ img->pix_y = img->mb_y * MB_BLOCK_SIZE; /* luma macroblock position */
+ img->pix_c_y = img->mb_y * img->mb_cr_size_y; /* chroma macroblock position */
+
+ /* Define horizontal positions */
+ img->block_x = img->mb_x * BLOCK_SIZE; /* luma block position */
+ img->pix_x = img->mb_x * MB_BLOCK_SIZE; /* luma pixel position */
+ img->pix_c_x = img->mb_x * img->mb_cr_size_x; /* chroma pixel position */
+
+ // 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;
+
+ if (img->current_slice_nr >= MAX_NUM_SLICES)
+ {
+ error ("maximum number of supported slices exceeded, please recompile with increased value for MAX_NUM_SLICES", 200);
+ }
+
+ dec_picture->slice_id[img->mb_y][img->mb_x] = img->current_slice_nr;
+ if (img->current_slice_nr > dec_picture->max_slice_id)
+ {
+ dec_picture->max_slice_id=img->current_slice_nr;
+ }
+
+ CheckAvailabilityOfNeighbors();
+
+ // Reset syntax element entries in MB struct
+ currMB->qp = img->qp ;
+ currMB->mb_type = 0;
+ currMB->delta_quant = 0;
+ currMB->cbp = 0;
+ currMB->cbp_blk = 0;
+ currMB->c_ipred_mode= DC_PRED_8; //GB
+
+ for (l=0; l < 2; l++)
+ for (j=0; j < BLOCK_MULTIPLE; j++)
+ memset(&(currMB->mvd[l][j][0][0]),0, BLOCK_MULTIPLE * 2 * sizeof(int));
+
+ currMB->cbp_bits = 0;
+
+ // initialize img->m7
+ memset(&(img->m7[0][0]), 0, MB_BLOCK_PIXELS * sizeof(int));
+
+ // store filtering parameters for this MB
+ currMB->LFDisableIdc = img->currentSlice->LFDisableIdc;
+ currMB->LFAlphaC0Offset = img->currentSlice->LFAlphaC0Offset;
+ currMB->LFBetaOffset = img->currentSlice->LFBetaOffset;
+
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * set coordinates of the next macroblock
+ * check end_of_slice condition
+ ************************************************************************
+ */
+Boolean exit_macroblock(struct img_par *img,struct inp_par *inp,int eos_bit)
+{
+ //! The if() statement below resembles the original code, which tested
+ //! img->current_mb_nr == img->PicSizeInMbs. Both is, of course, nonsense
+ //! In an error prone environment, one can only be sure to have a new
+ //! picture by checking the tr of the next slice header!
+
+// printf ("exit_macroblock: FmoGetLastMBOfPicture %d, img->current_mb_nr %d\n", FmoGetLastMBOfPicture(), img->current_mb_nr);
+ img->num_dec_mb++;
+
+ if (img->num_dec_mb == img->PicSizeInMbs)
+// if (img->current_mb_nr == FmoGetLastMBOfPicture(currSlice->structure))
+ {
+//thb
+/*
+ if (currSlice->next_header != EOS)
+ currSlice->next_header = SOP;
+*/
+//the
+// assert (nal_startcode_follows (img, eos_bit) == TRUE);
+ return TRUE;
+ }
+ // ask for last mb in the slice UVLC
+ else
+ {
+// printf ("exit_macroblock: Slice %d old MB %d, now using MB %d\n", img->current_slice_nr, img->current_mb_nr, FmoGetNextMBNr (img->current_mb_nr));
+
+ img->current_mb_nr = FmoGetNextMBNr (img->current_mb_nr);
+
+ if (img->current_mb_nr == -1) // End of Slice group, MUST be end of slice
+ {
+ assert (nal_startcode_follows (img, eos_bit) == TRUE);
+ return TRUE;
+ }
+
+ if(nal_startcode_follows(img, eos_bit) == FALSE)
+ return FALSE;
+
+ if(img->type == I_SLICE || img->type == SI_SLICE || active_pps->entropy_coding_mode_flag == CABAC)
+ return TRUE;
+ if(img->cod_counter<=0)
+ return TRUE;
+ return FALSE;
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the mb mode for P-Frames
+ ************************************************************************
+ */
+void interpret_mb_mode_P(struct img_par *img)
+{
+ const int ICBPTAB[6] = {0,16,32,15,31,47};
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ int mbmode = currMB->mb_type;
+
+#define ZERO_P8x8 (mbmode==5)
+#define MODE_IS_P8x8 (mbmode==4 || mbmode==5)
+#define MODE_IS_I4x4 (mbmode==6)
+#define I16OFFSET (mbmode-7)
+#define MODE_IS_IPCM (mbmode==31)
+
+ if(mbmode <4)
+ {
+ currMB->mb_type = mbmode;
+ memset(&currMB->b8mode[0],mbmode,4 * sizeof(char));
+ memset(&currMB->b8pdir[0],0,4 * sizeof(char));
+ }
+ else if(MODE_IS_P8x8)
+ {
+ currMB->mb_type = P8x8;
+ img->allrefzero = ZERO_P8x8;
+ }
+ else if(MODE_IS_I4x4)
+ {
+ currMB->mb_type = I4MB;
+ memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
+ memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
+ }
+ else if(MODE_IS_IPCM)
+ {
+ currMB->mb_type=IPCM;
+ currMB->cbp= -1;
+ currMB->i16mode = 0;
+
+ memset(&currMB->b8mode[0],0,4 * sizeof(char));
+ memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
+ }
+ else
+ {
+ currMB->mb_type = I16MB;
+ currMB->cbp= ICBPTAB[(I16OFFSET)>>2];
+ currMB->i16mode = (I16OFFSET) & 0x03;
+ memset(&currMB->b8mode[0],0,4 * sizeof(char));
+ memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the mb mode for I-Frames
+ ************************************************************************
+ */
+void interpret_mb_mode_I(struct img_par *img)
+{
+ const int ICBPTAB[6] = {0,16,32,15,31,47};
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ int mbmode = currMB->mb_type;
+
+ if (mbmode==0)
+ {
+ currMB->mb_type = I4MB;
+ memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
+ memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
+ }
+ else if(mbmode==25)
+ {
+ currMB->mb_type=IPCM;
+ currMB->cbp= -1;
+ currMB->i16mode = 0;
+
+ memset(&currMB->b8mode[0],0,4 * sizeof(char));
+ memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
+ }
+ else
+ {
+ currMB->mb_type = I16MB;
+ currMB->cbp= ICBPTAB[(mbmode-1)>>2];
+ currMB->i16mode = (mbmode-1) & 0x03;
+ memset(&currMB->b8mode[0],0,4 * sizeof(char));
+ memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the mb mode for B-Frames
+ ************************************************************************
+ */
+void interpret_mb_mode_B(struct img_par *img)
+{
+ static const int offset2pdir16x16[12] = {0, 0, 1, 2, 0,0,0,0,0,0,0,0};
+ static const int offset2pdir16x8[22][2] = {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{1,1},{0,0},{0,1},{0,0},{1,0},
+ {0,0},{0,2},{0,0},{1,2},{0,0},{2,0},{0,0},{2,1},{0,0},{2,2},{0,0}};
+ static const int offset2pdir8x16[22][2] = {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{1,1},{0,0},{0,1},{0,0},
+ {1,0},{0,0},{0,2},{0,0},{1,2},{0,0},{2,0},{0,0},{2,1},{0,0},{2,2}};
+
+ const int ICBPTAB[6] = {0,16,32,15,31,47};
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+
+ int i, mbmode;
+ int mbtype = currMB->mb_type;
+
+ //--- set mbtype, b8type, and b8pdir ---
+ if (mbtype==0) // direct
+ {
+ mbmode=0;
+ memset(&currMB->b8mode[0],0,4 * sizeof(char));
+ memset(&currMB->b8pdir[0],2,4 * sizeof(char));
+ }
+ else if (mbtype==23) // intra4x4
+ {
+ mbmode=I4MB;
+ memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
+ memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
+ }
+ else if ((mbtype>23) && (mbtype<48) ) // intra16x16
+ {
+ mbmode=I16MB;
+ memset(&currMB->b8mode[0],0,4 * sizeof(char));
+ memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
+
+ currMB->cbp = ICBPTAB[(mbtype-24)>>2];
+ currMB->i16mode = (mbtype-24) & 0x03;
+ }
+ else if (mbtype==22) // 8x8(+split)
+ {
+ mbmode=P8x8; // b8mode and pdir is transmitted in additional codewords
+ }
+ else if (mbtype<4) // 16x16
+ {
+ mbmode=1;
+ memset(&currMB->b8mode[0], 1,4 * sizeof(char));
+ memset(&currMB->b8pdir[0],offset2pdir16x16[mbtype],4 * sizeof(char));
+ }
+ else if(mbtype==48)
+ {
+ mbmode=IPCM;
+ memset(&currMB->b8mode[0], 0,4 * sizeof(char));
+ memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
+
+ currMB->cbp= -1;
+ currMB->i16mode = 0;
+ }
+
+ else if ((mbtype&0x01)==0) // 16x8
+ {
+ mbmode=2;
+ memset(&currMB->b8mode[0], 2,4 * sizeof(char));
+ for(i=0;i<4;i++)
+ {
+ currMB->b8pdir[i]=offset2pdir16x8 [mbtype][i>>1];
+ }
+ }
+ else
+ {
+ mbmode=3;
+ memset(&currMB->b8mode[0], 3,4 * sizeof(char));
+ for(i=0;i<4;i++)
+ {
+ currMB->b8pdir[i]=offset2pdir8x16 [mbtype][i&0x01];
+ }
+ }
+ currMB->mb_type = mbmode;
+}
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the mb mode for SI-Frames
+ ************************************************************************
+ */
+void interpret_mb_mode_SI(struct img_par *img)
+{
+ const int ICBPTAB[6] = {0,16,32,15,31,47};
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ int mbmode = currMB->mb_type;
+
+ if (mbmode==0)
+ {
+ currMB->mb_type = SI4MB;
+ memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
+ memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
+ img->siblock[img->mb_y][img->mb_x]=1;
+ }
+ else if (mbmode==1)
+ {
+ currMB->mb_type = I4MB;
+ memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
+ memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
+ }
+ else if(mbmode==26)
+ {
+ currMB->mb_type=IPCM;
+ currMB->cbp= -1;
+ currMB->i16mode = 0;
+ memset(&currMB->b8mode[0],0,4 * sizeof(char));
+ memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
+ }
+
+ else
+ {
+ currMB->mb_type = I16MB;
+ currMB->cbp= ICBPTAB[(mbmode-1)>>2];
+ currMB->i16mode = (mbmode-2) & 0x03;
+ memset(&currMB->b8mode[0],0,4 * sizeof(char));
+ memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
+ }
+}
+/*!
+ ************************************************************************
+ * \brief
+ * init macroblock I and P frames
+ ************************************************************************
+ */
+void init_macroblock(struct img_par *img)
+{
+ int i,j;
+
+ for(j=img->block_y;j<img->block_y+BLOCK_SIZE;j++)
+ { // reset vectors and pred. modes
+ memset(&dec_picture->mv[LIST_0][j][img->block_x][0], 0, 2 * BLOCK_SIZE * sizeof(short));
+ memset(&dec_picture->mv[LIST_1][j][img->block_x][0], 0, 2 * BLOCK_SIZE * sizeof(short));
+ memset(&dec_picture->ref_idx[LIST_0][j][img->block_x], -1, BLOCK_SIZE * sizeof(char));
+ memset(&dec_picture->ref_idx[LIST_1][j][img->block_x], -1, BLOCK_SIZE * sizeof(char));
+ memset(&img->ipredmode[j][img->block_x], DC_PRED, BLOCK_SIZE * sizeof(char));
+ for (i=img->block_x;i<img->block_x+BLOCK_SIZE;i++)
+ {
+ dec_picture->ref_pic_id[LIST_0][j][i] = INT64_MIN;
+ dec_picture->ref_pic_id[LIST_1][j][i] = INT64_MIN;
+ }
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Sets mode for 8x8 block
+ ************************************************************************
+ */
+void SetB8Mode (struct img_par* img, Macroblock* currMB, int value, int i)
+{
+ static const int p_v2b8 [ 5] = {4, 5, 6, 7, IBLOCK};
+ static const int p_v2pd [ 5] = {0, 0, 0, 0, -1};
+ static const int b_v2b8 [14] = {0, 4, 4, 4, 5, 6, 5, 6, 5, 6, 7, 7, 7, IBLOCK};
+ static const int b_v2pd [14] = {2, 0, 1, 2, 0, 0, 1, 1, 2, 2, 0, 1, 2, -1};
+
+ if (img->type==B_SLICE)
+ {
+ currMB->b8mode[i] = b_v2b8[value];
+ currMB->b8pdir[i] = b_v2pd[value];
+
+ }
+ else
+ {
+ currMB->b8mode[i] = p_v2b8[value];
+ currMB->b8pdir[i] = p_v2pd[value];
+ }
+
+}
+
+
+void reset_coeffs()
+{
+ int i, j;
+
+ // reset all coeffs
+ for (i=0;i<BLOCK_SIZE;i++)
+ {
+ for (j=0;j<BLOCK_SIZE +img->num_blk8x8_uv;j++)
+ memset(&img->cof[i][j][0][0],0,BLOCK_SIZE * BLOCK_SIZE * sizeof(int));
+ }
+
+ // CAVLC
+ memset(&img->nz_coeff[img->current_mb_nr][0][0],0, BLOCK_SIZE * (BLOCK_SIZE + img->num_blk8x8_uv) * sizeof(int));
+}
+
+void field_flag_inference()
+{
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+
+ if (currMB->mbAvailA)
+ {
+ currMB->mb_field = img->mb_data[currMB->mbAddrA].mb_field;
+ }
+ else
+ {
+ // check top macroblock pair
+ if (currMB->mbAvailB)
+ {
+ currMB->mb_field = img->mb_data[currMB->mbAddrB].mb_field;
+ }
+ else
+ currMB->mb_field = 0;
+ }
+
+}
+
+void set_chroma_qp(Macroblock* currMB)
+{
+ int i;
+ for (i=0; i<2; i++)
+ {
+ currMB->qpc[i] = iClip3 ( -img->bitdepth_chroma_qp_scale, 51, currMB->qp + dec_picture->chroma_qp_offset[i] );
+ currMB->qpc[i] = currMB->qpc[i] < 0 ? currMB->qpc[i] : QP_SCALE_CR[currMB->qpc[i]];
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Get the syntax elements from the NAL
+ ************************************************************************
+ */
+int read_one_macroblock(struct img_par *img,struct inp_par *inp)
+{
+ int i;
+
+ SyntaxElement currSE;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+
+ Slice *currSlice = img->currentSlice;
+ DataPartition *dP;
+ int *partMap = assignSE2partition[currSlice->dp_mode];
+ Macroblock *topMB = NULL;
+ int prevMbSkipped = 0;
+ int img_block_y;
+ int check_bottom, read_bottom, read_top;
+
+ if (img->MbaffFrameFlag)
+ {
+ if (img->current_mb_nr&0x01)
+ {
+ topMB= &img->mb_data[img->current_mb_nr-1];
+ if(!(img->type == B_SLICE))
+ prevMbSkipped = (topMB->mb_type == 0);
+ else
+ prevMbSkipped = topMB->skip_flag;
+ }
+ else
+ prevMbSkipped = 0;
+ }
+
+ if ((img->current_mb_nr&0x01) == 0)
+ currMB->mb_field = 0;
+ else
+ currMB->mb_field = img->mb_data[img->current_mb_nr-1].mb_field;
+
+
+ currMB->qp = img->qp ;
+ for (i=0; i<2; i++)
+ {
+ currMB->qpc[i] = iClip3 ( -img->bitdepth_chroma_qp_scale, 51, img->qp + dec_picture->chroma_qp_offset[i] );
+ currMB->qpc[i] = currMB->qpc[i] < 0 ? currMB->qpc[i] : QP_SCALE_CR[currMB->qpc[i]];
+ }
+
+ currSE.type = SE_MBTYPE;
+
+ // read MB mode *****************************************************************
+ dP = &(currSlice->partArr[partMap[currSE.type]]);
+
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_ue;
+
+ if(img->type == I_SLICE || img->type == SI_SLICE)
+ {
+ // read MB aff
+ if (img->MbaffFrameFlag && (img->current_mb_nr&0x01)==0)
+ {
+ TRACE_STRING("mb_field_decoding_flag");
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
+ {
+ currSE.len = 1;
+ readSyntaxElement_FLC(&currSE, dP->bitstream);
+ }
+ else
+ {
+ currSE.reading = readFieldModeInfo_CABAC;
+ dP->readSyntaxElement(&currSE,img,dP);
+ }
+ currMB->mb_field = currSE.value1;
+ }
+ if(active_pps->entropy_coding_mode_flag == CABAC)
+ CheckAvailabilityOfNeighborsCABAC();
+
+ // read MB type
+ TRACE_STRING("mb_type");
+ currSE.reading = readMB_typeInfo_CABAC;
+ dP->readSyntaxElement(&currSE,img,dP);
+
+ currMB->mb_type = currSE.value1;
+ if(!dP->bitstream->ei_flag)
+ currMB->ei_flag = 0;
+ }
+ // non I/SI-slice CABAC
+ else if (active_pps->entropy_coding_mode_flag == CABAC)
+ {
+ // read MB skip_flag
+ if (img->MbaffFrameFlag && ((img->current_mb_nr&0x01) == 0||prevMbSkipped))
+ field_flag_inference();
+
+ CheckAvailabilityOfNeighborsCABAC();
+ TRACE_STRING("mb_skip_flag");
+ currSE.reading = readMB_skip_flagInfo_CABAC;
+ dP->readSyntaxElement(&currSE,img,dP);
+
+ currMB->mb_type = currSE.value1;
+ currMB->skip_flag = !(currSE.value1);
+
+ if (img->type==B_SLICE)
+ currMB->cbp = currSE.value2;
+
+ if(!dP->bitstream->ei_flag)
+ currMB->ei_flag = 0;
+
+ if ((img->type==B_SLICE) && currSE.value1==0 && currSE.value2==0)
+ img->cod_counter=0;
+
+ // read MB AFF
+ if (img->MbaffFrameFlag)
+ {
+ check_bottom=read_bottom=read_top=0;
+ if ((img->current_mb_nr&0x01)==0)
+ {
+ check_bottom = currMB->skip_flag;
+ read_top = !check_bottom;
+ }
+ else
+ {
+ read_bottom = (topMB->skip_flag && (!currMB->skip_flag));
+ }
+
+ if (read_bottom || read_top)
+ {
+ TRACE_STRING("mb_field_decoding_flag");
+ currSE.reading = readFieldModeInfo_CABAC;
+ dP->readSyntaxElement(&currSE,img,dP);
+ currMB->mb_field = currSE.value1;
+ }
+ if (check_bottom)
+ check_next_mb_and_get_field_mode_CABAC(&currSE,img,dP);
+
+ }
+
+ CheckAvailabilityOfNeighborsCABAC();
+
+ // read MB type
+ if (currMB->mb_type != 0 )
+ {
+ currSE.reading = readMB_typeInfo_CABAC;
+ TRACE_STRING("mb_type");
+ dP->readSyntaxElement(&currSE,img,dP);
+ currMB->mb_type = currSE.value1;
+ if(!dP->bitstream->ei_flag)
+ currMB->ei_flag = 0;
+ }
+ }
+ // VLC Non-Intra
+ else
+ {
+ if(img->cod_counter == -1)
+ {
+ TRACE_STRING("mb_skip_run");
+ dP->readSyntaxElement(&currSE,img,dP);
+ img->cod_counter = currSE.value1;
+ }
+ if (img->cod_counter==0)
+ {
+ // read MB aff
+ if ((img->MbaffFrameFlag) && (((img->current_mb_nr&0x01)==0) || ((img->current_mb_nr&0x01) && prevMbSkipped)))
+ {
+ TRACE_STRING("mb_field_decoding_flag");
+ currSE.len = 1;
+ readSyntaxElement_FLC(&currSE, dP->bitstream);
+ currMB->mb_field = currSE.value1;
+ }
+
+ // read MB type
+ TRACE_STRING("mb_type");
+ dP->readSyntaxElement(&currSE,img,dP);
+ if(img->type == P_SLICE || img->type == SP_SLICE)
+ currSE.value1++;
+ currMB->mb_type = currSE.value1;
+ if(!dP->bitstream->ei_flag)
+ currMB->ei_flag = 0;
+ img->cod_counter--;
+ currMB->skip_flag = 0;
+ }
+ else
+ {
+ img->cod_counter--;
+ currMB->mb_type = 0;
+ currMB->ei_flag = 0;
+ currMB->skip_flag = 1;
+
+ // read field flag of bottom block
+ if(img->MbaffFrameFlag)
+ {
+ if(img->cod_counter == 0 && ((img->current_mb_nr&0x01) == 0))
+ {
+ TRACE_STRING("mb_field_decoding_flag (of coded bottom mb)");
+ currSE.len = 1;
+ readSyntaxElement_FLC(&currSE, dP->bitstream);
+ dP->bitstream->frame_bitoffset--;
+ currMB->mb_field = currSE.value1;
+ }
+ else if(img->cod_counter > 0 && ((img->current_mb_nr&0x01) == 0))
+ {
+ // check left macroblock pair first
+ if (mb_is_available(img->current_mb_nr-2, img->current_mb_nr)&&((img->current_mb_nr%(img->PicWidthInMbs*2))!=0))
+ {
+ currMB->mb_field = img->mb_data[img->current_mb_nr-2].mb_field;
+ }
+ else
+ {
+ // check top macroblock pair
+ if (mb_is_available(img->current_mb_nr-2*img->PicWidthInMbs, img->current_mb_nr))
+ {
+ currMB->mb_field = img->mb_data[img->current_mb_nr-2*img->PicWidthInMbs].mb_field;
+ }
+ else
+ currMB->mb_field = 0;
+ }
+ }
+ }
+ }
+ }
+
+ dec_picture->mb_field[img->current_mb_nr] = currMB->mb_field;
+
+ img->siblock[img->mb_y][img->mb_x]=0;
+
+ if ((img->type==P_SLICE )) // inter frame
+ interpret_mb_mode_P(img);
+ else if (img->type==I_SLICE) // intra frame
+ interpret_mb_mode_I(img);
+ else if ((img->type==B_SLICE)) // B frame
+ interpret_mb_mode_B(img);
+ else if ((img->type==SP_SLICE)) // SP frame
+ interpret_mb_mode_P(img);
+ else if (img->type==SI_SLICE) // SI frame
+ interpret_mb_mode_SI(img);
+
+ if(img->MbaffFrameFlag)
+ {
+ if(currMB->mb_field)
+ {
+ img->num_ref_idx_l0_active <<=1;
+ img->num_ref_idx_l1_active <<=1;
+ }
+ }
+
+ //init NoMbPartLessThan8x8Flag
+ currMB->NoMbPartLessThan8x8Flag = (IS_DIRECT(currMB) && !(active_sps->direct_8x8_inference_flag))? 0: 1;
+
+ //====== READ 8x8 SUB-PARTITION MODES (modes of 8x8 blocks) and Intra VBST block modes ======
+ if (IS_P8x8 (currMB))
+ {
+ currSE.type = SE_MBTYPE;
+ dP = &(currSlice->partArr[partMap[SE_MBTYPE]]);
+
+ for (i=0; i<4; i++)
+ {
+ if (active_pps->entropy_coding_mode_flag ==UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_ue;
+ else currSE.reading = readB8_typeInfo_CABAC;
+
+ TRACE_STRING("sub_mb_type");
+ dP->readSyntaxElement (&currSE, img, dP);
+ SetB8Mode (img, currMB, currSE.value1, i);
+
+ //set NoMbPartLessThan8x8Flag for P8x8 mode
+ currMB->NoMbPartLessThan8x8Flag &= (currMB->b8mode[i]==0 && active_sps->direct_8x8_inference_flag) ||
+ (currMB->b8mode[i]==4);
+ }
+ //--- init macroblock data ---
+ init_macroblock (img);
+ readMotionInfoFromNAL (img, inp);
+ }
+
+
+ //============= Transform Size Flag for INTRA MBs =============
+ //-------------------------------------------------------------
+ //transform size flag for INTRA_4x4 and INTRA_8x8 modes
+ if (currMB->mb_type == I4MB && img->Transform8x8Mode)
+ {
+ currSE.type = SE_HEADER;
+ dP = &(currSlice->partArr[partMap[SE_HEADER]]);
+ currSE.reading = readMB_transform_size_flag_CABAC;
+ TRACE_STRING("transform_size_8x8_flag");
+
+ // read UVLC transform_size_8x8_flag
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
+ {
+ currSE.len = 1;
+ readSyntaxElement_FLC(&currSE, dP->bitstream);
+ }
+ else
+ {
+ dP->readSyntaxElement(&currSE,img,dP);
+ }
+
+ currMB->luma_transform_size_8x8_flag = currSE.value1;
+
+ if (currMB->luma_transform_size_8x8_flag)
+ {
+ currMB->mb_type = I8MB;
+ for (i=0;i<4;i++)
+ {
+ currMB->b8mode[i]=I8MB;
+ currMB->b8pdir[i]=-1;
+ }
+ }
+ }
+ else
+ {
+ currMB->luma_transform_size_8x8_flag = 0;
+ }
+
+ if(active_pps->constrained_intra_pred_flag && (img->type==P_SLICE|| img->type==B_SLICE)) // inter frame
+ {
+ if( !IS_INTRA(currMB) )
+ {
+ img->intra_block[img->current_mb_nr] = 0;
+ }
+ }
+
+ //! TO for error concealment
+ //! If we have an INTRA Macroblock and we lost the partition
+ //! which contains the intra coefficients Copy MB would be better
+ //! than just a gray block.
+ //! Seems to be a bit at the wrong place to do this right here, but for this case
+ //! up to now there is no other way.
+ dP = &(currSlice->partArr[partMap[SE_CBP_INTRA]]);
+ if(IS_INTRA (currMB) && dP->bitstream->ei_flag && img->number)
+ {
+ currMB->mb_type = 0;
+ currMB->ei_flag = 1;
+ for (i=0;i<4;i++) {currMB->b8mode[i]=currMB->b8pdir[i]=0; }
+ }
+ dP = &(currSlice->partArr[partMap[currSE.type]]);
+ //! End TO
+
+
+ //--- init macroblock data ---
+ if (!IS_P8x8 (currMB))
+ init_macroblock (img);
+
+ if (IS_DIRECT (currMB) && img->cod_counter >= 0)
+ {
+ currMB->cbp = 0;
+ reset_coeffs();
+
+ if (active_pps->entropy_coding_mode_flag ==CABAC)
+ img->cod_counter=-1;
+
+ return DECODE_MB;
+ }
+
+ if (IS_COPY (currMB)) //keep last macroblock
+ {
+ int i, j, k;
+ short pmv[2];
+ int zeroMotionAbove;
+ int zeroMotionLeft;
+ PixelPos mb_a, mb_b;
+ int a_mv_y = 0;
+ int a_ref_idx = 0;
+ int b_mv_y = 0;
+ int b_ref_idx = 0;
+ int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? 4 : 2 : 0;
+ short ***cur_mv = dec_picture->mv[LIST_0];
+ getLuma4x4Neighbour(img->current_mb_nr,-1, 0, &mb_a);
+ getLuma4x4Neighbour(img->current_mb_nr, 0,-1, &mb_b);
+
+ if (mb_a.available)
+ {
+ a_mv_y = cur_mv[mb_a.pos_y][mb_a.pos_x][1];
+ a_ref_idx = dec_picture->ref_idx[LIST_0][mb_a.pos_y][mb_a.pos_x];
+
+ if (currMB->mb_field && !img->mb_data[mb_a.mb_addr].mb_field)
+ {
+ a_mv_y /=2;
+ a_ref_idx *=2;
+ }
+ if (!currMB->mb_field && img->mb_data[mb_a.mb_addr].mb_field)
+ {
+ a_mv_y *=2;
+ a_ref_idx >>=1;
+ }
+ }
+
+ if (mb_b.available)
+ {
+ b_mv_y = cur_mv[mb_b.pos_y][mb_b.pos_x][1];
+ b_ref_idx = dec_picture->ref_idx[LIST_0][mb_b.pos_y][mb_b.pos_x];
+
+ if (currMB->mb_field && !img->mb_data[mb_b.mb_addr].mb_field)
+ {
+ b_mv_y /=2;
+ b_ref_idx *=2;
+ }
+ if (!currMB->mb_field && img->mb_data[mb_b.mb_addr].mb_field)
+ {
+ b_mv_y *=2;
+ b_ref_idx >>=1;
+ }
+ }
+
+ zeroMotionLeft = !mb_a.available ? 1 : a_ref_idx==0 && cur_mv[mb_a.pos_y][mb_a.pos_x][0]==0 && a_mv_y==0 ? 1 : 0;
+ zeroMotionAbove = !mb_b.available ? 1 : b_ref_idx==0 && cur_mv[mb_b.pos_y][mb_b.pos_x][0]==0 && b_mv_y==0 ? 1 : 0;
+
+ currMB->cbp = 0;
+ reset_coeffs();
+
+ img_block_y = img->block_y;
+
+ if (zeroMotionAbove || zeroMotionLeft)
+ {
+ for(j=img_block_y;j<img_block_y + BLOCK_SIZE;j++)
+ {
+ memset(&cur_mv[j][img->block_x][0], 0, 2 * BLOCK_SIZE * sizeof(short));
+ }
+ }
+ else
+ {
+ SetMotionVectorPredictor (img, pmv, 0, LIST_0, dec_picture->ref_idx, dec_picture->mv, 0, 0, 16, 16);
+
+ for(j=img_block_y;j<img_block_y + BLOCK_SIZE;j++)
+ {
+ for(i=img->block_x;i<img->block_x + BLOCK_SIZE;i++)
+ for (k=0;k<2;k++)
+ {
+ cur_mv[j][i][k] = pmv[k];
+ }
+ }
+ }
+ for(j=img_block_y;j< img_block_y + BLOCK_SIZE;j++)
+ {
+ for(i=img->block_x;i<img->block_x + BLOCK_SIZE;i++)
+ {
+ dec_picture->ref_idx[LIST_0][j][i] = 0;
+ dec_picture->ref_pic_id[LIST_0][j][i] =
+ dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][(short)dec_picture->ref_idx[LIST_0][j][i]];
+ }
+ }
+ return DECODE_MB;
+ }
+ if(currMB->mb_type!=IPCM)
+ {
+
+ // intra prediction modes for a macroblock 4x4 **********************************************
+ read_ipred_modes(img,inp);
+
+ // read inter frame vector data *********************************************************
+ if (IS_INTERMV (currMB) && (!IS_P8x8(currMB)))
+ {
+ readMotionInfoFromNAL (img, inp);
+ }
+ // read CBP and Coeffs ***************************************************************
+ readCBPandCoeffsFromNAL (img,inp);
+ }
+ else
+ {
+ //read pcm_alignment_zero_bit and pcm_byte[i]
+
+ // here dP is assigned with the same dP as SE_MBTYPE, because IPCM syntax is in the
+ // same category as MBTYPE
+ dP = &(currSlice->partArr[partMap[SE_MBTYPE]]);
+ readIPCMcoeffsFromNAL(img,inp,dP);
+ }
+
+
+ return DECODE_MB;
+}
+
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Initialize decoding engine after decoding an IPCM macroblock
+ * (for IPCM CABAC 28/11/2003)
+ *
+ * \author
+ * Dong Wang <Dong.Wang at bristol.ac.uk>
+ ************************************************************************
+ */
+void init_decoding_engine_IPCM(struct img_par *img)
+{
+ Slice *currSlice = img->currentSlice;
+ Bitstream *currStream;
+ int ByteStartPosition;
+ int PartitionNumber;
+ int i;
+
+ if(currSlice->dp_mode==PAR_DP_1)
+ PartitionNumber=1;
+ else if(currSlice->dp_mode==PAR_DP_3)
+ PartitionNumber=3;
+ else
+ {
+ printf("Partition Mode is not supported\n");
+ exit(1);
+ }
+
+ for(i=0;i<PartitionNumber;i++)
+ {
+ currStream = currSlice->partArr[i].bitstream;
+ ByteStartPosition = currStream->read_len;
+
+
+ arideco_start_decoding (&currSlice->partArr[i].de_cabac, currStream->streamBuffer, ByteStartPosition, &currStream->read_len, img->type);
+ }
+}
+
+
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Read IPCM pcm_alignment_zero_bit and pcm_byte[i] from stream to img->cof
+ * (for IPCM CABAC and IPCM CAVLC)
+ *
+ * \author
+ * Dong Wang <Dong.Wang at bristol.ac.uk>
+ ************************************************************************
+ */
+
+void readIPCMcoeffsFromNAL(struct img_par *img, struct inp_par *inp, struct datapartition *dP)
+{
+ SyntaxElement currSE;
+ int i,j;
+
+ //For CABAC, we don't need to read bits to let stream byte aligned
+ // because we have variable for integer bytes position
+ if(active_pps->entropy_coding_mode_flag == CABAC)
+ {
+ //read luma and chroma IPCM coefficients
+ currSE.len=8;
+ TRACE_STRING("pcm_byte luma");
+
+ for(i=0;i<MB_BLOCK_SIZE;i++)
+ {
+ for(j=0;j<MB_BLOCK_SIZE;j++)
+ {
+ readIPCMBytes_CABAC(&currSE, dP->bitstream);
+ img->cof[(i>>2)][(j>>2)][i & 0x03][j & 0x03]=currSE.value1;
+ }
+ }
+ if (dec_picture->chroma_format_idc != YUV400)
+ {
+ TRACE_STRING("pcm_byte chroma");
+ for(i=0;i<img->mb_cr_size_y;i++)
+ {
+ for(j=0;j<img->mb_cr_size_x;j++)
+ {
+ readIPCMBytes_CABAC(&currSE, dP->bitstream);
+ img->cof[(i>>2)][(j>>2)+4][i & 0x03][j & 0x03]=currSE.value1;
+ }
+ }
+ for(i=0;i<img->mb_cr_size_y;i++)
+ {
+ for(j=0;j<img->mb_cr_size_x;j++)
+ {
+ readIPCMBytes_CABAC(&currSE, dP->bitstream);
+ img->cof[(i>>2)+2][(j>>2)+4][i & 0x03][j & 0x03]=currSE.value1;
+ }
+ }
+ }
+ //If the decoded MB is IPCM MB, decoding engine is initialized
+
+ // here the decoding engine is directly initialized without checking End of Slice
+ // The reason is that, whether current MB is the last MB in slice or not, there is
+ // at least one 'end of slice' syntax after this MB. So when fetching bytes in this
+ // initialisation process, we can guarantee there is bits available in bitstream.
+
+ init_decoding_engine_IPCM(img);
+ }
+ else
+ {
+ //read bits to let stream byte aligned
+
+ if((dP->bitstream->frame_bitoffset)%8!=0)
+ {
+ TRACE_STRING("pcm_alignment_zero_bit");
+ currSE.len=8-(dP->bitstream->frame_bitoffset)%8;
+ readSyntaxElement_FLC(&currSE, dP->bitstream);
+ }
+
+ //read luma and chroma IPCM coefficients
+ currSE.len=img->bitdepth_luma;
+ TRACE_STRING("pcm_sample_luma");
+
+ for(i=0;i<MB_BLOCK_SIZE;i++)
+ {
+ for(j=0;j<MB_BLOCK_SIZE;j++)
+ {
+ readSyntaxElement_FLC(&currSE, dP->bitstream);
+ img->cof[(i>>2)][(j>>2)][i & 0x03][j & 0x03]=currSE.value1;
+ }
+ }
+ currSE.len=img->bitdepth_chroma;
+ if (dec_picture->chroma_format_idc != YUV400)
+ {
+ TRACE_STRING("pcm_sample_chroma (u)");
+ for(i=0;i<img->mb_cr_size_y;i++)
+ {
+ for(j=0;j<img->mb_cr_size_x;j++)
+ {
+ readSyntaxElement_FLC(&currSE, dP->bitstream);
+ img->cof[(i>>2)][(j>>2)+4][i & 0x03][j & 0x03]=currSE.value1;
+ }
+ }
+ TRACE_STRING("pcm_sample_chroma (v)");
+ for(i=0;i<img->mb_cr_size_y;i++)
+ {
+ for(j=0;j<img->mb_cr_size_x;j++)
+ {
+ readSyntaxElement_FLC(&currSE, dP->bitstream);
+ img->cof[(i>>2)+2][(j>>2)+4][i & 0x03][j & 0x03]=currSE.value1;
+ }
+ }
+ }
+ }
+}
+
+
+
+void read_ipred_modes(struct img_par *img,struct inp_par *inp)
+{
+ int b8,i,j,bi,bj,bx,by,dec;
+ SyntaxElement currSE;
+ Slice *currSlice;
+ DataPartition *dP;
+ int *partMap;
+ Macroblock *currMB;
+ int ts, ls;
+ int mostProbableIntraPredMode;
+ int upIntraPredMode;
+ int leftIntraPredMode;
+ int IntraChromaPredModeFlag;
+ int bs_x, bs_y;
+ int ii,jj;
+
+ PixelPos left_block;
+ PixelPos top_block;
+
+ currMB = &img->mb_data[img->current_mb_nr];
+
+ IntraChromaPredModeFlag = IS_INTRA(currMB);
+
+ currSlice = img->currentSlice;
+ partMap = assignSE2partition[currSlice->dp_mode];
+
+ currSE.type = SE_INTRAPREDMODE;
+
+ TRACE_STRING("intra4x4_pred_mode");
+ dP = &(currSlice->partArr[partMap[currSE.type]]);
+
+ if (!(active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag))
+ currSE.reading = readIntraPredMode_CABAC;
+
+ for(b8=0;b8<4;b8++) //loop 8x8 blocks
+ {
+ if((currMB->b8mode[b8]==IBLOCK )||(currMB->b8mode[b8]==I8MB))
+ {
+ bs_x = bs_y = (currMB->b8mode[b8] == I8MB)?8:4;
+
+ IntraChromaPredModeFlag = 1;
+
+ ii=(bs_x>>2);
+ jj=(bs_y>>2);
+
+ for(j=0;j<2;j+=jj) //loop subblocks
+ {
+ by = (b8&2) + j;
+ bj = img->block_y + by;
+ for(i=0;i<2;i+=ii)
+ {
+ bx = ((b8&1)<<1) + i;
+ bi = img->block_x + bx;
+ //get from stream
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
+ readSyntaxElement_Intra4x4PredictionMode(&currSE,img,dP);
+ else
+ {
+ currSE.context=(b8<<2)+(j<<1)+i;
+ dP->readSyntaxElement(&currSE,img,dP);
+ }
+
+ getLuma4x4Neighbour(img->current_mb_nr, (bx<<2) - 1, (by<<2), &left_block);
+ getLuma4x4Neighbour(img->current_mb_nr, (bx<<2), (by<<2) - 1, &top_block);
+
+ //get from array and decode
+
+ if (active_pps->constrained_intra_pred_flag)
+ {
+ left_block.available = left_block.available ? img->intra_block[left_block.mb_addr] : 0;
+ top_block.available = top_block.available ? img->intra_block[top_block.mb_addr] : 0;
+ }
+
+ // !! KS: not sure if the following is still correct...
+ ts = ls = 0; // Check to see if the neighboring block is SI
+ if (IS_OLDINTRA(currMB) && img->type == SI_SLICE) // need support for MBINTLC1
+ {
+ if (left_block.available)
+ if (img->siblock [left_block.pos_y][left_block.pos_x])
+ ls=1;
+
+ if (top_block.available)
+ if (img->siblock [top_block.pos_y][top_block.pos_x])
+ ts=1;
+ }
+
+ upIntraPredMode = (top_block.available &&(ts == 0)) ? img->ipredmode[top_block.pos_y ][top_block.pos_x ] : -1;
+ leftIntraPredMode = (left_block.available &&(ls == 0)) ? img->ipredmode[left_block.pos_y][left_block.pos_x] : -1;
+
+ mostProbableIntraPredMode = (upIntraPredMode < 0 || leftIntraPredMode < 0) ? DC_PRED : upIntraPredMode < leftIntraPredMode ? upIntraPredMode : leftIntraPredMode;
+
+ dec = (currSE.value1 == -1) ? mostProbableIntraPredMode : currSE.value1 + (currSE.value1 >= mostProbableIntraPredMode);
+
+ //set
+ for(jj=0;jj<(bs_y>>2);jj++) //loop 4x4s in the subblock for 8x8 prediction setting
+ memset(&img->ipredmode[bj+jj][bi], dec, (bs_x>>2) * sizeof(char));
+ }
+ }
+ }
+ }
+
+ if (IntraChromaPredModeFlag && dec_picture->chroma_format_idc != YUV400)
+ {
+ currSE.type = SE_INTRAPREDMODE;
+ TRACE_STRING("intra_chroma_pred_mode");
+ dP = &(currSlice->partArr[partMap[currSE.type]]);
+
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_ue;
+ else currSE.reading = readCIPredMode_CABAC;
+
+ dP->readSyntaxElement(&currSE,img,dP);
+ currMB->c_ipred_mode = currSE.value1;
+
+ if (currMB->c_ipred_mode < DC_PRED_8 || currMB->c_ipred_mode > PLANE_8)
+ {
+ error("illegal chroma intra pred mode!\n", 600);
+ }
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Set motion vector predictor
+ ************************************************************************
+ */
+static void SetMotionVectorPredictor (struct img_par *img,
+ short pmv[2],
+ char ref_frame,
+ byte list,
+ char ***refPic,
+ short ****tmp_mv,
+ int block_x,
+ int block_y,
+ int blockshape_x,
+ int blockshape_y)
+{
+ int mb_x = BLOCK_SIZE*block_x;
+ int mb_y = BLOCK_SIZE*block_y;
+ int mb_nr = img->current_mb_nr;
+
+ int mv_a, mv_b, mv_c, pred_vec=0;
+ int mvPredType, rFrameL, rFrameU, rFrameUR;
+ int hv;
+
+
+ PixelPos block_a, block_b, block_c, block_d;
+
+ getLuma4x4Neighbour(mb_nr, mb_x - 1, mb_y, &block_a);
+ getLuma4x4Neighbour(mb_nr, mb_x, mb_y - 1, &block_b);
+ getLuma4x4Neighbour(mb_nr, mb_x + blockshape_x, mb_y - 1, &block_c);
+ getLuma4x4Neighbour(mb_nr, mb_x - 1, mb_y - 1, &block_d);
+
+ if (mb_y > 0)
+ {
+ if (mb_x < 8) // first column of 8x8 blocks
+ {
+ if (mb_y==8)
+ {
+ if (blockshape_x == 16) block_c.available = 0;
+ }
+ else
+ {
+ if (mb_x+blockshape_x == 8) block_c.available = 0;
+ }
+ }
+ else
+ {
+ if (mb_x+blockshape_x == 16) block_c.available = 0;
+ }
+ }
+
+ if (!block_c.available)
+ {
+ block_c=block_d;
+ }
+
+ mvPredType = MVPRED_MEDIAN;
+
+ if (!img->MbaffFrameFlag)
+ {
+ rFrameL = block_a.available ? refPic[list][block_a.pos_y][block_a.pos_x] : -1;
+ rFrameU = block_b.available ? refPic[list][block_b.pos_y][block_b.pos_x] : -1;
+ rFrameUR = block_c.available ? refPic[list][block_c.pos_y][block_c.pos_x] : -1;
+ }
+ else
+ {
+ if (img->mb_data[img->current_mb_nr].mb_field)
+ {
+ rFrameL = block_a.available ?
+ img->mb_data[block_a.mb_addr].mb_field ?
+ refPic[list][block_a.pos_y][block_a.pos_x]:
+ refPic[list][block_a.pos_y][block_a.pos_x] * 2:
+ -1;
+ rFrameU = block_b.available ?
+ img->mb_data[block_b.mb_addr].mb_field ?
+ refPic[list][block_b.pos_y][block_b.pos_x]:
+ refPic[list][block_b.pos_y][block_b.pos_x] * 2:
+ -1;
+ rFrameUR = block_c.available ?
+ img->mb_data[block_c.mb_addr].mb_field ?
+ refPic[list][block_c.pos_y][block_c.pos_x]:
+ refPic[list][block_c.pos_y][block_c.pos_x] * 2:
+ -1;
+ }
+ else
+ {
+ rFrameL = block_a.available ?
+ img->mb_data[block_a.mb_addr].mb_field ?
+ refPic[list][block_a.pos_y][block_a.pos_x] >>1:
+ refPic[list][block_a.pos_y][block_a.pos_x] :
+ -1;
+ rFrameU = block_b.available ?
+ img->mb_data[block_b.mb_addr].mb_field ?
+ refPic[list][block_b.pos_y][block_b.pos_x] >>1:
+ refPic[list][block_b.pos_y][block_b.pos_x] :
+ -1;
+ rFrameUR = block_c.available ?
+ img->mb_data[block_c.mb_addr].mb_field ?
+ refPic[list][block_c.pos_y][block_c.pos_x] >>1:
+ refPic[list][block_c.pos_y][block_c.pos_x] :
+ -1;
+ }
+ }
+
+
+ /* Prediction if only one of the neighbors uses the reference frame
+ * we are checking
+ */
+ if(rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame) mvPredType = MVPRED_L;
+ else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame) mvPredType = MVPRED_U;
+ else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame) mvPredType = MVPRED_UR;
+ // Directional predictions
+ if(blockshape_x == 8 && blockshape_y == 16)
+ {
+ if(mb_x == 0)
+ {
+ if(rFrameL == ref_frame)
+ mvPredType = MVPRED_L;
+ }
+ else
+ {
+ if( rFrameUR == ref_frame)
+ mvPredType = MVPRED_UR;
+ }
+ }
+ else if(blockshape_x == 16 && blockshape_y == 8)
+ {
+ if(mb_y == 0)
+ {
+ if(rFrameU == ref_frame)
+ mvPredType = MVPRED_U;
+ }
+ else
+ {
+ if(rFrameL == ref_frame)
+ mvPredType = MVPRED_L;
+ }
+ }
+
+ for (hv=0; hv < 2; hv++)
+ {
+ if (!img->MbaffFrameFlag || hv==0)
+ {
+ mv_a = block_a.available ? tmp_mv[list][block_a.pos_y][block_a.pos_x][hv] : 0;
+ mv_b = block_b.available ? tmp_mv[list][block_b.pos_y][block_b.pos_x][hv] : 0;
+ mv_c = block_c.available ? tmp_mv[list][block_c.pos_y][block_c.pos_x][hv] : 0;
+ }
+ else
+ {
+ if (img->mb_data[img->current_mb_nr].mb_field)
+ {
+ mv_a = block_a.available ? img->mb_data[block_a.mb_addr].mb_field?
+ tmp_mv[list][block_a.pos_y][block_a.pos_x][hv]:
+ tmp_mv[list][block_a.pos_y][block_a.pos_x][hv] / 2:
+ 0;
+ mv_b = block_b.available ? img->mb_data[block_b.mb_addr].mb_field?
+ tmp_mv[list][block_b.pos_y][block_b.pos_x][hv]:
+ tmp_mv[list][block_b.pos_y][block_b.pos_x][hv] / 2:
+ 0;
+ mv_c = block_c.available ? img->mb_data[block_c.mb_addr].mb_field?
+ tmp_mv[list][block_c.pos_y][block_c.pos_x][hv]:
+ tmp_mv[list][block_c.pos_y][block_c.pos_x][hv] / 2:
+ 0;
+ }
+ else
+ {
+ mv_a = block_a.available ? img->mb_data[block_a.mb_addr].mb_field?
+ tmp_mv[list][block_a.pos_y][block_a.pos_x][hv] * 2:
+ tmp_mv[list][block_a.pos_y][block_a.pos_x][hv]:
+ 0;
+ mv_b = block_b.available ? img->mb_data[block_b.mb_addr].mb_field?
+ tmp_mv[list][block_b.pos_y][block_b.pos_x][hv] * 2:
+ tmp_mv[list][block_b.pos_y][block_b.pos_x][hv]:
+ 0;
+ mv_c = block_c.available ? img->mb_data[block_c.mb_addr].mb_field?
+ tmp_mv[list][block_c.pos_y][block_c.pos_x][hv] * 2:
+ tmp_mv[list][block_c.pos_y][block_c.pos_x][hv]:
+ 0;
+ }
+ }
+
+ switch (mvPredType)
+ {
+ case MVPRED_MEDIAN:
+ if(!(block_b.available || block_c.available))
+ pred_vec = mv_a;
+ else
+ pred_vec = mv_a+mv_b+mv_c-imin(mv_a,imin(mv_b,mv_c))-imax(mv_a,imax(mv_b,mv_c));
+ break;
+ case MVPRED_L:
+ pred_vec = mv_a;
+ break;
+ case MVPRED_U:
+ pred_vec = mv_b;
+ break;
+ case MVPRED_UR:
+ pred_vec = mv_c;
+ break;
+ default:
+ break;
+ }
+
+ pmv[hv] = pred_vec;
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Set context for reference frames
+ ************************************************************************
+ */
+int
+BType2CtxRef (int btype)
+{
+ if (btype<4) return 0;
+ else return 1;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Read motion info
+ ************************************************************************
+ */
+void readMotionInfoFromNAL (struct img_par *img, struct inp_par *inp)
+{
+ int i,j,k;
+ int step_h,step_v;
+ int curr_mvd;
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ SyntaxElement currSE;
+ Slice *currSlice = img->currentSlice;
+ DataPartition *dP;
+ int *partMap = assignSE2partition[currSlice->dp_mode];
+ int bframe = (img->type==B_SLICE);
+ int partmode = (IS_P8x8(currMB)?4:currMB->mb_type);
+ int step_h0 = BLOCK_STEP [partmode][0];
+ int step_v0 = BLOCK_STEP [partmode][1];
+
+ int mv_mode, i0, j0;
+ char refframe;
+ short pmv[2];
+ int j4, i4, ii,jj;
+ int vec;
+
+ int mv_scale = 0;
+
+ int flag_mode;
+
+ int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? 4 : 2 : 0;
+
+ byte ** moving_block;
+ short **** co_located_mv;
+ char *** co_located_ref_idx;
+ int64 *** co_located_ref_id;
+
+ if ((img->MbaffFrameFlag)&&(currMB->mb_field))
+ {
+ if(img->current_mb_nr&0x01)
+ {
+ moving_block = Co_located->bottom_moving_block;
+ co_located_mv = Co_located->bottom_mv;
+ co_located_ref_idx = Co_located->bottom_ref_idx;
+ co_located_ref_id = Co_located->bottom_ref_pic_id;
+ }
+ else
+ {
+ moving_block = Co_located->top_moving_block;
+ co_located_mv = Co_located->top_mv;
+ co_located_ref_idx = Co_located->top_ref_idx;
+ co_located_ref_id = Co_located->top_ref_pic_id;
+ }
+ }
+ else
+ {
+ moving_block = Co_located->moving_block;
+ co_located_mv = Co_located->mv;
+ co_located_ref_idx = Co_located->ref_idx;
+ co_located_ref_id = Co_located->ref_pic_id;
+ }
+
+ if (bframe && IS_P8x8 (currMB))
+ {
+ if (img->direct_spatial_mv_pred_flag)
+ {
+ int imgblock_y= ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? (img->block_y-4)>>1:img->block_y>>1: img->block_y;
+ int l0_rFrameL, l0_rFrameU, l0_rFrameUL, l0_rFrameUR;
+ int l1_rFrameL, l1_rFrameU, l1_rFrameUL, l1_rFrameUR;
+
+ PixelPos mb_left, mb_up, mb_upleft, mb_upright;
+
+ char l0_rFrame,l1_rFrame;
+ short pmvl0[2]={0,0}, pmvl1[2]={0,0};
+
+ getLuma4x4Neighbour(img->current_mb_nr, -1, 0, &mb_left);
+ getLuma4x4Neighbour(img->current_mb_nr, 0, -1, &mb_up);
+ getLuma4x4Neighbour(img->current_mb_nr, 16, -1, &mb_upright);
+ getLuma4x4Neighbour(img->current_mb_nr, -1, -1, &mb_upleft);
+
+ if (!img->MbaffFrameFlag)
+ {
+ l0_rFrameL = mb_left.available ? dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] : -1;
+ l0_rFrameU = mb_up.available ? dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] : -1;
+ l0_rFrameUL = mb_upleft.available ? dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
+ l0_rFrameUR = mb_upright.available ? dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] : l0_rFrameUL;
+
+ l1_rFrameL = mb_left.available ? dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] : -1;
+ l1_rFrameU = mb_up.available ? dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] : -1;
+ l1_rFrameUL = mb_upleft.available ? dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
+ l1_rFrameUR = mb_upright.available ? dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] : l1_rFrameUL;
+ }
+ else
+ {
+ if (img->mb_data[img->current_mb_nr].mb_field)
+ {
+ l0_rFrameL = mb_left.available
+ ? img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] < 0
+ ? dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x]
+ : dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] * 2: -1;
+
+ l0_rFrameU = mb_up.available
+ ? img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] < 0
+ ? dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x]
+ : dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] * 2: -1;
+
+ l0_rFrameUL = mb_upleft.available
+ ? img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] < 0
+ ? dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x]
+ : dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] *2: -1;
+
+ l0_rFrameUR = mb_upright.available
+ ? img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] < 0
+ ? dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x]
+ : dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] * 2: l0_rFrameUL;
+
+ l1_rFrameL = mb_left.available
+ ? img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] < 0
+ ? dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x]
+ : dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] * 2: -1;
+
+ l1_rFrameU = mb_up.available
+ ? img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] < 0
+ ? dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x]
+ : dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] * 2: -1;
+
+ l1_rFrameUL = mb_upleft.available
+ ? img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] < 0
+ ? dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x]
+ : dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] *2 : -1;
+
+ l1_rFrameUR = mb_upright.available
+ ? img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] < 0
+ ? dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x]
+ : dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] * 2: l1_rFrameUL;
+
+ }
+ else
+ {
+ l0_rFrameL = mb_left.available ?
+ img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] < 0 ?
+ dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] >> 1 :
+ dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x]: -1;
+
+ l0_rFrameU = mb_up.available ?
+ img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] < 0 ?
+ dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] >> 1 :
+ dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] : -1;
+
+ l0_rFrameUL = mb_upleft.available ?
+ img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] < 0 ?
+ dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x]>> 1 :
+ dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
+
+ l0_rFrameUR = mb_upright.available ?
+ img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] < 0 ?
+ dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] >> 1 :
+ dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] : l0_rFrameUL;
+
+ l1_rFrameL = mb_left.available ?
+ img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] < 0 ?
+ dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] >> 1 :
+ dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] : -1;
+ l1_rFrameU = mb_up.available ?
+ img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] < 0 ?
+ dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] >> 1 :
+ dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] : -1;
+
+ l1_rFrameUL = mb_upleft.available ?
+ img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] < 0 ?
+ dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] >> 1 :
+ dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
+
+ l1_rFrameUR = mb_upright.available ?
+ img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] < 0 ?
+ dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] >> 1:
+ dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] : l1_rFrameUL;
+ }
+ }
+
+ l0_rFrame = (l0_rFrameL >= 0 && l0_rFrameU >= 0) ? imin(l0_rFrameL,l0_rFrameU): imax(l0_rFrameL,l0_rFrameU);
+ l0_rFrame = (l0_rFrame >= 0 && l0_rFrameUR >= 0) ? imin(l0_rFrame,l0_rFrameUR): imax(l0_rFrame,l0_rFrameUR);
+
+ l1_rFrame = (l1_rFrameL >= 0 && l1_rFrameU >= 0) ? imin(l1_rFrameL,l1_rFrameU): imax(l1_rFrameL,l1_rFrameU);
+ l1_rFrame = (l1_rFrame >= 0 && l1_rFrameUR >= 0) ? imin(l1_rFrame,l1_rFrameUR): imax(l1_rFrame,l1_rFrameUR);
+
+
+ if (l0_rFrame >=0)
+ SetMotionVectorPredictor (img, pmvl0, l0_rFrame, LIST_0, dec_picture->ref_idx, dec_picture->mv, 0, 0, 16, 16);
+
+ if (l1_rFrame >=0)
+ SetMotionVectorPredictor (img, pmvl1, l1_rFrame, LIST_1, dec_picture->ref_idx, dec_picture->mv, 0, 0, 16, 16);
+
+
+ for (i=0;i<4;i++)
+ {
+ if (currMB->b8mode[i] == 0)
+ {
+ for(j=2*(i>>1);j<2*(i>>1)+2;j++)
+ {
+ for(k=2*(i&0x01);k<2*(i&0x01)+2;k++)
+ {
+ int j6 = imgblock_y+j;
+ j4 = img->block_y+j;
+ i4 = img->block_x+k;
+
+
+ if (l0_rFrame >= 0)
+ {
+ if (!l0_rFrame && ((!moving_block[j6][i4]) && (!listX[1+list_offset][0]->is_long_term)))
+ {
+ dec_picture->mv [LIST_0][j4][i4][0] = 0;
+ dec_picture->mv [LIST_0][j4][i4][1] = 0;
+ dec_picture->ref_idx[LIST_0][j4][i4] = 0;
+ }
+ else
+ {
+ dec_picture->mv [LIST_0][j4][i4][0] = pmvl0[0];
+ dec_picture->mv [LIST_0][j4][i4][1] = pmvl0[1];
+ dec_picture->ref_idx[LIST_0][j4][i4] = l0_rFrame;
+ }
+ }
+ else
+ {
+ dec_picture->mv [LIST_0][j4][i4][0] = 0;
+ dec_picture->mv [LIST_0][j4][i4][1] = 0;
+ dec_picture->ref_idx[LIST_0][j4][i4] = -1;
+ }
+
+ if (l1_rFrame >= 0)
+ {
+ if (l1_rFrame==0 && ((!moving_block[j6][i4])&& (!listX[1+list_offset][0]->is_long_term)))
+ {
+ dec_picture->mv [LIST_1][j4][i4][0] = 0;
+ dec_picture->mv [LIST_1][j4][i4][1] = 0;
+ dec_picture->ref_idx[LIST_1][j4][i4] = 0;
+ }
+ else
+ {
+ dec_picture->mv [LIST_1][j4][i4][0] = pmvl1[0];
+ dec_picture->mv [LIST_1][j4][i4][1] = pmvl1[1];
+ dec_picture->ref_idx[LIST_1][j4][i4] = l1_rFrame;
+ }
+ }
+ else
+ {
+ dec_picture->mv [LIST_1][j4][i4][0] = 0;
+ dec_picture->mv [LIST_1][j4][i4][1] = 0;
+ dec_picture->ref_idx[LIST_1][j4][i4] = -1;
+ }
+
+ if (l0_rFrame <0 && l1_rFrame <0)
+ {
+ dec_picture->ref_idx[LIST_0][j4][i4] = 0;
+ dec_picture->ref_idx[LIST_1][j4][i4] = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ for (i=0;i<4;i++)
+ {
+ if (currMB->b8mode[i] == 0)
+ {
+ for(j=2*(i>>1);j<2*(i>>1)+2;j++)
+ {
+ for(k=2*(i&0x01);k<2*(i&0x01)+2;k++)
+ {
+
+ int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? 4 : 2 : 0;
+ int imgblock_y = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? (img->block_y-4)>>1 : img->block_y>>1 : img->block_y;
+ int refList = co_located_ref_idx[LIST_0 ][imgblock_y+j][img->block_x+k]== -1 ? LIST_1 : LIST_0;
+ int ref_idx = co_located_ref_idx[refList][imgblock_y + j][img->block_x + k];
+ int mapped_idx=-1, iref;
+
+ if (ref_idx == -1)
+ {
+ dec_picture->ref_idx [LIST_0][img->block_y + j][img->block_x + k] = 0;
+ dec_picture->ref_idx [LIST_1][img->block_y + j][img->block_x + k] = 0;
+ }
+ else
+ {
+ for (iref=0;iref<imin(img->num_ref_idx_l0_active,listXsize[LIST_0 + list_offset]);iref++)
+ {
+ int curr_mb_field = ((img->MbaffFrameFlag)&&(currMB->mb_field));
+
+ if(img->structure==0 && curr_mb_field==0)
+ {
+ // If the current MB is a frame MB and the colocated is from a field picture,
+ // then the co_located_ref_id may have been generated from the wrong value of
+ // frame_poc if it references it's complementary field, so test both POC values
+ if(listX[0][iref]->top_poc*2 == co_located_ref_id[refList][imgblock_y + j][img->block_x + k]
+ || listX[0][iref]->bottom_poc*2 == co_located_ref_id[refList][imgblock_y + j][img->block_x + k])
+ {
+ mapped_idx=iref;
+ break;
+ }
+ else //! invalid index. Default to zero even though this case should not happen
+ mapped_idx=INVALIDINDEX;
+ continue;
+ }
+ if (dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][iref]==co_located_ref_id[refList][imgblock_y + j][img->block_x + k])
+ {
+ mapped_idx=iref;
+ break;
+ }
+ else //! invalid index. Default to zero even though this case should not happen
+ mapped_idx=INVALIDINDEX;
+ }
+ if (INVALIDINDEX == mapped_idx)
+ {
+ error("temporal direct error\ncolocated block has ref that is unavailable",-1111);
+ }
+ dec_picture->ref_idx [LIST_0][img->block_y + j][img->block_x + k] = mapped_idx;
+ dec_picture->ref_idx [LIST_1][img->block_y + j][img->block_x + k] = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // If multiple ref. frames, read reference frame for the MB *********************************
+ if(img->num_ref_idx_l0_active>1)
+ {
+ flag_mode = ( img->num_ref_idx_l0_active == 2 ? 1 : 0);
+
+ currSE.type = SE_REFFRAME;
+ dP = &(currSlice->partArr[partMap[SE_REFFRAME]]);
+
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_ue;
+ else currSE.reading = readRefFrame_CABAC;
+
+ for (j0=0; j0<4; j0+=step_v0)
+ {
+ for (i0=0; i0<4; i0+=step_h0)
+ {
+ k=2*(j0>>1)+(i0>>1);
+ if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)
+ {
+ TRACE_STRING("ref_idx_l0");
+
+ img->subblock_x = i0;
+ img->subblock_y = j0;
+
+ if (!IS_P8x8 (currMB) || bframe || (!bframe && !img->allrefzero))
+ {
+ currSE.context = BType2CtxRef (currMB->b8mode[k]);
+ if( (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) && flag_mode )
+ {
+ currSE.len = 1;
+ readSyntaxElement_FLC(&currSE, dP->bitstream);
+ currSE.value1 = 1 - currSE.value1;
+ }
+ else
+ {
+ currSE.value2 = LIST_0;
+ dP->readSyntaxElement (&currSE,img,dP);
+ }
+ refframe = currSE.value1;
+
+ }
+ else
+ {
+ refframe = 0;
+ }
+
+ for (j=img->block_y +j0; j<img->block_y +j0+step_v0;j++)
+ memset(&dec_picture->ref_idx[LIST_0][j][img->block_x + i0], refframe, step_h0 * sizeof(char));
+ }
+ }
+ }
+ }
+ else
+ {
+ for (j0=0; j0<4; j0+=step_v0)
+ {
+ for (i0=0; i0<4; i0+=step_h0)
+ {
+ k=2*(j0>>1)+(i0>>1);
+ if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)
+ {
+ for (j=img->block_y + j0; j < img->block_y + j0+step_v0;j++)
+ memset(&dec_picture->ref_idx[LIST_0][j][img->block_x + i0], 0, step_h0 * sizeof(char));
+ }
+ }
+ }
+ }
+
+ // If backward multiple ref. frames, read backward reference frame for the MB *********************************
+ if(img->num_ref_idx_l1_active>1)
+ {
+ flag_mode = ( img->num_ref_idx_l1_active == 2 ? 1 : 0);
+
+ currSE.type = SE_REFFRAME;
+ dP = &(currSlice->partArr[partMap[SE_REFFRAME]]);
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
+ currSE.mapping = linfo_ue;
+ else
+ currSE.reading = readRefFrame_CABAC;
+
+ for (j0=0; j0<4; j0+=step_v0)
+ {
+ for (i0=0; i0<4; i0+=step_h0)
+ {
+ k=2*(j0>>1)+(i0>>1);
+ if ((currMB->b8pdir[k]==1 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)
+ {
+ TRACE_STRING("ref_idx_l1");
+
+ img->subblock_x = i0;
+ img->subblock_y = j0;
+
+ currSE.context = BType2CtxRef (currMB->b8mode[k]);
+ if( (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) && flag_mode )
+ {
+ currSE.len = 1;
+ readSyntaxElement_FLC(&currSE, dP->bitstream);
+ currSE.value1 = 1-currSE.value1;
+ }
+ else
+ {
+ currSE.value2 = LIST_1;
+ dP->readSyntaxElement (&currSE,img,dP);
+ }
+ refframe = currSE.value1;
+
+ for (j=img->block_y + j0; j<img->block_y + j0+step_v0;j++)
+ {
+ memset(&dec_picture->ref_idx[LIST_1][j][img->block_x + i0], refframe, step_h0 * sizeof(char));
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ for (j0=0; j0<4; j0+=step_v0)
+ {
+ for (i0=0; i0<4; i0+=step_h0)
+ {
+ k=2*(j0>>1)+(i0>>1);
+ if ((currMB->b8pdir[k]==1 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)
+ {
+ for (j=img->block_y + j0; j<img->block_y + j0+step_v0;j++)
+ memset(&dec_picture->ref_idx[LIST_1][ j][img->block_x + i0], 0, step_h0 * sizeof(char));
+ }
+ }
+ }
+ }
+
+ //===== READ FORWARD MOTION VECTORS =====
+ currSE.type = SE_MVD;
+ dP = &(currSlice->partArr[partMap[SE_MVD]]);
+
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_se;
+ else currSE.reading = readMVD_CABAC;
+
+ for (j0=0; j0<4; j0+=step_v0)
+ for (i0=0; i0<4; i0+=step_h0)
+ {
+ k=2*(j0>>1)+(i0>>1);
+
+ if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && (currMB->b8mode[k] !=0))//has forward vector
+ {
+ mv_mode = currMB->b8mode[k];
+ step_h = BLOCK_STEP [mv_mode][0];
+ step_v = BLOCK_STEP [mv_mode][1];
+
+ refframe = dec_picture->ref_idx[LIST_0][img->block_y+j0][img->block_x+i0];
+
+ for (j=j0; j<j0+step_v0; j+=step_v)
+ {
+ j4 = img->block_y+j;
+ for (i=i0; i<i0+step_h0; i+=step_h)
+ {
+ i4 = img->block_x+i;
+
+ // first make mv-prediction
+ SetMotionVectorPredictor (img, pmv, refframe, LIST_0, dec_picture->ref_idx, dec_picture->mv, i, j, 4*step_h, 4*step_v);
+
+ for (k=0; k < 2; k++)
+ {
+ TRACE_STRING("mvd_l0");
+
+ img->subblock_x = i; // position used for context determination
+ img->subblock_y = j; // position used for context determination
+ currSE.value2 = k<<1; // identifies the component; only used for context determination
+ dP->readSyntaxElement(&currSE,img,dP);
+ curr_mvd = currSE.value1;
+
+ vec=curr_mvd+pmv[k]; /* find motion vector */
+
+ for(jj=0;jj<step_v;jj++)
+ {
+ for(ii=0;ii<step_h;ii++)
+ {
+ dec_picture->mv [LIST_0][j4+jj][i4+ii][k] = vec;
+ currMB->mvd [LIST_0][j +jj][i +ii][k] = curr_mvd;
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (currMB->b8mode[k=2*(j0>>1)+(i0>>1)]==0)
+ {
+ if (!img->direct_spatial_mv_pred_flag)
+ {
+ int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? 4 : 2 : 0;
+ int imgblock_y = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? (img->block_y-4)>>1:img->block_y>>1 : img->block_y;
+
+ int refList = (co_located_ref_idx[LIST_0 ][imgblock_y+j0][img->block_x+i0]== -1 ? LIST_1 : LIST_0);
+ int ref_idx = co_located_ref_idx[refList][imgblock_y+j0][img->block_x+i0];
+
+ if (ref_idx==-1)
+ {
+ for (j4=img->block_y+j0; j4<img->block_y+j0+step_v0; j4++)
+ {
+ for (i4=img->block_x+i0; i4<img->block_x+i0+step_h0; i4++)
+ {
+ dec_picture->ref_idx [LIST_1][j4][i4]=0;
+ dec_picture->ref_idx [LIST_0][j4][i4]=0;
+
+ for (ii=0; ii < 2; ii++)
+ {
+ dec_picture->mv [LIST_0][j4][i4][ii]=0;
+ dec_picture->mv [LIST_1][j4][i4][ii]=0;
+ }
+ }
+ }
+ }
+ else
+ {
+ int mapped_idx=-1, iref;
+ int j6;
+
+ for (iref = 0; iref < imin(img->num_ref_idx_l0_active, listXsize[LIST_0 + list_offset]); iref++)
+ {
+ int curr_mb_field = ((img->MbaffFrameFlag)&&(currMB->mb_field));
+
+ if(img->structure==0 && curr_mb_field==0)
+ {
+ // If the current MB is a frame MB and the colocated is from a field picture,
+ // then the co_located_ref_id may have been generated from the wrong value of
+ // frame_poc if it references it's complementary field, so test both POC values
+ if(listX[0][iref]->top_poc * 2 == co_located_ref_id[refList][imgblock_y + j0][img->block_x + i0]
+ || listX[0][iref]->bottom_poc * 2 == co_located_ref_id[refList][imgblock_y + j0][img->block_x + i0])
+ {
+ mapped_idx=iref;
+ break;
+ }
+ else //! invalid index. Default to zero even though this case should not happen
+ mapped_idx=INVALIDINDEX;
+ continue;
+ }
+ if (dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][iref]==co_located_ref_id[refList][imgblock_y+j0][img->block_x+i0])
+ {
+ mapped_idx=iref;
+ break;
+ }
+ else //! invalid index. Default to zero even though this case should not happen
+ mapped_idx=INVALIDINDEX;
+ }
+
+ if (INVALIDINDEX == mapped_idx)
+ {
+ error("temporal direct error\ncolocated block has ref that is unavailable",-1111);
+ }
+
+
+ for (j=j0; j<j0+step_v0; j++)
+ {
+ j4 = img->block_y+j;
+ j6 = imgblock_y + j;
+
+ for (i4=img->block_x+i0; i4<img->block_x+i0+step_h0; i4++)
+ {
+ mv_scale = img->mvscale[LIST_0 + list_offset][mapped_idx];
+
+ dec_picture->ref_idx [LIST_0][j4][i4] = mapped_idx;
+ dec_picture->ref_idx [LIST_1][j4][i4] = 0;
+
+
+ for (ii=0; ii < 2; ii++)
+ {
+ if (mv_scale == 9999 || listX[LIST_0+list_offset][mapped_idx]->is_long_term)
+ {
+ dec_picture->mv [LIST_0][j4][i4][ii] = co_located_mv[refList][j6][i4][ii];
+ dec_picture->mv [LIST_1][j4][i4][ii] = 0;
+ }
+ else
+ {
+ dec_picture->mv [LIST_0][j4][i4][ii] = (mv_scale * co_located_mv[refList][j6][i4][ii] + 128 ) >> 8;
+ dec_picture->mv [LIST_1][j4][i4][ii] = dec_picture->mv[LIST_0][j4][i4][ii] - co_located_mv[refList][j6][i4][ii];
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //===== READ BACKWARD MOTION VECTORS =====
+ currSE.type = SE_MVD;
+ dP = &(currSlice->partArr[partMap[SE_MVD]]);
+
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_se;
+ else currSE.reading = readMVD_CABAC;
+
+ for (j0=0; j0<4; j0+=step_v0)
+ {
+ for (i0=0; i0<4; i0+=step_h0)
+ {
+ k=2*(j0>>1)+(i0>>1);
+ if ((currMB->b8pdir[k]==1 || currMB->b8pdir[k]==2) && (currMB->b8mode[k]!=0))//has backward vector
+ {
+ mv_mode = currMB->b8mode[k];
+ step_h = BLOCK_STEP [mv_mode][0];
+ step_v = BLOCK_STEP [mv_mode][1];
+
+ refframe = dec_picture->ref_idx[LIST_1][img->block_y+j0][img->block_x+i0];
+
+ for (j=j0; j<j0+step_v0; j+=step_v)
+ {
+ j4 = img->block_y+j;
+ for (i=i0; i<i0+step_h0; i+=step_h)
+ {
+ i4 = img->block_x+i;
+
+ // first make mv-prediction
+ SetMotionVectorPredictor (img, pmv, refframe, LIST_1, dec_picture->ref_idx, dec_picture->mv, i, j, 4*step_h, 4*step_v);
+
+ for (k=0; k < 2; k++)
+ {
+ TRACE_STRING("mvd_l1");
+
+ img->subblock_x = i; // position used for context determination
+ img->subblock_y = j; // position used for context determination
+ currSE.value2 = (k<<1) +1; // identifies the component; only used for context determination
+ dP->readSyntaxElement(&currSE,img,dP);
+ curr_mvd = currSE.value1;
+
+ vec=curr_mvd+pmv[k]; /* find motion vector */
+
+ for(jj=0;jj<step_v;jj++)
+ {
+ for(ii=0;ii<step_h;ii++)
+ {
+ dec_picture->mv [LIST_1][j4+jj][i4+ii][k] = vec;
+ currMB->mvd [LIST_1][j+jj] [i+ii] [k] = curr_mvd;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ // record reference picture Ids for deblocking decisions
+
+
+ for(j4=img->block_y;j4<(img->block_y+4);j4++)
+ {
+ for(i4=img->block_x;i4<(img->block_x+4);i4++)
+ {
+ if (dec_picture->ref_idx[LIST_0][j4][i4]>=0)
+ dec_picture->ref_pic_id[LIST_0][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][(short)dec_picture->ref_idx[LIST_0][j4][i4]];
+ else
+ dec_picture->ref_pic_id[LIST_0][j4][i4] = INT64_MIN;
+ if (dec_picture->ref_idx[LIST_1][j4][i4]>=0)
+ dec_picture->ref_pic_id[LIST_1][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_1 + list_offset][(short)dec_picture->ref_idx[LIST_1][j4][i4]];
+ else
+ dec_picture->ref_pic_id[LIST_1][j4][i4] = INT64_MIN;
+ }
+ }
+}
+
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Get the Prediction from the Neighboring Blocks for Number of Nonzero Coefficients
+ *
+ * Luma Blocks
+ ************************************************************************
+ */
+int predict_nnz(struct img_par *img, int i,int j)
+{
+ PixelPos pix;
+
+ int pred_nnz = 0;
+ int cnt = 0;
+ int mb_nr = img->current_mb_nr;
+ Macroblock *currMB = &(img->mb_data[mb_nr]);
+
+ // left block
+ getLuma4x4Neighbour(mb_nr, (i<<2) - 1, (j<<2), &pix);
+
+ if (IS_INTRA(currMB) && pix.available && active_pps->constrained_intra_pred_flag && (img->currentSlice->dp_mode==PAR_DP_3))
+ {
+ pix.available &= img->intra_block[pix.mb_addr];
+ if (!pix.available)
+ cnt++;
+ }
+
+ if (pix.available)
+ {
+ pred_nnz = img->nz_coeff [pix.mb_addr ][pix.x][pix.y];
+ cnt++;
+ }
+
+ // top block
+ getLuma4x4Neighbour(mb_nr, (i<<2), (j<<2) - 1, &pix);
+
+ if (IS_INTRA(currMB) && pix.available && active_pps->constrained_intra_pred_flag && (img->currentSlice->dp_mode==PAR_DP_3))
+ {
+ pix.available &= img->intra_block[pix.mb_addr];
+ if (!pix.available)
+ cnt++;
+ }
+
+ if (pix.available)
+ {
+ pred_nnz += img->nz_coeff [pix.mb_addr ][pix.x][pix.y];
+ cnt++;
+ }
+
+ if (cnt==2)
+ {
+ pred_nnz++;
+ pred_nnz>>=1;
+ }
+
+ return pred_nnz;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Get the Prediction from the Neighboring Blocks for Number of Nonzero Coefficients
+ *
+ * Chroma Blocks
+ ************************************************************************
+ */
+int predict_nnz_chroma(struct img_par *img, int i,int j)
+{
+ PixelPos pix;
+
+ int pred_nnz = 0;
+ int cnt =0;
+ int mb_nr = img->current_mb_nr;
+ static const int j_off_tab [12] = {0,0,0,0,4,4,4,4,8,8,8,8};
+ int j_off = j_off_tab[j];
+ Macroblock *currMB = &(img->mb_data[mb_nr]);
+
+ if (dec_picture->chroma_format_idc != YUV444)
+ {
+ //YUV420 and YUV422
+ // left block
+ getChroma4x4Neighbour(mb_nr, ((i&0x01)<<2) - 1, ((j-4)<<2), &pix);
+
+ if (IS_INTRA(currMB) && pix.available && active_pps->constrained_intra_pred_flag && (img->currentSlice->dp_mode==PAR_DP_3))
+ {
+ pix.available &= img->intra_block[pix.mb_addr];
+ if (!pix.available)
+ cnt++;
+ }
+
+ 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)<<2), ((j-4)<<2) - 1, &pix);
+
+ if (IS_INTRA(currMB) && pix.available && active_pps->constrained_intra_pred_flag && (img->currentSlice->dp_mode==PAR_DP_3))
+ {
+ pix.available &= img->intra_block[pix.mb_addr];
+ if (!pix.available)
+ cnt++;
+ }
+
+ 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<<2) - 1, ((j-j_off)<<2), &pix);
+
+ if (IS_INTRA(currMB) && pix.available && active_pps->constrained_intra_pred_flag && (img->currentSlice->dp_mode==PAR_DP_3))
+ {
+ pix.available &= img->intra_block[pix.mb_addr];
+ cnt--;
+ }
+
+ if (pix.available)
+ {
+ pred_nnz = img->nz_coeff [pix.mb_addr ][pix.x][j_off + pix.y];
+ cnt++;
+ }
+
+ // top block
+ getChroma4x4Neighbour(mb_nr, (i<<2), ((j-j_off)<<2) -1, &pix);
+
+ if (IS_INTRA(currMB) && pix.available && active_pps->constrained_intra_pred_flag && (img->currentSlice->dp_mode==PAR_DP_3))
+ {
+ pix.available &= img->intra_block[pix.mb_addr];
+ cnt--;
+ }
+
+ 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>>=1;
+ }
+
+ return pred_nnz;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Reads coeff of an 4x4 block (CAVLC)
+ *
+ * \author
+ * Karl Lillevold <karll at real.com>
+ * contributions by James Au <james at ubvideo.com>
+ ************************************************************************
+ */
+
+
+void readCoeff4x4_CAVLC (struct img_par *img,struct inp_par *inp,
+ int block_type,
+ int i, int j, int levarr[16], int runarr[16],
+ int *number_coefficients)
+{
+ int mb_nr = img->current_mb_nr;
+ Macroblock *currMB = &img->mb_data[mb_nr];
+ SyntaxElement currSE;
+ Slice *currSlice = img->currentSlice;
+ DataPartition *dP;
+ int *partMap = assignSE2partition[currSlice->dp_mode];
+
+
+ int k, code, vlcnum;
+ int numcoeff, numtrailingones, numcoeff_vlc;
+ int level_two_or_higher;
+ int numones, totzeros, level, cdc=0, cac=0;
+ int zerosleft, ntr, dptype = 0;
+ int max_coeff_num = 0, nnz;
+ char type[15];
+ static int incVlc[] = {0,3,6,12,24,48,32768}; // maximum vlc = 6
+
+ numcoeff = 0;
+
+ switch (block_type)
+ {
+ case LUMA:
+ max_coeff_num = 16;
+#if TRACE
+ sprintf(type, "%s", "Luma");
+#endif
+ dptype = IS_INTRA (currMB) ? SE_LUM_AC_INTRA : SE_LUM_AC_INTER;
+ break;
+ case LUMA_INTRA16x16DC:
+ max_coeff_num = 16;
+#if TRACE
+ sprintf(type, "%s", "Lum16DC");
+#endif
+ dptype = SE_LUM_DC_INTRA;
+ break;
+ case LUMA_INTRA16x16AC:
+ max_coeff_num = 15;
+#if TRACE
+ sprintf(type, "%s", "Lum16AC");
+#endif
+ dptype = SE_LUM_AC_INTRA;
+ break;
+
+ case CHROMA_DC:
+ max_coeff_num = img->num_cdc_coeff;
+ cdc = 1;
+#if TRACE
+ sprintf(type, "%s", "ChrDC");
+#endif
+ dptype = IS_INTRA (currMB) ? SE_CHR_DC_INTRA : SE_CHR_DC_INTER;
+ break;
+ case CHROMA_AC:
+ max_coeff_num = 15;
+ cac = 1;
+#if TRACE
+ sprintf(type, "%s", "ChrAC");
+#endif
+ dptype = IS_INTRA (currMB) ? SE_CHR_AC_INTRA : SE_CHR_AC_INTER;
+ break;
+ default:
+ error ("readCoeff4x4_CAVLC: invalid block type", 600);
+ break;
+ }
+
+ currSE.type = dptype;
+ dP = &(currSlice->partArr[partMap[dptype]]);
+
+ img->nz_coeff[img->current_mb_nr][i][j] = 0;
+
+
+ if (!cdc)
+ {
+ // luma or chroma AC
+ if (!cac)
+ {
+ nnz = predict_nnz(img, i, j);
+ }
+ else
+ {
+ nnz = predict_nnz_chroma(img, i, j);
+ }
+
+ if (nnz < 2)
+ {
+ numcoeff_vlc = 0;
+ }
+ else if (nnz < 4)
+ {
+ numcoeff_vlc = 1;
+ }
+ else if (nnz < 8)
+ {
+ numcoeff_vlc = 2;
+ }
+ else //
+ {
+ numcoeff_vlc = 3;
+ }
+
+ currSE.value1 = numcoeff_vlc;
+
+ readSyntaxElement_NumCoeffTrailingOnes(&currSE, dP, type);
+
+ numcoeff = currSE.value1;
+ numtrailingones = currSE.value2;
+
+ img->nz_coeff[img->current_mb_nr][i][j] = numcoeff;
+ }
+ else
+ {
+ // chroma DC
+ readSyntaxElement_NumCoeffTrailingOnesChromaDC(&currSE, dP);
+
+ numcoeff = currSE.value1;
+ numtrailingones = currSE.value2;
+ }
+
+
+ for (k = 0; k < max_coeff_num; k++)
+ {
+ levarr[k] = 0;
+ runarr[k] = 0;
+ }
+
+ numones = numtrailingones;
+ *number_coefficients = numcoeff;
+
+ if (numcoeff)
+ {
+ if (numtrailingones)
+ {
+
+ currSE.len = numtrailingones;
+
+#if TRACE
+ snprintf(currSE.tracestring,
+ TRACESTRING_SIZE, "%s trailing ones sign (%d,%d)", type, i, j);
+#endif
+
+ readSyntaxElement_FLC (&currSE, dP->bitstream);
+
+ code = currSE.inf;
+ ntr = numtrailingones;
+ for (k = numcoeff-1; k > numcoeff-1-numtrailingones; k--)
+ {
+ ntr --;
+ levarr[k] = (code>>ntr)&1 ? -1 : 1;
+ }
+ }
+
+ // decode levels
+ level_two_or_higher = (numcoeff > 3 && numtrailingones == 3)? 0 : 1;
+ vlcnum = (numcoeff > 10 && numtrailingones < 3) ? 1 : 0;
+
+ for (k = numcoeff - 1 - numtrailingones; k >= 0; k--)
+ {
+
+#if TRACE
+ snprintf(currSE.tracestring,
+ TRACESTRING_SIZE, "%s lev (%d,%d) k=%d vlc=%d ", type,
+ i, j, k, vlcnum);
+#endif
+
+ if (vlcnum == 0)
+ readSyntaxElement_Level_VLC0(&currSE, dP);
+ else
+ readSyntaxElement_Level_VLCN(&currSE, vlcnum, dP);
+
+ if (level_two_or_higher)
+ {
+ currSE.inf += (currSE.inf > 0) ? 1 : -1;
+ level_two_or_higher = 0;
+ }
+
+ level = levarr[k] = currSE.inf;
+ if (iabs(level) == 1)
+ numones ++;
+
+ // update VLC table
+ if (iabs(level)>incVlc[vlcnum])
+ vlcnum++;
+
+ if (k == numcoeff - 1 - numtrailingones && iabs(level)>3)
+ vlcnum = 2;
+
+ }
+
+ if (numcoeff < max_coeff_num)
+ {
+ // decode total run
+ vlcnum = numcoeff-1;
+ currSE.value1 = vlcnum;
+
+#if TRACE
+ snprintf(currSE.tracestring,
+ TRACESTRING_SIZE, "%s totalrun (%d,%d) vlc=%d ", type, i,j, vlcnum);
+#endif
+ if (cdc)
+ readSyntaxElement_TotalZerosChromaDC(&currSE, dP);
+ else
+ readSyntaxElement_TotalZeros(&currSE, dP);
+
+ totzeros = currSE.value1;
+ }
+ else
+ {
+ totzeros = 0;
+ }
+
+ // decode run before each coefficient
+ zerosleft = totzeros;
+ i = numcoeff - 1;
+ if (zerosleft > 0 && i > 0)
+ {
+ do
+ {
+ // select VLC for runbefore
+ vlcnum = zerosleft - 1;
+ if (vlcnum > RUNBEFORE_NUM - 1)
+ vlcnum = RUNBEFORE_NUM - 1;
+
+ currSE.value1 = vlcnum;
+#if TRACE
+ snprintf(currSE.tracestring,
+ TRACESTRING_SIZE, "%s run (%d,%d) k=%d vlc=%d ",
+ type, i, j, i, vlcnum);
+#endif
+
+ readSyntaxElement_Run(&currSE, dP);
+ runarr[i] = currSE.value1;
+
+ zerosleft -= runarr[i];
+ i --;
+ } while (zerosleft != 0 && i != 0);
+ }
+ runarr[i] = zerosleft;
+
+ } // if numcoeff
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Calculate the quantisation and inverse quantisation parameters
+ *
+ ************************************************************************
+ */
+void CalculateQuant8Param()
+{
+ int i, j, k, temp;
+
+ for(k=0; k<6; k++)
+ for(j=0; j<8; j++)
+ {
+ for(i=0; i<8; i++)
+ {
+ temp = (i<<3)+j;
+ InvLevelScale8x8Luma_Intra[k][i][j] = dequant_coef8[k][j][i]*qmatrix[6][temp];
+ InvLevelScale8x8Luma_Inter[k][i][j] = dequant_coef8[k][j][i]*qmatrix[7][temp];
+ }
+ }
+}
+
+/*!
+************************************************************************
+* \brief
+* Get coefficients (run/level) of one 8x8 block
+* from the NAL (CABAC Mode)
+************************************************************************
+*/
+void readLumaCoeff8x8_CABAC (struct img_par *img,struct inp_par *inp, int b8)
+{
+ int i,j,k;
+ int level = 1;
+ int mb_nr = img->current_mb_nr;
+ Macroblock *currMB = &img->mb_data[mb_nr];
+ int cbp = currMB->cbp;
+ SyntaxElement currSE;
+ Slice *currSlice = img->currentSlice;
+ DataPartition *dP;
+ int *partMap = assignSE2partition[currSlice->dp_mode];
+ int start_scan = 0; // take all coeffs
+ int coef_ctr = start_scan - 1;// i0, j0;
+ int boff_x, boff_y;
+
+ int run, len;
+
+ int qp_per = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)/6;
+ int qp_rem = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)%6;
+ Boolean lossless_qpprime = (Boolean) ((img->qp + img->bitdepth_luma_qp_scale)==0 && img->lossless_qpprime_flag==1);
+ int (*InvLevelScale8x8)[8] = IS_INTRA(currMB)? InvLevelScale8x8Luma_Intra[qp_rem] : InvLevelScale8x8Luma_Inter[qp_rem];
+ // select scan type
+ const byte (*pos_scan8x8)[2] = ((img->structure == FRAME) && (!currMB->mb_field)) ? SNGL_SCAN8x8 : FIELD_SCAN8x8;
+
+ img->is_intra_block = IS_INTRA(currMB);
+
+ if (cbp & (1<<b8)) // are there any coeff in current block at all
+ {
+ // === set offset in current macroblock ===
+ boff_x = (b8&0x01) << 3;
+ boff_y = (b8 >> 1) << 3;
+
+ img->subblock_x = boff_x >> 2; // position for coeff_count ctx
+ img->subblock_y = boff_y >> 2; // position for coeff_count ctx
+
+ if(!lossless_qpprime)
+ {
+ for(k=start_scan;(k < 65) && (level != 0);k++)
+ {
+ //============ read =============
+ /*
+ * make distinction between INTRA and INTER coded
+ * luminance coefficients
+ */
+ currSE.context = LUMA_8x8;
+ currSE.type = ((img->is_intra_block == 1)
+ ? (k==0 ? SE_LUM_DC_INTRA : SE_LUM_AC_INTRA)
+ : (k==0 ? SE_LUM_DC_INTER : SE_LUM_AC_INTER));
+
+#if TRACE
+ sprintf(currSE.tracestring, "Luma8x8 sng ");
+#endif
+ dP = &(currSlice->partArr[partMap[currSE.type]]);
+ currSE.reading = readRunLevel_CABAC;
+
+ dP->readSyntaxElement(&currSE,img,dP);
+ level = currSE.value1;
+ run = currSE.value2;
+ len = currSE.len;
+
+ //============ decode =============
+ if (level != 0) /* leave if len=1 */
+ {
+ coef_ctr += run + 1;
+
+ i=pos_scan8x8[coef_ctr][0];
+ j=pos_scan8x8[coef_ctr][1];
+
+ currMB->cbp_blk |= 51 << (4 * b8 - 2 * (b8 & 0x01)); // corresponds to 110011, as if all four 4x4 blocks contain coeff, shifted to block position
+ img->m7[boff_y + j][boff_x + i] = rshift_rnd_sf((level * InvLevelScale8x8[j][i]) << qp_per, 6); // dequantization
+ }
+ }
+ }
+ else
+ {
+ for(k=start_scan;(k < 65) && (level != 0);k++)
+ {
+ //============ read =============
+ /*
+ * make distinction between INTRA and INTER coded
+ * luminance coefficients
+ */
+ currSE.context = LUMA_8x8;
+ currSE.type = ((img->is_intra_block == 1)
+ ? (k==0 ? SE_LUM_DC_INTRA : SE_LUM_AC_INTRA)
+ : (k==0 ? SE_LUM_DC_INTER : SE_LUM_AC_INTER));
+
+#if TRACE
+ sprintf(currSE.tracestring, "Luma8x8 sng ");
+#endif
+ dP = &(currSlice->partArr[partMap[currSE.type]]);
+ currSE.reading = readRunLevel_CABAC;
+
+ dP->readSyntaxElement(&currSE,img,dP);
+ level = currSE.value1;
+ run = currSE.value2;
+ len = currSE.len;
+
+ //============ decode =============
+ if (level != 0) /* leave if len=1 */
+ {
+ coef_ctr += run+1;
+
+ i=pos_scan8x8[coef_ctr][0];
+ j=pos_scan8x8[coef_ctr][1];
+
+ currMB->cbp_blk |= 51 << (4 * b8 - 2 * (b8 & 0x01)); // corresponds to 110011, as if all four 4x4 blocks contain coeff, shifted to block position
+ img->m7[boff_y + j][boff_x + i] = level;
+ }
+ }
+ }
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Get coded block pattern and coefficients (run/level)
+ * from the NAL
+ ************************************************************************
+ */
+void readCBPandCoeffsFromNAL(struct img_par *img,struct inp_par *inp)
+{
+ int i,j,k;
+ int level;
+ int mb_nr = img->current_mb_nr;
+ int ii,jj;
+ int m2,jg2;// i1,j1;
+ Macroblock *currMB = &img->mb_data[mb_nr];
+ int cbp;
+ SyntaxElement currSE;
+ Slice *currSlice = img->currentSlice;
+ DataPartition *dP;
+ int *partMap = assignSE2partition[currSlice->dp_mode];
+ int coef_ctr, i0, j0, b8;
+ int ll;
+ int block_x,block_y;
+ int start_scan;
+ int run, len;
+ int levarr[16], runarr[16], numcoeff;
+
+ int qp_const;
+ int qp_per = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)/6;
+ int qp_rem = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)%6;
+ int smb = ((img->type==SP_SLICE) && IS_INTER (currMB)) || (img->type == SI_SLICE && currMB->mb_type == SI4MB);
+
+ int uv;
+ int qp_const_uv[2];
+ int qp_per_uv[2];
+ int qp_rem_uv[2];
+
+ int intra = IS_INTRA (currMB);
+ int temp[4];
+
+ int b4;
+ int yuv = dec_picture->chroma_format_idc-1;
+ int m5[4];
+ int m6[4];
+
+ int need_transform_size_flag;
+ Boolean lossless_qpprime = (Boolean) ((img->qp + img->bitdepth_luma_qp_scale)==0 && img->lossless_qpprime_flag==1);
+
+ int (*InvLevelScale4x4)[4] = NULL;
+ int (*InvLevelScale8x8)[8] = NULL;
+ // select scan type
+ const byte (*pos_scan8x8)[2] = ((img->structure == FRAME) && (!currMB->mb_field)) ? SNGL_SCAN8x8 : FIELD_SCAN8x8;
+ const byte (*pos_scan4x4)[2] = ((img->structure == FRAME) && (!currMB->mb_field)) ? SNGL_SCAN : FIELD_SCAN;
+
+ if(img->type==SP_SLICE && currMB->mb_type!=I16MB )
+ smb=1;
+
+ // QPI
+ //init constants for every chroma qp offset
+ if (dec_picture->chroma_format_idc != YUV400)
+ {
+ for (i=0; i<2; i++)
+ {
+ qp_per_uv[i] = (currMB->qpc[i] + img->bitdepth_chroma_qp_scale)/6;
+ qp_rem_uv[i] = (currMB->qpc[i] + img->bitdepth_chroma_qp_scale)%6;
+ }
+ }
+
+ // read CBP if not new intra mode
+ if (!IS_NEWINTRA (currMB))
+ {
+ //===== C B P =====
+ //---------------------
+ currSE.type = (IS_OLDINTRA (currMB) || currMB->mb_type == SI4MB || currMB->mb_type == I8MB)
+ ? SE_CBP_INTRA
+ : SE_CBP_INTER;
+
+ dP = &(currSlice->partArr[partMap[currSE.type]]);
+
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
+ {
+ currSE.mapping = (IS_OLDINTRA (currMB) || currMB->mb_type == SI4MB || currMB->mb_type == I8MB)
+ ? linfo_cbp_intra
+ : linfo_cbp_inter;
+ }
+ else
+ {
+ currSE.reading = readCBP_CABAC;
+ }
+
+ TRACE_STRING("coded_block_pattern");
+
+ dP->readSyntaxElement(&currSE,img,dP);
+ currMB->cbp = cbp = currSE.value1;
+
+
+ //============= 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)
+ && img->Transform8x8Mode);
+
+ if (need_transform_size_flag)
+ {
+ currSE.type = SE_HEADER;
+ dP = &(currSlice->partArr[partMap[SE_HEADER]]);
+ currSE.reading = readMB_transform_size_flag_CABAC;
+ TRACE_STRING("transform_size_8x8_flag");
+
+ // read UVLC transform_size_8x8_flag
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
+ {
+ currSE.len = 1;
+ readSyntaxElement_FLC(&currSE, dP->bitstream);
+ }
+ else
+ {
+ dP->readSyntaxElement(&currSE,img,dP);
+ }
+ currMB->luma_transform_size_8x8_flag = currSE.value1;
+ }
+
+ //===== DQUANT =====
+ //----------------------
+ // Delta quant only if nonzero coeffs
+ if (cbp !=0)
+ {
+ currSE.type = (IS_INTER (currMB)) ? SE_DELTA_QUANT_INTER : SE_DELTA_QUANT_INTRA;
+
+ dP = &(currSlice->partArr[partMap[currSE.type]]);
+
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
+ {
+ currSE.mapping = linfo_se;
+ }
+ else
+ currSE.reading= readDquant_CABAC; //gabi
+
+ TRACE_STRING("mb_qp_delta");
+
+ dP->readSyntaxElement(&currSE,img,dP);
+ currMB->delta_quant = currSE.value1;
+ if ((currMB->delta_quant < -(26 + img->bitdepth_luma_qp_scale/2)) || (currMB->delta_quant > (25 + img->bitdepth_luma_qp_scale/2)))
+ error ("mb_qp_delta is out of range", 500);
+
+ img->qp= ((img->qp + currMB->delta_quant + 52 + 2*img->bitdepth_luma_qp_scale)%(52+img->bitdepth_luma_qp_scale)) -
+ img->bitdepth_luma_qp_scale;
+ }
+ }
+ else
+ {
+ cbp = currMB->cbp;
+ }
+
+ for (i=0;i<BLOCK_SIZE;i++)
+ for (j=0;j<BLOCK_SIZE;j++)
+ memset(&img->cof[i][j][0][0], 0, BLOCK_SIZE * BLOCK_SIZE * sizeof(int)); // reset luma coeffs
+
+
+ if (IS_NEWINTRA (currMB)) // read DC coeffs for new intra modes
+ {
+ currSE.type = SE_DELTA_QUANT_INTRA;
+
+ dP = &(currSlice->partArr[partMap[currSE.type]]);
+
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
+ {
+ currSE.mapping = linfo_se;
+ }
+ else
+ {
+ currSE.reading= readDquant_CABAC;
+ }
+#if TRACE
+ snprintf(currSE.tracestring, TRACESTRING_SIZE, "Delta quant ");
+#endif
+ dP->readSyntaxElement(&currSE,img,dP);
+ currMB->delta_quant = currSE.value1;
+ if ((currMB->delta_quant < -(26 + img->bitdepth_luma_qp_scale/2)) || (currMB->delta_quant > (25 + img->bitdepth_luma_qp_scale/2)))
+ error ("mb_qp_delta is out of range", 500);
+
+ img->qp= ((img->qp + currMB->delta_quant + 52 + 2*img->bitdepth_luma_qp_scale)%(52+img->bitdepth_luma_qp_scale)) -
+ img->bitdepth_luma_qp_scale;
+
+ for (i=0;i<BLOCK_SIZE;i++)
+ for (j=0;j<BLOCK_SIZE;j++)
+ img->ipredmode[img->block_y+j][img->block_x+i]=DC_PRED;
+
+
+ if (active_pps->entropy_coding_mode_flag == UVLC)
+ {
+ readCoeff4x4_CAVLC(img, inp, LUMA_INTRA16x16DC, 0, 0,
+ levarr, runarr, &numcoeff);
+
+ coef_ctr=-1;
+ level = 1; // just to get inside the loop
+ for(k = 0; k < numcoeff; k++)
+ {
+ if (levarr[k] != 0) // leave if len=1
+ {
+ coef_ctr=coef_ctr+runarr[k]+1;
+
+ i0=pos_scan4x4[coef_ctr][0];
+ j0=pos_scan4x4[coef_ctr][1];
+
+ img->cof[i0][j0][0][0]=levarr[k];// add new intra DC coeff
+ }
+ }
+ }
+ else
+ {
+
+ currSE.type = SE_LUM_DC_INTRA;
+ dP = &(currSlice->partArr[partMap[currSE.type]]);
+
+ currSE.context = LUMA_16DC;
+ currSE.type = SE_LUM_DC_INTRA;
+ img->is_intra_block = 1;
+
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
+ {
+ currSE.mapping = linfo_levrun_inter;
+ }
+ else
+ {
+ currSE.reading = readRunLevel_CABAC;
+ }
+
+ coef_ctr = -1;
+ level = 1; // just to get inside the loop
+
+ for(k=0;(k<17) && (level!=0);k++)
+ {
+#if TRACE
+ snprintf(currSE.tracestring, TRACESTRING_SIZE, "DC luma 16x16 ");
+#endif
+ dP->readSyntaxElement(&currSE,img,dP);
+ level = currSE.value1;
+ run = currSE.value2;
+ len = currSE.len;
+
+ if (level != 0) // leave if len=1
+ {
+ coef_ctr=coef_ctr+run+1;
+
+ i0=pos_scan4x4[coef_ctr][0];
+ j0=pos_scan4x4[coef_ctr][1];
+
+ img->cof[i0][j0][0][0]=level;// add new intra DC coeff
+ }
+ }
+ }
+ if(!lossless_qpprime)
+ itrans_2(img);// transform new intra DC
+ }
+
+ currMB->qp = img->qp;
+
+ set_chroma_qp(currMB);
+
+ qp_per = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)/6;
+ qp_rem = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)%6;
+ qp_const = 1<<(3-qp_per);
+
+ InvLevelScale4x4 = intra? InvLevelScale4x4Luma_Intra[qp_rem] : InvLevelScale4x4Luma_Inter[qp_rem];
+ InvLevelScale8x8 = intra? InvLevelScale8x8Luma_Intra[qp_rem] : InvLevelScale8x8Luma_Inter[qp_rem];
+
+ //init constants for every chroma qp offset
+ if (dec_picture->chroma_format_idc != YUV400)
+ {
+ for(i=0; i < 2; i++)
+ {
+ qp_per_uv[i] = (currMB->qpc[i] + img->bitdepth_chroma_qp_scale)/6;
+ qp_rem_uv[i] = (currMB->qpc[i] + img->bitdepth_chroma_qp_scale)%6;
+ }
+ }
+
+
+ // luma coefficients
+ for (block_y=0; block_y < 4; block_y += 2) /* all modes */
+ {
+ for (block_x=0; block_x < 4; block_x += 2)
+ {
+
+ b8 = 2*(block_y>>1) + (block_x>>1);
+ if (active_pps->entropy_coding_mode_flag == UVLC)
+ {
+ for (j=block_y; j < block_y+2; j++)
+ {
+ for (i=block_x; i < block_x+2; i++)
+ {
+ ii = block_x >> 1;
+ jj = block_y >> 1;
+ b8 = 2 * jj + ii;
+
+ if (cbp & (1<<b8)) /* are there any coeff in current block at all */
+ {
+ readCoeff4x4_CAVLC(img, inp, (IS_NEWINTRA(currMB) ? LUMA_INTRA16x16AC : LUMA), i, j, levarr, runarr, &numcoeff);
+
+ start_scan = IS_NEWINTRA(currMB) ? 1 : 0;
+ coef_ctr = start_scan - 1;
+
+ if(!lossless_qpprime)
+ {
+ if (!currMB->luma_transform_size_8x8_flag) // 4x4 transform
+ {
+ for (k = 0; k < numcoeff; k++)
+ {
+ if (levarr[k] != 0)
+ {
+ coef_ctr += runarr[k]+1;
+
+ i0 = pos_scan4x4[coef_ctr][0];
+ j0 = pos_scan4x4[coef_ctr][1];
+
+ // inverse quant for 4x4 transform only
+ currMB->cbp_blk |= (int64) 1 << ((j<<2) + i);
+ img->cof[i][j][j0][i0]= rshift_rnd_sf((levarr[k]*InvLevelScale4x4[j0][i0])<<qp_per, 4);
+ }
+ }
+ }
+ else // 8x8 transform
+ {
+ int b4, iz, jz;
+ for (k = 0; k < numcoeff; k++)
+ {
+ if (levarr[k] != 0)
+ {
+ coef_ctr += runarr[k]+1;
+
+ // do same as CABAC for deblocking: any coeff in the 8x8 marks all the 4x4s
+ //as containing coefficients
+ currMB->cbp_blk |= 51 << ((block_y<<2) + block_x);
+
+ b4 = 2*(j - block_y)+(i - block_x);
+
+ iz = pos_scan8x8[(coef_ctr << 2) + b4][0];
+ jz = pos_scan8x8[(coef_ctr << 2) + b4][1];
+
+ img->m7[block_y*4 +jz][block_x*4 +iz] = rshift_rnd_sf((levarr[k]*InvLevelScale8x8[jz][iz])<<qp_per, 6); // dequantization
+ }
+ }//else (!currMB->luma_transform_size_8x8_flag)
+ }
+ }
+ else
+ {
+ if (!currMB->luma_transform_size_8x8_flag) // inverse quant for 4x4 transform
+ {
+ for (k = 0; k < numcoeff; k++)
+ {
+ if (levarr[k] != 0)
+ {
+ coef_ctr += runarr[k]+1;
+
+ i0=pos_scan4x4[coef_ctr][0];
+ j0=pos_scan4x4[coef_ctr][1];
+
+ currMB->cbp_blk |= (int64) 1 << ((j<<2) + i);
+ img->cof[i][j][j0][i0]= levarr[k];
+ }
+ }
+ }
+ else // inverse quant for 8x8 transform
+ {
+ int b4, iz, jz;
+ for (k = 0; k < numcoeff; k++)
+ {
+ if (levarr[k] != 0)
+ {
+ coef_ctr += runarr[k]+1;
+
+ // do same as CABAC for deblocking: any coeff in the 8x8 marks all the 4x4s
+ //as containing coefficients
+ currMB->cbp_blk |= 51 << ((block_y<<2) + block_x);
+
+ b4 = 2*(j-block_y)+(i-block_x);
+
+ iz=pos_scan8x8[coef_ctr*4+b4][0];
+ jz=pos_scan8x8[coef_ctr*4+b4][1];
+
+ img->m7[block_y*4 +jz][block_x*4 +iz] = levarr[k];
+ }
+ }
+ }//else (!currMB->luma_transform_size_8x8_flag)
+ }
+ }
+ else
+ {
+ img->nz_coeff[img->current_mb_nr][i][j] = 0;
+ }
+ }
+ }
+ } // VLC
+ else
+ {
+ if(currMB->luma_transform_size_8x8_flag)
+ readLumaCoeff8x8_CABAC(img, inp, b8); //======= 8x8 trannsform size & CABAC ========
+ else
+ {
+ //======= Other Modes & CABAC ========
+ //------------------------------------
+ for (j=block_y; j < block_y+2; j++)
+ {
+ for (i=block_x; i < block_x+2; i++)
+ {
+ start_scan = IS_NEWINTRA (currMB)? 1 : 0;
+
+ img->subblock_x = i; // position for coeff_count ctx
+ img->subblock_y = j; // position for coeff_count ctx
+
+ if (cbp & (1<<b8)) // are there any coeff in current block at all
+ {
+ coef_ctr = start_scan - 1;
+ level = 1;
+ img->is_intra_block = IS_INTRA(currMB);
+
+ if(!lossless_qpprime)
+ {
+ for(k=start_scan;(k<17) && (level!=0);k++)
+ {
+ /*
+ * make distinction between INTRA and INTER coded
+ * luminance coefficients
+ */
+ currSE.context = (IS_NEWINTRA(currMB) ? LUMA_16AC : LUMA_4x4);
+ currSE.type = (img->is_intra_block
+ ? (k==0 ? SE_LUM_DC_INTRA : SE_LUM_AC_INTRA)
+ : (k==0 ? SE_LUM_DC_INTER : SE_LUM_AC_INTER));
+
+#if TRACE
+ sprintf(currSE.tracestring, "Luma sng ");
+#endif
+ dP = &(currSlice->partArr[partMap[currSE.type]]);
+
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
+ currSE.mapping = linfo_levrun_inter;
+ else
+ currSE.reading = readRunLevel_CABAC;
+
+ dP->readSyntaxElement(&currSE,img,dP);
+ level = currSE.value1;
+ run = currSE.value2;
+ len = currSE.len;
+
+ if (level != 0) /* leave if len=1 */
+ {
+ coef_ctr += run+1;
+
+ i0=pos_scan4x4[coef_ctr][0];
+ j0=pos_scan4x4[coef_ctr][1];
+
+ currMB->cbp_blk |= (int64)1 << ((j<<2) + i) ;
+ img->cof[i][j][j0][i0]= rshift_rnd_sf((level*InvLevelScale4x4[j0][i0]) << qp_per, 4);
+ }
+ }
+ }
+ else
+ {
+ for(k=start_scan;(k<17) && (level!=0);k++)
+ {
+ /*
+ * make distinction between INTRA and INTER coded
+ * luminance coefficients
+ */
+ currSE.context = (IS_NEWINTRA(currMB) ? LUMA_16AC : LUMA_4x4);
+ currSE.type = (img->is_intra_block
+ ? (k==0 ? SE_LUM_DC_INTRA : SE_LUM_AC_INTRA)
+ : (k==0 ? SE_LUM_DC_INTER : SE_LUM_AC_INTER));
+
+#if TRACE
+ sprintf(currSE.tracestring, "Luma sng ");
+#endif
+ dP = &(currSlice->partArr[partMap[currSE.type]]);
+
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
+ currSE.mapping = linfo_levrun_inter;
+ else
+ currSE.reading = readRunLevel_CABAC;
+
+ dP->readSyntaxElement(&currSE,img,dP);
+ level = currSE.value1;
+ run = currSE.value2;
+ len = currSE.len;
+
+ if (level != 0) /* leave if len=1 */
+ {
+ coef_ctr += run+1;
+
+ i0=pos_scan4x4[coef_ctr][0];
+ j0=pos_scan4x4[coef_ctr][1];
+
+ currMB->cbp_blk |= (int64)1 << ((j<<2) + i) ;
+
+ img->cof[i][j][j0][i0]= level;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (dec_picture->chroma_format_idc != YUV400)
+ {
+
+ for (j=4;j<(4+img->num_blk8x8_uv);j++) // reset all chroma coeffs before read
+ for (i=0;i<4;i++)
+ memset(&img->cof[i][j][0][0], 0, 16 * sizeof(int));
+
+ m2 = img->mb_x * 2;
+ jg2 = img->mb_y * 2;
+
+ qp_const_uv[0] = 1<<(3-qp_per_uv[0]);
+ qp_const_uv[1] = 1<<(3-qp_per_uv[1]);
+
+
+ //========================== CHROMA DC ============================
+ //-----------------------------------------------------------------
+ // chroma DC coeff
+ if(cbp>15)
+ {
+ for (ll=0;ll<3;ll+=2)
+ {
+ uv = ll>>1;
+
+ if (dec_picture->chroma_format_idc == YUV420)
+ {
+ int (*InvLevelScale4x4Chroma)[4] = intra
+ ? InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv[uv]]
+ : InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv[uv]];
+
+ //===================== CHROMA DC YUV420 ======================
+ memset(&img->cofu[0], 0, 4 *sizeof(int));
+
+ if (active_pps->entropy_coding_mode_flag == UVLC)
+ {
+ readCoeff4x4_CAVLC(img, inp, CHROMA_DC, 0, 0,
+ levarr, runarr, &numcoeff);
+ coef_ctr=-1;
+ level=1;
+ for(k = 0; k < numcoeff; k++)
+ {
+ if (levarr[k] != 0)
+ {
+ currMB->cbp_blk |= 0xf0000 << (ll<<1) ;
+ coef_ctr=coef_ctr+runarr[k]+1;
+ img->cofu[coef_ctr]=levarr[k];
+ }
+ }
+ }
+ else
+ {
+ coef_ctr=-1;
+ level=1;
+ for(k=0;(k<(img->num_cdc_coeff+1))&&(level!=0);k++)
+ {
+ currSE.context = CHROMA_DC;
+ currSE.type = (IS_INTRA(currMB) ? SE_CHR_DC_INTRA : SE_CHR_DC_INTER);
+ img->is_intra_block = IS_INTRA(currMB);
+ img->is_v_block = ll;
+
+ #if TRACE
+ snprintf(currSE.tracestring, TRACESTRING_SIZE, "2x2 DC Chroma ");
+ #endif
+ dP = &(currSlice->partArr[partMap[currSE.type]]);
+
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
+ currSE.mapping = linfo_levrun_c2x2;
+ else
+ currSE.reading = readRunLevel_CABAC;
+
+ dP->readSyntaxElement(&currSE,img,dP);
+ level = currSE.value1;
+ run = currSE.value2;
+ len = currSE.len;
+ if (level != 0)
+ {
+ currMB->cbp_blk |= 0xf0000 << (ll<<1) ;
+ coef_ctr=coef_ctr+run+1;
+ // Bug: img->cofu has only 4 entries, hence coef_ctr MUST be <4 (which is
+ // caught by the assert(). If it is bigger than 4, it starts patching the
+ // img->predmode pointer, which leads to bugs later on.
+ //
+ // This assert() should be left in the code, because it captures a very likely
+ // bug early when testing in error prone environments (or when testing NAL
+ // functionality).
+ assert (coef_ctr < img->num_cdc_coeff);
+ img->cofu[coef_ctr]=level;
+ }
+ }
+ }
+
+ if (smb // check to see if MB type is SPred or SIntra4x4
+ || lossless_qpprime)
+ {
+ img->cof[0+ll][4][0][0]=img->cofu[0];
+ img->cof[1+ll][4][0][0]=img->cofu[1];
+ img->cof[0+ll][5][0][0]=img->cofu[2];
+ img->cof[1+ll][5][0][0]=img->cofu[3];
+ }
+ else
+ {
+ temp[0]=(img->cofu[0]+img->cofu[1]+img->cofu[2]+img->cofu[3]);
+ temp[1]=(img->cofu[0]-img->cofu[1]+img->cofu[2]-img->cofu[3]);
+ temp[2]=(img->cofu[0]+img->cofu[1]-img->cofu[2]-img->cofu[3]);
+ temp[3]=(img->cofu[0]-img->cofu[1]-img->cofu[2]+img->cofu[3]);
+
+ for (i=0;i<img->num_cdc_coeff;i++)
+ {
+ if(qp_per_uv[uv]<5)
+ {
+ temp[i]=(temp[i]*InvLevelScale4x4Chroma[0][0])>>(5-qp_per_uv[uv]);
+ }
+ else
+ {
+ temp[i]=(temp[i]*InvLevelScale4x4Chroma[0][0])<<(qp_per_uv[uv]-5);
+ }
+ }
+ img->cof[0+ll][4][0][0]=temp[0];
+ img->cof[1+ll][4][0][0]=temp[1];
+ img->cof[0+ll][5][0][0]=temp[2];
+ img->cof[1+ll][5][0][0]=temp[3];
+ }
+ }
+ else if (dec_picture->chroma_format_idc == YUV422)
+ {
+ int i,j,j1;
+ int uv_idx = ll;
+ int m3[2][4] = {{0,0,0,0},{0,0,0,0}};
+ int m4[2][4] = {{0,0,0,0},{0,0,0,0}};
+ int qp_per_uv_dc = (currMB->qpc[uv] + 3 + img->bitdepth_chroma_qp_scale)/6; //for YUV422 only
+ int qp_rem_uv_dc = (currMB->qpc[uv] + 3 + img->bitdepth_chroma_qp_scale)%6; //for YUV422 only
+
+ //===================== CHROMA DC YUV422 ======================
+ if (active_pps->entropy_coding_mode_flag == UVLC)
+ {
+ readCoeff4x4_CAVLC(img, inp, CHROMA_DC, 0, 0,
+ levarr, runarr, &numcoeff);
+ coef_ctr=-1;
+ level=1;
+ for(k = 0; k < numcoeff; k++)
+ {
+ if (levarr[k] != 0)
+ {
+ currMB->cbp_blk |= ((int64)0xff0000) << (ll<<2);
+ coef_ctr=coef_ctr+runarr[k]+1;
+ i0 = SCAN_YUV422[coef_ctr][0];
+ j0 = SCAN_YUV422[coef_ctr][1];
+
+ m3[i0][j0]=levarr[k];
+ }
+ }
+ }
+ else
+ {
+ coef_ctr=-1;
+ level=1;
+ for(k=0;(k<9)&&(level!=0);k++)
+ {
+ currSE.context = CHROMA_DC_2x4;
+ currSE.type = (IS_INTRA(currMB) ? SE_CHR_DC_INTRA : SE_CHR_DC_INTER);
+ img->is_intra_block = IS_INTRA(currMB);
+ img->is_v_block = ll;
+
+ #if TRACE
+ snprintf(currSE.tracestring, TRACESTRING_SIZE, "2x4 DC Chroma ");
+ #endif
+ dP = &(currSlice->partArr[partMap[currSE.type]]);
+
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
+ currSE.mapping = linfo_levrun_c2x2;
+ else
+ currSE.reading = readRunLevel_CABAC;
+
+ dP->readSyntaxElement(&currSE,img,dP);
+ level = currSE.value1;
+ run = currSE.value2;
+ len = currSE.len;
+ if (level != 0)
+ {
+ currMB->cbp_blk |= ((int64)0xff0000) << (ll<<2) ;
+ coef_ctr=coef_ctr+run+1;
+ assert (coef_ctr < img->num_cdc_coeff);
+ i0=SCAN_YUV422[coef_ctr][0];
+ j0=SCAN_YUV422[coef_ctr][1];
+
+ m3[i0][j0]=level;
+ }
+ }
+ }
+ // inverse CHROMA DC YUV422 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];
+ }
+ else
+ {
+ for(i=0;i<2;i++)
+ for(j=0;j<4;j++)
+ img->cof[i+uv_idx][j+4][0][0]=m3[i][j];
+ }
+
+ // vertical
+ for (i=0;i<2 && !lossless_qpprime;i++)
+ {
+ int (*imgcof)[4][4] = img->cof[i+uv_idx];
+ for (j=0; j < 4;j++) //TODO: remove m5 with m4
+ m5[j]=m4[i][j];
+
+ m6[0]=m5[0]+m5[2];
+ m6[1]=m5[0]-m5[2];
+ m6[2]=m5[1]-m5[3];
+ m6[3]=m5[1]+m5[3];
+
+ for (j=0;j<2;j++)
+ {
+ j1=3-j;
+ if(qp_per_uv_dc<4)
+ {
+ if(intra == 1)
+ {
+ imgcof[j +4][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv_dc][0][0]+(1<<(3-qp_per_uv_dc)))>>(4-qp_per_uv_dc))+2)>>2;
+ imgcof[j1+4][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv_dc][0][0]+(1<<(3-qp_per_uv_dc)))>>(4-qp_per_uv_dc))+2)>>2;
+ }
+ else
+ {
+ imgcof[j +4][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv_dc][0][0]+(1<<(3-qp_per_uv_dc)))>>(4-qp_per_uv_dc))+2)>>2;
+ imgcof[j1+4][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv_dc][0][0]+(1<<(3-qp_per_uv_dc)))>>(4-qp_per_uv_dc))+2)>>2;
+ }
+ }
+ else
+ {
+ if(intra == 1)
+ {
+ imgcof[j +4][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv_dc][0][0])<<(qp_per_uv_dc-4))+2)>>2;
+ imgcof[j1+4][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv_dc][0][0])<<(qp_per_uv_dc-4))+2)>>2;
+ }
+ else
+ {
+ imgcof[j +4][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv_dc][0][0])<<(qp_per_uv_dc-4))+2)>>2;
+ imgcof[j1+4][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv_dc][0][0])<<(qp_per_uv_dc-4))+2)>>2;
+ }
+ }
+ }//for (j=0;j<2;j++)
+ }//for (i=0;i<2;i++)
+ }//else if (dec_picture->chroma_format_idc == YUV422)
+ else
+ {
+ //===================== CHROMA DC YUV444 ======================
+ int i,j,i1,j1;
+ int uv_idx = 4 + (ll<<1);
+
+ if (active_pps->entropy_coding_mode_flag == UVLC)
+ {
+ readCoeff4x4_CAVLC(img, inp, CHROMA_DC, 0, 0,
+ levarr, runarr, &numcoeff);
+ coef_ctr=-1;
+ level=1;
+ for(k = 0; k < numcoeff; k++)
+ {
+ if (levarr[k] != 0)
+ {
+ currMB->cbp_blk |= ((int64)0xffff0000) << (ll<<3) ;
+ coef_ctr=coef_ctr+runarr[k]+1;
+ i0=SNGL_SCAN[coef_ctr][0];
+ j0=SNGL_SCAN[coef_ctr][1];
+
+ img->cof[i0][j0+uv_idx][0][0]=levarr[k];
+ }
+ }
+ }
+ else
+ {
+ coef_ctr=-1;
+ level=1;
+ for(k=0;(k<17)&&(level!=0);k++)
+ {
+ currSE.context = CHROMA_DC_4x4;
+ currSE.type = (IS_INTRA(currMB) ? SE_CHR_DC_INTRA : SE_CHR_DC_INTER);
+ img->is_intra_block = IS_INTRA(currMB);
+ img->is_v_block = ll;
+
+ #if TRACE
+ snprintf(currSE.tracestring, TRACESTRING_SIZE, "DC Chroma ");
+ #endif
+ dP = &(currSlice->partArr[partMap[currSE.type]]);
+
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
+ currSE.mapping = linfo_levrun_c2x2;
+ else
+ currSE.reading = readRunLevel_CABAC;
+
+ dP->readSyntaxElement(&currSE,img,dP);
+ level = currSE.value1;
+ run = currSE.value2;
+ len = currSE.len;
+ if (level != 0)
+ {
+ currMB->cbp_blk |= ((int64)0xffff0000) << (ll<<3) ;
+ coef_ctr=coef_ctr+run+1;
+ assert (coef_ctr < img->num_cdc_coeff);
+ i0=SNGL_SCAN[coef_ctr][0];
+ j0=SNGL_SCAN[coef_ctr][1];
+
+ img->cof[i0][j0+uv_idx][0][0]=level;
+ }
+ }
+ }
+
+ // inverse CHROMA DC YUV444 transform
+ // horizontal
+ for (j=uv_idx; (j < 4+uv_idx) && !lossless_qpprime;j++)
+ {
+ for (i=0;i<4;i++)
+ m5[i]=img->cof[i][j][0][0];
+
+ m6[0]=m5[0]+m5[2];
+ m6[1]=m5[0]-m5[2];
+ m6[2]=m5[1]-m5[3];
+ m6[3]=m5[1]+m5[3];
+
+ for (i=0;i<2;i++)
+ {
+ i1=3-i;
+ img->cof[i][j][0][0]= m6[i]+m6[i1];
+ img->cof[i1][j][0][0]=m6[i]-m6[i1];
+ }
+ }
+
+ // vertical
+ for (i=0;i<4 && !lossless_qpprime;i++)
+ {
+ for (j=0; j < 4;j++)
+ m5[j]=img->cof[i][j+uv_idx][0][0];
+
+ m6[0]=m5[0]+m5[2];
+ m6[1]=m5[0]-m5[2];
+ m6[2]=m5[1]-m5[3];
+ m6[3]=m5[1]+m5[3];
+
+ for (j=0;j<2;j++)
+ {
+ j1=3-j;
+ if(qp_per_uv[uv]<4)
+ {
+ if(intra == 1)
+ {
+ img->cof[i][j +uv_idx][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv[uv]][0][0]+(1<<(3-qp_per_uv[uv])))>>(4-qp_per_uv[uv]))+2)>>2;
+ img->cof[i][j1+uv_idx][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv[uv]][0][0]+(1<<(3-qp_per_uv[uv])))>>(4-qp_per_uv[uv]))+2)>>2;
+ }
+ else
+ {
+ img->cof[i][j +uv_idx][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv[uv]][0][0]+(1<<(3-qp_per_uv[uv])))>>(4-qp_per_uv[uv]))+2)>>2;
+ img->cof[i][j1+uv_idx][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv[uv]][0][0]+(1<<(3-qp_per_uv[uv])))>>(4-qp_per_uv[uv]))+2)>>2;
+ }
+ }
+ else
+ {
+ if(intra == 1)
+ {
+ img->cof[i][j +uv_idx][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv[uv]][0][0])<<(qp_per_uv[uv]-4))+2)>>2;
+ img->cof[i][j1+uv_idx][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv[uv]][0][0])<<(qp_per_uv[uv]-4))+2)>>2;
+ }
+ else
+ {
+ img->cof[i][j +uv_idx][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv[uv]][0][0])<<(qp_per_uv[uv]-4))+2)>>2;
+ img->cof[i][j1+uv_idx][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv[uv]][0][0])<<(qp_per_uv[uv]-4))+2)>>2;
+ }
+ }
+ }
+ }//for (i=0;i<4;i++)
+ }//else (dec_picture->chroma_format_idc == YUV444)
+ }//for (ll=0;ll<3;ll+=2)
+ }
+
+ // chroma AC coeff, all zero fram start_scan
+ if (cbp<=31)
+ for (i=0; i < 4; i++)
+ memset(&img->nz_coeff [img->current_mb_nr ][i][4], 0, img->num_blk8x8_uv * sizeof(int));
+
+
+ //========================== CHROMA AC ============================
+ //-----------------------------------------------------------------
+ // chroma AC coeff, all zero fram start_scan
+ if (cbp>31)
+ {
+ for (b8=0; b8 < img->num_blk8x8_uv; b8++)
+ {
+ int uvc = (b8 > ((img->num_blk8x8_uv>>1) - 1 ));
+ int (*InvLevelScale4x4Chroma)[4] = intra
+ ? InvLevelScale4x4Chroma_Intra[uvc][qp_rem_uv[uvc]]
+ : InvLevelScale4x4Chroma_Inter[uvc][qp_rem_uv[uvc]];
+
+ img->is_v_block = uv = uvc;
+
+ for (b4=0; b4 < 4; b4++)
+ {
+ i = cofuv_blk_x[yuv][b8][b4];
+ j = cofuv_blk_y[yuv][b8][b4];
+
+
+ if (active_pps->entropy_coding_mode_flag == UVLC)
+ {
+ readCoeff4x4_CAVLC(img, inp, CHROMA_AC, i, j,
+ levarr, runarr, &numcoeff);
+ coef_ctr=0;
+ level=1;
+ if(!lossless_qpprime)
+ {
+ for(k = 0; k < numcoeff;k++)
+ {
+ if (levarr[k] != 0)
+ {
+ currMB->cbp_blk |= ((int64)1) << cbp_blk_chroma[b8][b4];
+ coef_ctr=coef_ctr+runarr[k]+1;
+
+ i0=pos_scan4x4[coef_ctr][0];
+ j0=pos_scan4x4[coef_ctr][1];
+
+ img->cof[i][j][j0][i0] = rshift_rnd_sf((levarr[k]*InvLevelScale4x4Chroma[j0][i0])<<qp_per_uv[uv], 4);
+ }
+ }
+ }
+ else
+ {
+ for(k = 0; k < numcoeff;k++)
+ {
+ if (levarr[k] != 0)
+ {
+ currMB->cbp_blk |= ((int64)1) << cbp_blk_chroma[b8][b4];
+ coef_ctr=coef_ctr+runarr[k]+1;
+
+ i0=pos_scan4x4[coef_ctr][0];
+ j0=pos_scan4x4[coef_ctr][1];
+
+ img->cof[i][j][j0][i0]=levarr[k];
+ }
+ }
+ }
+ }
+ else
+ {
+ coef_ctr=0;
+ level=1;
+
+ img->subblock_y = subblk_offset_y[yuv][b8][b4]>>2;
+ img->subblock_x = subblk_offset_x[yuv][b8][b4]>>2;
+
+ currSE.context = CHROMA_AC;
+ currSE.type = (IS_INTRA(currMB) ? SE_CHR_AC_INTRA : SE_CHR_AC_INTER);
+ img->is_intra_block = IS_INTRA(currMB);
+
+ if(!lossless_qpprime)
+ {
+ for(k=0;(k<16)&&(level!=0);k++)
+ {
+#if TRACE
+ snprintf(currSE.tracestring, TRACESTRING_SIZE, "AC Chroma ");
+#endif
+ dP = &(currSlice->partArr[partMap[currSE.type]]);
+
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
+ currSE.mapping = linfo_levrun_inter;
+ else
+ currSE.reading = readRunLevel_CABAC;
+
+ dP->readSyntaxElement(&currSE,img,dP);
+ level = currSE.value1;
+ run = currSE.value2;
+ len = currSE.len;
+
+ if (level != 0)
+ {
+ currMB->cbp_blk |= ((int64)1) << cbp_blk_chroma[b8][b4];
+ coef_ctr += (run + 1);
+
+ i0=pos_scan4x4[coef_ctr][0];
+ j0=pos_scan4x4[coef_ctr][1];
+
+ img->cof[i][j][j0][i0] = rshift_rnd_sf((level*InvLevelScale4x4Chroma[j0][i0])<<qp_per_uv[uv], 4);
+ }
+ } //for(k=0;(k<16)&&(level!=0);k++)
+ }
+ else
+ {
+ for(k=0;(k<16)&&(level!=0);k++)
+ {
+#if TRACE
+ snprintf(currSE.tracestring, TRACESTRING_SIZE, "AC Chroma ");
+#endif
+ dP = &(currSlice->partArr[partMap[currSE.type]]);
+
+ if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
+ currSE.mapping = linfo_levrun_inter;
+ else
+ currSE.reading = readRunLevel_CABAC;
+
+ dP->readSyntaxElement(&currSE,img,dP);
+ level = currSE.value1;
+ run = currSE.value2;
+ len = currSE.len;
+
+ if (level != 0)
+ {
+ currMB->cbp_blk |= ((int64)1) << cbp_blk_chroma[b8][b4];
+ coef_ctr += (run + 1);
+
+ i0=pos_scan4x4[coef_ctr][0];
+ j0=pos_scan4x4[coef_ctr][1];
+
+ img->cof[i][j][j0][i0]=level;
+ }
+ } //for(k=0;(k<16)&&(level!=0);k++)
+ }
+ } //else / if (active_pps->entropy_coding_mode_flag == UVLC)
+ } //for (b4=0; b4 < 4; b4++)
+ } //for (b8=0; b8 < img->num_blk8x8_uv; b8++)
+ } //if (cbp>31)
+ } //if (dec_picture->chroma_format_idc != YUV400)
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Copy IPCM coefficients to decoded picture buffer and set parameters for this MB
+ * (for IPCM CABAC and IPCM CAVLC 28/11/2003)
+ *
+ * \author
+ * Dong Wang <Dong.Wang at bristol.ac.uk>
+ ************************************************************************
+ */
+
+void decode_ipcm_mb(struct img_par *img)
+{
+ int i,j;
+
+ Macroblock *currMb = &img->mb_data[img->current_mb_nr];
+
+ //Copy coefficients to decoded picture buffer
+ //IPCM coefficients are stored in img->cof which is set in function readIPCMcoeffsFromNAL()
+
+ for(i=0;i<16;i++)
+ for(j=0;j<16;j++)
+ dec_picture->imgY[img->pix_y+i][img->pix_x+j]=img->cof[(i>>2)][(j>>2)][i & 0x03][j & 0x03];
+
+ if (dec_picture->chroma_format_idc != YUV400)
+ {
+ for(i=0;i<img->mb_cr_size_y;i++)
+ for(j=0;j<img->mb_cr_size_x;j++)
+ dec_picture->imgUV[0][img->pix_c_y+i][img->pix_c_x+j]=img->cof[(i>>2) ][(j>>2)+4][i & 0x03][j & 0x03];
+
+ for(i=0;i<img->mb_cr_size_y;i++)
+ for(j=0;j<img->mb_cr_size_x;j++)
+ dec_picture->imgUV[1][img->pix_c_y+i][img->pix_c_x+j]=img->cof[(i>>2)+2][(j>>2)+4][i & 0x03][j & 0x03];
+ }
+
+ // for deblocking filter
+ currMb->qp=0;
+ set_chroma_qp(currMb);
+
+ // for CAVLC: Set the nz_coeff to 16.
+ // These parameters are to be used in CAVLC decoding of neighbour blocks
+ for(i=0;i<4;i++)
+ for (j=0;j<(4 + img->num_blk8x8_uv);j++)
+ img->nz_coeff[img->current_mb_nr][i][j]=16;
+
+
+ // for CABAC decoding of MB skip flag
+ currMb->skip_flag = 0;
+
+ //for deblocking filter CABAC
+ currMb->cbp_blk=0xFFFF;
+
+ //For CABAC decoding of Dquant
+ last_dquant=0;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * decode one macroblock
+ ************************************************************************
+ */
+
+int decode_one_macroblock(struct img_par *img,struct inp_par *inp)
+{
+ int tmp_block[BLOCK_SIZE][BLOCK_SIZE];
+ int tmp_blockbw[BLOCK_SIZE][BLOCK_SIZE];
+ int i=0,j=0,k,l,ii=0,jj=0,i1=0,j1=0,j4=0,i4=0;
+ int uv, hv;
+ int vec1_x=0,vec1_y=0,vec2_x=0,vec2_y=0;
+ int ioff,joff;
+ int block8x8; // needed for ABT
+
+ int bw_pred=0, fw_pred=0, pred, ifx;
+ int ii0,jj0,ii1,jj1,if1,jf1,if0,jf0;
+ int mv_mul, f1_x, f1_y, f2_x, f2_y, f3, f4;
+
+ static const byte decode_block_scan[16] = {0,1,4,5,2,3,6,7,8,9,12,13,10,11,14,15};
+
+ Macroblock *currMB = &img->mb_data[img->current_mb_nr];
+ short ref_idx, l0_refframe=-1, l1_refframe=-1;
+ int mv_mode, pred_dir, intra_prediction; // = currMB->ref_frame;
+ short l0_ref_idx=-1, l1_ref_idx=-1;
+ int alpha_l0, alpha_l1, wp_offset;
+
+ short *** mv_array, ***l0_mv_array, ***l1_mv_array;
+
+ int mv_scale;
+
+ int mb_nr = img->current_mb_nr;
+ int smb = ((img->type==SP_SLICE) && IS_INTER (currMB)) || (img->type == SI_SLICE && currMB->mb_type == SI4MB);
+ int list_offset;
+ int max_y_cr;
+
+ StorablePicture **list;
+
+ int jf;
+
+ char l0_rFrame = -1, l1_rFrame = -1;
+
+ short pmvl0[2]={0,0},
+ pmvl1[2]={0,0};
+
+ int direct_pdir=-1;
+
+ int curr_mb_field = ((img->MbaffFrameFlag)&&(currMB->mb_field));
+
+ byte ** moving_block;
+ short **** co_located_mv;
+ char *** co_located_ref_idx;
+ int64 *** co_located_ref_id;
+
+ int need_4x4_transform = (!currMB->luma_transform_size_8x8_flag);
+
+ int b8, b4;
+ int uv_shift;
+ int yuv = dec_picture->chroma_format_idc - 1;
+
+ if(img->type==SP_SLICE && currMB->mb_type!=I16MB)
+ smb=1;// modif ES added
+
+ if(currMB->mb_type==IPCM)
+ {
+ //copy readed data into imgY and set parameters
+ decode_ipcm_mb(img);
+ return 0;
+ }
+
+//////////////////////////
+
+ // find out the correct list offsets
+ if (curr_mb_field)
+ {
+ if(mb_nr&0x01)
+ {
+ list_offset = 4; // top field mb
+ moving_block = Co_located->bottom_moving_block;
+ co_located_mv = Co_located->bottom_mv;
+ co_located_ref_idx = Co_located->bottom_ref_idx;
+ co_located_ref_id = Co_located->bottom_ref_pic_id;
+ }
+ else
+ {
+ list_offset = 2; // bottom field mb
+ moving_block = Co_located->top_moving_block;
+ co_located_mv = Co_located->top_mv;
+ co_located_ref_idx = Co_located->top_ref_idx;
+ co_located_ref_id = Co_located->top_ref_pic_id;
+ }
+ max_y_cr = (dec_picture->size_y_cr>>1)-1;
+ }
+ else
+ {
+ list_offset = 0; // no mb aff or frame mb
+ moving_block = Co_located->moving_block;
+ co_located_mv = Co_located->mv;
+ co_located_ref_idx = Co_located->ref_idx;
+ co_located_ref_id = Co_located->ref_pic_id;
+ max_y_cr = dec_picture->size_y_cr-1;
+ }
+
+ if (!img->MbaffFrameFlag)
+ {
+ for (l = LIST_0 + list_offset; l <= (LIST_1 + list_offset); l++)
+ {
+ for(k = 0; k < listXsize[l]; k++)
+ {
+ listX[l][k]->chroma_vector_adjustment= 0;
+ if(img->structure == TOP_FIELD && img->structure != listX[l][k]->structure)
+ listX[l][k]->chroma_vector_adjustment = -2;
+ if(img->structure == BOTTOM_FIELD && img->structure != listX[l][k]->structure)
+ listX[l][k]->chroma_vector_adjustment = 2;
+ }
+ }
+ }
+ else
+ {
+ if (curr_mb_field)
+ {
+ for (l = LIST_0 + list_offset; l <= (LIST_1 + list_offset); l++)
+ {
+ for(k = 0; k < listXsize[l]; k++)
+ {
+ listX[l][k]->chroma_vector_adjustment= 0;
+ if(img->current_mb_nr % 2 == 0 && listX[l][k]->structure == BOTTOM_FIELD)
+ listX[l][k]->chroma_vector_adjustment = -2;
+ if(img->current_mb_nr % 2 == 1 && listX[l][k]->structure == TOP_FIELD)
+ listX[l][k]->chroma_vector_adjustment = 2;
+ }
+ }
+ }
+ else
+ {
+ for (l = LIST_0 + list_offset; l <= (LIST_1 + list_offset); l++)
+ {
+ for(k = 0; k < listXsize[l]; k++)
+ {
+ listX[l][k]->chroma_vector_adjustment= 0;
+ }
+ }
+ }
+ }
+
+ mv_mul=4;
+
+ // luma decoding **************************************************
+
+ // get prediction for INTRA_MB_16x16
+ if (IS_NEWINTRA (currMB))
+ {
+ intrapred_luma_16x16(img, currMB->i16mode);
+ }
+
+ if (img->type==B_SLICE && img->direct_spatial_mv_pred_flag && (IS_DIRECT (currMB) ||
+ (IS_P8x8(currMB) && !(currMB->b8mode[0] && currMB->b8mode[1] && currMB->b8mode[2] && currMB->b8mode[3]))))
+ {
+ char l0_rFrameL, l0_rFrameU, l0_rFrameUL, l0_rFrameUR;
+ char l1_rFrameL, l1_rFrameU, l1_rFrameUL, l1_rFrameUR;
+
+ PixelPos mb_left, mb_up, mb_upleft, mb_upright;
+
+ getLuma4x4Neighbour(img->current_mb_nr, -1, 0, &mb_left);
+ getLuma4x4Neighbour(img->current_mb_nr, 0, -1, &mb_up);
+ getLuma4x4Neighbour(img->current_mb_nr, 16, -1, &mb_upright);
+ getLuma4x4Neighbour(img->current_mb_nr, -1, -1, &mb_upleft);
+
+ if (!img->MbaffFrameFlag)
+ {
+ l0_rFrameL = mb_left.available ? dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] : -1;
+ l0_rFrameU = mb_up.available ? dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] : -1;
+ l0_rFrameUL = mb_upleft.available ? dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
+ l0_rFrameUR = mb_upright.available ? dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] : l0_rFrameUL;
+
+ l1_rFrameL = mb_left.available ? dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] : -1;
+ l1_rFrameU = mb_up.available ? dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] : -1;
+ l1_rFrameUL = mb_upleft.available ? dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
+ l1_rFrameUR = mb_upright.available ? dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] : l1_rFrameUL;
+ }
+ else
+ {
+ if (img->mb_data[img->current_mb_nr].mb_field)
+ {
+ l0_rFrameL = mb_left.available ?
+ img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] < 0?
+ dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] :
+ dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] * 2: -1;
+
+ l0_rFrameU = mb_up.available ?
+ img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] < 0?
+ dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] :
+ dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] * 2: -1;
+
+ l0_rFrameUL = mb_upleft.available ?
+ img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] < 0?
+ dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] :
+ dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] *2: -1;
+
+ l0_rFrameUR = mb_upright.available ?
+ img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] < 0?
+ dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] :
+ dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] * 2: l0_rFrameUL;
+
+ l1_rFrameL = mb_left.available ?
+ img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] < 0?
+ dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] :
+ dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] * 2: -1;
+
+ l1_rFrameU = mb_up.available ?
+ img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] < 0?
+ dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] :
+ dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] * 2: -1;
+
+ l1_rFrameUL = mb_upleft.available ?
+ img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] < 0?
+ dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] :
+ dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] *2: -1;
+
+ l1_rFrameUR = mb_upright.available ?
+ img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] < 0?
+ dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] :
+ dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] * 2: l1_rFrameUL;
+ }
+ else
+ {
+ l0_rFrameL = mb_left.available ?
+ img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] < 0 ?
+ dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] >> 1 :
+ dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x]: -1;
+
+ l0_rFrameU = mb_up.available ?
+ img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] < 0 ?
+ dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] >> 1 :
+ dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] : -1;
+
+ l0_rFrameUL = mb_upleft.available ?
+ img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] < 0 ?
+ dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x]>> 1 :
+ dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
+
+ l0_rFrameUR = mb_upright.available ?
+ img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] < 0 ?
+ dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] >> 1 :
+ dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] : l0_rFrameUL;
+
+ l1_rFrameL = mb_left.available ?
+ img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] < 0 ?
+ dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] >> 1 :
+ dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] : -1;
+
+ l1_rFrameU = mb_up.available ?
+ img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] < 0 ?
+ dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] >> 1 :
+ dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] : -1;
+
+ l1_rFrameUL = mb_upleft.available ?
+ img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] < 0 ?
+ dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] >> 1 :
+ dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
+
+ l1_rFrameUR = mb_upright.available ?
+ img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] < 0 ?
+ dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] >> 1:
+ dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] : l1_rFrameUL;
+ }
+ }
+
+ l0_rFrame = (l0_rFrameL >= 0 && l0_rFrameU >= 0) ? imin(l0_rFrameL,l0_rFrameU): imax(l0_rFrameL,l0_rFrameU);
+ l0_rFrame = (l0_rFrame >= 0 && l0_rFrameUR >= 0) ? imin(l0_rFrame,l0_rFrameUR): imax(l0_rFrame,l0_rFrameUR);
+
+ l1_rFrame = (l1_rFrameL >= 0 && l1_rFrameU >= 0) ? imin(l1_rFrameL,l1_rFrameU): imax(l1_rFrameL,l1_rFrameU);
+ l1_rFrame = (l1_rFrame >= 0 && l1_rFrameUR >= 0) ? imin(l1_rFrame,l1_rFrameUR): imax(l1_rFrame,l1_rFrameUR);
+
+ if (l0_rFrame >=0)
+ SetMotionVectorPredictor (img, pmvl0, l0_rFrame, LIST_0, dec_picture->ref_idx, dec_picture->mv, 0, 0, 16, 16);
+
+ if (l1_rFrame >=0)
+ SetMotionVectorPredictor (img, pmvl1, l1_rFrame, LIST_1, dec_picture->ref_idx, dec_picture->mv, 0, 0, 16, 16);
+ }
+
+ for (block8x8=0; block8x8<4; block8x8++)
+ {
+ if (currMB->b8mode[block8x8] == I8MB)
+ {
+ //=========== 8x8 BLOCK TYPE ============
+ ioff = 8*(block8x8&0x01);
+ joff = 8*(block8x8>>1);
+
+ //PREDICTION
+ intrapred8x8(img, block8x8);
+ itrans8x8(img,ioff,joff); // use DCT transform and make 8x8 block m7 from prediction block mpr
+
+ for(jj=joff;jj<joff + 8;jj++)
+ {
+ for(ii=ioff;ii<ioff + 8;ii++)
+ {
+ dec_picture->imgY[img->pix_y + jj][img->pix_x + ii] = img->m7[jj][ii]; // construct picture from 4x4 blocks
+ }
+ }
+ continue;
+ }
+
+ for (k = block8x8*4; k < block8x8*4+4; k ++)
+ {
+ i = (decode_block_scan[k] & 3);
+ j = ((decode_block_scan[k] >> 2) & 3);
+
+ ioff = (i << 2);
+ i4 = img->block_x + i;
+
+ joff = (j << 2);
+ j4 = img->block_y + j;
+
+ mv_mode = currMB->b8mode[2*(j>>1)+(i>>1)];
+ pred_dir = currMB->b8pdir[2*(j>>1)+(i>>1)];
+
+ assert (pred_dir<=2);
+
+ // PREDICTION
+ if (mv_mode==IBLOCK)
+ {
+ //===== INTRA PREDICTION =====
+ if (intrapred(img,ioff,joff,i4,j4)==SEARCH_SYNC) /* make 4x4 prediction block mpr from given prediction img->mb_mode */
+ return SEARCH_SYNC; /* bit error */
+ }
+ else if (!IS_NEWINTRA (currMB))
+ {
+ if (pred_dir != 2)
+ {
+ //===== FORWARD/BACKWARD PREDICTION =====
+ l0_refframe = ref_idx = dec_picture->ref_idx[LIST_0 + pred_dir][j4][i4];
+ mv_array = dec_picture->mv[LIST_0 + pred_dir];
+ list = listX[0+list_offset+ pred_dir];
+ vec1_x = i4*4*mv_mul + mv_array[j4][i4][0];
+
+ if (!curr_mb_field)
+ {
+ vec1_y = j4 * 4 * mv_mul + mv_array[j4][i4][1];
+ }
+ else
+ {
+ if ((mb_nr&0x01) == 0)
+ vec1_y = (img->block_y * 2 + joff) * mv_mul + mv_array[j4][i4][1];
+ else
+ vec1_y = ((img->block_y-4) * 2 + joff)* mv_mul + mv_array[j4][i4][1];
+ }
+
+ get_block (ref_idx, list, vec1_x, vec1_y, img, tmp_block);
+
+ if (img->apply_weights)
+ {
+ if (((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))||
+ (active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE))) && curr_mb_field)
+ {
+ ref_idx >>=1;
+ }
+
+ alpha_l0 = img->wp_weight[pred_dir][ref_idx][0];
+ wp_offset = img->wp_offset[pred_dir][l0_refframe>>curr_mb_field][0];
+ for(jj=0;jj<BLOCK_SIZE;jj++)
+ {
+ int jpos = jj+joff;
+ for(ii=0;ii<BLOCK_SIZE;ii++)
+ img->mpr[jpos][ii+ioff] = iClip1(img->max_imgpel_value,
+ (rshift_rnd_sf((alpha_l0 * tmp_block[jj][ii]), img->luma_log2_weight_denom) + wp_offset ));
+ }
+ }
+ else
+ {
+ for(jj=0;jj<BLOCK_SIZE;jj++)
+ {
+ int jpos = jj+joff;
+ for(ii=0;ii<BLOCK_SIZE;ii++)
+ img->mpr[jpos][ii+ioff] = tmp_block[jj][ii];
+ }
+ }
+ }
+ else
+ {
+ if (mv_mode != 0)
+ {
+ //===== BI-DIRECTIONAL PREDICTION =====
+ l0_mv_array = dec_picture->mv[LIST_0];
+ l1_mv_array = dec_picture->mv[LIST_1];
+
+ l0_refframe = dec_picture->ref_idx[LIST_0][j4][i4];
+ l1_refframe = dec_picture->ref_idx[LIST_1][j4][i4];
+ l0_ref_idx = l0_refframe;
+ l1_ref_idx = l1_refframe;
+ }
+ else
+ {
+ //===== DIRECT PREDICTION =====
+ l0_mv_array = dec_picture->mv[LIST_0];
+ l1_mv_array = dec_picture->mv[LIST_1];
+ l1_refframe = 0;
+
+ if (img->direct_spatial_mv_pred_flag )
+ {
+ int imgblock_y= ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? (img->block_y-4)>>1:img->block_y>>1: img->block_y;
+ int j6 = imgblock_y + j;
+
+ if (l0_rFrame >=0)
+ {
+ if (!l0_rFrame && ((!moving_block[j6][i4]) && (!listX[1+list_offset][0]->is_long_term)))
+ {
+ dec_picture->mv [LIST_0][j4][i4][0] = 0;
+ dec_picture->mv [LIST_0][j4][i4][1] = 0;
+ dec_picture->ref_idx[LIST_0][j4][i4] = 0;
+ }
+ else
+ {
+ dec_picture->mv [LIST_0][j4][i4][0] = pmvl0[0];
+ dec_picture->mv [LIST_0][j4][i4][1] = pmvl0[1];
+ dec_picture->ref_idx[LIST_0][j4][i4] = l0_rFrame;
+ }
+ }
+ else
+ {
+ dec_picture->ref_idx[LIST_0][j4][i4] = -1;
+ dec_picture->mv [LIST_0][j4][i4][0] = 0;
+ dec_picture->mv [LIST_0][j4][i4][1] = 0;
+ }
+
+ if (l1_rFrame >=0)
+ {
+ if (l1_rFrame==0 && ((!moving_block[j6][i4]) && (!listX[1+list_offset][0]->is_long_term)))
+ {
+
+ dec_picture->mv [LIST_1][j4][i4][0] = 0;
+ dec_picture->mv [LIST_1][j4][i4][1] = 0;
+ dec_picture->ref_idx[LIST_1][j4][i4] = l1_rFrame;
+
+ }
+ else
+ {
+ dec_picture->mv [LIST_1][j4][i4][0] = pmvl1[0];
+ dec_picture->mv [LIST_1][j4][i4][1] = pmvl1[1];
+ dec_picture->ref_idx[LIST_1][j4][i4] = l1_rFrame;
+ }
+ }
+ else
+ {
+ dec_picture->mv [LIST_1][j4][i4][0] = 0;
+ dec_picture->mv [LIST_1][j4][i4][1] = 0;
+ dec_picture->ref_idx[LIST_1][j4][i4] = -1;
+ }
+
+ if (l0_rFrame < 0 && l1_rFrame < 0)
+ {
+ dec_picture->ref_idx[LIST_0][j4][i4] = 0;
+ dec_picture->ref_idx[LIST_1][j4][i4] = 0;
+ }
+
+ l0_refframe = (dec_picture->ref_idx[LIST_0][j4][i4]!=-1) ? dec_picture->ref_idx[LIST_0][j4][i4] : 0;
+ l1_refframe = (dec_picture->ref_idx[LIST_1][j4][i4]!=-1) ? dec_picture->ref_idx[LIST_1][j4][i4] : 0;
+
+ l0_ref_idx = l0_refframe;
+ l1_ref_idx = l1_refframe;
+
+ if (dec_picture->ref_idx[LIST_1][j4][i4]==-1)
+ direct_pdir = 0;
+ else if (dec_picture->ref_idx[LIST_0][j4][i4]==-1)
+ direct_pdir = 1;
+ else
+ direct_pdir = 2;
+
+ }
+ else // Temporal Mode
+ {
+
+ int imgblock_y= ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? (img->block_y-4)>>1:img->block_y>>1: img->block_y;
+ int j6= imgblock_y + j;
+
+ int refList = (co_located_ref_idx[LIST_0][j6][i4]== -1 ? LIST_1 : LIST_0);
+ int ref_idx = co_located_ref_idx[refList][j6][i4];
+
+
+ if(ref_idx==-1) // co-located is intra mode
+ {
+ for(hv=0; hv<2; hv++)
+ {
+ dec_picture->mv [LIST_0][j4][i4][hv]=0;
+ dec_picture->mv [LIST_1][j4][i4][hv]=0;
+ }
+
+ dec_picture->ref_idx[LIST_0][j4][i4] = 0;
+ dec_picture->ref_idx[LIST_1][j4][i4] = 0;
+
+ l0_refframe = 0;
+ l0_ref_idx = 0;
+ }
+ else // co-located skip or inter mode
+ {
+ int mapped_idx=0;
+ int iref;
+
+ {
+ for (iref=0;iref<imin(img->num_ref_idx_l0_active,listXsize[LIST_0 + list_offset]);iref++)
+ {
+ if(img->structure==0 && curr_mb_field==0)
+ {
+ // If the current MB is a frame MB and the colocated is from a field picture,
+ // then the co_located_ref_id may have been generated from the wrong value of
+ // frame_poc if it references it's complementary field, so test both POC values
+ if(listX[0][iref]->top_poc*2 == co_located_ref_id[refList][j6][i4] || listX[0][iref]->bottom_poc*2 == co_located_ref_id[refList][j6][i4])
+ {
+ mapped_idx=iref;
+ break;
+ }
+ else //! invalid index. Default to zero even though this case should not happen
+ mapped_idx=INVALIDINDEX;
+ continue;
+ }
+
+ if (dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][iref]==co_located_ref_id[refList][j6][i4])
+ {
+ mapped_idx=iref;
+ break;
+ }
+ else //! invalid index. Default to zero even though this case should not happen
+ {
+ mapped_idx=INVALIDINDEX;
+ }
+ }
+ if (INVALIDINDEX == mapped_idx)
+ {
+ error("temporal direct error\ncolocated block has ref that is unavailable",-1111);
+ }
+ }
+
+ l0_ref_idx = mapped_idx;
+ mv_scale = img->mvscale[LIST_0 + list_offset][mapped_idx];
+
+ //! In such case, an array is needed for each different reference.
+ if (mv_scale == 9999 || listX[LIST_0+list_offset][mapped_idx]->is_long_term)
+ {
+ dec_picture->mv [LIST_0][j4][i4][0]=co_located_mv[refList][j6][i4][0];
+ dec_picture->mv [LIST_0][j4][i4][1]=co_located_mv[refList][j6][i4][1];
+
+ dec_picture->mv [LIST_1][j4][i4][0]=0;
+ dec_picture->mv [LIST_1][j4][i4][1]=0;
+ }
+ else
+ {
+ dec_picture->mv [LIST_0][j4][i4][0]=(mv_scale * co_located_mv[refList][j6][i4][0] + 128 ) >> 8;
+ dec_picture->mv [LIST_0][j4][i4][1]=(mv_scale * co_located_mv[refList][j6][i4][1] + 128 ) >> 8;
+
+ dec_picture->mv [LIST_1][j4][i4][0]=dec_picture->mv[LIST_0][j4][i4][0] - co_located_mv[refList][j6][i4][0] ;
+ dec_picture->mv [LIST_1][j4][i4][1]=dec_picture->mv[LIST_0][j4][i4][1] - co_located_mv[refList][j6][i4][1] ;
+ }
+
+ l0_refframe = dec_picture->ref_idx[LIST_0][j4][i4] = mapped_idx; //listX[1][0]->ref_idx[refList][j4][i4];
+ l1_refframe = dec_picture->ref_idx[LIST_1][j4][i4] = 0;
+
+ l0_ref_idx = l0_refframe;
+ l1_ref_idx = l1_refframe;
+ }
+ }
+ // store reference picture ID determined by direct mode
+ dec_picture->ref_pic_id[LIST_0][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][(short)dec_picture->ref_idx[LIST_0][j4][i4]];
+ dec_picture->ref_pic_id[LIST_1][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_1 + list_offset][(short)dec_picture->ref_idx[LIST_1][j4][i4]];
+ }
+
+ if (mv_mode==0 && img->direct_spatial_mv_pred_flag )
+ {
+ if (dec_picture->ref_idx[LIST_0][j4][i4] >= 0)
+ {
+
+ vec1_x = i4*4*mv_mul + l0_mv_array[j4][i4][0];
+ if (!curr_mb_field)
+ {
+ vec1_y = j4*4*mv_mul + l0_mv_array[j4][i4][1];
+ }
+ else
+ {
+ if ((mb_nr&0x01) == 0)
+ {
+ vec1_y = (img->block_y * 2 + joff) * mv_mul + l0_mv_array[j4][i4][1];
+ }
+ else
+ {
+ vec1_y = ((img->block_y-4) * 2 + joff)* mv_mul + l0_mv_array[j4][i4][1];
+ }
+ }
+ get_block(l0_refframe, listX[0+list_offset], vec1_x, vec1_y, img, tmp_block);
+ }
+
+ if (dec_picture->ref_idx[LIST_1][j4][i4] >= 0)
+ {
+ vec2_x = i4*4*mv_mul + l1_mv_array[j4][i4][0];
+ if (!curr_mb_field)
+ {
+ vec2_y = j4*4*mv_mul + l1_mv_array[j4][i4][1];
+ }
+ else
+ {
+ if ((mb_nr&0x01) == 0)
+ {
+ vec2_y = (img->block_y * 2 + joff) * mv_mul + l1_mv_array[j4][i4][1];
+ }
+ else
+ {
+ vec2_y = ((img->block_y-4) * 2 + joff)* mv_mul + l1_mv_array[j4][i4][1];
+ }
+ }
+ get_block(l1_refframe, listX[1+list_offset], vec2_x, vec2_y, img, tmp_blockbw);
+ }
+ }
+ else
+ {
+ vec1_x = i4 * 4 * mv_mul + l0_mv_array[j4][i4][0];
+ vec2_x = i4 * 4 * mv_mul + l1_mv_array[j4][i4][0];
+
+ if (!curr_mb_field)
+ {
+ vec1_y = j4 * 4 * mv_mul + l0_mv_array[j4][i4][1];
+ vec2_y = j4 * 4 * mv_mul + l1_mv_array[j4][i4][1];
+ }
+ else
+ {
+ if ((mb_nr&0x01) == 0)
+ {
+ vec1_y = (img->block_y * 2 + joff) * mv_mul + l0_mv_array[j4][i4][1];
+ vec2_y = (img->block_y * 2 + joff) * mv_mul + l1_mv_array[j4][i4][1];
+ }
+ else
+ {
+ vec1_y = ((img->block_y-4) * 2 + joff)* mv_mul + l0_mv_array[j4][i4][1];
+ vec2_y = ((img->block_y-4) * 2 + joff)* mv_mul + l1_mv_array[j4][i4][1];
+ }
+ }
+
+ get_block(l0_refframe, listX[0+list_offset], vec1_x, vec1_y, img, tmp_block);
+ get_block(l1_refframe, listX[1+list_offset], vec2_x, vec2_y, img, tmp_blockbw);
+ }
+
+ if (mv_mode==0 && img->direct_spatial_mv_pred_flag && direct_pdir==0)
+ {
+ if (img->apply_weights)
+ {
+ if (((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))||
+ (active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE))) && curr_mb_field)
+ {
+ l0_ref_idx >>=1;
+ }
+
+ alpha_l0 = img->wp_weight[LIST_0][l0_ref_idx][0];
+ wp_offset = img->wp_offset[LIST_0][l0_refframe>>curr_mb_field][0];
+
+ for(jj=0;jj<BLOCK_SIZE;jj++)
+ for(ii=0;ii<BLOCK_SIZE;ii++)
+ img->mpr[jj+joff][ii+ioff] = iClip1(img->max_imgpel_value,
+ (rshift_rnd_sf((alpha_l0 * tmp_block[jj][ii]), img->luma_log2_weight_denom) + wp_offset));
+ }
+ else
+ {
+ for(jj=0;jj<BLOCK_SIZE;jj++)
+ for(ii=0;ii<BLOCK_SIZE;ii++)
+ img->mpr[jj+joff][ii+ioff] = tmp_block[jj][ii];
+ }
+ }
+ else if (mv_mode==0 && img->direct_spatial_mv_pred_flag && direct_pdir==1)
+ {
+ if (img->apply_weights)
+ {
+ if (((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))||
+ (active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE))) && curr_mb_field)
+ {
+ l1_ref_idx >>=1;
+ }
+ alpha_l1 = img->wp_weight[LIST_1][l1_ref_idx][0];
+ wp_offset = img->wp_offset[LIST_1][l1_refframe>>curr_mb_field][0];
+
+ for(jj=0;jj<BLOCK_SIZE;jj++)
+ for(ii=0;ii<BLOCK_SIZE;ii++)
+ img->mpr[jj+joff][ii+ioff] = iClip1(img->max_imgpel_value,
+ (rshift_rnd_sf((alpha_l1 * tmp_blockbw[jj][ii]), img->luma_log2_weight_denom) + wp_offset));
+ }
+ else
+ {
+ for(jj=0;jj<BLOCK_SIZE;jj++)
+ for(ii=0;ii<BLOCK_SIZE;ii++)
+ img->mpr[jj+joff][ii+ioff] = tmp_blockbw[jj][ii];
+ }
+ }
+ else if(img->apply_weights)
+ {
+ int wt_list_offset = (active_pps->weighted_bipred_idc==2)?list_offset:0;
+
+ if (mv_mode==0 && img->direct_spatial_mv_pred_flag==0 )l1_ref_idx=0; //temporal direct
+
+ if (((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))||
+ (active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE))) && curr_mb_field)
+ {
+ l0_ref_idx >>=1;
+ l1_ref_idx >>=1;
+ }
+
+ alpha_l0 = img->wbp_weight[LIST_0 + wt_list_offset][l0_ref_idx][l1_ref_idx][0];
+ alpha_l1 = img->wbp_weight[LIST_1 + wt_list_offset][l0_ref_idx][l1_ref_idx][0];
+ wp_offset = ((img->wp_offset [LIST_0 + wt_list_offset][l0_ref_idx][0] + img->wp_offset[LIST_1 + wt_list_offset][l1_ref_idx][0] + 1) >>1);
+
+ for(ii=0;ii<BLOCK_SIZE;ii++)
+ for(jj=0;jj<BLOCK_SIZE;jj++)
+ img->mpr[jj+joff][ii+ioff] = (int)iClip1(img->max_imgpel_value,
+ (rshift_rnd_sf((alpha_l0 * tmp_block[jj][ii] + alpha_l1 * tmp_blockbw[jj][ii]), (img->luma_log2_weight_denom + 1)) + wp_offset));
+ }
+ else
+ {
+ for(jj=0;jj<BLOCK_SIZE;jj++)
+ for(ii=0;ii<BLOCK_SIZE;ii++)
+ img->mpr[jj+joff][ii+ioff] = (tmp_block[jj][ii]+tmp_blockbw[jj][ii]+1)>>1;
+ }
+ }
+ }
+
+ // =============== 4x4 itrans ================
+ // -------------------------------------------
+ if (smb && mv_mode!=IBLOCK)
+ {
+ if(!IS_NEWINTRA (currMB))// modif ES added
+ itrans_sp(img,ioff,joff,i,j);
+ else //modif ES added
+ itrans(img,ioff,joff,i,j,0); // modif ES added
+ }
+ else
+ {
+ if(need_4x4_transform)
+ {
+ if(img->type==SP_SLICE && currMB->mb_type != I16MB) // ES added
+ itrans_sp(img,ioff,joff,i,j);//ES added
+ else
+ itrans (img,ioff,joff,i,j, 0); // use DCT transform and make 4x4 block m7 from prediction block mpr
+ }
+ }
+ if(need_4x4_transform)
+ {
+ int j_pos = j4 * BLOCK_SIZE;
+ int i_pos = i4 * BLOCK_SIZE;
+
+ for(jj=0;jj<BLOCK_SIZE;jj++)
+ {
+ for(ii=0;ii<BLOCK_SIZE;ii++)
+ {
+ dec_picture->imgY[j_pos + jj][i_pos + ii]=img->m7[jj][ii]; // construct picture from 4x4 blocks
+ }
+ }
+ }// if(need_4x4_transform)
+ }
+
+ if(!need_4x4_transform)
+ {
+ // =============== 8x8 itrans ================
+ // -------------------------------------------
+ ioff = 8*(block8x8&0x01);
+ joff = 8*(block8x8>>1);
+
+ itrans8x8(img,ioff,joff); // use DCT transform and make 8x8 block m7 from prediction block mpr
+
+ for(jj=joff;jj<joff + 8;jj++)
+ {
+ for(ii=ioff;ii<ioff + 8;ii++)
+ {
+ dec_picture->imgY[img->pix_y + jj][img->pix_x + ii]=img->m7[jj][ii]; // construct picture from 4x4 blocks
+ }
+ }
+ }
+ }
+
+ if (dec_picture->chroma_format_idc != YUV400)
+ {
+ // chroma decoding *******************************************************
+ f1_x = 64/img->mb_cr_size_x;
+ f2_x = f1_x-1;
+
+ f1_y = 64/img->mb_cr_size_y;
+ f2_y = f1_y-1;
+
+ f3 = f1_x*f1_y;
+ f4 = f3>>1;
+
+ for(uv=0;uv<2;uv++)
+ {
+ uv_shift = uv*(img->num_blk8x8_uv>>1);
+ intra_prediction = IS_INTRA (currMB);
+
+ if (intra_prediction)
+ {
+ intrapred_chroma(img, uv);
+ }
+
+ for (b8=0;b8<(img->num_blk8x8_uv>>1);b8++)
+ {
+ for(b4=0;b4<4;b4++)
+ {
+ joff = subblk_offset_y[yuv][b8][b4];
+ j4 = img->pix_c_y+joff;
+ ioff = subblk_offset_x[yuv][b8][b4];
+ i4 = img->pix_c_x+ioff;
+
+ mv_mode = currMB->b8mode[block8x8_idx[yuv][b8][b4]];
+ pred_dir = currMB->b8pdir[block8x8_idx[yuv][b8][b4]];
+ assert (pred_dir<=2);
+
+
+ if (!intra_prediction)
+ {
+ if (pred_dir != 2)
+ {
+ int jpos;
+ //--- FORWARD/BACKWARD PREDICTION ---
+ mv_array = dec_picture->mv[LIST_0 + pred_dir];
+ list = listX[0+list_offset+pred_dir];
+
+ for(jj=0;jj<4;jj++)
+ {
+ jf=(j4+jj)/(img->mb_size_blk[1][1]); // jf = Subblock_y-coordinate
+
+ if (!curr_mb_field)
+ jpos=(j4+jj)*f1_y;
+ else
+ {
+ if ((mb_nr&0x01) == 0)
+ jpos=(((img->pix_c_y)>>1) + jj + joff)*f1_y;
+ else
+ jpos=(((img->pix_c_y-img->mb_cr_size_y)>>1) + jj + joff)*f1_y;
+ }
+
+ for(ii=0;ii<4;ii++)
+ {
+ ifx=(i4+ii)/(img->mb_size_blk[1][0]); // ifx = Subblock_x-coordinate
+ l0_refframe = ref_idx = dec_picture->ref_idx[LIST_0+pred_dir][jf][ifx];
+ i1=(i4+ii)*f1_x+mv_array[jf][ifx][0];
+
+ j1 = jpos+mv_array[jf][ifx][1];
+ if (active_sps->chroma_format_idc == 1)
+ j1 += list[ref_idx]->chroma_vector_adjustment;
+
+ ii0 = iClip3 (0, img->width_cr_m1, i1/f1_x);
+ jj0 = iClip3 (0, max_y_cr, j1/f1_y);
+ ii1 = iClip3 (0, img->width_cr_m1, ((i1+f2_x)/f1_x));
+ jj1 = iClip3 (0, max_y_cr, ((j1+f2_y)/f1_y));
+
+ if1=(i1 & f2_x);
+ jf1=(j1 & f2_y);
+ if0=f1_x-if1;
+ jf0=f1_y-jf1;
+
+ if (img->apply_weights)
+ {
+ imgpel **curUV = list[ref_idx]->imgUV[uv];
+ pred = (if0*jf0*curUV[jj0][ii0] + if1*jf0*curUV[jj0][ii1]+
+ if0*jf1*curUV[jj1][ii0] + if1*jf1*curUV[jj1][ii1]+f4)/f3;
+
+ if (((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))||
+ (active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE))) && curr_mb_field)
+ {
+ ref_idx >>=1;
+ }
+
+ img->mpr[jj+joff][ii+ioff] = iClip1(img->max_imgpel_value_uv, (((img->wp_weight[pred_dir][ref_idx][uv+1] * pred + img->wp_round_chroma)>>img->chroma_log2_weight_denom) + img->wp_offset[pred_dir][ref_idx][uv+1]));
+ }
+ else
+ {
+ imgpel **curUV = list[ref_idx]->imgUV[uv];
+ img->mpr[jj+joff][ii+ioff]=(
+ if0*jf0*curUV[jj0][ii0] + if1*jf0*curUV[jj0][ii1]+
+ if0*jf1*curUV[jj1][ii0] + if1*jf1*curUV[jj1][ii1]+f4)/f3;
+ }
+ }
+ }
+ }
+ else
+ {
+ l0_mv_array = dec_picture->mv[LIST_0];
+ l1_mv_array = dec_picture->mv[LIST_1];
+
+ for(jj=0;jj<4;jj++)
+ {
+ int jpos;
+ jf=(j4+jj)/(img->mb_size_blk[1][1]); // jf = Subblock_y-coordinate
+
+ if (!curr_mb_field)
+ {
+ jpos=(j4+jj)*f1_y;
+ }
+ else
+ {
+ if ((mb_nr&0x01) == 0)
+ jpos=(((img->pix_c_y)>>1) + jj + joff)*f1_y;
+ else
+ jpos=(((img->pix_c_y-img->mb_cr_size_y)>>1) + jj + joff)*f1_y;
+ }
+
+ for(ii=0;ii<4;ii++)
+ {
+ ifx=(i4+ii)/(img->mb_size_blk[1][0]); // ifx = Subblock_x-coordinate
+ direct_pdir = 2;
+
+ if (mv_mode == 0 && img->direct_spatial_mv_pred_flag)
+ {
+ //===== DIRECT PREDICTION =====
+ if (dec_picture->ref_idx[LIST_0][2*(jf>>1)][(ifx>>1)*2]!=-1)
+ {
+ l0_refframe = dec_picture->ref_idx[LIST_0][2*(jf>>1)][(ifx>>1)*2];
+ l0_ref_idx = l0_refframe;
+ }
+ if (dec_picture->ref_idx[LIST_1][2*(jf>>1)][(ifx>>1)*2]!=-1)
+ {
+ l1_refframe = dec_picture->ref_idx[LIST_1][2*(jf>>1)][(ifx>>1)*2];
+ l1_ref_idx = l1_refframe;
+ }
+
+ if (dec_picture->ref_idx[LIST_1][2*(jf>>1)][(ifx>>1)*2]==-1) direct_pdir = 0;
+ else if (dec_picture->ref_idx[LIST_0][2*(jf>>1)][(ifx>>1)*2]==-1) direct_pdir = 1;
+
+ if (direct_pdir == 0 || direct_pdir == 2)
+ {
+ i1=(i4+ii)*f1_x+l0_mv_array[jf][ifx][0];
+
+ j1=jpos+l0_mv_array[jf][ifx][1];
+ if (active_sps->chroma_format_idc == 1)
+ j1 += listX[0+list_offset][l0_refframe]->chroma_vector_adjustment;
+
+ ii0 = iClip3 (0, img->width_cr_m1, i1/f1_x);
+ jj0 = iClip3 (0, max_y_cr, j1/f1_y);
+ ii1 = iClip3 (0, img->width_cr_m1, ((i1+f2_x)/f1_x));
+ jj1 = iClip3 (0, max_y_cr, ((j1+f2_y)/f1_y));
+
+
+ if1=(i1 & f2_x);
+ jf1=(j1 & f2_y);
+ if0=f1_x-if1;
+ jf0=f1_y-jf1;
+
+ {
+ imgpel **curUV = listX[LIST_0 + list_offset][l0_refframe]->imgUV[uv];
+ fw_pred=(if0*jf0 * curUV[jj0][ii0]+
+ if1*jf0 * curUV[jj0][ii1]+
+ if0*jf1 * curUV[jj1][ii0]+
+ if1*jf1 * curUV[jj1][ii1]+f4)/f3;
+ }
+ }
+ if (direct_pdir == 1 || direct_pdir == 2)
+ {
+ i1=(i4+ii)*f1_x+l1_mv_array[jf][ifx][0];
+
+ j1=jpos+l1_mv_array[jf][ifx][1];
+ if (active_sps->chroma_format_idc == 1)
+ j1 += listX[1+list_offset][l1_refframe]->chroma_vector_adjustment;
+
+ ii0 = iClip3 (0, img->width_cr_m1, i1/f1_x);
+ jj0 = iClip3 (0, max_y_cr, j1/f1_y);
+ ii1 = iClip3 (0, img->width_cr_m1, ((i1+f2_x)/f1_x));
+ jj1 = iClip3 (0, max_y_cr, ((j1+f2_y)/f1_y));
+
+ if1=(i1 & f2_x);
+ jf1=(j1 & f2_y);
+ if0=f1_x-if1;
+ jf0=f1_y-jf1;
+
+ {
+ imgpel **curUV = listX[1+list_offset][l1_refframe]->imgUV[uv];
+ bw_pred=(if0*jf0*curUV[jj0][ii0] + if1*jf0*curUV[jj0][ii1]+
+ if0*jf1*curUV[jj1][ii0] + if1*jf1*curUV[jj1][ii1]+f4)/f3;
+ }
+ }
+
+ }
+ else
+ {
+ //===== BI-DIRECTIONAL PREDICTION =====
+ l0_refframe = dec_picture->ref_idx[LIST_0][jf][ifx];
+ l1_refframe = dec_picture->ref_idx[LIST_1][jf][ifx];
+
+ l0_ref_idx = l0_refframe;
+ l1_ref_idx = l1_refframe;
+
+ i1=(i4+ii)*f1_x+l0_mv_array[jf][ifx][0];
+
+ j1=jpos+l0_mv_array[jf][ifx][1];
+ if (active_sps->chroma_format_idc == 1)
+ j1 += listX[0+list_offset][l0_refframe]->chroma_vector_adjustment;
+
+ ii0 = iClip3 (0, img->width_cr_m1, i1/f1_x);
+ jj0 = iClip3 (0, max_y_cr, j1/f1_y);
+ ii1 = iClip3 (0, img->width_cr_m1, ((i1+f2_x)/f1_x));
+ jj1 = iClip3 (0, max_y_cr, ((j1+f2_y)/f1_y));
+
+ if1=(i1 & f2_x);
+ jf1=(j1 & f2_y);
+ if0=f1_x-if1;
+ jf0=f1_y-jf1;
+ {
+ imgpel **curUV = listX[0+list_offset][l0_refframe]->imgUV[uv];
+
+ fw_pred=(if0*jf0*curUV[jj0][ii0]+
+ if1*jf0*curUV[jj0][ii1]+
+ if0*jf1*curUV[jj1][ii0]+
+ if1*jf1*curUV[jj1][ii1]+f4)/f3;
+ }
+ i1=(i4+ii)*f1_x+l1_mv_array[jf][ifx][0];
+
+ j1=jpos+l1_mv_array[jf][ifx][1];
+ if (active_sps->chroma_format_idc == 1)
+ j1 += listX[1+list_offset][l1_refframe]->chroma_vector_adjustment;
+
+ ii0 = iClip3 (0, img->width_cr_m1, i1/f1_x);
+ jj0 = iClip3 (0, max_y_cr, j1/f1_y);
+ ii1 = iClip3 (0, img->width_cr_m1, ((i1+f2_x)/f1_x));
+ jj1 = iClip3 (0, max_y_cr, ((j1+f2_y)/f1_y));
+
+
+ if1=(i1 & f2_x);
+ jf1=(j1 & f2_y);
+ if0=f1_x-if1;
+ jf0=f1_y-jf1;
+
+ {
+ imgpel **curUV = listX[1+list_offset][l1_refframe]->imgUV[uv];
+ bw_pred=(if0*jf0*curUV[jj0][ii0]+ if1*jf0*curUV[jj0][ii1]+
+ if0*jf1*curUV[jj1][ii0]+if1*jf1*curUV[jj1][ii1]+f4)/f3;
+ }
+
+ }
+
+ if (img->apply_weights)
+ {
+ if (((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))||
+ (active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE))) && curr_mb_field)
+ {
+ l0_ref_idx >>=1;
+ l1_ref_idx >>=1;
+ }
+
+ if (img->direct_spatial_mv_pred_flag && direct_pdir==1)
+ {
+ img->mpr[jj+joff][ii+ioff]= iClip1(img->max_imgpel_value_uv,
+ (((img->wp_weight[1][l1_ref_idx][uv+1] * bw_pred + img->wp_round_chroma)>>img->chroma_log2_weight_denom) + img->wp_offset[1][l1_refframe>>curr_mb_field][uv+1])); // Replaced with integer only operations
+ }
+ else if (img->direct_spatial_mv_pred_flag && direct_pdir==0)
+ {
+ img->mpr[jj+joff][ii+ioff]=iClip1(img->max_imgpel_value_uv, (((img->wp_weight[0][l0_ref_idx][uv+1] * fw_pred + img->wp_round_chroma)>>img->chroma_log2_weight_denom) + img->wp_offset[0][l0_refframe>>curr_mb_field][uv+1])); // Replaced with integer only operations
+ }
+ else
+ {
+ int wt_list_offset = (active_pps->weighted_bipred_idc==2)?list_offset:0;
+
+ alpha_l0 = img->wbp_weight[0+wt_list_offset][l0_ref_idx][l1_ref_idx][uv+1];
+ alpha_l1 = img->wbp_weight[1+wt_list_offset][l0_ref_idx][l1_ref_idx][uv+1];
+
+ img->mpr[jj+joff][ii+ioff]= iClip1(img->max_imgpel_value_uv, (((alpha_l0 * fw_pred + alpha_l1 * bw_pred + (1<<img->chroma_log2_weight_denom)) >> (img->chroma_log2_weight_denom + 1))+ ((img->wp_offset[wt_list_offset + 0][l0_ref_idx][uv+1] + img->wp_offset[wt_list_offset + 1][l1_ref_idx][uv+1] + 1)>>1)));
+ }
+ }
+ else
+ {
+ if (img->direct_spatial_mv_pred_flag && direct_pdir==1)
+ {
+ img->mpr[jj+joff][ii+ioff]=bw_pred;
+ }
+ else if (img->direct_spatial_mv_pred_flag && direct_pdir==0)
+ {
+ img->mpr[jj+joff][ii+ioff]=fw_pred;
+ }
+ else
+ {
+ img->mpr[jj+joff][ii+ioff]=(fw_pred + bw_pred + 1 )>>1;
+ }
+ }
+ }
+ }
+ }
+ } //if (!intra_prediction)
+
+ if (!smb)
+ {
+ imgpel **curUV = dec_picture->imgUV[uv];
+ itrans(img,ioff,joff, cofuv_blk_x[yuv][b8+uv_shift][b4], cofuv_blk_y[yuv][b8+uv_shift][b4], 1);
+
+ for(jj=0;jj<4;jj++)
+ for(ii=0;ii<4;ii++)
+ {
+ curUV[j4+jj][i4+ii]=img->m7[jj][ii];
+ }
+ }
+ }
+ }
+
+ if(smb)
+ {
+ imgpel **curUV = dec_picture->imgUV[uv];
+ itrans_sp_chroma(img,2*uv);
+
+ for (j=4;j<6;j++)
+ {
+ joff=(j-4)*4;
+ j4=img->pix_c_y+joff;
+ for(i=0;i<2;i++)
+ {
+ ioff=i*4;
+ i4=img->pix_c_x+ioff;
+ itrans(img,ioff,joff,2*uv+i,j, 1);
+
+ for(jj=0;jj<4;jj++)
+ for(ii=0;ii<4;ii++)
+ {
+ curUV[j4+jj][i4+ii]=img->m7[jj][ii];
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
Index: llvm-test/MultiSource/Applications/JM/ldecod/macroblock.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/macroblock.h:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/macroblock.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,335 @@
+
+/*!
+ ************************************************************************
+ * \file macroblock.h
+ *
+ * \brief
+ * Arrays for macroblock encoding
+ *
+ * \author
+ * Inge Lille-Langoy <inge.lille-langoy at telenor.com>
+ * Copyright (C) 1999 Telenor Satellite Services, Norway
+ ************************************************************************
+ */
+
+#ifndef _MACROBLOCK_H_
+#define _MACROBLOCK_H_
+
+
+//! 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}
+};
+
+
+//! gives CBP value from codeword number, both for intra and inter
+const unsigned char NCBP[2][48][2]=
+{
+ { // 0 1 2 3 4 5 6 7 8 9 10 11
+ {15, 0},{ 0, 1},{ 7, 2},{11, 4},{13, 8},{14, 3},{ 3, 5},{ 5,10},{10,12},{12,15},{ 1, 7},{ 2,11},
+ { 4,13},{ 8,14},{ 6, 6},{ 9, 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}
+ },
+ {
+ {47, 0},{31,16},{15, 1},{ 0, 2},{23, 4},{27, 8},{29,32},{30, 3},{ 7, 5},{11,10},{13,12},{14,15},
+ {39,47},{43, 7},{45,11},{46,13},{16,14},{ 3, 6},{ 5, 9},{10,31},{12,35},{19,37},{21,42},{26,44},
+ {28,33},{35,34},{37,36},{42,40},{44,39},{ 1,43},{ 2,45},{ 4,46},{ 8,17},{17,18},{18,20},{20,24},
+ {24,19},{ 6,21},{ 9,26},{22,28},{25,23},{32,27},{33,29},{34,30},{36,22},{40,25},{38,38},{41,41}
+ }
+};
+
+
+//! used to control block sizes : Not used/16x16/16x8/8x16/8x8/8x4/4x8/4x4
+const int BLOCK_STEP[8][2]=
+{
+ {0,0},{4,4},{4,2},{2,4},{2,2},{2,1},{1,2},{1,1}
+};
+
+//! Dequantization coefficients
+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}}
+};
+
+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_SCAN8x8[64][2] = {
+ {0,0}, {1,0}, {0,1}, {0,2}, {1,1}, {2,0}, {3,0}, {2,1}, {1,2}, {0,3}, {0,4}, {1,3}, {2,2}, {3,1}, {4,0}, {5,0},
+ {4,1}, {3,2}, {2,3}, {1,4}, {0,5}, {0,6}, {1,5}, {2,4}, {3,3}, {4,2}, {5,1}, {6,0}, {7,0}, {6,1}, {5,2}, {4,3},
+ {3,4}, {2,5}, {1,6}, {0,7}, {1,7}, {2,6}, {3,5}, {4,4}, {5,3}, {6,2}, {7,1}, {7,2}, {6,3}, {5,4}, {4,5}, {3,6},
+ {2,7}, {3,7}, {4,6}, {5,5}, {6,4}, {7,3}, {7,4}, {6,5}, {5,6}, {4,7}, {5,7}, {6,6}, {7,5}, {7,6}, {6,7}, {7,7}
+};
+
+/*
+//! field scan pattern
+const byte FIELD_SCAN8x8[64][2] = {
+{0,0}, {0,1}, {0,2}, {1,0}, {1,1}, {0,3}, {0,4}, {1,2}, {2,0}, {2,1}, {1,3}, {0,5}, {0,6}, {1,4}, {2,2}, {3,0},
+{3,1}, {2,3}, {1,5}, {0,7}, {1,6}, {2,4}, {3,2}, {4,0}, {4,1}, {3,3}, {2,5}, {1,7}, {2,6}, {3,4}, {4,2}, {5,0},
+{5,1}, {4,3}, {3,5}, {2,7}, {3,6}, {4,4}, {5,2}, {6,0}, {6,1}, {5,3}, {4,5}, {3,7}, {4,6}, {5,4}, {6,2}, {7,0},
+{7,1}, {6,3}, {5,5}, {4,7}, {5,6}, {6,4}, {7,2}, {7,3}, {6,5}, {5,7}, {6,6}, {7,4}, {7,5}, {6,7}, {7,6}, {7,7}
+};
+*/
+
+//! field scan pattern
+//original from ABT
+const byte FIELD_SCAN8x8[64][2] = { // 8x8
+ {0,0}, {0,1}, {0,2}, {1,0}, {1,1}, {0,3}, {0,4}, {1,2}, {2,0}, {1,3}, {0,5}, {0,6}, {0,7}, {1,4}, {2,1}, {3,0},
+ {2,2}, {1,5}, {1,6}, {1,7}, {2,3}, {3,1}, {4,0}, {3,2}, {2,4}, {2,5}, {2,6}, {2,7}, {3,3}, {4,1}, {5,0}, {4,2},
+ {3,4}, {3,5}, {3,6}, {3,7}, {4,3}, {5,1}, {6,0}, {5,2}, {4,4}, {4,5}, {4,6}, {4,7}, {5,3}, {6,1}, {6,2}, {5,4},
+ {5,5}, {5,6}, {5,7}, {6,3}, {7,0}, {7,1}, {6,4}, {6,5}, {6,6}, {6,7}, {7,2}, {7,3}, {7,4}, {7,5}, {7,6}, {7,7}
+};
+
+
+static const int dequant_coef8[6][8][8] =
+{
+ {
+ {20, 19, 25, 19, 20, 19, 25, 19},
+ {19, 18, 24, 18, 19, 18, 24, 18},
+ {25, 24, 32, 24, 25, 24, 32, 24},
+ {19, 18, 24, 18, 19, 18, 24, 18},
+ {20, 19, 25, 19, 20, 19, 25, 19},
+ {19, 18, 24, 18, 19, 18, 24, 18},
+ {25, 24, 32, 24, 25, 24, 32, 24},
+ {19, 18, 24, 18, 19, 18, 24, 18}
+ },
+ {
+ {22, 21, 28, 21, 22, 21, 28, 21},
+ {21, 19, 26, 19, 21, 19, 26, 19},
+ {28, 26, 35, 26, 28, 26, 35, 26},
+ {21, 19, 26, 19, 21, 19, 26, 19},
+ {22, 21, 28, 21, 22, 21, 28, 21},
+ {21, 19, 26, 19, 21, 19, 26, 19},
+ {28, 26, 35, 26, 28, 26, 35, 26},
+ {21, 19, 26, 19, 21, 19, 26, 19}
+ },
+ {
+ {26, 24, 33, 24, 26, 24, 33, 24},
+ {24, 23, 31, 23, 24, 23, 31, 23},
+ {33, 31, 42, 31, 33, 31, 42, 31},
+ {24, 23, 31, 23, 24, 23, 31, 23},
+ {26, 24, 33, 24, 26, 24, 33, 24},
+ {24, 23, 31, 23, 24, 23, 31, 23},
+ {33, 31, 42, 31, 33, 31, 42, 31},
+ {24, 23, 31, 23, 24, 23, 31, 23}
+ },
+ {
+ {28, 26, 35, 26, 28, 26, 35, 26},
+ {26, 25, 33, 25, 26, 25, 33, 25},
+ {35, 33, 45, 33, 35, 33, 45, 33},
+ {26, 25, 33, 25, 26, 25, 33, 25},
+ {28, 26, 35, 26, 28, 26, 35, 26},
+ {26, 25, 33, 25, 26, 25, 33, 25},
+ {35, 33, 45, 33, 35, 33, 45, 33},
+ {26, 25, 33, 25, 26, 25, 33, 25}
+ },
+ {
+ {32, 30, 40, 30, 32, 30, 40, 30},
+ {30, 28, 38, 28, 30, 28, 38, 28},
+ {40, 38, 51, 38, 40, 38, 51, 38},
+ {30, 28, 38, 28, 30, 28, 38, 28},
+ {32, 30, 40, 30, 32, 30, 40, 30},
+ {30, 28, 38, 28, 30, 28, 38, 28},
+ {40, 38, 51, 38, 40, 38, 51, 38},
+ {30, 28, 38, 28, 30, 28, 38, 28}
+ },
+ {
+ {36, 34, 46, 34, 36, 34, 46, 34},
+ {34, 32, 43, 32, 34, 32, 43, 32},
+ {46, 43, 58, 43, 46, 43, 58, 43},
+ {34, 32, 43, 32, 34, 32, 43, 32},
+ {36, 34, 46, 34, 36, 34, 46, 34},
+ {34, 32, 43, 32, 34, 32, 43, 32},
+ {46, 43, 58, 43, 46, 43, 58, 43},
+ {34, 32, 43, 32, 34, 32, 43, 32}
+ }
+
+};
+
+//! 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 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} }
+};
+
+
+static unsigned char cofuv_blk_x[3][8][4] =
+{ { {0, 1, 0, 1},
+ {2, 3, 2, 3},
+ {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, 0, 1},
+ {0, 1, 0, 1},
+ {2, 3, 2, 3},
+ {2, 3, 2, 3},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0} },
+
+ { {0, 1, 0, 1},
+ {2, 3, 2, 3},
+ {0, 1, 0, 1},
+ {2, 3, 2, 3},
+ {0, 1, 0, 1},
+ {2, 3, 2, 3},
+ {0, 1, 0, 1},
+ {2, 3, 2, 3} }
+};
+
+static unsigned char cofuv_blk_y[3][8][4] =
+{
+ { { 4, 4, 5, 5},
+ { 4, 4, 5, 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} },
+
+ { { 4, 4, 5, 5},
+ { 6, 6, 7, 7},
+ { 4, 4, 5, 5},
+ { 6, 6, 7, 7},
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0} },
+
+ { { 4, 4, 5, 5},
+ { 4, 4, 5, 5},
+ { 6, 6, 7, 7},
+ { 6, 6, 7, 7},
+ { 8, 8, 9, 9},
+ { 8, 8, 9, 9},
+ {10,10,11,11},
+ {10,10,11,11} }
+};
+
+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} };
+
+
+int block8x8_idx[3][4][4] =
+{ { {0, 1, 2, 3},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}, },
+
+ { {0, 1, 0, 1},
+ {2, 3, 2, 3},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0} },
+
+ { {0, 0, 0, 0},
+ {1, 1, 1, 1},
+ {2, 2, 2, 2},
+ {3, 3, 3, 3} }
+};
+
+#define _NEW_8x8_ARRAYS_INCLUDED_
+
+
+#endif
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/mb_access.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/mb_access.c:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/mb_access.c Sun Feb 4 08:38:31 2007
@@ -0,0 +1,679 @@
+
+/*!
+ *************************************************************************************
+ * \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"
+#include "mbuffer.h"
+#include "mb_access.h"
+
+extern StorablePicture *dec_picture;
+
+/*!
+ ************************************************************************
+ * \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)dec_picture->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(void)
+{
+ 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 (dec_picture->MbaffFrameFlag)
+ {
+ int cur_mb_pair = mb_nr >> 1;
+ currMB->mbAddrA = 2 * (cur_mb_pair - 1);
+ currMB->mbAddrB = 2 * (cur_mb_pair - dec_picture->PicWidthInMbs);
+ currMB->mbAddrC = 2 * (cur_mb_pair - dec_picture->PicWidthInMbs + 1);
+ currMB->mbAddrD = 2 * (cur_mb_pair - dec_picture->PicWidthInMbs - 1);
+
+ currMB->mbAvailA = mb_is_available(currMB->mbAddrA, mb_nr) && ((PicPos[ cur_mb_pair ][0])!=0);
+ currMB->mbAvailB = mb_is_available(currMB->mbAddrB, mb_nr);
+ currMB->mbAvailC = mb_is_available(currMB->mbAddrC, mb_nr) && ((PicPos[ cur_mb_pair + 1 ][0])!=0);
+ currMB->mbAvailD = mb_is_available(currMB->mbAddrD, mb_nr) && ((PicPos[ cur_mb_pair ][0])!=0);
+ }
+ else
+ {
+ currMB->mbAddrA = mb_nr - 1;
+ currMB->mbAddrB = mb_nr - dec_picture->PicWidthInMbs;
+ currMB->mbAddrC = mb_nr - dec_picture->PicWidthInMbs + 1;
+ currMB->mbAddrD = mb_nr - dec_picture->PicWidthInMbs - 1;
+
+ currMB->mbAvailA = mb_is_available(currMB->mbAddrA, mb_nr) && ((PicPos[ mb_nr ][0])!=0);
+ currMB->mbAvailB = mb_is_available(currMB->mbAddrB, mb_nr);
+ currMB->mbAvailC = mb_is_available(currMB->mbAddrC, mb_nr) && ((PicPos[ mb_nr + 1][0])!=0);
+ currMB->mbAvailD = mb_is_available(currMB->mbAddrD, mb_nr) && ((PicPos[ mb_nr ][0])!=0);
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * returns the x and y macroblock coordinates for a given MbAddress
+ ************************************************************************
+ */
+void get_mb_block_pos_normal (int mb_addr, int *x, int*y)
+{
+ *x = PicPos[ mb_addr ][0];
+ *y = PicPos[ mb_addr ][1];
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * returns the x and y macroblock coordinates for a given MbAddress
+ * for mbaff type slices
+ ************************************************************************
+ */
+void get_mb_block_pos_mbaff (int mb_addr, int *x, int*y)
+{
+ *x = PicPos[mb_addr>>1][0];
+ *y = (PicPos[mb_addr>>1][1] << 1) + (mb_addr & 0x01);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * returns the x and y sample coordinates for a given MbAddress
+ ************************************************************************
+ */
+void get_mb_pos (int mb_addr, int *x, int*y, int is_chroma)
+{
+ get_mb_block_pos(mb_addr, x, y);
+
+ (*x) *= img->mb_size[is_chroma][0];
+ (*y) *= img->mb_size[is_chroma][1];
+}
+
+
+/*!
+ ************************************************************************
+ * \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 is_chroma, PixelPos *pix)
+{
+ Macroblock *currMb = &img->mb_data[curr_mb_nr];
+ int maxW = img->mb_size[is_chroma][0], maxH = img->mb_size[is_chroma][1];
+/*
+ if (!is_chroma)
+ {
+ maxW = 16;
+ maxH = 16;
+ }
+ else
+ {
+ assert(dec_picture->chroma_format_idc != 0);
+ maxW = img->mb_cr_size_x;
+ maxH = img->mb_cr_size_y;
+ }
+*/
+
+ if ((xN<0))
+ {
+ if (yN<0)
+ {
+ pix->mb_addr = currMb->mbAddrD;
+ pix->available = currMb->mbAvailD;
+ }
+ else if (yN<maxH)
+ {
+ pix->mb_addr = currMb->mbAddrA;
+ pix->available = currMb->mbAvailA;
+ }
+ else
+ pix->available = FALSE;
+ }
+ else if (xN<maxW)
+ {
+ if (yN<0)
+ {
+ pix->mb_addr = currMb->mbAddrB;
+ pix->available = currMb->mbAvailB;
+ }
+ else if (yN<maxH)
+ {
+ pix->mb_addr = curr_mb_nr;
+ pix->available = TRUE;
+ }
+ else
+ {
+ pix->available = FALSE;
+ }
+ }
+ else if ((xN>=maxW)&&(yN<0))
+ {
+ pix->mb_addr = currMb->mbAddrC;
+ pix->available = currMb->mbAvailC;
+ }
+ else
+ {
+ pix->available = FALSE;
+ }
+
+ if (pix->available || img->DeblockCall)
+ {
+ int *CurPos = PicPos[ pix->mb_addr ];
+
+ pix->x = xN & (maxW - 1);
+ pix->y = yN & (maxH - 1);
+ pix->pos_x = CurPos[0] * maxW + pix->x;
+ pix->pos_y = CurPos[1] * maxH + pix->y;
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * get neighbouring positions for 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 getAffNeighbour(unsigned int curr_mb_nr, int xN, int yN, int is_chroma, PixelPos *pix)
+{
+ Macroblock *currMb = &img->mb_data[curr_mb_nr];
+ int maxW, maxH;
+ int yM = -1;
+
+/*
+ if (!is_chroma)
+ {
+ maxW = 16;
+ maxH = 16;
+ }
+ else
+ {
+ assert(dec_picture->chroma_format_idc != 0);
+ maxW = img->mb_cr_size_x;
+ maxH = img->mb_cr_size_y;
+ }
+*/
+ maxW = img->mb_size[is_chroma][0];
+ maxH = img->mb_size[is_chroma][1];
+
+ // initialize to "not available"
+ pix->available = FALSE;
+
+ if(yN > (maxH - 1))
+ {
+ return;
+ }
+ if (xN > (maxW - 1) && yN >= 0 && yN < maxH)
+ {
+ return;
+ }
+
+ if (xN < 0)
+ {
+ if (yN < 0)
+ {
+ if(!currMb->mb_field)
+ {
+ // frame
+ if ((curr_mb_nr & 0x01) == 0)
+ {
+ // top
+ pix->mb_addr = currMb->mbAddrD + 1;
+ pix->available = currMb->mbAvailD;
+ yM = yN;
+ }
+ else
+ {
+ // bottom
+ pix->mb_addr = currMb->mbAddrA;
+ pix->available = currMb->mbAvailA;
+ if (currMb->mbAvailA)
+ {
+ if(!img->mb_data[currMb->mbAddrA].mb_field)
+ {
+ yM = yN;
+ }
+ else
+ {
+ (pix->mb_addr)++;
+ yM = (yN + maxH) >> 1;
+ }
+ }
+ }
+ }
+ else
+ {
+ // field
+ if ((curr_mb_nr & 0x01) == 0)
+ {
+ // top
+ pix->mb_addr = currMb->mbAddrD;
+ pix->available = currMb->mbAvailD;
+ if (currMb->mbAvailD)
+ {
+ if(!img->mb_data[currMb->mbAddrD].mb_field)
+ {
+ (pix->mb_addr)++;
+ yM = 2 * yN;
+ }
+ else
+ {
+ yM = yN;
+ }
+ }
+ }
+ else
+ {
+ // bottom
+ pix->mb_addr = currMb->mbAddrD+1;
+ pix->available = currMb->mbAvailD;
+ yM = yN;
+ }
+ }
+ }
+ else
+ { // xN < 0 && yN >= 0
+ if (yN >= 0 && yN <maxH)
+ {
+ if (!currMb->mb_field)
+ {
+ // frame
+ if ((curr_mb_nr & 0x01) == 0)
+ {
+ // top
+ pix->mb_addr = currMb->mbAddrA;
+ pix->available = currMb->mbAvailA;
+ if (currMb->mbAvailA)
+ {
+ if(!img->mb_data[currMb->mbAddrA].mb_field)
+ {
+ yM = yN;
+ }
+ else
+ {
+ if ((yN & 0x01) == 0)
+ {
+ yM = yN>> 1;
+ }
+ else
+ {
+ (pix->mb_addr)++;
+ yM = yN>> 1;
+ }
+ }
+ }
+ }
+ else
+ {
+ // bottom
+ pix->mb_addr = currMb->mbAddrA;
+ pix->available = currMb->mbAvailA;
+ if (currMb->mbAvailA)
+ {
+ if(!img->mb_data[currMb->mbAddrA].mb_field)
+ {
+ (pix->mb_addr)++;
+ yM = yN;
+ }
+ else
+ {
+ if ((yN & 0x01) == 0)
+ {
+ yM = (yN + maxH) >> 1;
+ }
+ else
+ {
+ (pix->mb_addr)++;
+ yM = (yN + maxH) >> 1;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // field
+ if ((curr_mb_nr & 0x01) == 0)
+ {
+ // top
+ pix->mb_addr = currMb->mbAddrA;
+ pix->available = currMb->mbAvailA;
+ if (currMb->mbAvailA)
+ {
+ if(!img->mb_data[currMb->mbAddrA].mb_field)
+ {
+ if (yN < (maxH >> 1))
+ {
+ yM = yN << 1;
+ }
+ else
+ {
+ (pix->mb_addr)++;
+ yM = (yN << 1 ) - maxH;
+ }
+ }
+ else
+ {
+ yM = yN;
+ }
+ }
+ }
+ else
+ {
+ // bottom
+ pix->mb_addr = currMb->mbAddrA;
+ pix->available = currMb->mbAvailA;
+ if (currMb->mbAvailA)
+ {
+ if(!img->mb_data[currMb->mbAddrA].mb_field)
+ {
+ if (yN < (maxH >> 1))
+ {
+ yM = (yN << 1) + 1;
+ }
+ else
+ {
+ (pix->mb_addr)++;
+ yM = (yN << 1 ) + 1 - maxH;
+ }
+ }
+ else
+ {
+ (pix->mb_addr)++;
+ yM = yN;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ { // xN >= 0
+ if (xN >= 0 && xN < maxW)
+ {
+ if (yN<0)
+ {
+ if (!currMb->mb_field)
+ {
+ //frame
+ if ((curr_mb_nr & 0x01) == 0)
+ {
+ //top
+ pix->mb_addr = currMb->mbAddrB;
+ // for the deblocker if the current MB is a frame and the one above is a field
+ // then the neighbor is the top MB of the pair
+ if (currMb->mbAvailB)
+ {
+ if (!(img->DeblockCall == 1 && (img->mb_data[currMb->mbAddrB]).mb_field))
+ pix->mb_addr += 1;
+ }
+
+ pix->available = currMb->mbAvailB;
+ yM = yN;
+ }
+ else
+ {
+ // bottom
+ pix->mb_addr = curr_mb_nr - 1;
+ pix->available = TRUE;
+ yM = yN;
+ }
+ }
+ else
+ {
+ // field
+ if ((curr_mb_nr & 0x01) == 0)
+ {
+ // top
+ pix->mb_addr = currMb->mbAddrB;
+ pix->available = currMb->mbAvailB;
+ if (currMb->mbAvailB)
+ {
+ if(!img->mb_data[currMb->mbAddrB].mb_field)
+ {
+ (pix->mb_addr)++;
+ yM = 2* yN;
+ }
+ else
+ {
+ yM = yN;
+ }
+ }
+ }
+ else
+ {
+ // bottom
+ pix->mb_addr = currMb->mbAddrB + 1;
+ pix->available = currMb->mbAvailB;
+ yM = yN;
+ }
+ }
+ }
+ else
+ {
+ // yN >=0
+ // for the deblocker if this is the extra edge then do this special stuff
+ if (yN == 0 && img->DeblockCall == 2)
+ {
+ pix->mb_addr = currMb->mbAddrB + 1;
+ pix->available = TRUE;
+ yM = yN - 1;
+ }
+
+ else if ((yN >= 0) && (yN <maxH))
+ {
+ pix->mb_addr = curr_mb_nr;
+ pix->available = TRUE;
+ yM = yN;
+ }
+ }
+ }
+ else
+ { // xN >= maxW
+ if(yN < 0)
+ {
+ if (!currMb->mb_field)
+ {
+ // frame
+ if ((curr_mb_nr & 0x01) == 0)
+ {
+ // top
+ pix->mb_addr = currMb->mbAddrC + 1;
+ pix->available = currMb->mbAvailC;
+ yM = yN;
+ }
+ else
+ {
+ // bottom
+ pix->available = FALSE;
+ }
+ }
+ else
+ {
+ // field
+ if ((curr_mb_nr & 0x01) == 0)
+ {
+ // top
+ pix->mb_addr = currMb->mbAddrC;
+ pix->available = currMb->mbAvailC;
+ if (currMb->mbAvailC)
+ {
+ if(!img->mb_data[currMb->mbAddrC].mb_field)
+ {
+ (pix->mb_addr)++;
+ yM = 2* yN;
+ }
+ else
+ {
+ yM = yN;
+ }
+ }
+ }
+ else
+ {
+ // bottom
+ pix->mb_addr = currMb->mbAddrC + 1;
+ pix->available = currMb->mbAvailC;
+ yM = yN;
+ }
+ }
+ }
+ }
+ }
+ if (pix->available || img->DeblockCall)
+ {
+ pix->x = xN & (maxW - 1);
+ pix->y = yM & (maxH - 1);
+ get_mb_pos(pix->mb_addr, &(pix->pos_x), &(pix->pos_y), is_chroma);
+ pix->pos_x += pix->x;
+ pix->pos_y += pix->y;
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * get neighbouring positions. MB AFF is automatically used from img structure
+ * \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 getNeighbour(int curr_mb_nr, int xN, int yN, int is_chroma, PixelPos *pix)
+{
+ if (curr_mb_nr<0)
+ error ("getNeighbour: invalid macroblock number", 100);
+
+ if (dec_picture->MbaffFrameFlag)
+ getAffNeighbour(curr_mb_nr, xN, yN, is_chroma, pix);
+ else
+ getNonAffNeighbour(curr_mb_nr, xN, yN, is_chroma, pix);
+}
+*/
+
+/*!
+ ************************************************************************
+ * \brief
+ * get neighbouring get neighbouring 4x4 luma block
+ * \param curr_mb_nr
+ * current macroblock number (decoding order)
+ * \param block_x
+ * input x block position
+ * \param block_y
+ * input y block position
+ * \param rel_x
+ * relative x position of neighbor
+ * \param rel_y
+ * relative y position of neighbor
+ * \param pix
+ * returns position informations
+ ************************************************************************
+ */
+void getLuma4x4Neighbour (int curr_mb_nr, int block_x, int block_y, PixelPos *pix)
+{
+ getNeighbour(curr_mb_nr, block_x, block_y, IS_LUMA, pix);
+
+ if (pix->available)
+ {
+ pix->x >>= 2;
+ pix->y >>= 2;
+ pix->pos_x >>= 2;
+ pix->pos_y >>= 2;
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * get neighbouring 4x4 chroma block
+ * \param curr_mb_nr
+ * current macroblock number (decoding order)
+ * \param block_x
+ * input x block position
+ * \param block_y
+ * input y block position
+ * \param rel_x
+ * relative x position of neighbor
+ * \param rel_y
+ * relative y position of neighbor
+ * \param pix
+ * returns position informations
+ ************************************************************************
+ */
+void getChroma4x4Neighbour (int curr_mb_nr, int block_x, int block_y, PixelPos *pix)
+{
+ getNeighbour(curr_mb_nr, block_x, block_y, IS_CHROMA, pix);
+
+ if (pix->available)
+ {
+ pix->x >>= 2;
+ pix->y >>= 2;
+ pix->pos_x >>= 2;
+ pix->pos_y >>= 2;
+ }
+}
Index: llvm-test/MultiSource/Applications/JM/ldecod/mb_access.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/mb_access.h:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/mb_access.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,36 @@
+
+/*!
+ *************************************************************************************
+ * \file mb_access.h
+ *
+ * \brief
+ * Functions for macroblock neighborhoods
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Karsten Sühring <suehring at hhi.de>
+ *************************************************************************************
+ */
+
+#ifndef _MB_ACCESS_H_
+#define _MB_ACCESS_H_
+
+void CheckAvailabilityOfNeighbors(void);
+
+//void getNeighbour(int curr_mb_nr, int xN, int yN, int luma, PixelPos *pix);
+void (*getNeighbour)(unsigned int curr_mb_nr, int xN, int yN, int is_chroma, PixelPos *pix);
+void getAffNeighbour(unsigned int curr_mb_nr, int xN, int yN, int is_chroma, PixelPos *pix);
+void getNonAffNeighbour(unsigned int curr_mb_nr, int xN, int yN, int is_chroma, PixelPos *pix);
+
+void getLuma4x4Neighbour (int curr_mb_nr, int block_x, int block_y, PixelPos *pix);
+void getChroma4x4Neighbour (int curr_mb_nr, int block_x, int block_y, PixelPos *pix);
+
+int mb_is_available(int mbAddr, int currMbAddr);
+void get_mb_pos (int mb_addr, int *x, int*y, int is_chroma);
+void (*get_mb_block_pos) (int mb_addr, int *x, int*y);
+void get_mb_block_pos_normal (int mb_addr, int *x, int*y);
+void get_mb_block_pos_mbaff (int mb_addr, int *x, int*y);
+
+
+
+#endif
Index: llvm-test/MultiSource/Applications/JM/ldecod/mbuffer.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/mbuffer.c:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/mbuffer.c Sun Feb 4 08:38:31 2007
@@ -0,0 +1,3864 @@
+
+/*!
+ ***********************************************************************
+ * \file
+ * mbuffer.c
+ *
+ * \brief
+ * Frame buffer functions
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Karsten Sühring <suehring at hhi.de>
+ * - Alexis Tourapis <alexismt at ieee.org>
+ * - Jill Boyce <jill.boyce at thomson.net>
+ * - Saurav K Bandyopadhyay <saurav at ieee.org>
+ * - Zhenyu Wu <Zhenyu.Wu at thomson.net
+ * - Purvin Pandit <Purvin.Pandit at thomson.net>
+ *
+ ***********************************************************************
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+
+#include "global.h"
+#include "mbuffer.h"
+#include "memalloc.h"
+#include "output.h"
+#include "image.h"
+#include "header.h"
+
+// picture error concealment
+#include "erc_api.h"
+
+static void insert_picture_in_dpb(FrameStore* fs, StorablePicture* p);
+static void output_one_frame_from_dpb();
+static int is_used_for_reference(FrameStore* fs);
+static void get_smallest_poc(int *poc,int * pos);
+static int remove_unused_frame_from_dpb();
+static int is_short_term_reference(FrameStore* fs);
+static int is_long_term_reference(FrameStore* fs);
+void gen_field_ref_ids(StorablePicture *p);
+
+DecodedPictureBuffer dpb;
+
+StorablePicture **listX[6];
+
+StorablePicture *no_reference_picture; //!< dummy storable picture for recovery point
+
+ColocatedParams *Co_located = NULL;
+
+extern StorablePicture *dec_picture;
+
+int listXsize[6];
+
+#define MAX_LIST_SIZE 33
+
+/*!
+ ************************************************************************
+ * \brief
+ * Print out list of pictures in DPB. Used for debug purposes.
+ ************************************************************************
+ */
+void dump_dpb()
+{
+#if DUMP_DPB
+ unsigned i;
+ for (i=0; i<dpb.used_size;i++)
+ {
+ printf("(");
+ printf("fn=%d ", dpb.fs[i]->frame_num);
+ if (dpb.fs[i]->is_used & 1)
+ {
+ if (dpb.fs[i]->top_field)
+ printf("T: poc=%d ", dpb.fs[i]->top_field->poc);
+ else
+ printf("T: poc=%d ", dpb.fs[i]->frame->top_poc);
+ }
+ if (dpb.fs[i]->is_used & 2)
+ {
+ if (dpb.fs[i]->bottom_field)
+ printf("B: poc=%d ", dpb.fs[i]->bottom_field->poc);
+ else
+ printf("B: poc=%d ", dpb.fs[i]->frame->bottom_poc);
+ }
+ if (dpb.fs[i]->is_used == 3)
+ printf("F: poc=%d ", dpb.fs[i]->frame->poc);
+ printf("G: poc=%d) ", dpb.fs[i]->poc);
+ if (dpb.fs[i]->is_reference) printf ("ref (%d) ", dpb.fs[i]->is_reference);
+ if (dpb.fs[i]->is_long_term) printf ("lt_ref (%d) ", dpb.fs[i]->is_reference);
+ if (dpb.fs[i]->is_output) printf ("out ");
+ if (dpb.fs[i]->is_used == 3)
+ {
+ if (dpb.fs[i]->frame->non_existing) printf ("ne ");
+ }
+ printf ("\n");
+ }
+#endif
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Returns the size of the dpb depending on level and picture size
+ *
+ *
+ ************************************************************************
+ */
+int getDpbSize()
+{
+ int pic_size = (active_sps->pic_width_in_mbs_minus1 + 1) * (active_sps->pic_height_in_map_units_minus1 + 1) * (active_sps->frame_mbs_only_flag?1:2) * 384;
+
+ int size = 0;
+
+ switch (active_sps->level_idc)
+ {
+ case 9:
+ size = 152064;
+ break;
+ case 10:
+ size = 152064;
+ break;
+ case 11:
+ if ((active_sps->profile_idc < FREXT_HP)&&(active_sps->constrained_set3_flag == 0))
+ size = 345600;
+ else
+ size = 152064;
+ break;
+ case 12:
+ size = 912384;
+ break;
+ case 13:
+ size = 912384;
+ break;
+ case 20:
+ size = 912384;
+ break;
+ case 21:
+ size = 1824768;
+ break;
+ case 22:
+ size = 3110400;
+ break;
+ case 30:
+ size = 3110400;
+ break;
+ case 31:
+ size = 6912000;
+ break;
+ case 32:
+ size = 7864320;
+ break;
+ case 40:
+ size = 12582912;
+ break;
+ case 41:
+ size = 12582912;
+ break;
+ case 42:
+ if( (active_sps->profile_idc==FREXT_HP ) || (active_sps->profile_idc==FREXT_Hi10P)
+ || (active_sps->profile_idc==FREXT_Hi422) || (active_sps->profile_idc==FREXT_Hi444))
+ size = 13369344;
+ else
+ size = 12582912;
+ break;
+ case 50:
+ size = 42393600;
+ break;
+ case 51:
+ size = 70778880;
+ break;
+ default:
+ error ("undefined level", 500);
+ break;
+ }
+
+ size /= pic_size;
+ size = imin( size, 16);
+
+ if (active_sps->vui_parameters_present_flag && active_sps->vui_seq_parameters.bitstream_restriction_flag)
+ {
+ if ((int)active_sps->vui_seq_parameters.max_dec_frame_buffering > size)
+ {
+ error ("max_dec_frame_buffering larger than MaxDpbSize", 500);
+ }
+ size = imax (1, active_sps->vui_seq_parameters.max_dec_frame_buffering);
+ }
+
+ return size;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Check then number of frames marked "used for reference" and break
+ * if maximum is exceeded
+ *
+ ************************************************************************
+ */
+void check_num_ref()
+{
+ if ((int)(dpb.ltref_frames_in_buffer + dpb.ref_frames_in_buffer ) > (imax(1,dpb.num_ref_frames)))
+ {
+ error ("Max. number of reference frames exceeded. Invalid stream.", 500);
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocate memory for decoded picture buffer and initialize with sane values.
+ *
+ ************************************************************************
+ */
+void init_dpb()
+{
+ unsigned i,j;
+
+ if (dpb.init_done)
+ {
+ free_dpb();
+ }
+
+ dpb.size = getDpbSize();
+
+ dpb.num_ref_frames = active_sps->num_ref_frames;
+
+ if (dpb.size < active_sps->num_ref_frames)
+ {
+ error ("DPB size at specified level is smaller than the specified number of reference frames. This is not allowed.\n", 1000);
+ }
+
+ dpb.used_size = 0;
+ dpb.last_picture = NULL;
+
+ dpb.ref_frames_in_buffer = 0;
+ dpb.ltref_frames_in_buffer = 0;
+
+ dpb.fs = calloc(dpb.size, sizeof (FrameStore*));
+ if (NULL==dpb.fs)
+ no_mem_exit("init_dpb: dpb->fs");
+
+ dpb.fs_ref = calloc(dpb.size, sizeof (FrameStore*));
+ if (NULL==dpb.fs_ref)
+ no_mem_exit("init_dpb: dpb->fs_ref");
+
+ dpb.fs_ltref = calloc(dpb.size, sizeof (FrameStore*));
+ if (NULL==dpb.fs_ltref)
+ no_mem_exit("init_dpb: dpb->fs_ltref");
+
+ for (i=0; i<dpb.size; i++)
+ {
+ dpb.fs[i] = alloc_frame_store();
+ dpb.fs_ref[i] = NULL;
+ dpb.fs_ltref[i] = NULL;
+ }
+
+ for (i=0; i<6; i++)
+ {
+ listX[i] = calloc(MAX_LIST_SIZE, sizeof (StorablePicture*)); // +1 for reordering
+ if (NULL==listX[i])
+ no_mem_exit("init_dpb: listX[i]");
+ }
+
+ /* allocate a dummy storable picture */
+ no_reference_picture = alloc_storable_picture (FRAME, img->width, img->height, img->width_cr, img->height_cr);
+ no_reference_picture->top_field = no_reference_picture;
+ no_reference_picture->bottom_field = no_reference_picture;
+ no_reference_picture->frame = no_reference_picture;
+
+
+ for (j=0;j<6;j++)
+ {
+ for (i=0; i<MAX_LIST_SIZE; i++)
+ {
+ listX[j][i] = NULL;
+ }
+ listXsize[j]=0;
+ }
+
+ dpb.last_output_poc = INT_MIN;
+
+ img->last_has_mmco_5 = 0;
+
+ dpb.init_done = 1;
+
+ // picture error concealment
+ if(img->conceal_mode !=0)
+ last_out_fs = alloc_frame_store();
+}
+/*!
+ ************************************************************************
+ * \brief
+ * Free memory for decoded picture buffer.
+ ************************************************************************
+ */
+void free_dpb()
+{
+ unsigned i;
+ if (dpb.fs)
+ {
+ for (i=0; i<dpb.size; i++)
+ {
+ free_frame_store(dpb.fs[i]);
+ }
+ free (dpb.fs);
+ dpb.fs=NULL;
+ }
+ if (dpb.fs_ref)
+ {
+ free (dpb.fs_ref);
+ }
+ if (dpb.fs_ltref)
+ {
+ free (dpb.fs_ltref);
+ }
+ dpb.last_output_poc = INT_MIN;
+
+ for (i=0; i<6; i++)
+ if (listX[i])
+ {
+ free (listX[i]);
+ listX[i] = NULL;
+ }
+
+ dpb.init_done = 0;
+
+ // picture error concealment
+ if(img->conceal_mode != 0)
+ free_frame_store(last_out_fs);
+
+ free_storable_picture(no_reference_picture);
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocate memory for decoded picture buffer frame stores an initialize with sane values.
+ *
+ * \return
+ * the allocated FrameStore structure
+ ************************************************************************
+ */
+FrameStore* alloc_frame_store()
+{
+ FrameStore *f;
+
+ f = calloc (1, sizeof(FrameStore));
+ if (NULL==f)
+ no_mem_exit("alloc_frame_store: f");
+
+ f->is_used = 0;
+ f->is_reference = 0;
+ f->is_long_term = 0;
+ f->is_orig_reference = 0;
+
+ f->is_output = 0;
+
+ f->frame = NULL;;
+ f->top_field = NULL;
+ f->bottom_field = NULL;
+
+ return f;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocate memory for a stored picture.
+ *
+ * \param structure
+ * picture structure
+ * \param size_x
+ * horizontal luma size
+ * \param size_y
+ * vertical luma size
+ * \param size_x_cr
+ * horizontal chroma size
+ * \param size_y_cr
+ * vertical chroma size
+ *
+ * \return
+ * the allocated StorablePicture structure
+ ************************************************************************
+ */
+StorablePicture* alloc_storable_picture(PictureStructure structure, int size_x, int size_y, int size_x_cr, int size_y_cr)
+{
+ StorablePicture *s;
+
+ //printf ("Allocating (%s) picture (x=%d, y=%d, x_cr=%d, y_cr=%d)\n", (type == FRAME)?"FRAME":(type == TOP_FIELD)?"TOP_FIELD":"BOTTOM_FIELD", size_x, size_y, size_x_cr, size_y_cr);
+
+ s = calloc (1, sizeof(StorablePicture));
+ if (NULL==s)
+ no_mem_exit("alloc_storable_picture: s");
+
+ if (structure!=FRAME)
+ {
+ size_y /= 2;
+ size_y_cr /= 2;
+ }
+
+ s->PicSizeInMbs = (size_x*size_y)/256;
+ s->imgUV = NULL;
+
+ get_mem2Dpel (&(s->imgY), size_y, size_x);
+ if (active_sps->chroma_format_idc != YUV400)
+ get_mem3Dpel (&(s->imgUV), 2, size_y_cr, size_x_cr);
+
+ s->mb_field = calloc (s->PicSizeInMbs, sizeof(int));
+ if (NULL==s->mb_field)
+ no_mem_exit("alloc_storable_picture: s->mb_field");
+
+ get_mem2Dshort (&(s->slice_id), size_y / MB_BLOCK_SIZE, size_x / MB_BLOCK_SIZE);
+
+ get_mem3D ((byte****)(&(s->ref_idx)) , 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
+ get_mem3Dint64 (&(s->ref_pic_id), 6, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
+ get_mem3Dint64 (&(s->ref_id) , 6, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
+ get_mem4Dshort (&(s->mv) , 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE, 2);
+
+ get_mem2D (&(s->moving_block), size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
+ get_mem2D (&(s->field_frame) , size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
+
+ s->pic_num=0;
+ s->frame_num=0;
+ s->long_term_frame_idx=0;
+ s->long_term_pic_num=0;
+ s->used_for_reference=0;
+ s->is_long_term=0;
+ s->non_existing=0;
+ s->is_output = 0;
+ s->max_slice_id = 0;
+
+ s->structure=structure;
+
+ s->size_x = size_x;
+ s->size_y = size_y;
+ s->size_x_cr = size_x_cr;
+ s->size_y_cr = size_y_cr;
+ s->size_x_m1 = size_x - 1;
+ s->size_y_m1 = size_y - 1;
+ s->size_x_cr_m1 = size_x_cr - 1;
+ s->size_y_cr_m1 = size_y_cr - 1;
+
+// s->top_field = NULL;
+// s->bottom_field = NULL;
+// s->frame = NULL;
+ s->top_field = no_reference_picture;
+ s->bottom_field = no_reference_picture;
+ s->frame = no_reference_picture;
+
+ s->dec_ref_pic_marking_buffer = NULL;
+
+ s->coded_frame = 0;
+ s->MbaffFrameFlag = 0;
+
+ s->top_poc = s->bottom_poc = s->poc = 0;
+
+ return s;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Free frame store memory.
+ *
+ * \param f
+ * FrameStore to be freed
+ *
+ ************************************************************************
+ */
+void free_frame_store(FrameStore* f)
+{
+ if (f)
+ {
+ if (f->frame)
+ {
+ free_storable_picture(f->frame);
+ f->frame=NULL;
+ }
+ if (f->top_field)
+ {
+ free_storable_picture(f->top_field);
+ f->top_field=NULL;
+ }
+ if (f->bottom_field)
+ {
+ free_storable_picture(f->bottom_field);
+ f->bottom_field=NULL;
+ }
+ free(f);
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Free picture memory.
+ *
+ * \param p
+ * Picture to be freed
+ *
+ ************************************************************************
+ */
+void free_storable_picture(StorablePicture* p)
+{
+ if (p)
+ {
+ if (p->ref_idx)
+ {
+ free_mem3D ((byte***)p->ref_idx, 2);
+ p->ref_idx = NULL;
+ }
+
+ if (p->ref_pic_id)
+ {
+ free_mem3Dint64 (p->ref_pic_id, 6);
+ p->ref_pic_id = NULL;
+ }
+ if (p->ref_id)
+ {
+ free_mem3Dint64 (p->ref_id, 6);
+ p->ref_id = NULL;
+ }
+ if (p->mv)
+ {
+ free_mem4Dshort (p->mv, 2, p->size_y / BLOCK_SIZE);
+ p->mv = NULL;
+ }
+
+ if (p->moving_block)
+ {
+ free_mem2D (p->moving_block);
+ p->moving_block=NULL;
+ }
+
+ if (p->field_frame)
+ {
+ free_mem2D (p->field_frame);
+ p->field_frame=NULL;
+ }
+
+
+ if (p->imgY)
+ {
+ free_mem2Dpel (p->imgY);
+ p->imgY=NULL;
+ }
+ if (p->imgUV)
+ {
+ free_mem3Dpel (p->imgUV, 2);
+ p->imgUV=NULL;
+ }
+
+ if (p->mb_field)
+ {
+ free(p->mb_field);
+ p->mb_field=NULL;
+ }
+
+ if (p->slice_id)
+ {
+ free_mem2Dshort(p->slice_id);
+ p->slice_id=NULL;
+ }
+
+ free(p);
+ p = NULL;
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * mark FrameStore unused for reference
+ *
+ ************************************************************************
+ */
+static void unmark_for_reference(FrameStore* fs)
+{
+
+ if (fs->is_used & 1)
+ {
+ if (fs->top_field)
+ {
+ fs->top_field->used_for_reference = 0;
+ }
+ }
+ if (fs->is_used & 2)
+ {
+ if (fs->bottom_field)
+ {
+ fs->bottom_field->used_for_reference = 0;
+ }
+ }
+ if (fs->is_used == 3)
+ {
+ if (fs->top_field && fs->bottom_field)
+ {
+ fs->top_field->used_for_reference = 0;
+ fs->bottom_field->used_for_reference = 0;
+ }
+ fs->frame->used_for_reference = 0;
+ }
+
+ fs->is_reference = 0;
+
+ if(fs->frame)
+ {
+ if (fs->frame->ref_pic_id)
+ {
+ free_mem3Dint64 (fs->frame->ref_pic_id, 6);
+ fs->frame->ref_pic_id = NULL;
+ }
+ if (fs->frame->ref_id)
+ {
+ free_mem3Dint64 (fs->frame->ref_id, 6);
+ fs->frame->ref_id = NULL;
+ }
+ }
+
+ if (fs->top_field)
+ {
+ if (fs->top_field->ref_pic_id)
+ {
+ free_mem3Dint64 (fs->top_field->ref_pic_id, 6);
+ fs->top_field->ref_pic_id = NULL;
+ }
+ if (fs->top_field->ref_id)
+ {
+ free_mem3Dint64 (fs->top_field->ref_id, 6);
+ fs->top_field->ref_id = NULL;
+ }
+
+ }
+ if (fs->bottom_field)
+ {
+ if (fs->bottom_field->ref_pic_id)
+ {
+ free_mem3Dint64 (fs->bottom_field->ref_pic_id, 6);
+ fs->bottom_field->ref_pic_id = NULL;
+ }
+ if (fs->bottom_field->ref_id)
+ {
+ free_mem3Dint64 (fs->bottom_field->ref_id, 6);
+ fs->bottom_field->ref_id = NULL;
+ }
+ }
+
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * mark FrameStore unused for reference and reset long term flags
+ *
+ ************************************************************************
+ */
+static void unmark_for_long_term_reference(FrameStore* fs)
+{
+
+ if (fs->is_used & 1)
+ {
+ if (fs->top_field)
+ {
+ fs->top_field->used_for_reference = 0;
+ fs->top_field->is_long_term = 0;
+ }
+ }
+ if (fs->is_used & 2)
+ {
+ if (fs->bottom_field)
+ {
+ fs->bottom_field->used_for_reference = 0;
+ fs->bottom_field->is_long_term = 0;
+ }
+ }
+ if (fs->is_used == 3)
+ {
+ if (fs->top_field && fs->bottom_field)
+ {
+ fs->top_field->used_for_reference = 0;
+ fs->top_field->is_long_term = 0;
+ fs->bottom_field->used_for_reference = 0;
+ fs->bottom_field->is_long_term = 0;
+ }
+ fs->frame->used_for_reference = 0;
+ fs->frame->is_long_term = 0;
+ }
+
+ fs->is_reference = 0;
+ fs->is_long_term = 0;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * compares two stored pictures by picture number for qsort in descending order
+ *
+ ************************************************************************
+ */
+static int compare_pic_by_pic_num_desc( const void *arg1, const void *arg2 )
+{
+ if ( (*(StorablePicture**)arg1)->pic_num < (*(StorablePicture**)arg2)->pic_num)
+ return 1;
+ if ( (*(StorablePicture**)arg1)->pic_num > (*(StorablePicture**)arg2)->pic_num)
+ return -1;
+ else
+ return 0;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * compares two stored pictures by picture number for qsort in descending order
+ *
+ ************************************************************************
+ */
+static int compare_pic_by_lt_pic_num_asc( const void *arg1, const void *arg2 )
+{
+ if ( (*(StorablePicture**)arg1)->long_term_pic_num < (*(StorablePicture**)arg2)->long_term_pic_num)
+ return -1;
+ if ( (*(StorablePicture**)arg1)->long_term_pic_num > (*(StorablePicture**)arg2)->long_term_pic_num)
+ return 1;
+ else
+ return 0;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * compares two frame stores by pic_num for qsort in descending order
+ *
+ ************************************************************************
+ */
+static int compare_fs_by_frame_num_desc( const void *arg1, const void *arg2 )
+{
+ if ( (*(FrameStore**)arg1)->frame_num_wrap < (*(FrameStore**)arg2)->frame_num_wrap)
+ return 1;
+ if ( (*(FrameStore**)arg1)->frame_num_wrap > (*(FrameStore**)arg2)->frame_num_wrap)
+ return -1;
+ else
+ return 0;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * compares two frame stores by lt_pic_num for qsort in descending order
+ *
+ ************************************************************************
+ */
+static int compare_fs_by_lt_pic_idx_asc( const void *arg1, const void *arg2 )
+{
+ if ( (*(FrameStore**)arg1)->long_term_frame_idx < (*(FrameStore**)arg2)->long_term_frame_idx)
+ return -1;
+ if ( (*(FrameStore**)arg1)->long_term_frame_idx > (*(FrameStore**)arg2)->long_term_frame_idx)
+ return 1;
+ else
+ return 0;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * compares two stored pictures by poc for qsort in ascending order
+ *
+ ************************************************************************
+ */
+static int compare_pic_by_poc_asc( const void *arg1, const void *arg2 )
+{
+ if ( (*(StorablePicture**)arg1)->poc < (*(StorablePicture**)arg2)->poc)
+ return -1;
+ if ( (*(StorablePicture**)arg1)->poc > (*(StorablePicture**)arg2)->poc)
+ return 1;
+ else
+ return 0;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * compares two stored pictures by poc for qsort in descending order
+ *
+ ************************************************************************
+ */
+static int compare_pic_by_poc_desc( const void *arg1, const void *arg2 )
+{
+ if ( (*(StorablePicture**)arg1)->poc < (*(StorablePicture**)arg2)->poc)
+ return 1;
+ if ( (*(StorablePicture**)arg1)->poc > (*(StorablePicture**)arg2)->poc)
+ return -1;
+ else
+ return 0;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * compares two frame stores by poc for qsort in ascending order
+ *
+ ************************************************************************
+ */
+static int compare_fs_by_poc_asc( const void *arg1, const void *arg2 )
+{
+ if ( (*(FrameStore**)arg1)->poc < (*(FrameStore**)arg2)->poc)
+ return -1;
+ if ( (*(FrameStore**)arg1)->poc > (*(FrameStore**)arg2)->poc)
+ return 1;
+ else
+ return 0;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * compares two frame stores by poc for qsort in descending order
+ *
+ ************************************************************************
+ */
+static int compare_fs_by_poc_desc( const void *arg1, const void *arg2 )
+{
+ if ( (*(FrameStore**)arg1)->poc < (*(FrameStore**)arg2)->poc)
+ return 1;
+ if ( (*(FrameStore**)arg1)->poc > (*(FrameStore**)arg2)->poc)
+ return -1;
+ else
+ return 0;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * returns true, if picture is short term reference picture
+ *
+ ************************************************************************
+ */
+int is_short_ref(StorablePicture *s)
+{
+ return ((s->used_for_reference) && (!(s->is_long_term)));
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * returns true, if picture is long term reference picture
+ *
+ ************************************************************************
+ */
+int is_long_ref(StorablePicture *s)
+{
+ return ((s->used_for_reference) && (s->is_long_term));
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Generates a alternating field list from a given FrameStore list
+ *
+ ************************************************************************
+ */
+static void gen_pic_list_from_frame_list(PictureStructure currStrcture, FrameStore **fs_list, int list_idx, StorablePicture **list, int *list_size, int long_term)
+{
+ int top_idx = 0;
+ int bot_idx = 0;
+
+ int (*is_ref)(StorablePicture *s);
+
+ if (long_term)
+ is_ref=is_long_ref;
+ else
+ is_ref=is_short_ref;
+
+ if (currStrcture == TOP_FIELD)
+ {
+ while ((top_idx<list_idx)||(bot_idx<list_idx))
+ {
+ for ( ; top_idx<list_idx; top_idx++)
+ {
+ if(fs_list[top_idx]->is_used & 1)
+ {
+ if(is_ref(fs_list[top_idx]->top_field))
+ {
+ // short term ref pic
+ list[*list_size] = fs_list[top_idx]->top_field;
+ (*list_size)++;
+ top_idx++;
+ break;
+ }
+ }
+ }
+ for ( ; bot_idx<list_idx; bot_idx++)
+ {
+ if(fs_list[bot_idx]->is_used & 2)
+ {
+ if(is_ref(fs_list[bot_idx]->bottom_field))
+ {
+ // short term ref pic
+ list[*list_size] = fs_list[bot_idx]->bottom_field;
+ (*list_size)++;
+ bot_idx++;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (currStrcture == BOTTOM_FIELD)
+ {
+ while ((top_idx<list_idx)||(bot_idx<list_idx))
+ {
+ for ( ; bot_idx<list_idx; bot_idx++)
+ {
+ if(fs_list[bot_idx]->is_used & 2)
+ {
+ if(is_ref(fs_list[bot_idx]->bottom_field))
+ {
+ // short term ref pic
+ list[*list_size] = fs_list[bot_idx]->bottom_field;
+ (*list_size)++;
+ bot_idx++;
+ break;
+ }
+ }
+ }
+ for ( ; top_idx<list_idx; top_idx++)
+ {
+ if(fs_list[top_idx]->is_used & 1)
+ {
+ if(is_ref(fs_list[top_idx]->top_field))
+ {
+ // short term ref pic
+ list[*list_size] = fs_list[top_idx]->top_field;
+ (*list_size)++;
+ top_idx++;
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Initialize listX[0] and list 1 depending on current picture type
+ *
+ ************************************************************************
+ */
+void init_lists(int currSliceType, PictureStructure currPicStructure)
+{
+ int add_top = 0, add_bottom = 0;
+ unsigned i;
+ int j;
+ int MaxFrameNum = 1 << (active_sps->log2_max_frame_num_minus4 + 4);
+ int diff;
+
+ int list0idx = 0;
+ int list0idx_1 = 0;
+ int listltidx = 0;
+
+ FrameStore **fs_list0;
+ FrameStore **fs_list1;
+ FrameStore **fs_listlt;
+
+ StorablePicture *tmp_s;
+
+ if (currPicStructure == FRAME)
+ {
+ for (i=0; i<dpb.ref_frames_in_buffer; i++)
+ {
+ if (dpb.fs_ref[i]->is_used==3)
+ {
+ if ((dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
+ {
+ if( dpb.fs_ref[i]->frame_num > img->frame_num )
+ {
+ dpb.fs_ref[i]->frame_num_wrap = dpb.fs_ref[i]->frame_num - MaxFrameNum;
+ }
+ else
+ {
+ dpb.fs_ref[i]->frame_num_wrap = dpb.fs_ref[i]->frame_num;
+ }
+ dpb.fs_ref[i]->frame->pic_num = dpb.fs_ref[i]->frame_num_wrap;
+ }
+ }
+ }
+ // update long_term_pic_num
+ for (i=0; i<dpb.ltref_frames_in_buffer; i++)
+ {
+ if (dpb.fs_ltref[i]->is_used==3)
+ {
+ if (dpb.fs_ltref[i]->frame->is_long_term)
+ {
+ dpb.fs_ltref[i]->frame->long_term_pic_num = dpb.fs_ltref[i]->frame->long_term_frame_idx;
+ }
+ }
+ }
+ }
+ else
+ {
+ if (currPicStructure == TOP_FIELD)
+ {
+ add_top = 1;
+ add_bottom = 0;
+ }
+ else
+ {
+ add_top = 0;
+ add_bottom = 1;
+ }
+
+ for (i=0; i<dpb.ref_frames_in_buffer; i++)
+ {
+ if (dpb.fs_ref[i]->is_reference)
+ {
+ if( dpb.fs_ref[i]->frame_num > img->frame_num )
+ {
+ dpb.fs_ref[i]->frame_num_wrap = dpb.fs_ref[i]->frame_num - MaxFrameNum;
+ }
+ else
+ {
+ dpb.fs_ref[i]->frame_num_wrap = dpb.fs_ref[i]->frame_num;
+ }
+ if (dpb.fs_ref[i]->is_reference & 1)
+ {
+ dpb.fs_ref[i]->top_field->pic_num = (2 * dpb.fs_ref[i]->frame_num_wrap) + add_top;
+ }
+ if (dpb.fs_ref[i]->is_reference & 2)
+ {
+ dpb.fs_ref[i]->bottom_field->pic_num = (2 * dpb.fs_ref[i]->frame_num_wrap) + add_bottom;
+ }
+ }
+ }
+ // update long_term_pic_num
+ for (i=0; i<dpb.ltref_frames_in_buffer; i++)
+ {
+ if (dpb.fs_ltref[i]->is_long_term & 1)
+ {
+ dpb.fs_ltref[i]->top_field->long_term_pic_num = 2 * dpb.fs_ltref[i]->top_field->long_term_frame_idx + add_top;
+ }
+ if (dpb.fs_ltref[i]->is_long_term & 2)
+ {
+ dpb.fs_ltref[i]->bottom_field->long_term_pic_num = 2 * dpb.fs_ltref[i]->bottom_field->long_term_frame_idx + add_bottom;
+ }
+ }
+ }
+
+
+
+ if ((currSliceType == I_SLICE)||(currSliceType == SI_SLICE))
+ {
+ listXsize[0] = 0;
+ listXsize[1] = 0;
+ return;
+ }
+
+ if ((currSliceType == P_SLICE)||(currSliceType == SP_SLICE))
+ {
+ // Calculate FrameNumWrap and PicNum
+ if (currPicStructure == FRAME)
+ {
+ for (i=0; i<dpb.ref_frames_in_buffer; i++)
+ {
+ if (dpb.fs_ref[i]->is_used==3)
+ {
+ if ((dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
+ {
+ listX[0][list0idx++] = dpb.fs_ref[i]->frame;
+ }
+ }
+ }
+ // order list 0 by PicNum
+ qsort((void *)listX[0], list0idx, sizeof(StorablePicture*), compare_pic_by_pic_num_desc);
+ listXsize[0] = list0idx;
+// printf("listX[0] (PicNum): "); for (i=0; i<list0idx; i++){printf ("%d ", listX[0][i]->pic_num);} printf("\n");
+
+ // long term handling
+ for (i=0; i<dpb.ltref_frames_in_buffer; i++)
+ {
+ if (dpb.fs_ltref[i]->is_used==3)
+ {
+ if (dpb.fs_ltref[i]->frame->is_long_term)
+ {
+ listX[0][list0idx++]=dpb.fs_ltref[i]->frame;
+ }
+ }
+ }
+ qsort((void *)&listX[0][listXsize[0]], list0idx-listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
+ listXsize[0] = list0idx;
+ }
+ else
+ {
+ fs_list0 = calloc(dpb.size, sizeof (FrameStore*));
+ if (NULL==fs_list0)
+ no_mem_exit("init_lists: fs_list0");
+ fs_listlt = calloc(dpb.size, sizeof (FrameStore*));
+ if (NULL==fs_listlt)
+ no_mem_exit("init_lists: fs_listlt");
+
+ for (i=0; i<dpb.ref_frames_in_buffer; i++)
+ {
+ if (dpb.fs_ref[i]->is_reference)
+ {
+ fs_list0[list0idx++] = dpb.fs_ref[i];
+ }
+ }
+
+ qsort((void *)fs_list0, list0idx, sizeof(FrameStore*), compare_fs_by_frame_num_desc);
+
+// printf("fs_list0 (FrameNum): "); for (i=0; i<list0idx; i++){printf ("%d ", fs_list0[i]->frame_num_wrap);} printf("\n");
+
+ listXsize[0] = 0;
+ gen_pic_list_from_frame_list(currPicStructure, fs_list0, list0idx, listX[0], &listXsize[0], 0);
+
+// printf("listX[0] (PicNum): "); for (i=0; i<listXsize[0]; i++){printf ("%d ", listX[0][i]->pic_num);} printf("\n");
+
+ // long term handling
+ for (i=0; i<dpb.ltref_frames_in_buffer; i++)
+ {
+ fs_listlt[listltidx++]=dpb.fs_ltref[i];
+ }
+
+ qsort((void *)fs_listlt, listltidx, sizeof(FrameStore*), compare_fs_by_lt_pic_idx_asc);
+
+ gen_pic_list_from_frame_list(currPicStructure, fs_listlt, listltidx, listX[0], &listXsize[0], 1);
+
+ free(fs_list0);
+ free(fs_listlt);
+ }
+ listXsize[1] = 0;
+ }
+ else
+ {
+ // B-Slice
+ if (currPicStructure == FRAME)
+ {
+ for (i=0; i<dpb.ref_frames_in_buffer; i++)
+ {
+ if (dpb.fs_ref[i]->is_used==3)
+ {
+ if ((dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
+ {
+ if (img->framepoc >= dpb.fs_ref[i]->frame->poc) //!KS use >= for error concealment
+// if (img->framepoc > dpb.fs_ref[i]->frame->poc)
+ {
+ listX[0][list0idx++] = dpb.fs_ref[i]->frame;
+ }
+ }
+ }
+ }
+ qsort((void *)listX[0], list0idx, sizeof(StorablePicture*), compare_pic_by_poc_desc);
+ list0idx_1 = list0idx;
+ for (i=0; i<dpb.ref_frames_in_buffer; i++)
+ {
+ if (dpb.fs_ref[i]->is_used==3)
+ {
+ if ((dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
+ {
+ if (img->framepoc < dpb.fs_ref[i]->frame->poc)
+ {
+ listX[0][list0idx++] = dpb.fs_ref[i]->frame;
+ }
+ }
+ }
+ }
+ qsort((void *)&listX[0][list0idx_1], list0idx-list0idx_1, sizeof(StorablePicture*), compare_pic_by_poc_asc);
+
+ for (j=0; j<list0idx_1; j++)
+ {
+ listX[1][list0idx-list0idx_1+j]=listX[0][j];
+ }
+ for (j=list0idx_1; j<list0idx; j++)
+ {
+ listX[1][j-list0idx_1]=listX[0][j];
+ }
+
+ listXsize[0] = listXsize[1] = list0idx;
+
+// printf("listX[0] currPoc=%d (Poc): ", img->framepoc); for (i=0; i<listXsize[0]; i++){printf ("%d ", listX[0][i]->poc);} printf("\n");
+// printf("listX[1] currPoc=%d (Poc): ", img->framepoc); for (i=0; i<listXsize[1]; i++){printf ("%d ", listX[1][i]->poc);} printf("\n");
+
+ // long term handling
+ for (i=0; i<dpb.ltref_frames_in_buffer; i++)
+ {
+ if (dpb.fs_ltref[i]->is_used==3)
+ {
+ if (dpb.fs_ltref[i]->frame->is_long_term)
+ {
+ listX[0][list0idx] =dpb.fs_ltref[i]->frame;
+ listX[1][list0idx++]=dpb.fs_ltref[i]->frame;
+ }
+ }
+ }
+ qsort((void *)&listX[0][listXsize[0]], list0idx-listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
+ qsort((void *)&listX[1][listXsize[0]], list0idx-listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
+ listXsize[0] = listXsize[1] = list0idx;
+ }
+ else
+ {
+ fs_list0 = calloc(dpb.size, sizeof (FrameStore*));
+ if (NULL==fs_list0)
+ no_mem_exit("init_lists: fs_list0");
+ fs_list1 = calloc(dpb.size, sizeof (FrameStore*));
+ if (NULL==fs_list1)
+ no_mem_exit("init_lists: fs_list1");
+ fs_listlt = calloc(dpb.size, sizeof (FrameStore*));
+ if (NULL==fs_listlt)
+ no_mem_exit("init_lists: fs_listlt");
+
+ listXsize[0] = 0;
+ listXsize[1] = 1;
+
+ for (i=0; i<dpb.ref_frames_in_buffer; i++)
+ {
+ if (dpb.fs_ref[i]->is_used)
+ {
+ if (img->ThisPOC >= dpb.fs_ref[i]->poc)
+ {
+ fs_list0[list0idx++] = dpb.fs_ref[i];
+ }
+ }
+ }
+ qsort((void *)fs_list0, list0idx, sizeof(FrameStore*), compare_fs_by_poc_desc);
+ list0idx_1 = list0idx;
+ for (i=0; i<dpb.ref_frames_in_buffer; i++)
+ {
+ if (dpb.fs_ref[i]->is_used)
+ {
+ if (img->ThisPOC < dpb.fs_ref[i]->poc)
+ {
+ fs_list0[list0idx++] = dpb.fs_ref[i];
+ }
+ }
+ }
+ qsort((void *)&fs_list0[list0idx_1], list0idx-list0idx_1, sizeof(FrameStore*), compare_fs_by_poc_asc);
+
+ for (j=0; j<list0idx_1; j++)
+ {
+ fs_list1[list0idx-list0idx_1+j]=fs_list0[j];
+ }
+ for (j=list0idx_1; j<list0idx; j++)
+ {
+ fs_list1[j-list0idx_1]=fs_list0[j];
+ }
+
+// printf("fs_list0 currPoc=%d (Poc): ", img->ThisPOC); for (i=0; i<list0idx; i++){printf ("%d ", fs_list0[i]->poc);} printf("\n");
+// printf("fs_list1 currPoc=%d (Poc): ", img->ThisPOC); for (i=0; i<list0idx; i++){printf ("%d ", fs_list1[i]->poc);} printf("\n");
+
+ listXsize[0] = 0;
+ listXsize[1] = 0;
+ gen_pic_list_from_frame_list(currPicStructure, fs_list0, list0idx, listX[0], &listXsize[0], 0);
+ gen_pic_list_from_frame_list(currPicStructure, fs_list1, list0idx, listX[1], &listXsize[1], 0);
+
+// printf("listX[0] currPoc=%d (Poc): ", img->framepoc); for (i=0; i<listXsize[0]; i++){printf ("%d ", listX[0][i]->poc);} printf("\n");
+// printf("listX[1] currPoc=%d (Poc): ", img->framepoc); for (i=0; i<listXsize[1]; i++){printf ("%d ", listX[1][i]->poc);} printf("\n");
+
+ // long term handling
+ for (i=0; i<dpb.ltref_frames_in_buffer; i++)
+ {
+ fs_listlt[listltidx++]=dpb.fs_ltref[i];
+ }
+
+ qsort((void *)fs_listlt, listltidx, sizeof(FrameStore*), compare_fs_by_lt_pic_idx_asc);
+
+ gen_pic_list_from_frame_list(currPicStructure, fs_listlt, listltidx, listX[0], &listXsize[0], 1);
+ gen_pic_list_from_frame_list(currPicStructure, fs_listlt, listltidx, listX[1], &listXsize[1], 1);
+
+ free(fs_list0);
+ free(fs_list1);
+ free(fs_listlt);
+ }
+ }
+
+ if ((listXsize[0] == listXsize[1]) && (listXsize[0] > 1))
+ {
+ // check if lists are identical, if yes swap first two elements of listX[1]
+ diff=0;
+ for (j = 0; j< listXsize[0]; j++)
+ {
+ if (listX[0][j]!=listX[1][j])
+ diff=1;
+ }
+ if (!diff)
+ {
+ tmp_s = listX[1][0];
+ listX[1][0]=listX[1][1];
+ listX[1][1]=tmp_s;
+ }
+ }
+ // set max size
+ listXsize[0] = imin (listXsize[0], img->num_ref_idx_l0_active);
+ listXsize[1] = imin (listXsize[1], img->num_ref_idx_l1_active);
+
+ // set the unused list entries to NULL
+ for (i=listXsize[0]; i< (MAX_LIST_SIZE) ; i++)
+ {
+// listX[0][i] = NULL;
+ listX[0][i] = no_reference_picture;
+
+ }
+ for (i=listXsize[1]; i< (MAX_LIST_SIZE) ; i++)
+ {
+// listX[1][i] = NULL;
+ listX[1][i] = no_reference_picture;
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Initialize listX[2..5] from lists 0 and 1
+ * listX[2]: list0 for current_field==top
+ * listX[3]: list1 for current_field==top
+ * listX[4]: list0 for current_field==bottom
+ * listX[5]: list1 for current_field==bottom
+ *
+ ************************************************************************
+ */
+void init_mbaff_lists()
+{
+ unsigned j;
+ int i;
+
+ for (i=2;i<6;i++)
+ {
+ for (j=0; j<MAX_LIST_SIZE; j++)
+ {
+// listX[i][j] = NULL;
+ listX[i][j] = no_reference_picture;
+ }
+ listXsize[i]=0;
+ }
+
+ for (i=0; i<listXsize[0]; i++)
+ {
+ listX[2][2*i] =listX[0][i]->top_field;
+ listX[2][2*i+1]=listX[0][i]->bottom_field;
+ listX[4][2*i] =listX[0][i]->bottom_field;
+ listX[4][2*i+1]=listX[0][i]->top_field;
+ }
+ listXsize[2]=listXsize[4]=listXsize[0] * 2;
+
+ for (i=0; i<listXsize[1]; i++)
+ {
+ listX[3][2*i] =listX[1][i]->top_field;
+ listX[3][2*i+1]=listX[1][i]->bottom_field;
+ listX[5][2*i] =listX[1][i]->bottom_field;
+ listX[5][2*i+1]=listX[1][i]->top_field;
+ }
+ listXsize[3]=listXsize[5]=listXsize[1] * 2;
+}
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Returns short term pic with given picNum
+ *
+ ************************************************************************
+ */
+static StorablePicture* get_short_term_pic(int picNum)
+{
+ unsigned i;
+
+ for (i=0; i<dpb.ref_frames_in_buffer; i++)
+ {
+ if (img->structure==FRAME)
+ {
+ if (dpb.fs_ref[i]->is_reference == 3)
+ if ((!dpb.fs_ref[i]->frame->is_long_term)&&(dpb.fs_ref[i]->frame->pic_num == picNum))
+ return dpb.fs_ref[i]->frame;
+ }
+ else
+ {
+ if (dpb.fs_ref[i]->is_reference & 1)
+ if ((!dpb.fs_ref[i]->top_field->is_long_term)&&(dpb.fs_ref[i]->top_field->pic_num == picNum))
+ return dpb.fs_ref[i]->top_field;
+ if (dpb.fs_ref[i]->is_reference & 2)
+ if ((!dpb.fs_ref[i]->bottom_field->is_long_term)&&(dpb.fs_ref[i]->bottom_field->pic_num == picNum))
+ return dpb.fs_ref[i]->bottom_field;
+ }
+ }
+// return NULL;
+ return no_reference_picture;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Returns short term pic with given LongtermPicNum
+ *
+ ************************************************************************
+ */
+static StorablePicture* get_long_term_pic(int LongtermPicNum)
+{
+ unsigned i;
+
+ for (i=0; i<dpb.ltref_frames_in_buffer; i++)
+ {
+ if (img->structure==FRAME)
+ {
+ if (dpb.fs_ltref[i]->is_reference == 3)
+ if ((dpb.fs_ltref[i]->frame->is_long_term)&&(dpb.fs_ltref[i]->frame->long_term_pic_num == LongtermPicNum))
+ return dpb.fs_ltref[i]->frame;
+ }
+ else
+ {
+ if (dpb.fs_ltref[i]->is_reference & 1)
+ if ((dpb.fs_ltref[i]->top_field->is_long_term)&&(dpb.fs_ltref[i]->top_field->long_term_pic_num == LongtermPicNum))
+ return dpb.fs_ltref[i]->top_field;
+ if (dpb.fs_ltref[i]->is_reference & 2)
+ if ((dpb.fs_ltref[i]->bottom_field->is_long_term)&&(dpb.fs_ltref[i]->bottom_field->long_term_pic_num == LongtermPicNum))
+ return dpb.fs_ltref[i]->bottom_field;
+ }
+ }
+ return NULL;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Reordering process for short-term reference pictures
+ *
+ ************************************************************************
+ */
+static void reorder_short_term(StorablePicture **RefPicListX, int num_ref_idx_lX_active_minus1, int picNumLX, int *refIdxLX)
+{
+ int cIdx, nIdx;
+
+ StorablePicture *picLX;
+
+ picLX = get_short_term_pic(picNumLX);
+
+ for( cIdx = num_ref_idx_lX_active_minus1+1; cIdx > *refIdxLX; cIdx-- )
+ RefPicListX[ cIdx ] = RefPicListX[ cIdx - 1];
+
+ RefPicListX[ (*refIdxLX)++ ] = picLX;
+
+ nIdx = *refIdxLX;
+
+ for( cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1+1; cIdx++ )
+ if (RefPicListX[ cIdx ])
+ if( (RefPicListX[ cIdx ]->is_long_term ) || (RefPicListX[ cIdx ]->pic_num != picNumLX ))
+ RefPicListX[ nIdx++ ] = RefPicListX[ cIdx ];
+
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Reordering process for short-term reference pictures
+ *
+ ************************************************************************
+ */
+static void reorder_long_term(StorablePicture **RefPicListX, int num_ref_idx_lX_active_minus1, int LongTermPicNum, int *refIdxLX)
+{
+ int cIdx, nIdx;
+
+ StorablePicture *picLX;
+
+ picLX = get_long_term_pic(LongTermPicNum);
+
+ for( cIdx = num_ref_idx_lX_active_minus1+1; cIdx > *refIdxLX; cIdx-- )
+ RefPicListX[ cIdx ] = RefPicListX[ cIdx - 1];
+
+ RefPicListX[ (*refIdxLX)++ ] = picLX;
+
+ nIdx = *refIdxLX;
+
+ for( cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1+1; cIdx++ )
+ if (RefPicListX[ cIdx ])
+ if( (!RefPicListX[ cIdx ]->is_long_term ) || (RefPicListX[ cIdx ]->long_term_pic_num != LongTermPicNum ))
+ RefPicListX[ nIdx++ ] = RefPicListX[ cIdx ];
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Reordering process for reference picture lists
+ *
+ ************************************************************************
+ */
+void reorder_ref_pic_list(StorablePicture **list, int *list_size, int num_ref_idx_lX_active_minus1, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx)
+{
+ int i;
+
+ int maxPicNum, currPicNum, picNumLXNoWrap, picNumLXPred, picNumLX;
+ int refIdxLX = 0;
+
+ if (img->structure==FRAME)
+ {
+ maxPicNum = img->MaxFrameNum;
+ currPicNum = img->frame_num;
+ }
+ else
+ {
+ maxPicNum = 2 * img->MaxFrameNum;
+ currPicNum = 2 * img->frame_num + 1;
+ }
+
+ picNumLXPred = currPicNum;
+
+ for (i=0; reordering_of_pic_nums_idc[i]!=3; i++)
+ {
+ if (reordering_of_pic_nums_idc[i]>3)
+ error ("Invalid remapping_of_pic_nums_idc command", 500);
+
+ if (reordering_of_pic_nums_idc[i] < 2)
+ {
+ if (reordering_of_pic_nums_idc[i] == 0)
+ {
+ if( picNumLXPred - ( abs_diff_pic_num_minus1[i] + 1 ) < 0 )
+ picNumLXNoWrap = picNumLXPred - ( abs_diff_pic_num_minus1[i] + 1 ) + maxPicNum;
+ else
+ picNumLXNoWrap = picNumLXPred - ( abs_diff_pic_num_minus1[i] + 1 );
+ }
+ else // (remapping_of_pic_nums_idc[i] == 1)
+ {
+ if( picNumLXPred + ( abs_diff_pic_num_minus1[i] + 1 ) >= maxPicNum )
+ picNumLXNoWrap = picNumLXPred + ( abs_diff_pic_num_minus1[i] + 1 ) - maxPicNum;
+ else
+ picNumLXNoWrap = picNumLXPred + ( abs_diff_pic_num_minus1[i] + 1 );
+ }
+ picNumLXPred = picNumLXNoWrap;
+
+ if( picNumLXNoWrap > currPicNum )
+ picNumLX = picNumLXNoWrap - maxPicNum;
+ else
+ picNumLX = picNumLXNoWrap;
+
+ reorder_short_term(list, num_ref_idx_lX_active_minus1, picNumLX, &refIdxLX);
+ }
+ else //(remapping_of_pic_nums_idc[i] == 2)
+ {
+ reorder_long_term(list, num_ref_idx_lX_active_minus1, long_term_pic_idx[i], &refIdxLX);
+ }
+
+ }
+ // that's a definition
+ *list_size = num_ref_idx_lX_active_minus1 + 1;
+}
+
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Update the list of frame stores that contain reference frames/fields
+ *
+ ************************************************************************
+ */
+void update_ref_list()
+{
+ unsigned i, j;
+ for (i=0, j=0; i<dpb.used_size; i++)
+ {
+ if (is_short_term_reference(dpb.fs[i]))
+ {
+ dpb.fs_ref[j++]=dpb.fs[i];
+ }
+ }
+
+ dpb.ref_frames_in_buffer = j;
+
+ while (j<dpb.size)
+ {
+ dpb.fs_ref[j++]=NULL;
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Update the list of frame stores that contain long-term reference
+ * frames/fields
+ *
+ ************************************************************************
+ */
+void update_ltref_list()
+{
+ unsigned i, j;
+ for (i=0, j=0; i<dpb.used_size; i++)
+ {
+ if (is_long_term_reference(dpb.fs[i]))
+ {
+ dpb.fs_ltref[j++]=dpb.fs[i];
+ }
+ }
+
+ dpb.ltref_frames_in_buffer=j;
+
+ while (j<dpb.size)
+ {
+ dpb.fs_ltref[j++]=NULL;
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Perform Memory management for idr pictures
+ *
+ ************************************************************************
+ */
+static void idr_memory_management(StorablePicture* p)
+{
+ unsigned i;
+
+ assert (p->idr_flag);
+
+ if (p->no_output_of_prior_pics_flag)
+ {
+ // free all stored pictures
+ for (i=0; i<dpb.used_size; i++)
+ {
+ // reset all reference settings
+ free_frame_store(dpb.fs[i]);
+ dpb.fs[i] = alloc_frame_store();
+ }
+ for (i=0; i<dpb.ref_frames_in_buffer; i++)
+ {
+ dpb.fs_ref[i]=NULL;
+ }
+ for (i=0; i<dpb.ltref_frames_in_buffer; i++)
+ {
+ dpb.fs_ltref[i]=NULL;
+ }
+ dpb.used_size=0;
+ }
+ else
+ {
+ flush_dpb();
+ }
+ dpb.last_picture = NULL;
+
+ update_ref_list();
+ update_ltref_list();
+ dpb.last_output_poc = INT_MIN;
+
+ if (p->long_term_reference_flag)
+ {
+ dpb.max_long_term_pic_idx = 0;
+ p->is_long_term = 1;
+ p->long_term_frame_idx = 0;
+ }
+ else
+ {
+ dpb.max_long_term_pic_idx = -1;
+ p->is_long_term = 0;
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Perform Sliding window decoded reference picture marking process
+ *
+ ************************************************************************
+ */
+static void sliding_window_memory_management(StorablePicture* p)
+{
+ unsigned i;
+
+ assert (!p->idr_flag);
+ // if this is a reference pic with sliding sliding window, unmark first ref frame
+ if (dpb.ref_frames_in_buffer==dpb.num_ref_frames - dpb.ltref_frames_in_buffer)
+ {
+ for (i=0; i<dpb.used_size;i++)
+ {
+ if (dpb.fs[i]->is_reference && (!(dpb.fs[i]->is_long_term)))
+ {
+ unmark_for_reference(dpb.fs[i]);
+ update_ref_list();
+ break;
+ }
+ }
+ }
+
+ p->is_long_term = 0;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Calculate picNumX
+ ************************************************************************
+ */
+static int get_pic_num_x (StorablePicture *p, int difference_of_pic_nums_minus1)
+{
+ int currPicNum;
+
+ if (p->structure == FRAME)
+ currPicNum = p->frame_num;
+ else
+ currPicNum = 2 * p->frame_num + 1;
+
+ return currPicNum - (difference_of_pic_nums_minus1 + 1);
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Adaptive Memory Management: Mark short term picture unused
+ ************************************************************************
+ */
+static void mm_unmark_short_term_for_reference(StorablePicture *p, int difference_of_pic_nums_minus1)
+{
+ int picNumX;
+
+ unsigned i;
+
+ picNumX = get_pic_num_x(p, difference_of_pic_nums_minus1);
+
+ for (i=0; i<dpb.ref_frames_in_buffer; i++)
+ {
+ if (p->structure == FRAME)
+ {
+ if ((dpb.fs_ref[i]->is_reference==3) && (dpb.fs_ref[i]->is_long_term==0))
+ {
+ if (dpb.fs_ref[i]->frame->pic_num == picNumX)
+ {
+ unmark_for_reference(dpb.fs_ref[i]);
+ return;
+ }
+ }
+ }
+ else
+ {
+ if ((dpb.fs_ref[i]->is_reference & 1) && (!(dpb.fs_ref[i]->is_long_term & 1)))
+ {
+ if (dpb.fs_ref[i]->top_field->pic_num == picNumX)
+ {
+ dpb.fs_ref[i]->top_field->used_for_reference = 0;
+ dpb.fs_ref[i]->is_reference &= 2;
+ if (dpb.fs_ref[i]->is_used == 3)
+ {
+ dpb.fs_ref[i]->frame->used_for_reference = 0;
+ }
+ return;
+ }
+ }
+ if ((dpb.fs_ref[i]->is_reference & 2) && (!(dpb.fs_ref[i]->is_long_term & 2)))
+ {
+ if (dpb.fs_ref[i]->bottom_field->pic_num == picNumX)
+ {
+ dpb.fs_ref[i]->bottom_field->used_for_reference = 0;
+ dpb.fs_ref[i]->is_reference &= 1;
+ if (dpb.fs_ref[i]->is_used == 3)
+ {
+ dpb.fs_ref[i]->frame->used_for_reference = 0;
+ }
+ return;
+ }
+ }
+ }
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Adaptive Memory Management: Mark long term picture unused
+ ************************************************************************
+ */
+static void mm_unmark_long_term_for_reference(StorablePicture *p, int long_term_pic_num)
+{
+ unsigned i;
+ for (i=0; i<dpb.ltref_frames_in_buffer; i++)
+ {
+ if (p->structure == FRAME)
+ {
+ if ((dpb.fs_ltref[i]->is_reference==3) && (dpb.fs_ltref[i]->is_long_term==3))
+ {
+ if (dpb.fs_ltref[i]->frame->long_term_pic_num == long_term_pic_num)
+ {
+ unmark_for_long_term_reference(dpb.fs_ltref[i]);
+ }
+ }
+ }
+ else
+ {
+ if ((dpb.fs_ltref[i]->is_reference & 1) && ((dpb.fs_ltref[i]->is_long_term & 1)))
+ {
+ if (dpb.fs_ltref[i]->top_field->long_term_pic_num == long_term_pic_num)
+ {
+ dpb.fs_ltref[i]->top_field->used_for_reference = 0;
+ dpb.fs_ltref[i]->top_field->is_long_term = 0;
+ dpb.fs_ltref[i]->is_reference &= 2;
+ dpb.fs_ltref[i]->is_long_term &= 2;
+ if (dpb.fs_ltref[i]->is_used == 3)
+ {
+ dpb.fs_ltref[i]->frame->used_for_reference = 0;
+ dpb.fs_ltref[i]->frame->is_long_term = 0;
+ }
+ return;
+ }
+ }
+ if ((dpb.fs_ltref[i]->is_reference & 2) && ((dpb.fs_ltref[i]->is_long_term & 2)))
+ {
+ if (dpb.fs_ltref[i]->bottom_field->long_term_pic_num == long_term_pic_num)
+ {
+ dpb.fs_ltref[i]->bottom_field->used_for_reference = 0;
+ dpb.fs_ltref[i]->bottom_field->is_long_term = 0;
+ dpb.fs_ltref[i]->is_reference &= 1;
+ dpb.fs_ltref[i]->is_long_term &= 1;
+ if (dpb.fs_ltref[i]->is_used == 3)
+ {
+ dpb.fs_ltref[i]->frame->used_for_reference = 0;
+ dpb.fs_ltref[i]->frame->is_long_term = 0;
+ }
+ return;
+ }
+ }
+ }
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Mark a long-term reference frame or complementary field pair unused for referemce
+ ************************************************************************
+ */
+static void unmark_long_term_frame_for_reference_by_frame_idx(int long_term_frame_idx)
+{
+ unsigned i;
+ for(i=0; i<dpb.ltref_frames_in_buffer; i++)
+ {
+ if (dpb.fs_ltref[i]->long_term_frame_idx == long_term_frame_idx)
+ unmark_for_long_term_reference(dpb.fs_ltref[i]);
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Mark a long-term reference field unused for reference only if it's not
+ * the complementary field of the picture indicated by picNumX
+ ************************************************************************
+ */
+static void unmark_long_term_field_for_reference_by_frame_idx(PictureStructure structure, int long_term_frame_idx, int mark_current, unsigned curr_frame_num, int curr_pic_num)
+{
+ unsigned i;
+
+ assert(structure!=FRAME);
+ if (curr_pic_num<0)
+ curr_pic_num+=(2*img->MaxFrameNum);
+
+ for(i=0; i<dpb.ltref_frames_in_buffer; i++)
+ {
+ if (dpb.fs_ltref[i]->long_term_frame_idx == long_term_frame_idx)
+ {
+ if (structure == TOP_FIELD)
+ {
+ if ((dpb.fs_ltref[i]->is_long_term == 3))
+ {
+ unmark_for_long_term_reference(dpb.fs_ltref[i]);
+ }
+ else
+ {
+ if ((dpb.fs_ltref[i]->is_long_term == 1))
+ {
+ unmark_for_long_term_reference(dpb.fs_ltref[i]);
+ }
+ else
+ {
+ if (mark_current)
+ {
+ if (dpb.last_picture)
+ {
+ if ( ( dpb.last_picture != dpb.fs_ltref[i] )|| dpb.last_picture->frame_num != curr_frame_num)
+ unmark_for_long_term_reference(dpb.fs_ltref[i]);
+ }
+ else
+ {
+ unmark_for_long_term_reference(dpb.fs_ltref[i]);
+ }
+ }
+ else
+ {
+ if ((dpb.fs_ltref[i]->frame_num) != (unsigned)(curr_pic_num/2))
+ {
+ unmark_for_long_term_reference(dpb.fs_ltref[i]);
+ }
+ }
+ }
+ }
+ }
+ if (structure == BOTTOM_FIELD)
+ {
+ if ((dpb.fs_ltref[i]->is_long_term == 3))
+ {
+ unmark_for_long_term_reference(dpb.fs_ltref[i]);
+ }
+ else
+ {
+ if ((dpb.fs_ltref[i]->is_long_term == 2))
+ {
+ unmark_for_long_term_reference(dpb.fs_ltref[i]);
+ }
+ else
+ {
+ if (mark_current)
+ {
+ if (dpb.last_picture)
+ {
+ if ( ( dpb.last_picture != dpb.fs_ltref[i] )|| dpb.last_picture->frame_num != curr_frame_num)
+ unmark_for_long_term_reference(dpb.fs_ltref[i]);
+ }
+ else
+ {
+ unmark_for_long_term_reference(dpb.fs_ltref[i]);
+ }
+ }
+ else
+ {
+ if ((dpb.fs_ltref[i]->frame_num) != (unsigned)(curr_pic_num/2))
+ {
+ unmark_for_long_term_reference(dpb.fs_ltref[i]);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * mark a picture as long-term reference
+ ************************************************************************
+ */
+static void mark_pic_long_term(StorablePicture* p, int long_term_frame_idx, int picNumX)
+{
+ unsigned i;
+ int add_top, add_bottom;
+
+ if (p->structure == FRAME)
+ {
+ for (i=0; i<dpb.ref_frames_in_buffer; i++)
+ {
+ if (dpb.fs_ref[i]->is_reference == 3)
+ {
+ if ((!dpb.fs_ref[i]->frame->is_long_term)&&(dpb.fs_ref[i]->frame->pic_num == picNumX))
+ {
+ dpb.fs_ref[i]->long_term_frame_idx = dpb.fs_ref[i]->frame->long_term_frame_idx
+ = long_term_frame_idx;
+ dpb.fs_ref[i]->frame->long_term_pic_num = long_term_frame_idx;
+ dpb.fs_ref[i]->frame->is_long_term = 1;
+
+ if (dpb.fs_ref[i]->top_field && dpb.fs_ref[i]->bottom_field)
+ {
+ dpb.fs_ref[i]->top_field->long_term_frame_idx = dpb.fs_ref[i]->bottom_field->long_term_frame_idx
+ = long_term_frame_idx;
+ dpb.fs_ref[i]->top_field->long_term_pic_num = long_term_frame_idx;
+ dpb.fs_ref[i]->bottom_field->long_term_pic_num = long_term_frame_idx;
+
+ dpb.fs_ref[i]->top_field->is_long_term = dpb.fs_ref[i]->bottom_field->is_long_term
+ = 1;
+
+ }
+ dpb.fs_ref[i]->is_long_term = 3;
+ return;
+ }
+ }
+ }
+ printf ("Warning: reference frame for long term marking not found\n");
+ }
+ else
+ {
+ if (p->structure == TOP_FIELD)
+ {
+ add_top = 1;
+ add_bottom = 0;
+ }
+ else
+ {
+ add_top = 0;
+ add_bottom = 1;
+ }
+ for (i=0; i<dpb.ref_frames_in_buffer; i++)
+ {
+ if (dpb.fs_ref[i]->is_reference & 1)
+ {
+ if ((!dpb.fs_ref[i]->top_field->is_long_term)&&(dpb.fs_ref[i]->top_field->pic_num == picNumX))
+ {
+ if ((dpb.fs_ref[i]->is_long_term) && (dpb.fs_ref[i]->long_term_frame_idx != long_term_frame_idx))
+ {
+ printf ("Warning: assigning long_term_frame_idx different from other field\n");
+ }
+
+ dpb.fs_ref[i]->long_term_frame_idx = dpb.fs_ref[i]->top_field->long_term_frame_idx
+ = long_term_frame_idx;
+ dpb.fs_ref[i]->top_field->long_term_pic_num = 2 * long_term_frame_idx + add_top;
+ dpb.fs_ref[i]->top_field->is_long_term = 1;
+ dpb.fs_ref[i]->is_long_term |= 1;
+ if (dpb.fs_ref[i]->is_long_term == 3)
+ {
+ dpb.fs_ref[i]->frame->is_long_term = 1;
+ dpb.fs_ref[i]->frame->long_term_frame_idx = dpb.fs_ref[i]->frame->long_term_pic_num = long_term_frame_idx;
+ }
+ return;
+ }
+ }
+ if (dpb.fs_ref[i]->is_reference & 2)
+ {
+ if ((!dpb.fs_ref[i]->bottom_field->is_long_term)&&(dpb.fs_ref[i]->bottom_field->pic_num == picNumX))
+ {
+ if ((dpb.fs_ref[i]->is_long_term) && (dpb.fs_ref[i]->long_term_frame_idx != long_term_frame_idx))
+ {
+ printf ("Warning: assigning long_term_frame_idx different from other field\n");
+ }
+
+ dpb.fs_ref[i]->long_term_frame_idx = dpb.fs_ref[i]->bottom_field->long_term_frame_idx
+ = long_term_frame_idx;
+ dpb.fs_ref[i]->bottom_field->long_term_pic_num = 2 * long_term_frame_idx + add_top;
+ dpb.fs_ref[i]->bottom_field->is_long_term = 1;
+ dpb.fs_ref[i]->is_long_term |= 2;
+ if (dpb.fs_ref[i]->is_long_term == 3)
+ {
+ dpb.fs_ref[i]->frame->is_long_term = 1;
+ dpb.fs_ref[i]->frame->long_term_frame_idx = dpb.fs_ref[i]->frame->long_term_pic_num = long_term_frame_idx;
+ }
+ return;
+ }
+ }
+ }
+ printf ("Warning: reference field for long term marking not found\n");
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Assign a long term frame index to a short term picture
+ ************************************************************************
+ */
+static void mm_assign_long_term_frame_idx(StorablePicture* p, int difference_of_pic_nums_minus1, int long_term_frame_idx)
+{
+ int picNumX;
+
+ picNumX = get_pic_num_x(p, difference_of_pic_nums_minus1);
+
+ // remove frames/fields with same long_term_frame_idx
+ if (p->structure == FRAME)
+ {
+ unmark_long_term_frame_for_reference_by_frame_idx(long_term_frame_idx);
+ }
+ else
+ {
+ unsigned i;
+ PictureStructure structure = FRAME;
+
+ for (i=0; i<dpb.ref_frames_in_buffer; i++)
+ {
+ if (dpb.fs_ref[i]->is_reference & 1)
+ {
+ if (dpb.fs_ref[i]->top_field->pic_num == picNumX)
+ {
+ structure = TOP_FIELD;
+ break;
+ }
+ }
+ if (dpb.fs_ref[i]->is_reference & 2)
+ {
+ if (dpb.fs_ref[i]->bottom_field->pic_num == picNumX)
+ {
+ structure = BOTTOM_FIELD;
+ break;
+ }
+ }
+ }
+ if (structure==FRAME)
+ {
+ error ("field for long term marking not found",200);
+ }
+
+ unmark_long_term_field_for_reference_by_frame_idx(structure, long_term_frame_idx, 0, 0, picNumX);
+ }
+
+ mark_pic_long_term(p, long_term_frame_idx, picNumX);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Set new max long_term_frame_idx
+ ************************************************************************
+ */
+void mm_update_max_long_term_frame_idx(int max_long_term_frame_idx_plus1)
+{
+ unsigned i;
+
+ dpb.max_long_term_pic_idx = max_long_term_frame_idx_plus1 - 1;
+
+ // check for invalid frames
+ for (i=0; i<dpb.ltref_frames_in_buffer; i++)
+ {
+ if (dpb.fs_ltref[i]->long_term_frame_idx > dpb.max_long_term_pic_idx)
+ {
+ unmark_for_long_term_reference(dpb.fs_ltref[i]);
+ }
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Mark all long term reference pictures unused for reference
+ ************************************************************************
+ */
+static void mm_unmark_all_long_term_for_reference ()
+{
+ mm_update_max_long_term_frame_idx(0);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Mark all short term reference pictures unused for reference
+ ************************************************************************
+ */
+static void mm_unmark_all_short_term_for_reference ()
+{
+ unsigned int i;
+ for (i=0; i<dpb.ref_frames_in_buffer; i++)
+ {
+ unmark_for_reference(dpb.fs_ref[i]);
+ }
+ update_ref_list();
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Mark the current picture used for long term reference
+ ************************************************************************
+ */
+static void mm_mark_current_picture_long_term(StorablePicture *p, int long_term_frame_idx)
+{
+ // remove long term pictures with same long_term_frame_idx
+ if (p->structure == FRAME)
+ {
+ unmark_long_term_frame_for_reference_by_frame_idx(long_term_frame_idx);
+ }
+ else
+ {
+ unmark_long_term_field_for_reference_by_frame_idx(p->structure, long_term_frame_idx, 1, p->pic_num, 0);
+ }
+
+ p->is_long_term = 1;
+ p->long_term_frame_idx = long_term_frame_idx;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Perform Adaptive memory control decoded reference picture marking process
+ ************************************************************************
+ */
+static void adaptive_memory_management(StorablePicture* p)
+{
+ DecRefPicMarking_t *tmp_drpm;
+
+ img->last_has_mmco_5 = 0;
+
+ assert (!p->idr_flag);
+ assert (p->adaptive_ref_pic_buffering_flag);
+
+ while (p->dec_ref_pic_marking_buffer)
+ {
+ tmp_drpm = p->dec_ref_pic_marking_buffer;
+ switch (tmp_drpm->memory_management_control_operation)
+ {
+ case 0:
+ if (tmp_drpm->Next != NULL)
+ {
+ error ("memory_management_control_operation = 0 not last operation in buffer", 500);
+ }
+ break;
+ case 1:
+ mm_unmark_short_term_for_reference(p, tmp_drpm->difference_of_pic_nums_minus1);
+ update_ref_list();
+ break;
+ case 2:
+ mm_unmark_long_term_for_reference(p, tmp_drpm->long_term_pic_num);
+ update_ltref_list();
+ break;
+ case 3:
+ mm_assign_long_term_frame_idx(p, tmp_drpm->difference_of_pic_nums_minus1, tmp_drpm->long_term_frame_idx);
+ update_ref_list();
+ update_ltref_list();
+ break;
+ case 4:
+ mm_update_max_long_term_frame_idx (tmp_drpm->max_long_term_frame_idx_plus1);
+ update_ltref_list();
+ break;
+ case 5:
+ mm_unmark_all_short_term_for_reference();
+ mm_unmark_all_long_term_for_reference();
+ img->last_has_mmco_5 = 1;
+ break;
+ case 6:
+ mm_mark_current_picture_long_term(p, tmp_drpm->long_term_frame_idx);
+ check_num_ref();
+ break;
+ default:
+ error ("invalid memory_management_control_operation in buffer", 500);
+ }
+ p->dec_ref_pic_marking_buffer = tmp_drpm->Next;
+ free (tmp_drpm);
+ }
+ if ( img->last_has_mmco_5 )
+ {
+ p->pic_num = p->frame_num = 0;
+
+ switch (p->structure)
+ {
+ case TOP_FIELD:
+ {
+ p->poc = p->top_poc = img->toppoc =0;
+ break;
+ }
+ case BOTTOM_FIELD:
+ {
+ p->poc = p->bottom_poc = img->bottompoc = 0;
+ break;
+ }
+ case FRAME:
+ {
+ p->top_poc -= p->poc;
+ p->bottom_poc -= p->poc;
+
+ img->toppoc = p->top_poc;
+ img->bottompoc = p->bottom_poc;
+
+ p->poc = imin (p->top_poc, p->bottom_poc);
+ img->framepoc = p->poc;
+ break;
+ }
+ }
+ img->ThisPOC = p->poc;
+ flush_dpb();
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Store a picture in DPB. This includes cheking for space in DPB and
+ * flushing frames.
+ * If we received a frame, we need to check for a new store, if we
+ * got a field, check if it's the second field of an already allocated
+ * store.
+ *
+ * \param p
+ * Picture to be stored
+ *
+ ************************************************************************
+ */
+void store_picture_in_dpb(StorablePicture* p)
+{
+ unsigned i;
+ int poc, pos;
+ // picture error concealment
+ extern int pocs_in_dpb[100];
+ // diagnostics
+ //printf ("Storing (%s) non-ref pic with frame_num #%d\n", (p->type == FRAME)?"FRAME":(p->type == TOP_FIELD)?"TOP_FIELD":"BOTTOM_FIELD", p->pic_num);
+ // if frame, check for new store,
+ assert (p!=NULL);
+
+ img->last_has_mmco_5=0;
+ img->last_pic_bottom_field = (p->structure == BOTTOM_FIELD);
+
+ if (p->idr_flag)
+ {
+ idr_memory_management(p);
+ // picture error concealment
+ memset(pocs_in_dpb, 0, sizeof(int)*100);
+ }
+ else
+ {
+ // adaptive memory management
+ if (p->used_for_reference && (p->adaptive_ref_pic_buffering_flag))
+ adaptive_memory_management(p);
+ }
+
+ if ((p->structure==TOP_FIELD)||(p->structure==BOTTOM_FIELD))
+ {
+ // check for frame store with same pic_number
+ if (dpb.last_picture)
+ {
+ if ((int)dpb.last_picture->frame_num == p->pic_num)
+ {
+ if (((p->structure==TOP_FIELD)&&(dpb.last_picture->is_used==2))||((p->structure==BOTTOM_FIELD)&&(dpb.last_picture->is_used==1)))
+ {
+ if ((p->used_for_reference && (dpb.last_picture->is_orig_reference!=0))||
+ (!p->used_for_reference && (dpb.last_picture->is_orig_reference==0)))
+ {
+ insert_picture_in_dpb(dpb.last_picture, p);
+ update_ref_list();
+ update_ltref_list();
+ dump_dpb();
+ dpb.last_picture = NULL;
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ // this is a frame or a field which has no stored complementary field
+
+ // sliding window, if necessary
+ if ((!p->idr_flag)&&(p->used_for_reference && (!p->adaptive_ref_pic_buffering_flag)))
+ {
+ sliding_window_memory_management(p);
+ }
+
+ // picture error concealment
+ if(img->conceal_mode != 0)
+ for(i=0;i<dpb.size;i++)
+ if(dpb.fs[i]->is_reference)
+ dpb.fs[i]->concealment_reference = 1;
+
+ // first try to remove unused frames
+ if (dpb.used_size==dpb.size)
+ {
+ // picture error concealment
+ if (img->conceal_mode != 0)
+ conceal_non_ref_pics(2);
+ remove_unused_frame_from_dpb();
+
+ if(img->conceal_mode != 0)
+ sliding_window_poc_management(p);
+ }
+
+ // then output frames until one can be removed
+ while (dpb.used_size==dpb.size)
+ {
+ // non-reference frames may be output directly
+ if (!p->used_for_reference)
+ {
+ get_smallest_poc(&poc, &pos);
+ if ((-1==pos) || (p->poc < poc))
+ {
+ direct_output(p, p_out);
+ return;
+ }
+ }
+ // flush a frame
+ output_one_frame_from_dpb();
+ }
+
+ // check for duplicate frame number in short term reference buffer
+ if ((p->used_for_reference)&&(!p->is_long_term))
+ {
+ for (i=0; i<dpb.ref_frames_in_buffer; i++)
+ {
+ if (dpb.fs_ref[i]->frame_num == p->frame_num)
+ {
+ error("duplicate frame_num in short-term reference picture buffer", 500);
+ }
+ }
+
+ }
+ // store at end of buffer
+// printf ("store frame/field at pos %d\n",dpb.used_size);
+ insert_picture_in_dpb(dpb.fs[dpb.used_size],p);
+
+ // picture error concealment
+ if (p->idr_flag)
+ {
+ img->earlier_missing_poc = 0;
+ }
+
+ if (p->structure != FRAME)
+ {
+ dpb.last_picture = dpb.fs[dpb.used_size];
+ }
+ else
+ {
+ dpb.last_picture = NULL;
+ }
+
+ dpb.used_size++;
+
+ if(img->conceal_mode != 0)
+ pocs_in_dpb[dpb.used_size-1] = p->poc;
+
+ update_ref_list();
+ update_ltref_list();
+
+ check_num_ref();
+
+ dump_dpb();
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Insert the picture into the DPB. A free DPB position is necessary
+ * for frames, .
+ *
+ * \param fs
+ * FrameStore into which the picture will be inserted
+ * \param p
+ * StorablePicture to be inserted
+ *
+ ************************************************************************
+ */
+static void insert_picture_in_dpb(FrameStore* fs, StorablePicture* p)
+{
+// printf ("insert (%s) pic with frame_num #%d, poc %d\n", (p->structure == FRAME)?"FRAME":(p->structure == TOP_FIELD)?"TOP_FIELD":"BOTTOM_FIELD", p->pic_num, p->poc);
+ assert (p!=NULL);
+ assert (fs!=NULL);
+ switch (p->structure)
+ {
+ case FRAME:
+ fs->frame = p;
+ fs->is_used = 3;
+ if (p->used_for_reference)
+ {
+ fs->is_reference = 3;
+ fs->is_orig_reference = 3;
+ if (p->is_long_term)
+ {
+ fs->is_long_term = 3;
+ fs->long_term_frame_idx = p->long_term_frame_idx;
+ }
+ }
+ // generate field views
+ dpb_split_field(fs);
+ break;
+ case TOP_FIELD:
+ fs->top_field = p;
+ fs->is_used |= 1;
+ if (p->used_for_reference)
+ {
+ fs->is_reference |= 1;
+ fs->is_orig_reference |= 1;
+ if (p->is_long_term)
+ {
+ fs->is_long_term |= 1;
+ fs->long_term_frame_idx = p->long_term_frame_idx;
+ }
+ }
+ if (fs->is_used == 3)
+ {
+ // generate frame view
+ dpb_combine_field(fs);
+ } else
+ {
+ fs->poc = p->poc;
+ gen_field_ref_ids(p);
+ }
+ break;
+ case BOTTOM_FIELD:
+ fs->bottom_field = p;
+ fs->is_used |= 2;
+ if (p->used_for_reference)
+ {
+ fs->is_reference |= 2;
+ fs->is_orig_reference |= 2;
+ if (p->is_long_term)
+ {
+ fs->is_long_term |= 2;
+ fs->long_term_frame_idx = p->long_term_frame_idx;
+ }
+ }
+ if (fs->is_used == 3)
+ {
+ // generate frame view
+ dpb_combine_field(fs);
+ } else
+ {
+ fs->poc = p->poc;
+ gen_field_ref_ids(p);
+ }
+ break;
+ }
+ fs->frame_num = p->pic_num;
+ fs->recovery_frame = p->recovery_frame;
+
+ fs->is_output = p->is_output;
+
+ if (fs->is_used==3)
+ {
+ if (-1!=p_ref && !input->silent)
+ find_snr(snr, fs->frame, p_ref);
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Check if one of the frames/fields in frame store is used for reference
+ ************************************************************************
+ */
+static int is_used_for_reference(FrameStore* fs)
+{
+ if (fs->is_reference)
+ {
+ return 1;
+ }
+
+ if (fs->is_used == 3) // frame
+ {
+ if (fs->frame->used_for_reference)
+ {
+ return 1;
+ }
+ }
+
+ if (fs->is_used & 1) // top field
+ {
+ if (fs->top_field)
+ {
+ if (fs->top_field->used_for_reference)
+ {
+ return 1;
+ }
+ }
+ }
+
+ if (fs->is_used & 2) // bottom field
+ {
+ if (fs->bottom_field)
+ {
+ if (fs->bottom_field->used_for_reference)
+ {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Check if one of the frames/fields in frame store is used for short-term reference
+ ************************************************************************
+ */
+static int is_short_term_reference(FrameStore* fs)
+{
+
+ if (fs->is_used==3) // frame
+ {
+ if ((fs->frame->used_for_reference)&&(!fs->frame->is_long_term))
+ {
+ return 1;
+ }
+ }
+
+ if (fs->is_used & 1) // top field
+ {
+ if (fs->top_field)
+ {
+ if ((fs->top_field->used_for_reference)&&(!fs->top_field->is_long_term))
+ {
+ return 1;
+ }
+ }
+ }
+
+ if (fs->is_used & 2) // bottom field
+ {
+ if (fs->bottom_field)
+ {
+ if ((fs->bottom_field->used_for_reference)&&(!fs->bottom_field->is_long_term))
+ {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Check if one of the frames/fields in frame store is used for short-term reference
+ ************************************************************************
+ */
+static int is_long_term_reference(FrameStore* fs)
+{
+
+ if (fs->is_used==3) // frame
+ {
+ if ((fs->frame->used_for_reference)&&(fs->frame->is_long_term))
+ {
+ return 1;
+ }
+ }
+
+ if (fs->is_used & 1) // top field
+ {
+ if (fs->top_field)
+ {
+ if ((fs->top_field->used_for_reference)&&(fs->top_field->is_long_term))
+ {
+ return 1;
+ }
+ }
+ }
+
+ if (fs->is_used & 2) // bottom field
+ {
+ if (fs->bottom_field)
+ {
+ if ((fs->bottom_field->used_for_reference)&&(fs->bottom_field->is_long_term))
+ {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * remove one frame from DPB
+ ************************************************************************
+ */
+static void remove_frame_from_dpb(int pos)
+{
+ FrameStore* fs = dpb.fs[pos];
+ FrameStore* tmp;
+ unsigned i;
+
+// printf ("remove frame with frame_num #%d\n", fs->frame_num);
+ switch (fs->is_used)
+ {
+ case 3:
+ free_storable_picture(fs->frame);
+ free_storable_picture(fs->top_field);
+ free_storable_picture(fs->bottom_field);
+ fs->frame=NULL;
+ fs->top_field=NULL;
+ fs->bottom_field=NULL;
+ break;
+ case 2:
+ free_storable_picture(fs->bottom_field);
+ fs->bottom_field=NULL;
+ break;
+ case 1:
+ free_storable_picture(fs->top_field);
+ fs->top_field=NULL;
+ break;
+ case 0:
+ break;
+ default:
+ error("invalid frame store type",500);
+ }
+ fs->is_used = 0;
+ fs->is_long_term = 0;
+ fs->is_reference = 0;
+ fs->is_orig_reference = 0;
+
+ // move empty framestore to end of buffer
+ tmp = dpb.fs[pos];
+
+ for (i=pos; i<dpb.used_size-1;i++)
+ {
+ dpb.fs[i] = dpb.fs[i+1];
+ }
+ dpb.fs[dpb.used_size-1] = tmp;
+ dpb.used_size--;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * find smallest POC in the DPB.
+ ************************************************************************
+ */
+static void get_smallest_poc(int *poc,int * pos)
+{
+ unsigned i;
+
+ if (dpb.used_size<1)
+ {
+ error("Cannot determine smallest POC, DPB empty.",150);
+ }
+
+ *pos=-1;
+ *poc = INT_MAX;
+ for (i=0; i<dpb.used_size; i++)
+ {
+ if ((*poc>dpb.fs[i]->poc)&&(!dpb.fs[i]->is_output))
+ {
+ *poc = dpb.fs[i]->poc;
+ *pos=i;
+ }
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Remove a picture from DPB which is no longer needed.
+ ************************************************************************
+ */
+static int remove_unused_frame_from_dpb()
+{
+ unsigned i;
+
+ // check for frames that were already output and no longer used for reference
+ for (i=0; i<dpb.used_size; i++)
+ {
+ if (dpb.fs[i]->is_output && (!is_used_for_reference(dpb.fs[i])))
+ {
+ remove_frame_from_dpb(i);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Output one picture stored in the DPB.
+ ************************************************************************
+ */
+static void output_one_frame_from_dpb()
+{
+ int poc, pos;
+ //diagnostics
+ if (dpb.used_size<1)
+ {
+ error("Cannot output frame, DPB empty.",150);
+ }
+
+ // find smallest POC
+ get_smallest_poc(&poc, &pos);
+
+ if(pos==-1)
+ {
+ error("no frames for output available", 150);
+ }
+
+ // call the output function
+// printf ("output frame with frame_num #%d, poc %d (dpb. dpb.size=%d, dpb.used_size=%d)\n", dpb.fs[pos]->frame_num, dpb.fs[pos]->frame->poc, dpb.size, dpb.used_size);
+
+ // picture error concealment
+ if(img->conceal_mode != 0)
+ {
+ if(dpb.last_output_poc == 0)
+ {
+ write_lost_ref_after_idr(pos);
+ }
+ write_lost_non_ref_pic(poc, p_out);
+ }
+
+// JVT-P072 ends
+
+ write_stored_frame(dpb.fs[pos], p_out);
+
+ // picture error concealment
+ if(img->conceal_mode == 0)
+ if (dpb.last_output_poc >= poc)
+ {
+ error ("output POC must be in ascending order", 150);
+ }
+ dpb.last_output_poc = poc;
+ // free frame store and move empty store to end of buffer
+ if (!is_used_for_reference(dpb.fs[pos]))
+ {
+ remove_frame_from_dpb(pos);
+ }
+}
+
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * All stored picture are output. Should be called to empty the buffer
+ ************************************************************************
+ */
+void flush_dpb()
+{
+ unsigned i;
+
+ //diagnostics
+// printf("Flush remaining frames from dpb. dpb.size=%d, dpb.used_size=%d\n",dpb.size,dpb.used_size);
+
+// if(img->conceal_mode == 0)
+ if (img->conceal_mode != 0)
+ conceal_non_ref_pics(0);
+
+ // mark all frames unused
+ for (i=0; i<dpb.used_size; i++)
+ {
+ unmark_for_reference (dpb.fs[i]);
+ }
+
+ while (remove_unused_frame_from_dpb()) ;
+
+ // output frames in POC order
+ while (dpb.used_size)
+ {
+ output_one_frame_from_dpb();
+ }
+
+ dpb.last_output_poc = INT_MIN;
+}
+
+
+void gen_field_ref_ids(StorablePicture *p)
+{
+ int i,j, dummylist0, dummylist1;
+ //! Generate Frame parameters from field information.
+ for (i=0 ; i<p->size_x/4 ; i++)
+ {
+ for (j=0 ; j<p->size_y/4 ; j++)
+ {
+ dummylist0= p->ref_idx[LIST_0][j][i];
+ dummylist1= p->ref_idx[LIST_1][j][i];
+ //! association with id already known for fields.
+ p->ref_id[LIST_0][j][i] = (dummylist0>=0)? p->ref_pic_num[p->slice_id[j>>2][i>>2]][LIST_0][dummylist0] : 0;
+ p->ref_id[LIST_1][j][i] = (dummylist1>=0)? p->ref_pic_num[p->slice_id[j>>2][i>>2]][LIST_1][dummylist1] : 0;
+ p->field_frame[j][i]=1;
+ }
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Extract top field from a frame
+ ************************************************************************
+ */
+void dpb_split_field(FrameStore *fs)
+{
+ int i, j, ii, jj, jj4;
+ int idiv,jdiv;
+ int currentmb;
+ int dummylist0,dummylist1;
+ int twosz16 = 2*(fs->frame->size_x/16);
+
+ fs->poc = fs->frame->poc;
+
+ if (!fs->frame->frame_mbs_only_flag)
+ {
+ fs->top_field = alloc_storable_picture(TOP_FIELD, fs->frame->size_x, fs->frame->size_y, fs->frame->size_x_cr, fs->frame->size_y_cr);
+ fs->bottom_field = alloc_storable_picture(BOTTOM_FIELD, fs->frame->size_x, fs->frame->size_y, fs->frame->size_x_cr, fs->frame->size_y_cr);
+
+ for (i=0; i<fs->frame->size_y/2; i++)
+ {
+ memcpy(fs->top_field->imgY[i], fs->frame->imgY[i*2], fs->frame->size_x*sizeof(imgpel));
+ }
+
+ for (i=0; i<fs->frame->size_y_cr/2; i++)
+ {
+ memcpy(fs->top_field->imgUV[0][i], fs->frame->imgUV[0][i*2], fs->frame->size_x_cr*sizeof(imgpel));
+ memcpy(fs->top_field->imgUV[1][i], fs->frame->imgUV[1][i*2], fs->frame->size_x_cr*sizeof(imgpel));
+ }
+
+ for (i=0; i<fs->frame->size_y/2; i++)
+ {
+ memcpy(fs->bottom_field->imgY[i], fs->frame->imgY[i*2 + 1], fs->frame->size_x*sizeof(imgpel));
+ }
+
+ for (i=0; i<fs->frame->size_y_cr/2; i++)
+ {
+ memcpy(fs->bottom_field->imgUV[0][i], fs->frame->imgUV[0][i*2 + 1], fs->frame->size_x_cr*sizeof(imgpel));
+ memcpy(fs->bottom_field->imgUV[1][i], fs->frame->imgUV[1][i*2 + 1], fs->frame->size_x_cr*sizeof(imgpel));
+ }
+
+ fs->top_field->poc = fs->frame->top_poc;
+ fs->bottom_field->poc = fs->frame->bottom_poc;
+
+ fs->top_field->frame_poc = fs->frame->frame_poc;
+
+ fs->top_field->bottom_poc =fs->bottom_field->bottom_poc = fs->frame->bottom_poc;
+ fs->top_field->top_poc =fs->bottom_field->top_poc = fs->frame->top_poc;
+ fs->bottom_field->frame_poc = fs->frame->frame_poc;
+
+ fs->top_field->used_for_reference = fs->bottom_field->used_for_reference
+ = fs->frame->used_for_reference;
+ fs->top_field->is_long_term = fs->bottom_field->is_long_term
+ = fs->frame->is_long_term;
+ fs->long_term_frame_idx = fs->top_field->long_term_frame_idx
+ = fs->bottom_field->long_term_frame_idx
+ = fs->frame->long_term_frame_idx;
+
+ fs->top_field->coded_frame = fs->bottom_field->coded_frame = 1;
+ fs->top_field->MbaffFrameFlag = fs->bottom_field->MbaffFrameFlag
+ = fs->frame->MbaffFrameFlag;
+
+ fs->frame->top_field = fs->top_field;
+ fs->frame->bottom_field = fs->bottom_field;
+
+ fs->top_field->bottom_field = fs->bottom_field;
+ fs->top_field->frame = fs->frame;
+ fs->bottom_field->top_field = fs->top_field;
+ fs->bottom_field->frame = fs->frame;
+
+ fs->top_field->chroma_format_idc = fs->bottom_field->chroma_format_idc = fs->frame->chroma_format_idc;
+
+ //store reference picture index
+ for (j=0; j<=fs->frame->max_slice_id; j++)
+ {
+ for (i=0;i<16;i++)
+ {
+ fs->top_field->ref_pic_num[j][LIST_1][2*i] =fs->frame->ref_pic_num[j][2 + LIST_1][2*i];
+ fs->top_field->ref_pic_num[j][LIST_1][2*i + 1] =fs->frame->ref_pic_num[j][2 + LIST_1][2*i+1];
+ fs->bottom_field->ref_pic_num[j][LIST_1][2*i] =fs->frame->ref_pic_num[j][4 + LIST_1][2*i];
+ fs->bottom_field->ref_pic_num[j][LIST_1][2*i+1]=fs->frame->ref_pic_num[j][4 + LIST_1][2*i+1] ;
+
+ fs->top_field->ref_pic_num[j][LIST_0][2*i] =fs->frame->ref_pic_num[j][2 + LIST_0][2*i];
+ fs->top_field->ref_pic_num[j][LIST_0][2*i + 1] =fs->frame->ref_pic_num[j][2 + LIST_0][2*i+1];
+ fs->bottom_field->ref_pic_num[j][LIST_0][2*i] =fs->frame->ref_pic_num[j][4 + LIST_0][2*i];
+ fs->bottom_field->ref_pic_num[j][LIST_0][2*i+1]=fs->frame->ref_pic_num[j][4 + LIST_0][2*i+1] ;
+ }
+ }
+ }
+ else
+ {
+ fs->top_field=NULL;
+ fs->bottom_field=NULL;
+ fs->frame->top_field=NULL;
+ fs->frame->bottom_field=NULL;
+ }
+
+ for (j=0 ; j<fs->frame->size_y/4 ; j++)
+ {
+ jdiv=j/4;
+ for (i=0 ; i<fs->frame->size_x/4 ; i++)
+ {
+ idiv=i/4;
+ currentmb = twosz16*(jdiv/2)+ (idiv)*2 + (jdiv%2);
+
+ if (fs->frame->MbaffFrameFlag && fs->frame->mb_field[currentmb])
+ {
+ int list_offset = currentmb%2? 4: 2;
+ dummylist0 = fs->frame->ref_idx[LIST_0][j][i];
+ dummylist1 = fs->frame->ref_idx[LIST_1][j][i];
+ //! association with id already known for fields.
+ fs->frame->ref_id[LIST_0 + list_offset][j][i] = (dummylist0>=0)? fs->frame->ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_0 + list_offset][dummylist0] : 0;
+ fs->frame->ref_id[LIST_1 + list_offset][j][i] = (dummylist1>=0)? fs->frame->ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_1 + list_offset][dummylist1] : 0;
+ //! need to make association with frames
+ fs->frame->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->frm_ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_0 + list_offset][dummylist0] : 0;
+ fs->frame->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->frm_ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_1 + list_offset][dummylist1] : 0;
+
+ }
+ else
+ {
+ dummylist0 = fs->frame->ref_idx[LIST_0][j][i];
+ dummylist1 = fs->frame->ref_idx[LIST_1][j][i];
+ fs->frame->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_0][dummylist0] : -1;
+ fs->frame->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_1][dummylist1] : -1;
+ }
+ }
+ }
+
+ if (!fs->frame->frame_mbs_only_flag && fs->frame->MbaffFrameFlag)
+ {
+ for (j=0 ; j<fs->frame->size_y/8; j++)
+ {
+ jj = (j/4)*8 + j%4;
+ jj4 = jj + 4;
+ jdiv=j/2;
+ for (i=0 ; i<fs->frame->size_x/4 ; i++)
+ {
+ idiv=i/4;
+
+ currentmb = twosz16*(jdiv/2)+ (idiv)*2 + (jdiv%2);
+ // Assign field mvs attached to MB-Frame buffer to the proper buffer
+ if (fs->frame->mb_field[currentmb])
+ {
+ fs->bottom_field->field_frame[j][i] = fs->top_field->field_frame[j][i]=1;
+ fs->frame->field_frame[2*j][i] = fs->frame->field_frame[2*j+1][i]=1;
+
+ fs->bottom_field->mv[LIST_0][j][i][0] = fs->frame->mv[LIST_0][jj4][i][0];
+ fs->bottom_field->mv[LIST_0][j][i][1] = fs->frame->mv[LIST_0][jj4][i][1];
+ fs->bottom_field->mv[LIST_1][j][i][0] = fs->frame->mv[LIST_1][jj4][i][0];
+ fs->bottom_field->mv[LIST_1][j][i][1] = fs->frame->mv[LIST_1][jj4][i][1];
+ fs->bottom_field->ref_idx[LIST_0][j][i] = fs->frame->ref_idx[LIST_0][jj4][i];
+ fs->bottom_field->ref_idx[LIST_1][j][i] = fs->frame->ref_idx[LIST_1][jj4][i];
+ fs->bottom_field->ref_id[LIST_0][j][i] = fs->frame->ref_id[LIST_0+4][jj4][i];
+ fs->bottom_field->ref_id[LIST_1][j][i] = fs->frame->ref_id[LIST_1+4][jj4][i];
+
+
+ fs->top_field->mv[LIST_0][j][i][0] = fs->frame->mv[LIST_0][jj][i][0];
+ fs->top_field->mv[LIST_0][j][i][1] = fs->frame->mv[LIST_0][jj][i][1];
+ fs->top_field->mv[LIST_1][j][i][0] = fs->frame->mv[LIST_1][jj][i][0];
+ fs->top_field->mv[LIST_1][j][i][1] = fs->frame->mv[LIST_1][jj][i][1];
+ fs->top_field->ref_idx[LIST_0][j][i] = fs->frame->ref_idx[LIST_0][jj][i];
+ fs->top_field->ref_idx[LIST_1][j][i] = fs->frame->ref_idx[LIST_1][jj][i];
+ fs->top_field->ref_id[LIST_0][j][i] = fs->frame->ref_id[LIST_0+2][jj][i];
+ fs->top_field->ref_id[LIST_1][j][i] = fs->frame->ref_id[LIST_1+2][jj][i];
+ }
+ }
+ }
+ }
+
+ //! Generate field MVs from Frame MVs
+ if (!fs->frame->frame_mbs_only_flag)
+ {
+ for (j=0 ; j<fs->frame->size_y/8 ; j++)
+ {
+ jj = 2* RSD(j);
+ jdiv = j/2;
+ for (i=0 ; i<fs->frame->size_x/4 ; i++)
+ {
+ ii = RSD(i);
+ idiv = i/4;
+
+ currentmb = twosz16*(jdiv/2)+ (idiv)*2 + (jdiv%2);
+
+ if (!fs->frame->MbaffFrameFlag || !fs->frame->mb_field[currentmb])
+ {
+ fs->frame->field_frame[2*j+1][i] = fs->frame->field_frame[2*j][i]=0;
+
+ fs->top_field->field_frame[j][i] = fs->bottom_field->field_frame[j][i] = 0;
+
+ fs->top_field->mv[LIST_0][j][i][0] = fs->bottom_field->mv[LIST_0][j][i][0] = fs->frame->mv[LIST_0][jj][ii][0];
+ fs->top_field->mv[LIST_0][j][i][1] = fs->bottom_field->mv[LIST_0][j][i][1] = fs->frame->mv[LIST_0][jj][ii][1];
+ fs->top_field->mv[LIST_1][j][i][0] = fs->bottom_field->mv[LIST_1][j][i][0] = fs->frame->mv[LIST_1][jj][ii][0];
+ fs->top_field->mv[LIST_1][j][i][1] = fs->bottom_field->mv[LIST_1][j][i][1] = fs->frame->mv[LIST_1][jj][ii][1];
+
+ // Scaling of references is done here since it will not affect spatial direct (2*0 =0)
+ if (fs->frame->ref_idx[LIST_0][jj][ii] == -1)
+ fs->top_field->ref_idx[LIST_0][j][i] = fs->bottom_field->ref_idx[LIST_0][j][i] = - 1;
+ else
+ {
+ dummylist0=fs->top_field->ref_idx[LIST_0][j][i] = fs->bottom_field->ref_idx[LIST_0][j][i] = fs->frame->ref_idx[LIST_0][jj][ii] ;
+ fs->top_field ->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->top_ref_pic_num[fs->frame->slice_id[jj>>2][ii>>2]][LIST_0][dummylist0] : 0;
+ fs->bottom_field->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->bottom_ref_pic_num[fs->frame->slice_id[jj>>2][ii>>2]][LIST_0][dummylist0] : 0;
+ }
+
+ if (fs->frame->ref_idx[LIST_1][jj][ii] == -1)
+ fs->top_field->ref_idx[LIST_1][j][i] = fs->bottom_field->ref_idx[LIST_1][j][i] = - 1;
+ else
+ {
+ dummylist1=fs->top_field->ref_idx[LIST_1][j][i] = fs->bottom_field->ref_idx[LIST_1][j][i] = fs->frame->ref_idx[LIST_1][jj][ii];
+
+ fs->top_field ->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->top_ref_pic_num[fs->frame->slice_id[jj>>2][ii>>2]][LIST_1][dummylist1] : 0;
+ fs->bottom_field->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->bottom_ref_pic_num[fs->frame->slice_id[jj>>2][ii>>2]][LIST_1][dummylist1] : 0;
+ }
+ }
+ else
+ {
+ fs->frame->field_frame[2*j+1][i] = fs->frame->field_frame[2*j][i]= fs->frame->mb_field[currentmb];
+ }
+ }
+ }
+ }
+ else
+ {
+ memset( &(fs->frame->field_frame[0][0]), 0, fs->frame->size_y * fs->frame->size_x /16 * sizeof(byte));
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Generate a frame from top and bottom fields,
+ * YUV components and display information only
+ ************************************************************************
+ */
+void dpb_combine_field_yuv(FrameStore *fs)
+{
+ int i;
+
+ fs->frame = alloc_storable_picture(FRAME, fs->top_field->size_x, fs->top_field->size_y*2, fs->top_field->size_x_cr, fs->top_field->size_y_cr*2);
+
+ for (i=0; i<fs->top_field->size_y; i++)
+ {
+ memcpy(fs->frame->imgY[i*2], fs->top_field->imgY[i] , fs->top_field->size_x*sizeof(imgpel)); // top field
+ memcpy(fs->frame->imgY[i*2 + 1], fs->bottom_field->imgY[i], fs->bottom_field->size_x*sizeof(imgpel)); // bottom field
+ }
+
+ for (i=0; i<fs->top_field->size_y_cr; i++)
+ {
+ memcpy(fs->frame->imgUV[0][i*2], fs->top_field->imgUV[0][i], fs->top_field->size_x_cr*sizeof(imgpel));
+ memcpy(fs->frame->imgUV[0][i*2 + 1], fs->bottom_field->imgUV[0][i], fs->bottom_field->size_x_cr*sizeof(imgpel));
+ memcpy(fs->frame->imgUV[1][i*2], fs->top_field->imgUV[1][i], fs->top_field->size_x_cr*sizeof(imgpel));
+ memcpy(fs->frame->imgUV[1][i*2 + 1], fs->bottom_field->imgUV[1][i], fs->bottom_field->size_x_cr*sizeof(imgpel));
+ }
+
+ fs->poc=fs->frame->poc =fs->frame->frame_poc = imin (fs->top_field->poc, fs->bottom_field->poc);
+
+ fs->bottom_field->frame_poc=fs->top_field->frame_poc=fs->frame->poc;
+
+ fs->bottom_field->top_poc=fs->frame->top_poc=fs->top_field->poc;
+ fs->top_field->bottom_poc=fs->frame->bottom_poc=fs->bottom_field->poc;
+
+ fs->frame->used_for_reference = (fs->top_field->used_for_reference && fs->bottom_field->used_for_reference );
+ fs->frame->is_long_term = (fs->top_field->is_long_term && fs->bottom_field->is_long_term );
+
+ if (fs->frame->is_long_term)
+ fs->frame->long_term_frame_idx = fs->long_term_frame_idx;
+
+ fs->frame->top_field = fs->top_field;
+ fs->frame->bottom_field = fs->bottom_field;
+
+ fs->frame->coded_frame = 0;
+
+ fs->frame->chroma_format_idc = fs->top_field->chroma_format_idc;
+ fs->frame->frame_cropping_flag = fs->top_field->frame_cropping_flag;
+ if (fs->frame->frame_cropping_flag)
+ {
+ fs->frame->frame_cropping_rect_top_offset = fs->top_field->frame_cropping_rect_top_offset;
+ fs->frame->frame_cropping_rect_bottom_offset = fs->top_field->frame_cropping_rect_bottom_offset;
+ fs->frame->frame_cropping_rect_left_offset = fs->top_field->frame_cropping_rect_left_offset;
+ fs->frame->frame_cropping_rect_right_offset = fs->top_field->frame_cropping_rect_right_offset;
+ }
+
+ fs->top_field->frame = fs->bottom_field->frame = fs->frame;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Generate a frame from top and bottom fields
+ ************************************************************************
+ */
+void dpb_combine_field(FrameStore *fs)
+{
+ int i,j, jj, jj4;
+ int dummylist0, dummylist1;
+
+ dpb_combine_field_yuv(fs);
+
+
+ //combine field for frame
+ for (j=0; j<=(imax(fs->top_field->max_slice_id, fs->bottom_field->max_slice_id)); j++)
+ {
+ for (i=0;i<16;i++)
+ {
+ fs->frame->ref_pic_num[j][LIST_1][i]= i64min ((fs->top_field->ref_pic_num[j][LIST_1][2*i]/2)*2, (fs->bottom_field->ref_pic_num[j][LIST_1][2*i]/2)*2);
+ }
+
+ for (i=0;i<16;i++)
+ {
+ fs->frame->ref_pic_num[j][LIST_0][i] = i64min((fs->top_field->ref_pic_num[j][LIST_0][2*i]/2)*2, (fs->bottom_field->ref_pic_num[j][LIST_0][2*i]/2)*2);
+ }
+ }
+
+ //! Use inference flag to remap mvs/references
+
+ //! Generate Frame parameters from field information.
+ for (j=0 ; j<fs->top_field->size_y/4 ; j++)
+ {
+ jj = 8*(j/4) + (j%4);
+ jj4 = jj + 4;
+ for (i=0 ; i<fs->top_field->size_x/4 ; i++)
+ {
+ fs->frame->field_frame[jj][i]= fs->frame->field_frame[jj4][i]=1;
+
+ fs->frame->mv[LIST_0][jj][i][0] = fs->top_field->mv[LIST_0][j][i][0];
+ fs->frame->mv[LIST_0][jj][i][1] = fs->top_field->mv[LIST_0][j][i][1] ;
+ fs->frame->mv[LIST_1][jj][i][0] = fs->top_field->mv[LIST_1][j][i][0];
+ fs->frame->mv[LIST_1][jj][i][1] = fs->top_field->mv[LIST_1][j][i][1] ;
+
+ dummylist0=fs->frame->ref_idx[LIST_0][jj][i] = fs->top_field->ref_idx[LIST_0][j][i];
+ dummylist1=fs->frame->ref_idx[LIST_1][jj][i] = fs->top_field->ref_idx[LIST_1][j][i];
+
+ //! association with id already known for fields.
+ fs->top_field->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->top_field->ref_pic_num[fs->top_field->slice_id[j>>2][i>>2]][LIST_0][dummylist0] : 0;
+ fs->top_field->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->top_field->ref_pic_num[fs->top_field->slice_id[j>>2][i>>2]][LIST_1][dummylist1] : 0;
+
+ //! need to make association with frames
+ fs->frame->ref_id[LIST_0][jj][i] = (dummylist0>=0)? fs->top_field->frm_ref_pic_num[fs->top_field->slice_id[j>>2][i>>2]][LIST_0][dummylist0] : 0;
+ fs->frame->ref_id[LIST_1][jj][i] = (dummylist1>=0)? fs->top_field->frm_ref_pic_num[fs->top_field->slice_id[j>>2][i>>2]][LIST_1][dummylist1] : 0;
+
+ fs->frame->mv[LIST_0][jj4][i][0] = fs->bottom_field->mv[LIST_0][j][i][0];
+ fs->frame->mv[LIST_0][jj4][i][1] = fs->bottom_field->mv[LIST_0][j][i][1] ;
+ fs->frame->mv[LIST_1][jj4][i][0] = fs->bottom_field->mv[LIST_1][j][i][0];
+ fs->frame->mv[LIST_1][jj4][i][1] = fs->bottom_field->mv[LIST_1][j][i][1] ;
+
+ dummylist0=fs->frame->ref_idx[LIST_0][jj4][i] = fs->bottom_field->ref_idx[LIST_0][j][i];
+ dummylist1=fs->frame->ref_idx[LIST_1][jj4][i] = fs->bottom_field->ref_idx[LIST_1][j][i];
+
+ fs->bottom_field->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->bottom_field->ref_pic_num[fs->bottom_field->slice_id[j>>2][i>>2]][LIST_0][dummylist0] : 0;
+ fs->bottom_field->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->bottom_field->ref_pic_num[fs->bottom_field->slice_id[j>>2][i>>2]][LIST_1][dummylist1] : 0;
+
+ //! need to make association with frames
+ fs->frame->ref_id[LIST_0][jj4][i] = (dummylist0>=0)? fs->bottom_field->frm_ref_pic_num[fs->bottom_field->slice_id[j>>2][i>>2]][LIST_0][dummylist0] : -1;
+ fs->frame->ref_id[LIST_1][jj4][i] = (dummylist1>=0)? fs->bottom_field->frm_ref_pic_num[fs->bottom_field->slice_id[j>>2][i>>2]][LIST_1][dummylist1] : -1;
+
+ fs->top_field->field_frame[j][i]=1;
+ fs->bottom_field->field_frame[j][i]=1;
+ }
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocate memory for buffering of reference picture reordering commands
+ ************************************************************************
+ */
+void alloc_ref_pic_list_reordering_buffer(Slice *currSlice)
+{
+ int size = img->num_ref_idx_l0_active+1;
+
+ if (img->type!=I_SLICE && img->type!=SI_SLICE)
+ {
+ if ((currSlice->reordering_of_pic_nums_idc_l0 = calloc(size,sizeof(int)))==NULL) no_mem_exit("alloc_ref_pic_list_reordering_buffer: reordering_of_pic_nums_idc_l0");
+ if ((currSlice->abs_diff_pic_num_minus1_l0 = calloc(size,sizeof(int)))==NULL) no_mem_exit("alloc_ref_pic_list_reordering_buffer: abs_diff_pic_num_minus1_l0");
+ if ((currSlice->long_term_pic_idx_l0 = calloc(size,sizeof(int)))==NULL) no_mem_exit("alloc_ref_pic_list_reordering_buffer: long_term_pic_idx_l0");
+ }
+ else
+ {
+ currSlice->reordering_of_pic_nums_idc_l0 = NULL;
+ currSlice->abs_diff_pic_num_minus1_l0 = NULL;
+ currSlice->long_term_pic_idx_l0 = NULL;
+ }
+
+ size = img->num_ref_idx_l1_active+1;
+
+ if (img->type==B_SLICE)
+ {
+ if ((currSlice->reordering_of_pic_nums_idc_l1 = calloc(size,sizeof(int)))==NULL) no_mem_exit("alloc_ref_pic_list_reordering_buffer: reordering_of_pic_nums_idc_l1");
+ if ((currSlice->abs_diff_pic_num_minus1_l1 = calloc(size,sizeof(int)))==NULL) no_mem_exit("alloc_ref_pic_list_reordering_buffer: abs_diff_pic_num_minus1_l1");
+ if ((currSlice->long_term_pic_idx_l1 = calloc(size,sizeof(int)))==NULL) no_mem_exit("alloc_ref_pic_list_reordering_buffer: long_term_pic_idx_l1");
+ }
+ else
+ {
+ currSlice->reordering_of_pic_nums_idc_l1 = NULL;
+ currSlice->abs_diff_pic_num_minus1_l1 = NULL;
+ currSlice->long_term_pic_idx_l1 = NULL;
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Free memory for buffering of reference picture reordering commands
+ ************************************************************************
+ */
+void free_ref_pic_list_reordering_buffer(Slice *currSlice)
+{
+
+ if (currSlice->reordering_of_pic_nums_idc_l0)
+ free(currSlice->reordering_of_pic_nums_idc_l0);
+ if (currSlice->abs_diff_pic_num_minus1_l0)
+ free(currSlice->abs_diff_pic_num_minus1_l0);
+ if (currSlice->long_term_pic_idx_l0)
+ free(currSlice->long_term_pic_idx_l0);
+
+ currSlice->reordering_of_pic_nums_idc_l0 = NULL;
+ currSlice->abs_diff_pic_num_minus1_l0 = NULL;
+ currSlice->long_term_pic_idx_l0 = NULL;
+
+ if (currSlice->reordering_of_pic_nums_idc_l1)
+ free(currSlice->reordering_of_pic_nums_idc_l1);
+ if (currSlice->abs_diff_pic_num_minus1_l1)
+ free(currSlice->abs_diff_pic_num_minus1_l1);
+ if (currSlice->long_term_pic_idx_l1)
+ free(currSlice->long_term_pic_idx_l1);
+
+ currSlice->reordering_of_pic_nums_idc_l1 = NULL;
+ currSlice->abs_diff_pic_num_minus1_l1 = NULL;
+ currSlice->long_term_pic_idx_l1 = NULL;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Tian Dong
+ * June 13, 2002, Modifed on July 30, 2003
+ *
+ * If a gap in frame_num is found, try to fill the gap
+ * \param img
+ *
+ ************************************************************************
+ */
+void fill_frame_num_gap(ImageParameters *img)
+{
+ int CurrFrameNum;
+ int UnusedShortTermFrameNum;
+ StorablePicture *picture = NULL;
+ int tmp1 = img->delta_pic_order_cnt[0];
+ int tmp2 = img->delta_pic_order_cnt[1];
+ img->delta_pic_order_cnt[0] = img->delta_pic_order_cnt[1] = 0;
+
+// printf("A gap in frame number is found, try to fill it.\n");
+
+
+ UnusedShortTermFrameNum = (img->pre_frame_num + 1) % img->MaxFrameNum;
+ CurrFrameNum = img->frame_num;
+
+ while (CurrFrameNum != UnusedShortTermFrameNum)
+ {
+ picture = alloc_storable_picture (FRAME, img->width, img->height, img->width_cr, img->height_cr);
+ picture->coded_frame = 1;
+ picture->pic_num = UnusedShortTermFrameNum;
+ picture->frame_num = UnusedShortTermFrameNum;
+ picture->non_existing = 1;
+ picture->is_output = 1;
+ picture->used_for_reference = 1;
+
+ picture->adaptive_ref_pic_buffering_flag = 0;
+
+ img->frame_num = UnusedShortTermFrameNum;
+ if (active_sps->pic_order_cnt_type!=0)
+ {
+ decode_poc(img);
+ }
+ picture->top_poc=img->toppoc;
+ picture->bottom_poc=img->bottompoc;
+ picture->frame_poc=img->framepoc;
+ picture->poc=img->framepoc;
+
+ store_picture_in_dpb(picture);
+
+ picture=NULL;
+ img->pre_frame_num = UnusedShortTermFrameNum;
+ UnusedShortTermFrameNum = (UnusedShortTermFrameNum + 1) % img->MaxFrameNum;
+ }
+ img->delta_pic_order_cnt[0] = tmp1;
+ img->delta_pic_order_cnt[1] = tmp2;
+ img->frame_num = CurrFrameNum;
+
+}
+
+/*!
+ ************************************************************************
+ * \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 StorablePicture structure
+ ************************************************************************
+ */
+ColocatedParams* alloc_colocated(int size_x, int size_y, int mb_adaptive_frame_field_flag)
+{
+ ColocatedParams *s;
+
+ s = calloc(1, sizeof(ColocatedParams));
+ if (NULL == s)
+ no_mem_exit("alloc_colocated: s");
+
+ s->size_x = size_x;
+ s->size_y = size_y;
+
+
+ get_mem3D ((byte****)(&(s->ref_idx)) , 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
+ get_mem3Dint64 (&(s->ref_pic_id), 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
+ get_mem4Dshort (&(s->mv) , 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE,2 );
+
+ get_mem2D (&(s->moving_block), size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
+ get_mem2D (&(s->field_frame) , size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
+
+ if (mb_adaptive_frame_field_flag)
+ {
+ get_mem3D ((byte****)(&(s->top_ref_idx)) , 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE);
+ get_mem3Dint64 (&(s->top_ref_pic_id), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE);
+ get_mem4Dshort (&(s->top_mv), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE, 2);
+ get_mem2D (&(s->top_moving_block), size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE);
+
+ get_mem3D ((byte****)(&(s->bottom_ref_idx)), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE);
+ get_mem3Dint64 (&(s->bottom_ref_pic_id), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE);
+ get_mem4Dshort (&(s->bottom_mv), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE, 2);
+ get_mem2D (&(s->bottom_moving_block), size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE);
+ }
+
+ s->mb_adaptive_frame_field_flag = mb_adaptive_frame_field_flag;
+
+ return s;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Free co-located memory.
+ *
+ * \param p
+ * Picture to be freed
+ *
+ ************************************************************************
+ */
+void free_colocated(ColocatedParams* p)
+{
+ if (p)
+ {
+ free_mem3D ((byte***)p->ref_idx, 2);
+ free_mem3Dint64 (p->ref_pic_id, 2);
+ free_mem4Dshort (p->mv, 2, p->size_y / BLOCK_SIZE);
+
+ if (p->moving_block)
+ {
+ free_mem2D (p->moving_block);
+ p->moving_block=NULL;
+ }
+ if (p->field_frame)
+ {
+ free_mem2D (p->field_frame);
+ p->field_frame=NULL;
+ }
+
+ if (p->mb_adaptive_frame_field_flag)
+ {
+ free_mem3D ((byte***)p->top_ref_idx, 2);
+ free_mem3Dint64 (p->top_ref_pic_id, 2);
+ free_mem4Dshort (p->top_mv, 2, p->size_y / BLOCK_SIZE / 2);
+
+
+ if (p->top_moving_block)
+ {
+ free_mem2D (p->top_moving_block);
+ p->top_moving_block=NULL;
+ }
+
+ free_mem3D ((byte***)p->bottom_ref_idx, 2);
+ free_mem3Dint64 (p->bottom_ref_pic_id, 2);
+ free_mem4Dshort (p->bottom_mv, 2, p->size_y / BLOCK_SIZE / 2);
+
+
+ if (p->bottom_moving_block)
+ {
+ free_mem2D (p->bottom_moving_block);
+ p->bottom_moving_block=NULL;
+ }
+
+ }
+
+ free(p);
+
+ p=NULL;
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Compute co-located motion info
+ *
+ ************************************************************************
+ */
+
+void compute_colocated(ColocatedParams* p, StorablePicture **listX[6])
+{
+ StorablePicture *fs, *fs_top, *fs_bottom;
+ int i,j, ii, jj, jdiv;
+
+ fs_top=fs_bottom=fs = listX[LIST_1 ][0];
+
+ if (img->MbaffFrameFlag)
+ {
+ fs_top= listX[LIST_1 + 2][0];
+ fs_bottom= listX[LIST_1 + 4][0];
+ }
+ else
+ {
+ if (img->field_pic_flag)
+ {
+ if ((img->structure != fs->structure) && (fs->coded_frame))
+ {
+ if (img->structure==TOP_FIELD)
+ {
+ fs_top=fs_bottom=fs = listX[LIST_1 ][0]->top_field;
+ }
+ else
+ {
+ fs_top=fs_bottom=fs = listX[LIST_1 ][0]->bottom_field;
+ }
+ }
+ }
+ }
+
+ if (!active_sps->frame_mbs_only_flag || active_sps->direct_8x8_inference_flag)
+ {
+ for (j=0 ; j<fs->size_y/4 ; j++)
+ {
+ jdiv = j/2;
+ jj = j/2 + 4 * (j/8);
+ for (i=0 ; i<fs->size_x/4 ; 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 (iabs(dec_picture->poc - fs_bottom->poc)> iabs(dec_picture->poc -fs_top->poc) )
+ {
+ p->mv[LIST_0][j][i][0] = fs_top->mv[LIST_0][jdiv][i][0];
+ p->mv[LIST_0][j][i][1] = fs_top->mv[LIST_0][jdiv][i][1] ;
+ p->mv[LIST_1][j][i][0] = fs_top->mv[LIST_1][jdiv][i][0];
+ p->mv[LIST_1][j][i][1] = fs_top->mv[LIST_1][jdiv][i][1] ;
+ p->ref_idx[LIST_0][j][i] = fs_top->ref_idx[LIST_0][jdiv][i];
+ p->ref_idx[LIST_1][j][i] = fs_top->ref_idx[LIST_1][jdiv][i];
+ p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][jj][i];
+ p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][jj][i];
+
+ p->is_long_term = fs_top->is_long_term;
+ }
+ else
+ {
+ p->mv[LIST_0][j][i][0] = fs_bottom->mv[LIST_0][jdiv][i][0];
+ p->mv[LIST_0][j][i][1] = fs_bottom->mv[LIST_0][jdiv][i][1] ;
+ p->mv[LIST_1][j][i][0] = fs_bottom->mv[LIST_1][jdiv][i][0];
+ p->mv[LIST_1][j][i][1] = fs_bottom->mv[LIST_1][jdiv][i][1] ;
+ p->ref_idx[LIST_0][j][i] = fs_bottom->ref_idx[LIST_0][jdiv][i];
+ p->ref_idx[LIST_1][j][i] = fs_bottom->ref_idx[LIST_1][jdiv][i];
+ p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][jj + 4][i];
+ p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][jj + 4][i];
+
+ p->is_long_term = fs_bottom->is_long_term;
+ }
+ }
+ else
+ {
+ p->mv[LIST_0][j][i][0] = fs->mv[LIST_0][j][i][0];
+ p->mv[LIST_0][j][i][1] = fs->mv[LIST_0][j][i][1] ;
+ p->mv[LIST_1][j][i][0] = fs->mv[LIST_1][j][i][0];
+ p->mv[LIST_1][j][i][1] = fs->mv[LIST_1][j][i][1] ;
+ p->ref_idx[LIST_0][j][i] = fs->ref_idx[LIST_0][j][i];
+ p->ref_idx[LIST_1][j][i] = fs->ref_idx[LIST_1][j][i];
+ p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][j][i];
+ p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][j][i];
+
+ p->is_long_term = fs->is_long_term;
+ }
+ }
+ }
+ }
+
+
+ //! Generate field MVs from Frame MVs
+ if (img->structure || img->MbaffFrameFlag)
+ {
+ for (j=0 ; j<fs->size_y/8 ; j++)
+ {
+ jj = RSD(j);
+ for (i=0 ; i<fs->size_x/4 ; i++)
+ {
+ ii = RSD(i);
+ //! Do nothing if macroblock as field coded in MB-AFF
+ if (!img->MbaffFrameFlag )
+ {
+ p->mv[LIST_0][j][i][0] = fs->mv[LIST_0][jj][ii][0];
+ p->mv[LIST_0][j][i][1] = fs->mv[LIST_0][jj][ii][1];
+ p->mv[LIST_1][j][i][0] = fs->mv[LIST_1][jj][ii][0];
+ p->mv[LIST_1][j][i][1] = fs->mv[LIST_1][jj][ii][1];
+
+ // Scaling of references is done here since it will not affect spatial direct (2*0 =0)
+
+ if (fs->ref_idx[LIST_0][jj][ii] == -1)
+ {
+ p->ref_idx [LIST_0][j][i] = -1;
+ p->ref_pic_id[LIST_0][j][i] = -1;
+ }
+ else
+ {
+ p->ref_idx [LIST_0][j][i] = fs->ref_idx[LIST_0][jj][ii] ;
+ p->ref_pic_id[LIST_0][j][i] = fs->ref_id [LIST_0][jj][ii];
+ }
+
+ if (fs->ref_idx[LIST_1][jj][ii] == -1)
+ {
+ p->ref_idx [LIST_1][j][i] = -1;
+ p->ref_pic_id[LIST_1][j][i] = -1;
+ }
+ else
+ {
+ p->ref_idx [LIST_1][j][i] = fs->ref_idx[LIST_1][jj][ii];
+ p->ref_pic_id[LIST_1][j][i] = fs->ref_id [LIST_1][jj][ii];
+ }
+
+ p->is_long_term = fs->is_long_term;
+
+ if (img->direct_spatial_mv_pred_flag == 1)
+ {
+ p->moving_block[j][i] =
+ !((!p->is_long_term
+ && ((p->ref_idx[LIST_0][j][i] == 0)
+ && (iabs(p->mv[LIST_0][j][i][0])>>1 == 0)
+ && (iabs(p->mv[LIST_0][j][i][1])>>1 == 0)))
+ || ((p->ref_idx[LIST_0][j][i] == -1)
+ && (p->ref_idx[LIST_1][j][i] == 0)
+ && (iabs(p->mv[LIST_1][j][i][0])>>1 == 0)
+ && (iabs(p->mv[LIST_1][j][i][1])>>1 == 0)));
+ }
+ }
+ else
+ {
+ p->bottom_mv[LIST_0][j][i][0] = fs_bottom->mv[LIST_0][jj][ii][0];
+ p->bottom_mv[LIST_0][j][i][1] = fs_bottom->mv[LIST_0][jj][ii][1];
+ p->bottom_mv[LIST_1][j][i][0] = fs_bottom->mv[LIST_1][jj][ii][0];
+ p->bottom_mv[LIST_1][j][i][1] = fs_bottom->mv[LIST_1][jj][ii][1];
+ p->bottom_ref_idx[LIST_0][j][i] = fs_bottom->ref_idx[LIST_0][jj][ii];
+ p->bottom_ref_idx[LIST_1][j][i] = fs_bottom->ref_idx[LIST_1][jj][ii];
+ p->bottom_ref_pic_id[LIST_0][j][i] = fs_bottom->ref_id[LIST_0][jj][ii];
+ p->bottom_ref_pic_id[LIST_1][j][i] = fs_bottom->ref_id[LIST_1][jj][ii];
+
+ if (img->direct_spatial_mv_pred_flag == 1)
+ {
+ p->bottom_moving_block[j][i] =
+ !((!fs_bottom->is_long_term
+ && ((p->bottom_ref_idx[LIST_0][j][i] == 0)
+ && (iabs(p->bottom_mv[LIST_0][j][i][0])>>1 == 0)
+ && (iabs(p->bottom_mv[LIST_0][j][i][1])>>1 == 0)))
+ || ((p->bottom_ref_idx[LIST_0][j][i] == -1)
+ && (p->bottom_ref_idx[LIST_1][j][i] == 0)
+ && (iabs(p->bottom_mv[LIST_1][j][i][0])>>1 == 0)
+ && (iabs(p->bottom_mv[LIST_1][j][i][1])>>1 == 0)));
+ }
+
+ p->top_mv[LIST_0][j][i][0] = fs_top->mv[LIST_0][jj][ii][0];
+ p->top_mv[LIST_0][j][i][1] = fs_top->mv[LIST_0][jj][ii][1];
+ p->top_mv[LIST_1][j][i][0] = fs_top->mv[LIST_1][jj][ii][0];
+ p->top_mv[LIST_1][j][i][1] = fs_top->mv[LIST_1][jj][ii][1];
+ p->top_ref_idx[LIST_0][j][i] = fs_top->ref_idx[LIST_0][jj][ii];
+ p->top_ref_idx[LIST_1][j][i] = fs_top->ref_idx[LIST_1][jj][ii];
+ p->top_ref_pic_id[LIST_0][j][i] = fs_top->ref_id[LIST_0][jj][ii];
+ p->top_ref_pic_id[LIST_1][j][i] = fs_top->ref_id[LIST_1][jj][ii];
+
+ if (img->direct_spatial_mv_pred_flag == 1)
+ {
+ p->top_moving_block[j][i] =
+ !((!fs_top->is_long_term
+ && ((p->top_ref_idx[LIST_0][j][i] == 0)
+ && (iabs(p->top_mv[LIST_0][j][i][0])>>1 == 0)
+ && (iabs(p->top_mv[LIST_0][j][i][1])>>1 == 0)))
+ || ((p->top_ref_idx[LIST_0][j][i] == -1)
+ && (p->top_ref_idx[LIST_1][j][i] == 0)
+ && (iabs(p->top_mv[LIST_1][j][i][0])>>1 == 0)
+ && (iabs(p->top_mv[LIST_1][j][i][1])>>1 == 0)));
+ }
+
+ if ((img->direct_spatial_mv_pred_flag == 0 ) && !fs->field_frame[2*j][i])
+ {
+ p->top_mv[LIST_0][j][i][1] /= 2;
+ p->top_mv[LIST_1][j][i][1] /= 2;
+ p->bottom_mv[LIST_0][j][i][1] /= 2;
+ p->bottom_mv[LIST_1][j][i][1] /= 2;
+ }
+
+ }
+ }
+ }
+ }
+
+
+ if (!active_sps->frame_mbs_only_flag || active_sps->direct_8x8_inference_flag)
+ {
+ //! Use inference flag to remap mvs/references
+ //! Frame with field co-located
+
+ if (!img->structure)
+ {
+ for (j=0 ; j<fs->size_y/4 ; j++)
+ {
+ jdiv = j/2;
+ jj = j/2 + 4*(j/8);
+ for (i=0 ; i<fs->size_x/4 ; i++)
+ {
+
+ if (fs->field_frame[j][i])
+ {
+ if (iabs(dec_picture->poc - fs->bottom_field->poc) > iabs(dec_picture->poc - fs->top_field->poc))
+ {
+ p->mv[LIST_0][j][i][0] = fs->top_field->mv[LIST_0][jdiv][i][0];
+ p->mv[LIST_0][j][i][1] = fs->top_field->mv[LIST_0][jdiv][i][1] ;
+ p->mv[LIST_1][j][i][0] = fs->top_field->mv[LIST_1][jdiv][i][0];
+ p->mv[LIST_1][j][i][1] = fs->top_field->mv[LIST_1][jdiv][i][1] ;
+
+ p->ref_idx[LIST_0][j][i] = fs->top_field->ref_idx[LIST_0][jdiv][i];
+ p->ref_idx[LIST_1][j][i] = fs->top_field->ref_idx[LIST_1][jdiv][i];
+ p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][jj][i];
+ p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][jj][i];
+ p->is_long_term = fs->top_field->is_long_term;
+ }
+ else
+ {
+ p->mv[LIST_0][j][i][0] = fs->bottom_field->mv[LIST_0][jdiv][i][0];
+ p->mv[LIST_0][j][i][1] = fs->bottom_field->mv[LIST_0][jdiv][i][1] ;
+ p->mv[LIST_1][j][i][0] = fs->bottom_field->mv[LIST_1][jdiv][i][0];
+ p->mv[LIST_1][j][i][1] = fs->bottom_field->mv[LIST_1][jdiv][i][1] ;
+
+ p->ref_idx[LIST_0][j][i] = fs->bottom_field->ref_idx[LIST_0][jdiv][i];
+ p->ref_idx[LIST_1][j][i] = fs->bottom_field->ref_idx[LIST_1][jdiv][i];
+ p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][jj + 4][i];
+ p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][jj + 4][i];
+ p->is_long_term = fs->bottom_field->is_long_term;
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ p->is_long_term = fs->is_long_term;
+
+ if (!active_sps->frame_mbs_only_flag || active_sps->direct_8x8_inference_flag)
+ {
+ for (j=0 ; j<fs->size_y/4 ; j++)
+ {
+ jj = RSD(j);
+ for (i=0 ; i<fs->size_x/4 ; i++)
+ {
+ ii = RSD(i);
+
+ p->mv[LIST_0][j][i][0]=p->mv[LIST_0][jj][ii][0];
+ p->mv[LIST_0][j][i][1]=p->mv[LIST_0][jj][ii][1];
+ p->mv[LIST_1][j][i][0]=p->mv[LIST_1][jj][ii][0];
+ p->mv[LIST_1][j][i][1]=p->mv[LIST_1][jj][ii][1];
+
+ p->ref_idx[LIST_0][j][i]=p->ref_idx[LIST_0][jj][ii];
+ p->ref_idx[LIST_1][j][i]=p->ref_idx[LIST_1][jj][ii];
+ p->ref_pic_id[LIST_0][j][i] = p->ref_pic_id[LIST_0][jj][ii];
+ p->ref_pic_id[LIST_1][j][i] = p->ref_pic_id[LIST_1][jj][ii];
+
+ if (img->direct_spatial_mv_pred_flag == 1)
+ {
+ p->moving_block[j][i]=
+ !((!p->is_long_term
+ && ((p->ref_idx[LIST_0][j][i] == 0)
+ && (iabs(p->mv[LIST_0][j][i][0])>>1 == 0)
+ && (iabs(p->mv[LIST_0][j][i][1])>>1 == 0)))
+ || ((p->ref_idx[LIST_0][j][i] == -1)
+ && (p->ref_idx[LIST_1][j][i] == 0)
+ && (iabs(p->mv[LIST_1][j][i][0])>>1 == 0)
+ && (iabs(p->mv[LIST_1][j][i][1])>>1 == 0)));
+ }
+ }
+ }
+ }
+ else
+ {
+ for (j=0 ; j<fs->size_y/4 ; j++)
+ {
+ jj = RSD(j);
+ for (i=0 ; i<fs->size_x/4 ; i++)
+ {
+ ii = RSD(i);
+ //! Use inference flag to remap mvs/references
+ p->mv[LIST_0][j][i][0]=fs->mv[LIST_0][j][i][0];
+ p->mv[LIST_0][j][i][1]=fs->mv[LIST_0][j][i][1];
+ p->mv[LIST_1][j][i][0]=fs->mv[LIST_1][j][i][0];
+ p->mv[LIST_1][j][i][1]=fs->mv[LIST_1][j][i][1];
+
+ p->ref_idx[LIST_0][j][i]=fs->ref_idx[LIST_0][j][i];
+ p->ref_idx[LIST_1][j][i]=fs->ref_idx[LIST_1][j][i];
+ p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][j][i];
+ p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][j][i];
+
+ if (img->direct_spatial_mv_pred_flag == 1)
+ {
+ p->moving_block[j][i]=
+ !((!p->is_long_term
+ && ((p->ref_idx[LIST_0][j][i] == 0)
+ && (iabs(p->mv[LIST_0][j][i][0])>>1 == 0)
+ && (iabs(p->mv[LIST_0][j][i][1])>>1 == 0)))
+ || ((p->ref_idx[LIST_0][j][i] == -1)
+ && (p->ref_idx[LIST_1][j][i] == 0)
+ && (iabs(p->mv[LIST_1][j][i][0])>>1 == 0)
+ && (iabs(p->mv[LIST_1][j][i][1])>>1 == 0)));
+ }
+ }
+ }
+ }
+
+
+ if (img->direct_spatial_mv_pred_flag ==0)
+ {
+ for (j=0 ; j<fs->size_y/4 ; j++)
+ {
+ for (i=0 ; i<fs->size_x/4 ; 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] /= 2;
+ p->mv[LIST_1][j][i][1] /= 2;
+ }
+
+ }
+ }
+
+ for (j=0; j<2 + (img->MbaffFrameFlag * 4);j+=2)
+ {
+ for (i=0; i<listXsize[j];i++)
+ {
+ int prescale, iTRb, iTRp;
+
+ if (j==0)
+ {
+ iTRb = iClip3( -128, 127, dec_picture->poc - listX[LIST_0 + j][i]->poc );
+ }
+ else if (j == 2)
+ {
+ iTRb = iClip3( -128, 127, dec_picture->top_poc - listX[LIST_0 + j][i]->poc );
+ }
+ else
+ {
+ iTRb = iClip3( -128, 127, dec_picture->bottom_poc - listX[LIST_0 + j][i]->poc );
+ }
+
+ iTRp = iClip3( -128, 127, listX[LIST_1 + j][0]->poc - listX[LIST_0 + j][i]->poc);
+
+ if (iTRp!=0)
+ {
+ prescale = ( 16384 + iabs( iTRp / 2 ) ) / iTRp;
+ img->mvscale[j][i] = iClip3( -1024, 1023, ( iTRb * prescale + 32 ) >> 6 ) ;
+ }
+ else
+ {
+ img->mvscale[j][i] = 9999;
+ }
+ }
+ }
+ }
+}
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/mbuffer.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/mbuffer.h:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/mbuffer.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,223 @@
+
+/*!
+ ***********************************************************************
+ * \file
+ * mbuffer.h
+ *
+ * \brief
+ * Frame buffer functions
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Karsten Sühring <suehring at hhi.de>
+ * - Jill Boyce <jill.boyce at thomson.net>
+ * - Saurav K Bandyopadhyay <saurav at ieee.org>
+ * - Zhenyu Wu <Zhenyu.Wu at thomson.net
+ * - Purvin Pandit <Purvin.Pandit at thomson.net>
+ *
+ ***********************************************************************
+ */
+#ifndef _MBUFFER_H_
+#define _MBUFFER_H_
+
+#include "global.h"
+
+#define MAX_LIST_SIZE 33
+
+//! definition a picture (field or frame)
+typedef struct storable_picture
+{
+ PictureStructure structure;
+
+ int poc;
+ int top_poc;
+ int bottom_poc;
+ int frame_poc;
+ int64 ref_pic_num [MAX_NUM_SLICES][6][MAX_LIST_SIZE];
+ int64 frm_ref_pic_num [MAX_NUM_SLICES][6][MAX_LIST_SIZE];
+ int64 top_ref_pic_num [MAX_NUM_SLICES][6][MAX_LIST_SIZE];
+ int64 bottom_ref_pic_num [MAX_NUM_SLICES][6][MAX_LIST_SIZE];
+ unsigned frame_num;
+ unsigned recovery_frame;
+
+ int pic_num;
+ int long_term_pic_num;
+ int long_term_frame_idx;
+
+ int is_long_term;
+ int used_for_reference;
+ int is_output;
+ int non_existing;
+
+ short max_slice_id;
+
+ int size_x, size_y, size_x_cr, size_y_cr;
+ int size_x_m1, size_y_m1, size_x_cr_m1, size_y_cr_m1;
+ int chroma_vector_adjustment;
+ int coded_frame;
+ int MbaffFrameFlag;
+ unsigned PicWidthInMbs;
+ unsigned PicSizeInMbs;
+
+ imgpel ** imgY; //!< Y picture component
+ imgpel *** imgUV; //!< U and V picture components
+
+ byte * mb_field; //!< field macroblock indicator
+
+ short ** slice_id; //!< reference picture [mb_x][mb_y]
+
+ char *** ref_idx; //!< reference picture [list][subblock_y][subblock_x]
+
+ int64 *** ref_pic_id; //!< reference picture identifier [list][subblock_y][subblock_x]
+ // (not simply index)
+
+ int64 *** ref_id; //!< reference picture identifier [list][subblock_y][subblock_x]
+ // (not simply index)
+
+ short **** mv; //!< motion vector [list][subblock_y][subblock_x][component]
+
+ byte ** moving_block;
+ byte ** field_frame; //!< indicates if co_located is field or frame.
+
+ struct storable_picture *top_field; // for mb aff, if frame for referencing the top field
+ struct storable_picture *bottom_field; // for mb aff, if frame for referencing the bottom field
+ struct storable_picture *frame; // for mb aff, if field for referencing the combined frame
+
+ int slice_type;
+ int idr_flag;
+ int no_output_of_prior_pics_flag;
+ int long_term_reference_flag;
+ int adaptive_ref_pic_buffering_flag;
+
+ int chroma_format_idc;
+ int frame_mbs_only_flag;
+ int frame_cropping_flag;
+ int frame_cropping_rect_left_offset;
+ int frame_cropping_rect_right_offset;
+ int frame_cropping_rect_top_offset;
+ int frame_cropping_rect_bottom_offset;
+ int qp;
+ int chroma_qp_offset[2];
+ int slice_qp_delta;
+ DecRefPicMarking_t *dec_ref_pic_marking_buffer; //!< stores the memory management control operations
+
+ // picture error concealment
+ int concealed_pic; //indicates if this is a concealed picutre
+
+} StorablePicture;
+
+
+//! definition a picture (field or frame)
+typedef struct colocated_params
+{
+ int mb_adaptive_frame_field_flag;
+ int size_x, size_y;
+
+ int64 ref_pic_num[6][MAX_LIST_SIZE];
+
+ char *** ref_idx; //!< reference picture [list][subblock_y][subblock_x]
+ int64 *** ref_pic_id; //!< reference picture identifier [list][subblock_y][subblock_x]
+ short **** mv; //!< motion vector [list][subblock_y][subblock_x][component]
+ byte ** moving_block;
+
+ // Top field params
+ int64 top_ref_pic_num[6][MAX_LIST_SIZE];
+ char *** top_ref_idx; //!< reference picture [list][subblock_y][subblock_x]
+ int64 *** top_ref_pic_id; //!< reference picture identifier [list][subblock_y][subblock_x]
+ short **** top_mv; //!< motion vector [list][subblock_y][subblock_x][component]
+ byte ** top_moving_block;
+
+ // Bottom field params
+ int64 bottom_ref_pic_num[6][MAX_LIST_SIZE];
+ char *** bottom_ref_idx; //!< reference picture [list][subblock_y][subblock_x]
+ int64 *** bottom_ref_pic_id; //!< reference picture identifier [list][subblock_y][subblock_x]
+ short **** bottom_mv; //!< motion vector [list][subblock_y][subblock_x][component]
+ byte ** bottom_moving_block;
+
+ byte is_long_term;
+ byte ** field_frame; //!< indicates if co_located is field or frame.
+
+} ColocatedParams;
+
+//! Frame Stores for Decoded Picture Buffer
+typedef struct frame_store
+{
+ int is_used; //!< 0=empty; 1=top; 2=bottom; 3=both fields (or frame)
+ int is_reference; //!< 0=not used for ref; 1=top used; 2=bottom used; 3=both fields (or frame) used
+ int is_long_term; //!< 0=not used for ref; 1=top used; 2=bottom used; 3=both fields (or frame) used
+ int is_orig_reference; //!< original marking by nal_ref_idc: 0=not used for ref; 1=top used; 2=bottom used; 3=both fields (or frame) used
+
+ int is_non_existent;
+
+ unsigned frame_num;
+ unsigned recovery_frame;
+
+ int frame_num_wrap;
+ int long_term_frame_idx;
+ int is_output;
+ int poc;
+
+ // picture error concealment
+ int concealment_reference;
+
+ StorablePicture *frame;
+ StorablePicture *top_field;
+ StorablePicture *bottom_field;
+
+} FrameStore;
+
+
+//! Decoded Picture Buffer
+typedef struct decoded_picture_buffer
+{
+ FrameStore **fs;
+ FrameStore **fs_ref;
+ FrameStore **fs_ltref;
+ unsigned size;
+ unsigned used_size;
+ unsigned ref_frames_in_buffer;
+ unsigned ltref_frames_in_buffer;
+ int last_output_poc;
+ int max_long_term_pic_idx;
+
+ int init_done;
+ int num_ref_frames;
+
+ FrameStore *last_picture;
+} DecodedPictureBuffer;
+
+
+extern DecodedPictureBuffer dpb;
+extern StorablePicture **listX[6];
+extern int listXsize[6];
+
+void init_dpb(void);
+void free_dpb(void);
+FrameStore* alloc_frame_store(void);
+void free_frame_store(FrameStore* f);
+StorablePicture* alloc_storable_picture(PictureStructure type, int size_x, int size_y, int size_x_cr, int size_y_cr);
+void free_storable_picture(StorablePicture* p);
+void store_picture_in_dpb(StorablePicture* p);
+void flush_dpb(void);
+
+void dpb_split_field(FrameStore *fs);
+void dpb_combine_field(FrameStore *fs);
+void dpb_combine_field_yuv(FrameStore *fs);
+
+void init_lists(int currSliceType, PictureStructure currPicStructure);
+void reorder_ref_pic_list(StorablePicture **list, int *list_size,
+ int num_ref_idx_lX_active_minus1, int *reordering_of_pic_nums_idc,
+ int *abs_diff_pic_num_minus1, int *long_term_pic_idx);
+
+void init_mbaff_lists();
+void alloc_ref_pic_list_reordering_buffer(Slice *currSlice);
+void free_ref_pic_list_reordering_buffer(Slice *currSlice);
+
+void fill_frame_num_gap(ImageParameters *img);
+
+ColocatedParams* alloc_colocated(int size_x, int size_y,int mb_adaptive_frame_field_flag);
+void free_colocated(ColocatedParams* p);
+void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]);
+
+#endif
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/memalloc.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/memalloc.c:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/memalloc.c Sun Feb 4 08:38:31 2007
@@ -0,0 +1,591 @@
+
+/*!
+************************************************************************
+* \file memalloc.c
+*
+* \brief
+* Memory allocation and free helper funtions
+*
+* \author
+* Main contributors (see contributors.h for copyright, address and affiliation details)
+************************************************************************
+*/
+
+#include <stdlib.h>
+#include "memalloc.h"
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocate 2D memory array -> imgpel array2D[rows][columns]
+ *
+ * \par Output:
+ * memory size in bytes
+ ************************************************************************/
+int get_mem2Dpel(imgpel ***array2D, int rows, int columns)
+{
+ int i;
+
+ if((*array2D = (imgpel**)calloc(rows, sizeof(imgpel*))) == NULL)
+ no_mem_exit("get_mem2Dpel: array2D");
+ if(((*array2D)[0] = (imgpel* )calloc(rows*columns,sizeof(imgpel ))) == NULL)
+ no_mem_exit("get_mem2Dpel: array2D");
+
+ for(i=1 ; i<rows ; i++)
+ (*array2D)[i] = (*array2D)[i-1] + columns ;
+
+ return rows*columns*sizeof(imgpel);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocate 3D memory array -> imgpel array3D[frames][rows][columns]
+ *
+ * \par Output:
+ * memory size in bytes
+ ************************************************************************
+ */
+int get_mem3Dpel(imgpel ****array3D, int frames, int rows, int columns)
+{
+ int j;
+
+ if(((*array3D) = (imgpel***)calloc(frames,sizeof(imgpel**))) == NULL)
+ no_mem_exit("get_mem3Dpel: array3D");
+
+ for(j=0;j<frames;j++)
+ get_mem2Dpel( (*array3D)+j, rows, columns ) ;
+
+ return frames*rows*columns*sizeof(imgpel);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * free 2D memory array
+ * which was alocated with get_mem2Dpel()
+ ************************************************************************
+ */
+void free_mem2Dpel(imgpel **array2D)
+{
+ if (array2D)
+ {
+ if (array2D[0])
+ free (array2D[0]);
+ else error ("free_mem2Dpel: trying to free unused memory",100);
+
+ free (array2D);
+ } else
+ {
+ error ("free_mem2Dpel: trying to free unused memory",100);
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * free 3D memory array
+ * which was alocated with get_mem3Dpel()
+ ************************************************************************
+ */
+void free_mem3Dpel(imgpel ***array3D, int frames)
+{
+ int i;
+
+ if (array3D)
+ {
+ for (i=0;i<frames;i++)
+ {
+ free_mem2Dpel(array3D[i]);
+ }
+ free (array3D);
+ } else
+ {
+ error ("free_mem3Dpel: trying to free unused memory",100);
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocate 2D memory array -> unsigned char array2D[rows][columns]
+ *
+ * \par Output:
+ * memory size in bytes
+ ************************************************************************/
+// Change 9-Aug-2001 P. List: dont allocate independant row arrays anymore
+// but one complete array and move row-pointers to array. Now you can step
+// to the next line with an offset of img->width
+int get_mem2D(byte ***array2D, int rows, int columns)
+{
+ int i;
+
+ if((*array2D = (byte**)calloc(rows, sizeof(byte*))) == NULL)
+ no_mem_exit("get_mem2D: array2D");
+ if(((*array2D)[0] = (byte* )calloc(columns*rows,sizeof(byte ))) == NULL)
+ no_mem_exit("get_mem2D: array2D");
+
+ for(i=1;i<rows;i++)
+ (*array2D)[i] = (*array2D)[i-1] + columns ;
+
+ return rows*columns;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocate 2D memory array -> int array2D[rows][columns]
+ *
+ * \par Output:
+ * memory size in bytes
+ ************************************************************************
+ */
+// same change as in get_mem2Dint
+int get_mem2Dint(int ***array2D, int rows, int columns)
+{
+ int i;
+
+ if((*array2D = (int**)calloc(rows, sizeof(int*))) == NULL)
+ no_mem_exit("get_mem2Dint: array2D");
+ if(((*array2D)[0] = (int* )calloc(rows*columns,sizeof(int ))) == NULL)
+ no_mem_exit("get_mem2Dint: array2D");
+
+ for(i=1 ; i<rows ; i++)
+ (*array2D)[i] = (*array2D)[i-1] + columns ;
+
+ return rows*columns*sizeof(int);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocate 2D memory array -> int64 array2D[rows][columns]
+ *
+ * \par Output:
+ * memory size in bytes
+ ************************************************************************
+ */
+// same change as in get_mem2Dint
+int get_mem2Dint64(int64 ***array2D, int rows, int columns)
+{
+ int i;
+
+ if((*array2D = (int64**)calloc(rows, sizeof(int64*))) == NULL)
+ no_mem_exit("get_mem2Dint64: array2D");
+ if(((*array2D)[0] = (int64* )calloc(rows*columns,sizeof(int64 ))) == NULL)
+ no_mem_exit("get_mem2Dint64: array2D");
+
+ for(i=1 ; i<rows ; i++)
+ (*array2D)[i] = (*array2D)[i-1] + columns ;
+
+ return rows*columns*sizeof(int64);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocate 3D memory array -> unsigned char array3D[frames][rows][columns]
+ *
+ * \par Output:
+ * memory size in bytes
+ ************************************************************************
+ */
+// same change as in get_mem2Dint
+int get_mem3D(byte ****array3D, int frames, int rows, int columns)
+{
+ int j;
+
+ if(((*array3D) = (byte***)calloc(frames,sizeof(byte**))) == NULL)
+ no_mem_exit("get_mem3D: array3D");
+
+ for(j=0;j<frames;j++)
+ get_mem2D( (*array3D)+j, rows, columns ) ;
+
+ return frames*rows*columns;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocate 3D memory array -> int array3D[frames][rows][columns]
+ *
+ * \par Output:
+ * memory size in bytes
+ ************************************************************************
+ */
+// same change as in get_mem2Dint
+int get_mem3Dint(int ****array3D, int frames, int rows, int columns)
+{
+ int j;
+
+ if(((*array3D) = (int***)calloc(frames,sizeof(int**))) == NULL)
+ no_mem_exit("get_mem3Dint: array3D");
+
+ for(j=0;j<frames;j++)
+ get_mem2Dint( (*array3D)+j, rows, columns ) ;
+
+ return frames*rows*columns*sizeof(int);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocate 3D memory array -> int64 array3D[frames][rows][columns]
+ *
+ * \par Output:
+ * memory size in bytes
+ ************************************************************************
+ */
+// same change as in get_mem2Dint
+int get_mem3Dint64(int64 ****array3D, int frames, int rows, int columns)
+{
+ int j;
+
+ if(((*array3D) = (int64***)calloc(frames,sizeof(int64**))) == NULL)
+ no_mem_exit("get_mem3Dint64: array3D");
+
+ for(j=0;j<frames;j++)
+ get_mem2Dint64( (*array3D)+j, rows, columns ) ;
+
+ return frames*rows*columns*sizeof(int64);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocate 4D memory array -> int array3D[frames][rows][columns][component]
+ *
+ * \par Output:
+ * memory size in bytes
+ ************************************************************************
+ */
+// same change as in get_mem2Dint
+int get_mem4Dint(int *****array4D, int idx, int frames, int rows, int columns )
+{
+ int j;
+
+ if(((*array4D) = (int****)calloc(idx,sizeof(int**))) == NULL)
+ no_mem_exit("get_mem4Dint: array4D");
+
+ for(j=0;j<idx;j++)
+ get_mem3Dint( (*array4D)+j, frames, rows, columns ) ;
+
+ return idx*frames*rows*columns*sizeof(int);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * free 2D memory array
+ * which was alocated with get_mem2D()
+ ************************************************************************
+ */
+void free_mem2D(byte **array2D)
+{
+ if (array2D)
+ {
+ if (array2D[0])
+ free (array2D[0]);
+ else error ("free_mem2D: trying to free unused memory",100);
+
+ free (array2D);
+ } else
+ {
+ error ("free_mem2D: trying to free unused memory",100);
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * free 2D memory array
+ * which was alocated with get_mem2Dint()
+ ************************************************************************
+ */
+void free_mem2Dint(int **array2D)
+{
+ if (array2D)
+ {
+ if (array2D[0])
+ free (array2D[0]);
+ else error ("free_mem2Dint: trying to free unused memory",100);
+
+ free (array2D);
+
+ } else
+ {
+ error ("free_mem2Dint: trying to free unused memory",100);
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * free 2D memory array
+ * which was alocated with get_mem2Dint64()
+ ************************************************************************
+ */
+void free_mem2Dint64(int64 **array2D)
+{
+ if (array2D)
+ {
+ if (array2D[0])
+ free (array2D[0]);
+ else error ("free_mem2Dint64: trying to free unused memory",100);
+
+ free (array2D);
+
+ } else
+ {
+ error ("free_mem2Dint64: trying to free unused memory",100);
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * free 3D memory array
+ * which was alocated with get_mem3D()
+ ************************************************************************
+ */
+void free_mem3D(byte ***array3D, int frames)
+{
+ int i;
+
+ if (array3D)
+ {
+ for (i=0;i<frames;i++)
+ {
+ free_mem2D(array3D[i]);
+ }
+ free (array3D);
+ } else
+ {
+ error ("free_mem3D: trying to free unused memory",100);
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * free 3D memory array
+ * which was alocated with get_mem3Dint()
+ ************************************************************************
+ */
+void free_mem3Dint(int ***array3D, int frames)
+{
+ int i;
+
+ if (array3D)
+ {
+ for (i=0;i<frames;i++)
+ {
+ free_mem2Dint(array3D[i]);
+ }
+ free (array3D);
+ } else
+ {
+ error ("free_mem3D: trying to free unused memory",100);
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * free 3D memory array
+ * which was alocated with get_mem3Dint64()
+ ************************************************************************
+ */
+void free_mem3Dint64(int64 ***array3D, int frames)
+{
+ int i;
+
+ if (array3D)
+ {
+ for (i=0;i<frames;i++)
+ {
+ free_mem2Dint64(array3D[i]);
+ }
+ free (array3D);
+ } else
+ {
+ error ("free_mem3Dint64: trying to free unused memory",100);
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * free 4D memory array
+ * which was alocated with get_mem4Dint()
+ ************************************************************************
+ */
+void free_mem4Dint(int ****array4D, int idx, int frames )
+{
+ int j;
+
+ if (array4D)
+ {
+ for(j=0;j<idx;j++)
+ free_mem3Dint( array4D[j], frames) ;
+ free (array4D);
+ } else
+ {
+ error ("free_mem4D: trying to free unused memory",100);
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Exit program if memory allocation failed (using error())
+ * \param where
+ * string indicating which memory allocation failed
+ ************************************************************************
+ */
+void no_mem_exit(char *where)
+{
+ snprintf(errortext, ET_SIZE, "Could not allocate memory: %s",where);
+ error (errortext, 100);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocate 2D short memory array -> short array2D[rows][columns]
+ *
+ * \par Output:
+ * memory size in bytes
+ ************************************************************************
+ */
+int get_mem2Dshort(short ***array2D, int rows, int columns)
+{
+ int i;
+
+ if((*array2D = (short**)calloc(rows, sizeof(short*))) == NULL)
+ no_mem_exit("get_mem2Dshort: array2D");
+ if(((*array2D)[0] = (short* )calloc(rows*columns,sizeof(short ))) == NULL)
+ no_mem_exit("get_mem2Dshort: array2D");
+
+ for(i=1 ; i<rows ; i++)
+ (*array2D)[i] = (*array2D)[i-1] + columns ;
+
+ return rows*columns*sizeof(short);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocate 3D memory short array -> short array3D[frames][rows][columns]
+ *
+ * \par Output:
+ * memory size in bytes
+ ************************************************************************
+ */
+int get_mem3Dshort(short ****array3D, int frames, int rows, int columns)
+{
+ int j;
+
+ if(((*array3D) = (short***)calloc(frames,sizeof(short**))) == NULL)
+ no_mem_exit("get_mem3Dshort: array3D");
+
+ for(j=0;j<frames;j++)
+ get_mem2Dshort( (*array3D)+j, rows, columns ) ;
+
+ return frames*rows*columns*sizeof(short);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Allocate 4D memory short array -> short array3D[frames][rows][columns][component]
+ *
+ * \par Output:
+ * memory size in bytes
+ ************************************************************************
+ */
+int get_mem4Dshort(short *****array4D, int idx, int frames, int rows, int columns )
+{
+ int j;
+
+ if(((*array4D) = (short****)calloc(idx,sizeof(short**))) == NULL)
+ no_mem_exit("get_mem4Dshort: array4D");
+
+ for(j=0;j<idx;j++)
+ get_mem3Dshort( (*array4D)+j, frames, rows, columns ) ;
+
+ return idx*frames*rows*columns*sizeof(short);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * free 2D short memory array
+ * which was allocated with get_mem2Dshort()
+ ************************************************************************
+ */
+void free_mem2Dshort(short **array2D)
+{
+ if (array2D)
+ {
+ if (array2D[0])
+ free (array2D[0]);
+ else error ("free_mem2Dshort: trying to free unused memory",100);
+
+ free (array2D);
+
+ } else
+ {
+ error ("free_mem2Dshort: trying to free unused memory",100);
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * free 3D short memory array
+ * which was allocated with get_mem3Dshort()
+ ************************************************************************
+ */
+void free_mem3Dshort(short ***array3D, int frames)
+{
+ int i;
+
+ if (array3D)
+ {
+ for (i=0;i<frames;i++)
+ {
+ free_mem2Dshort(array3D[i]);
+ }
+ free (array3D);
+ } else
+ {
+ error ("free_mem3Dshort: trying to free unused memory",100);
+ }
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * free 4D short memory array
+ * which was allocated with get_mem4Dshort()
+ ************************************************************************
+ */
+void free_mem4Dshort(short ****array4D, int idx, int frames )
+{
+ int j;
+
+ if (array4D)
+ {
+ for(j=0;j<idx;j++)
+ free_mem3Dshort( array4D[j], frames) ;
+ free (array4D);
+ } else
+ {
+ error ("free_mem4Dshort: trying to free unused memory",100);
+ }
+}
Index: llvm-test/MultiSource/Applications/JM/ldecod/memalloc.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/memalloc.h:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/memalloc.h Sun Feb 4 08:38:31 2007
@@ -0,0 +1,55 @@
+
+/*!
+ ************************************************************************
+ * \file memalloc.h
+ *
+ * \brief
+ * Memory allocation and free helper funtions
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ ************************************************************************
+ */
+
+#ifndef _MEMALLOC_H_
+#define _MEMALLOC_H_
+
+#include "global.h"
+
+int get_mem2D(byte ***array2D, int rows, int columns);
+int get_mem3D(byte ****array2D, int frames, int rows, int columns);
+
+int get_mem2Dint(int ***array2D, int rows, int columns);
+int get_mem3Dint(int ****array3D, int frames, int rows, int columns);
+int get_mem4Dint(int *****array4D, int idx, int frames, int rows, int columns );
+
+int get_mem3Dint64(int64 ****array3D, int frames, int rows, int columns);
+int get_mem2Dint64(int64 ***array2D, int rows, int columns);
+
+int get_mem2Dshort(short ***array2D, int rows, int columns);
+int get_mem3Dshort(short ****array3D, int frames, int rows, int columns);
+int get_mem4Dshort(short *****array4D, int idx, int frames, int rows, int columns );
+
+int get_mem2Dpel(imgpel ***array2D, int rows, int columns);
+int get_mem3Dpel(imgpel ****array3D, int frames, int rows, int columns);
+
+void free_mem2D(byte **array2D);
+void free_mem3D(byte ***array2D, int frames);
+
+void free_mem2Dint(int **array2D);
+void free_mem3Dint(int ***array3D, int frames);
+void free_mem4Dint(int ****array4D, int idx, int frames);
+
+void free_mem2Dint64(int64 **array2D);
+void free_mem3Dint64(int64 ***array3D64, int frames);
+
+void free_mem2Dshort(short **array2D);
+void free_mem3Dshort(short ***array3D, int frames);
+void free_mem4Dshort(short ****array4D, int idx, int frames);
+
+void free_mem2Dpel(imgpel **array2D);
+void free_mem3Dpel(imgpel ***array3D, int frames);
+
+void no_mem_exit(char *where);
+
+#endif
Index: llvm-test/MultiSource/Applications/JM/ldecod/nal.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/nal.c:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/nal.c Sun Feb 4 08:38:32 2007
@@ -0,0 +1,118 @@
+
+/*!
+ ************************************************************************
+ * \file nal.c
+ *
+ * \brief
+ * Converts Encapsulated Byte Sequence Packets (EBSP) to Raw Byte
+ * Sequence Packets (RBSP), and then onto String Of Data Bits (SODB)
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Shankar L. Regunathan <shanre at microsoft.com>
+ ************************************************************************
+ */
+
+#include "contributors.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#include "defines.h"
+#include "global.h"
+
+
+ /*!
+ ************************************************************************
+ * \brief
+ * Converts RBSP to string of data bits
+ * \param streamBuffer
+ * pointer to buffer containing data
+ * \param last_byte_pos
+ * position of the last byte containing data.
+ * \return last_byte_pos
+ * position of the last byte pos. If the last-byte was entirely a stuffing byte,
+ * it is removed, and the last_byte_pos is updated.
+ *
+************************************************************************/
+
+int RBSPtoSODB(byte *streamBuffer, int last_byte_pos)
+{
+ int ctr_bit, bitoffset;
+
+ bitoffset = 0;
+ //find trailing 1
+ ctr_bit = (streamBuffer[last_byte_pos-1] & (0x01<<bitoffset)); // set up control bit
+
+ while (ctr_bit==0)
+ { // find trailing 1 bit
+ bitoffset++;
+ if(bitoffset == 8)
+ {
+ if(last_byte_pos == 0)
+ printf(" Panic: All zero data sequence in RBSP \n");
+ assert(last_byte_pos != 0);
+ last_byte_pos -= 1;
+ bitoffset = 0;
+ }
+ ctr_bit= streamBuffer[last_byte_pos-1] & (0x01<<(bitoffset));
+ }
+
+
+ // We keep the stop bit for now
+/* if (remove_stop)
+ {
+ streamBuffer[last_byte_pos-1] -= (0x01<<(bitoffset));
+ if(bitoffset == 7)
+ return(last_byte_pos-1);
+ else
+ return(last_byte_pos);
+ }
+*/
+ return(last_byte_pos);
+
+}
+
+
+/*!
+************************************************************************
+* \brief
+* Converts Encapsulated Byte Sequence Packets to RBSP
+* \param streamBuffer
+* pointer to data stream
+* \param end_bytepos
+* size of data stream
+* \param begin_bytepos
+* Position after beginning
+************************************************************************/
+
+
+int EBSPtoRBSP(byte *streamBuffer, int end_bytepos, int begin_bytepos)
+{
+ int i, j, count;
+ count = 0;
+
+ if(end_bytepos < begin_bytepos)
+ return end_bytepos;
+
+ j = begin_bytepos;
+
+ for(i = begin_bytepos; i < end_bytepos; i++)
+ { //starting from begin_bytepos to avoid header information
+ if(count == ZEROBYTES_SHORTSTARTCODE && streamBuffer[i] == 0x03)
+ {
+ i++;
+ count = 0;
+ }
+ streamBuffer[j] = streamBuffer[i];
+ if(streamBuffer[i] == 0x00)
+ count++;
+ else
+ count = 0;
+ j++;
+ }
+
+ return j;
+}
Index: llvm-test/MultiSource/Applications/JM/ldecod/nal_part.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/nal_part.c:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/nal_part.c Sun Feb 4 08:38:32 2007
@@ -0,0 +1,44 @@
+
+/*!
+ ************************************************************************
+ * \file nal_part.c
+ *
+ * \brief
+ * Network Adaptation layer for partition file
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Tobias Oelbaum <oelbaum at hhi.de, oelbaum at drehvial.de>
+ ************************************************************************
+ */
+
+#include <string.h>
+
+#include "contributors.h"
+#include "global.h"
+#include "elements.h"
+
+int assignSE2partition[][SE_MAX_ELEMENTS] =
+{
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // elementnumber (no not uncomment)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //!< all elements in one partition no data partitioning
+ { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 2, 2, 2, 2, 0, 0, 0, 0 } //!< three partitions per slice
+};
+
+int PartitionMode;
+
+/*!
+ ************************************************************************
+ * \brief
+ * Resets the entries in the bitstream struct
+ ************************************************************************
+ */
+void free_Partition(Bitstream *currStream)
+{
+ byte *buf = currStream->streamBuffer;
+
+ currStream->bitstream_length = 0;
+ currStream->frame_bitoffset = 0;
+ currStream->ei_flag =0;
+ memset (buf, 0x00, MAX_CODED_FRAME_SIZE);
+}
Index: llvm-test/MultiSource/Applications/JM/ldecod/nalu.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/nalu.c:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/nalu.c Sun Feb 4 08:38:32 2007
@@ -0,0 +1,44 @@
+
+/*!
+ ************************************************************************
+ * \file nalu.c
+ *
+ * \brief
+ * Decoder NALU support functions
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Stephan Wenger <stewe at cs.tu-berlin.de>
+ ************************************************************************
+ */
+
+#include <assert.h>
+
+#include "global.h"
+#include "nalu.h"
+
+
+
+
+/*!
+ *************************************************************************************
+ * \brief
+ * Converts a NALU to an RBSP
+ *
+ * \param
+ * nalu: nalu structure to be filled
+ *
+ * \return
+ * length of the RBSP in bytes
+ *************************************************************************************
+ */
+
+int NALUtoRBSP (NALU_t *nalu)
+{
+ assert (nalu != NULL);
+
+ nalu->len = EBSPtoRBSP (nalu->buf, nalu->len, 1) ;
+
+ return nalu->len ;
+}
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/nalu.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/nalu.h:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/nalu.h Sun Feb 4 08:38:32 2007
@@ -0,0 +1,28 @@
+
+/*!
+ **************************************************************************************
+ * \file
+ * parset.h
+ * \brief
+ * Picture and Sequence Parameter Sets, encoder operations
+ * This code reflects JVT version xxx
+ * \date 25 November 2002
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Stephan Wenger <stewe at cs.tu-berlin.de>
+ ***************************************************************************************
+ */
+
+
+#ifndef _NALU_H_
+#define _NALU_H_
+
+#include <stdio.h>
+#include "nalucommon.h"
+
+extern FILE *bits;
+
+int GetAnnexbNALU (NALU_t *nalu);
+int NALUtoRBSP (NALU_t *nalu);
+
+#endif
Index: llvm-test/MultiSource/Applications/JM/ldecod/nalucommon.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/nalucommon.c:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/nalucommon.c Sun Feb 4 08:38:32 2007
@@ -0,0 +1,80 @@
+
+/*!
+ ************************************************************************
+ * \file nalucommon.c
+ *
+ * \brief
+ * Common NALU support functions
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Stephan Wenger <stewe at cs.tu-berlin.de>
+ ************************************************************************
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "global.h"
+#include "nalu.h"
+#include "memalloc.h"
+
+
+/*!
+ *************************************************************************************
+ * \brief
+ * Allocates memory for a NALU
+ *
+ * \param buffersize
+ * size of NALU buffer
+ *
+ * \return
+ * pointer to a NALU
+ *************************************************************************************
+ */
+
+
+NALU_t *AllocNALU(int buffersize)
+{
+ NALU_t *n;
+
+ if ((n = (NALU_t*)calloc (1, sizeof (NALU_t))) == NULL)
+ no_mem_exit ("AllocNALU: n");
+
+ n->max_size=buffersize;
+
+ if ((n->buf = (byte*)calloc (buffersize, sizeof (byte))) == NULL)
+ {
+ free (n);
+ no_mem_exit ("AllocNALU: n->buf");
+ }
+
+ return n;
+}
+
+
+/*!
+ *************************************************************************************
+ * \brief
+ * Frees a NALU
+ *
+ * \param n
+ * NALU to be freed
+ *
+ *************************************************************************************
+ */
+
+void FreeNALU(NALU_t *n)
+{
+ if (n)
+ {
+ if (n->buf)
+ {
+ free(n->buf);
+ n->buf=NULL;
+ }
+ free (n);
+ }
+}
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/nalucommon.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/nalucommon.h:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/nalucommon.h Sun Feb 4 08:38:32 2007
@@ -0,0 +1,55 @@
+
+/*!
+ **************************************************************************************
+ * \file
+ * nalucommon.h.h
+ * \brief
+ * NALU handling common to encoder and decoder
+ * \date 25 November 2002
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Stephan Wenger <stewe at cs.tu-berlin.de>
+ ***************************************************************************************
+ */
+
+
+#ifndef _NALUCOMMON_H_
+#define _NALUCOMMON_H_
+
+#define MAXRBSPSIZE 64000
+
+#define NALU_TYPE_SLICE 1
+#define NALU_TYPE_DPA 2
+#define NALU_TYPE_DPB 3
+#define NALU_TYPE_DPC 4
+#define NALU_TYPE_IDR 5
+#define NALU_TYPE_SEI 6
+#define NALU_TYPE_SPS 7
+#define NALU_TYPE_PPS 8
+#define NALU_TYPE_AUD 9
+#define NALU_TYPE_EOSEQ 10
+#define NALU_TYPE_EOSTREAM 11
+#define NALU_TYPE_FILL 12
+
+#define NALU_PRIORITY_HIGHEST 3
+#define NALU_PRIORITY_HIGH 2
+#define NALU_PRIRITY_LOW 1
+#define NALU_PRIORITY_DISPOSABLE 0
+
+
+typedef struct
+{
+ int startcodeprefix_len; //! 4 for parameter sets and first slice in picture, 3 for everything else (suggested)
+ unsigned len; //! Length of the NAL unit (Excluding the start code, which does not belong to the NALU)
+ unsigned max_size; //! Nal Unit Buffer size
+ int nal_unit_type; //! NALU_TYPE_xxxx
+ int nal_reference_idc; //! NALU_PRIORITY_xxxx
+ int forbidden_bit; //! should be always FALSE
+ byte *buf; //! conjtains the first byte followed by the EBSP
+} NALU_t;
+
+
+NALU_t *AllocNALU();
+void FreeNALU(NALU_t *n);
+
+#endif
Index: llvm-test/MultiSource/Applications/JM/ldecod/output.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/output.c:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/output.c Sun Feb 4 08:38:32 2007
@@ -0,0 +1,703 @@
+
+/*!
+ ************************************************************************
+ * \file output.c
+ *
+ * \brief
+ * Output an image and Trance support
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Karsten Suehring <suehring at hhi.de>
+ ************************************************************************
+ */
+
+#include "contributors.h"
+
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#ifdef WIN32
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+#include "global.h"
+#include "mbuffer.h"
+#include "image.h"
+#include "memalloc.h"
+
+FrameStore* out_buffer;
+
+StorablePicture *pending_output = NULL;
+int pending_output_state = FRAME;
+int recovery_flag = 0;
+
+extern int non_conforming_stream;
+
+void write_out_picture(StorablePicture *p, int p_out);
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * checks if the System is big- or little-endian
+ * \return
+ * 0, little-endian (e.g. Intel architectures)
+ * 1, big-endian (e.g. SPARC, MIPS, PowerPC)
+ ************************************************************************
+ */
+int testEndian()
+{
+ short s;
+ byte *p;
+
+ p=(byte*)&s;
+
+ s=1;
+
+ return (*p==0);
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Convert image plane to temporary buffer for file writing
+ * \param imgX
+ * Pointer to image plane
+ * \param buf
+ * Buffer for file output
+ * \param size_x
+ * horizontal size
+ * \param size_y
+ * vertical size
+ * \param symbol_size_in_bytes
+ * number of bytes used per pel
+ * \param crop_left
+ * pixels to crop from left
+ * \param crop_right
+ * pixels to crop from right
+ * \param crop_top
+ * pixels to crop from top
+ * \param crop_bottom
+ * pixels to crop from bottom
+ ************************************************************************
+ */
+void img2buf (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes, int crop_left, int crop_right, int crop_top, int crop_bottom)
+{
+ int i,j;
+
+ int twidth = size_x - crop_left - crop_right;
+ int theight = size_y - crop_top - crop_bottom;
+
+ int size = 0;
+
+ unsigned char ui8;
+ unsigned short tmp16, ui16;
+ unsigned long tmp32, ui32;
+
+ if (( sizeof(char) == sizeof (imgpel)) && ( sizeof(char) == symbol_size_in_bytes))
+ {
+ // imgpel == pixel_in_file == 1 byte -> simple copy
+ for(i=0;i<theight;i++)
+ memcpy(buf+crop_left+(i*twidth),&(imgX[i+crop_top][crop_left]), twidth);
+
+ }
+ else
+ {
+ // sizeof (imgpel) > sizeof(char)
+ if (testEndian())
+ {
+ // big endian
+ switch (symbol_size_in_bytes)
+ {
+ case 1:
+ {
+ for(i=crop_top;i<size_y-crop_bottom;i++)
+ for(j=crop_left;j<size_x-crop_right;j++)
+ {
+ ui8 = (unsigned char) (imgX[i][j]);
+ buf[(j-crop_left+((i-crop_top)*(twidth)))] = ui8;
+ }
+ break;
+ }
+ case 2:
+ {
+ for(i=crop_top;i<size_y-crop_bottom;i++)
+ for(j=crop_left;j<size_x-crop_right;j++)
+ {
+ tmp16 = (unsigned short) (imgX[i][j]);
+ ui16 = (tmp16 >> 8) | ((tmp16&0xFF)<<8);
+ memcpy(buf+((j-crop_left+((i-crop_top)*(twidth)))*2),&(ui16), 2);
+ }
+ break;
+ }
+ case 4:
+ {
+ for(i=crop_top;i<size_y-crop_bottom;i++)
+ for(j=crop_left;j<size_x-crop_right;j++)
+ {
+ tmp32 = (unsigned long) (imgX[i][j]);
+ ui32 = ((tmp32&0xFF00)<<8) | ((tmp32&0xFF)<<24) | ((tmp32&0xFF0000)>>8) | ((tmp32&0xFF000000)>>24);
+ memcpy(buf+((j-crop_left+((i-crop_top)*(twidth)))*4),&(ui32), 4);
+ }
+ break;
+ }
+ default:
+ {
+ error ("writing only to formats of 8, 16 or 32 bit allowed on big endian architecture", 500);
+ break;
+ }
+ }
+
+ }
+ else
+ {
+ // little endian
+ if (sizeof (imgpel) < symbol_size_in_bytes)
+ {
+ // this should not happen. we should not have smaller imgpel than our source material.
+ size = sizeof (imgpel);
+ // clear buffer
+ memset (buf, 0, (twidth*theight*symbol_size_in_bytes));
+ }
+ else
+ {
+ size = symbol_size_in_bytes;
+ }
+
+ if ((crop_top || crop_bottom || crop_left || crop_right) || (size != 1))
+ {
+ for(i=crop_top;i<size_y-crop_bottom;i++)
+ {
+ int ipos = (i-crop_top)*(twidth);
+ for(j=crop_left;j<size_x-crop_right;j++)
+ {
+ memcpy(buf+((j-crop_left+(ipos))*symbol_size_in_bytes),&(imgX[i][j]), size);
+ }
+ }
+ }
+ else
+ {
+ for(i=0;i<size_y;i++)
+ {
+ for(j=0;j<size_x;j++)
+ {
+ *(buf++)=(char) imgX[i][j];
+ }
+ }
+ }
+ }
+ }
+}
+
+
+#ifdef PAIR_FIELDS_IN_OUTPUT
+
+void clear_picture(StorablePicture *p);
+
+/*!
+ ************************************************************************
+ * \brief
+ * output the pending frame buffer
+ * \param p_out
+ * Output file
+ ************************************************************************
+ */
+void flush_pending_output(int p_out)
+{
+ if (pending_output_state!=FRAME)
+ {
+ write_out_picture(pending_output, p_out);
+ }
+
+ if (pending_output->imgY)
+ {
+ free_mem2Dpel (pending_output->imgY);
+ pending_output->imgY=NULL;
+ }
+ if (pending_output->imgUV)
+ {
+ free_mem3Dpel (pending_output->imgUV, 2);
+ pending_output->imgUV=NULL;
+ }
+
+ pending_output_state = FRAME;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Writes out a storable picture
+ * If the picture is a field, the output buffers the picture and tries
+ * to pair it with the next field.
+ * \param p
+ * Picture to be written
+ * \param p_out
+ * Output file
+ ************************************************************************
+ */
+void write_picture(StorablePicture *p, int p_out, int real_structure)
+{
+ int i, add;
+
+ if (real_structure==FRAME)
+ {
+ flush_pending_output(p_out);
+ write_out_picture(p, p_out);
+ return;
+ }
+ if (real_structure==pending_output_state)
+ {
+ flush_pending_output(p_out);
+ write_picture(p, p_out, real_structure);
+ return;
+ }
+
+ if (pending_output_state == FRAME)
+ {
+ pending_output->size_x = p->size_x;
+ pending_output->size_y = p->size_y;
+ pending_output->size_x_cr = p->size_x_cr;
+ pending_output->size_y_cr = p->size_y_cr;
+ pending_output->chroma_format_idc = p->chroma_format_idc;
+
+ pending_output->frame_mbs_only_flag = p->frame_mbs_only_flag;
+ pending_output->frame_cropping_flag = p->frame_cropping_flag;
+ if (pending_output->frame_cropping_flag)
+ {
+ pending_output->frame_cropping_rect_left_offset = p->frame_cropping_rect_left_offset;
+ pending_output->frame_cropping_rect_right_offset = p->frame_cropping_rect_right_offset;
+ pending_output->frame_cropping_rect_top_offset = p->frame_cropping_rect_top_offset;
+ pending_output->frame_cropping_rect_bottom_offset = p->frame_cropping_rect_bottom_offset;
+ }
+
+ get_mem2Dpel (&(pending_output->imgY), pending_output->size_y, pending_output->size_x);
+ get_mem3Dpel (&(pending_output->imgUV), 2, pending_output->size_y_cr, pending_output->size_x_cr);
+
+ clear_picture(pending_output);
+
+ // copy first field
+ if (real_structure == TOP_FIELD)
+ {
+ add = 0;
+ }
+ else
+ {
+ add = 1;
+ }
+
+ for (i=0; i<pending_output->size_y; i+=2)
+ {
+ memcpy(pending_output->imgY[(i+add)], p->imgY[(i+add)], p->size_x * sizeof(imgpel));
+ }
+ for (i=0; i<pending_output->size_y_cr; i+=2)
+ {
+ memcpy(pending_output->imgUV[0][(i+add)], p->imgUV[0][(i+add)], p->size_x_cr * sizeof(imgpel));
+ memcpy(pending_output->imgUV[1][(i+add)], p->imgUV[1][(i+add)], p->size_x_cr * sizeof(imgpel));
+ }
+ pending_output_state = real_structure;
+ }
+ else
+ {
+ if ( (pending_output->size_x!=p->size_x) || (pending_output->size_y!= p->size_y)
+ || (pending_output->frame_mbs_only_flag != p->frame_mbs_only_flag)
+ || (pending_output->frame_cropping_flag != p->frame_cropping_flag)
+ || ( pending_output->frame_cropping_flag &&
+ ( (pending_output->frame_cropping_rect_left_offset != p->frame_cropping_rect_left_offset)
+ ||(pending_output->frame_cropping_rect_right_offset != p->frame_cropping_rect_right_offset)
+ ||(pending_output->frame_cropping_rect_top_offset != p->frame_cropping_rect_top_offset)
+ ||(pending_output->frame_cropping_rect_bottom_offset != p->frame_cropping_rect_bottom_offset)
+ )
+ )
+ )
+ {
+ flush_pending_output(p_out);
+ write_picture (p, p_out, real_structure);
+ return;
+ }
+ // copy second field
+ if (real_structure == TOP_FIELD)
+ {
+ add = 0;
+ }
+ else
+ {
+ add = 1;
+ }
+
+ for (i=0; i<pending_output->size_y; i+=2)
+ {
+ memcpy(pending_output->imgY[(i+add)], p->imgY[(i+add)], p->size_x * sizeof(imgpel));
+ }
+ for (i=0; i<pending_output->size_y_cr; i+=2)
+ {
+ memcpy(pending_output->imgUV[0][(i+add)], p->imgUV[0][(i+add)], p->size_x_cr * sizeof(imgpel));
+ memcpy(pending_output->imgUV[1][(i+add)], p->imgUV[1][(i+add)], p->size_x_cr * sizeof(imgpel));
+ }
+
+ flush_pending_output(p_out);
+ }
+}
+
+#else
+
+/*!
+ ************************************************************************
+ * \brief
+ * Writes out a storable picture without doing any output modifications
+ * \param p
+ * Picture to be written
+ * \param p_out
+ * Output file
+ * \param real_structure
+ * real picture structure
+ ************************************************************************
+ */
+void write_picture(StorablePicture *p, int p_out, int real_structure)
+{
+ write_out_picture(p, p_out);
+}
+
+
+#endif
+
+/*!
+************************************************************************
+* \brief
+* Writes out a storable picture
+* \param p
+* Picture to be written
+* \param p_out
+* Output file
+************************************************************************
+*/
+void write_out_picture(StorablePicture *p, int p_out)
+{
+ int SubWidthC [4]= { 1, 2, 2, 1};
+ int SubHeightC [4]= { 1, 2, 1, 1};
+
+ int crop_left, crop_right, crop_top, crop_bottom;
+ int symbol_size_in_bytes = img->pic_unit_bitsize_on_disk/8;
+ Boolean rgb_output = (Boolean) (active_sps->vui_seq_parameters.matrix_coefficients==0);
+ unsigned char *buf;
+
+ if (p->non_existing)
+ return;
+
+ if (p->frame_cropping_flag)
+ {
+ crop_left = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_left_offset;
+ crop_right = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_right_offset;
+ crop_top = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
+ crop_bottom = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
+ }
+ else
+ {
+ crop_left = crop_right = crop_top = crop_bottom = 0;
+ }
+
+ //printf ("write frame size: %dx%d\n", p->size_x-crop_left-crop_right,p->size_y-crop_top-crop_bottom );
+
+ // KS: this buffer should actually be allocated only once, but this is still much faster than the previous version
+ buf = malloc (p->size_x*p->size_y*symbol_size_in_bytes);
+ if (NULL==buf)
+ {
+ no_mem_exit("write_out_picture: buf");
+ }
+
+ if(rgb_output)
+ {
+ crop_left = p->frame_cropping_rect_left_offset;
+ crop_right = p->frame_cropping_rect_right_offset;
+ crop_top = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
+ crop_bottom = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
+
+ img2buf (p->imgUV[1], buf, p->size_x_cr, p->size_y_cr, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
+ write(p_out, buf, (p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)*symbol_size_in_bytes);
+
+ if (p->frame_cropping_flag)
+ {
+ crop_left = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_left_offset;
+ crop_right = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_right_offset;
+ crop_top = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
+ crop_bottom = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
+ }
+ else
+ {
+ crop_left = crop_right = crop_top = crop_bottom = 0;
+ }
+ }
+
+ img2buf (p->imgY, buf, p->size_x, p->size_y, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
+ write(p_out, buf, (p->size_y-crop_bottom-crop_top)*(p->size_x-crop_right-crop_left)*symbol_size_in_bytes);
+
+ if (p->chroma_format_idc!=YUV400)
+ {
+ crop_left = p->frame_cropping_rect_left_offset;
+ crop_right = p->frame_cropping_rect_right_offset;
+ crop_top = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
+ crop_bottom = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
+
+ img2buf (p->imgUV[0], buf, p->size_x_cr, p->size_y_cr, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
+ write(p_out, buf, (p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)* symbol_size_in_bytes);
+
+ if (!rgb_output)
+ {
+ img2buf (p->imgUV[1], buf, p->size_x_cr, p->size_y_cr, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
+ write(p_out, buf, (p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)*symbol_size_in_bytes);
+ }
+ }
+ else
+ {
+ if (input->write_uv)
+ {
+ int i,j;
+ imgpel cr_val = (imgpel) (1<<(img->bitdepth_luma - 1));
+
+ get_mem3Dpel (&(p->imgUV), 1, p->size_y/2, p->size_x/2);
+ for (j=0; j<p->size_y/2; j++)
+ for (i=0; i<p->size_x/2; i++)
+ p->imgUV[0][j][i]=cr_val;
+
+ // fake out U=V=128 to make a YUV 4:2:0 stream
+ img2buf (p->imgUV[0], buf, p->size_x/2, p->size_y/2, symbol_size_in_bytes, crop_left/2, crop_right/2, crop_top/2, crop_bottom/2);
+
+ write(p_out, buf, symbol_size_in_bytes * (p->size_y-crop_bottom-crop_top)/2 * (p->size_x-crop_right-crop_left)/2 );
+ write(p_out, buf, symbol_size_in_bytes * (p->size_y-crop_bottom-crop_top)/2 * (p->size_x-crop_right-crop_left)/2 );
+
+ free_mem3Dpel(p->imgUV, 1);
+ p->imgUV=NULL;
+ }
+ }
+
+ free(buf);
+
+// fsync(p_out);
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Initialize output buffer for direct output
+ ************************************************************************
+ */
+void init_out_buffer()
+{
+ out_buffer = alloc_frame_store();
+#ifdef PAIR_FIELDS_IN_OUTPUT
+ pending_output = calloc (sizeof(StorablePicture), 1);
+ if (NULL==pending_output) no_mem_exit("init_out_buffer");
+ pending_output->imgUV = NULL;
+ pending_output->imgY = NULL;
+#endif
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Uninitialize output buffer for direct output
+ ************************************************************************
+ */
+void uninit_out_buffer()
+{
+ free_frame_store(out_buffer);
+ out_buffer=NULL;
+#ifdef PAIR_FIELDS_IN_OUTPUT
+ flush_pending_output(p_out);
+ free (pending_output);
+#endif
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Initialize picture memory with (Y:0,U:128,V:128)
+ ************************************************************************
+ */
+void clear_picture(StorablePicture *p)
+{
+ int i,j;
+
+ for(i=0;i<p->size_y;i++)
+ {
+ for (j=0; j<p->size_x; j++)
+ p->imgY[i][j] = (imgpel) img->dc_pred_value_luma;
+ }
+ for(i=0;i<p->size_y_cr;i++)
+ {
+ for (j=0; j<p->size_x_cr; j++)
+ p->imgUV[0][i][j] = (imgpel) img->dc_pred_value_chroma;
+ }
+ for(i=0;i<p->size_y_cr;i++)
+ {
+ for (j=0; j<p->size_x_cr; j++)
+ p->imgUV[1][i][j] = (imgpel) img->dc_pred_value_chroma;
+ }
+
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Write out not paired direct output fields. A second empty field is generated
+ * and combined into the frame buffer.
+ * \param fs
+ * FrameStore that contains a single field
+ * \param p_out
+ * Output file
+ ************************************************************************
+ */
+void write_unpaired_field(FrameStore* fs, int p_out)
+{
+ StorablePicture *p;
+ assert (fs->is_used<3);
+ if(fs->is_used &1)
+ {
+ // we have a top field
+ // construct an empty bottom field
+ p = fs->top_field;
+ fs->bottom_field = alloc_storable_picture(BOTTOM_FIELD, p->size_x, 2*p->size_y, p->size_x_cr, 2*p->size_y_cr);
+ fs->bottom_field->chroma_format_idc = p->chroma_format_idc;
+ clear_picture(fs->bottom_field);
+ dpb_combine_field_yuv(fs);
+ write_picture (fs->frame, p_out, TOP_FIELD);
+ }
+
+ if(fs->is_used &2)
+ {
+ // we have a bottom field
+ // construct an empty top field
+ p = fs->bottom_field;
+ fs->top_field = alloc_storable_picture(TOP_FIELD, p->size_x, 2*p->size_y, p->size_x_cr, 2*p->size_y_cr);
+ fs->top_field->chroma_format_idc = p->chroma_format_idc;
+ clear_picture(fs->top_field);
+ fs ->top_field->frame_cropping_flag = fs->bottom_field->frame_cropping_flag;
+ if(fs ->top_field->frame_cropping_flag)
+ {
+ fs ->top_field->frame_cropping_rect_top_offset = fs->bottom_field->frame_cropping_rect_top_offset;
+ fs ->top_field->frame_cropping_rect_bottom_offset = fs->bottom_field->frame_cropping_rect_bottom_offset;
+ fs ->top_field->frame_cropping_rect_left_offset = fs->bottom_field->frame_cropping_rect_left_offset;
+ fs ->top_field->frame_cropping_rect_right_offset = fs->bottom_field->frame_cropping_rect_right_offset;
+ }
+ dpb_combine_field_yuv(fs);
+ write_picture (fs->frame, p_out, BOTTOM_FIELD);
+ }
+
+ fs->is_used=3;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Write out unpaired fields from output buffer.
+ * \param p_out
+ * Output file
+ ************************************************************************
+ */
+void flush_direct_output(int p_out)
+{
+ write_unpaired_field(out_buffer, p_out);
+
+ free_storable_picture(out_buffer->frame);
+ out_buffer->frame = NULL;
+ free_storable_picture(out_buffer->top_field);
+ out_buffer->top_field = NULL;
+ free_storable_picture(out_buffer->bottom_field);
+ out_buffer->bottom_field = NULL;
+ out_buffer->is_used = 0;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Write a frame (from FrameStore)
+ * \param fs
+ * FrameStore containing the frame
+ * \param p_out
+ * Output file
+ ************************************************************************
+ */
+void write_stored_frame( FrameStore *fs,int p_out)
+{
+ // make sure no direct output field is pending
+ flush_direct_output(p_out);
+
+ if (fs->is_used<3)
+ {
+ write_unpaired_field(fs, p_out);
+ }
+ else
+ {
+ if (fs->recovery_frame)
+ recovery_flag = 1;
+ if ((!non_conforming_stream) || recovery_flag)
+ write_picture(fs->frame, p_out, FRAME);
+ }
+
+ fs->is_output = 1;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Directly output a picture without storing it in the DPB. Fields
+ * are buffered before they are written to the file.
+ * \param p
+ * Picture for output
+ * \param p_out
+ * Output file
+ ************************************************************************
+ */
+void direct_output(StorablePicture *p, int p_out)
+{
+ if (p->structure==FRAME)
+ {
+ // we have a frame (or complementary field pair)
+ // so output it directly
+ flush_direct_output(p_out);
+ write_picture (p, p_out, FRAME);
+ if (-1!=p_ref && !input->silent)
+ find_snr(snr, p, p_ref);
+ free_storable_picture(p);
+ return;
+ }
+
+ if (p->structure == TOP_FIELD)
+ {
+ if (out_buffer->is_used &1)
+ flush_direct_output(p_out);
+ out_buffer->top_field = p;
+ out_buffer->is_used |= 1;
+ }
+
+ if (p->structure == BOTTOM_FIELD)
+ {
+ if (out_buffer->is_used &2)
+ flush_direct_output(p_out);
+ out_buffer->bottom_field = p;
+ out_buffer->is_used |= 2;
+ }
+
+ if (out_buffer->is_used == 3)
+ {
+ // we have both fields, so output them
+ dpb_combine_field_yuv(out_buffer);
+ write_picture (out_buffer->frame, p_out, FRAME);
+ if (-1!=p_ref && !input->silent)
+ find_snr(snr, out_buffer->frame, p_ref);
+ free_storable_picture(out_buffer->frame);
+ out_buffer->frame = NULL;
+ free_storable_picture(out_buffer->top_field);
+ out_buffer->top_field = NULL;
+ free_storable_picture(out_buffer->bottom_field);
+ out_buffer->bottom_field = NULL;
+ out_buffer->is_used = 0;
+ }
+}
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/output.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/output.h:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/output.h Sun Feb 4 08:38:32 2007
@@ -0,0 +1,27 @@
+
+/*!
+ **************************************************************************************
+ * \file
+ * output.h
+ * \brief
+ * Picture writing routine headers
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Karsten Suehring <suehring at hhi.de>
+ ***************************************************************************************
+ */
+#ifndef _OUTPUT_H_
+#define _OUTPUT_H_
+
+int testEndian();
+
+void write_stored_frame(FrameStore *fs, int p_out);
+void direct_output(StorablePicture *p, int p_out);
+void init_out_buffer();
+void uninit_out_buffer();
+
+#ifdef PAIR_FIELDS_IN_OUTPUT
+void flush_pending_output(int p_out);
+#endif
+
+#endif //_OUTPUT_H_
Index: llvm-test/MultiSource/Applications/JM/ldecod/parset.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/parset.c:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/parset.c Sun Feb 4 08:38:32 2007
@@ -0,0 +1,702 @@
+
+/*!
+ ************************************************************************
+ * \file
+ * parset.c
+ * \brief
+ * Parameter Sets
+ * \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 <string.h>
+
+#include "global.h"
+#include "parsetcommon.h"
+#include "parset.h"
+#include "nalu.h"
+#include "memalloc.h"
+#include "fmo.h"
+#include "cabac.h"
+#include "vlc.h"
+#include "mbuffer.h"
+#include "erc_api.h"
+
+#if TRACE
+#define SYMTRACESTRING(s) strncpy(sym->tracestring,s,TRACESTRING_SIZE)
+#else
+#define SYMTRACESTRING(s) // do nothing
+#endif
+
+const byte ZZ_SCAN[16] =
+{ 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
+};
+
+const byte ZZ_SCAN8[64] =
+{ 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
+ 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
+};
+
+extern int UsedBits; // for internal statistics, is adjusted by se_v, ue_v, u_1
+extern ColocatedParams *Co_located;
+
+extern int quant_intra_default[16];
+extern int quant_inter_default[16];
+extern int quant8_intra_default[64];
+extern int quant8_inter_default[64];
+
+seq_parameter_set_rbsp_t SeqParSet[MAXSPS];
+pic_parameter_set_rbsp_t PicParSet[MAXPPS];
+
+extern StorablePicture* dec_picture;
+
+extern void init_frext(struct img_par *img);
+
+// syntax for scaling list matrix values
+void Scaling_List(int *scalingList, int sizeOfScalingList, Boolean *UseDefaultScalingMatrix, Bitstream *s)
+{
+ int j, scanj;
+ int delta_scale, lastScale, nextScale;
+
+ lastScale = 8;
+ nextScale = 8;
+
+ for(j=0; j<sizeOfScalingList; j++)
+ {
+ scanj = (sizeOfScalingList==16) ? ZZ_SCAN[j]:ZZ_SCAN8[j];
+
+ if(nextScale!=0)
+ {
+ delta_scale = se_v ( " : delta_sl " , s);
+ nextScale = (lastScale + delta_scale + 256) % 256;
+ *UseDefaultScalingMatrix = (Boolean) (scanj==0 && nextScale==0);
+ }
+
+ scalingList[scanj] = (nextScale==0) ? lastScale:nextScale;
+ lastScale = scalingList[scanj];
+ }
+}
+// fill sps with content of p
+
+int InterpretSPS (DataPartition *p, seq_parameter_set_rbsp_t *sps)
+{
+ unsigned i;
+ int reserved_zero;
+ Bitstream *s = p->bitstream;
+
+ assert (p != NULL);
+ assert (p->bitstream != NULL);
+ assert (p->bitstream->streamBuffer != 0);
+ assert (sps != NULL);
+
+ UsedBits = 0;
+
+ sps->profile_idc = u_v (8, "SPS: profile_idc" , s);
+
+ if ((sps->profile_idc!=66 ) &&
+ (sps->profile_idc!=77 ) &&
+ (sps->profile_idc!=88 ) &&
+ (sps->profile_idc!=100 ) &&
+ (sps->profile_idc!=110 ) &&
+ (sps->profile_idc!=122 ) &&
+ (sps->profile_idc!=144 ))
+ {
+ return UsedBits;
+ }
+
+ sps->constrained_set0_flag = u_1 ( "SPS: constrained_set0_flag" , s);
+ sps->constrained_set1_flag = u_1 ( "SPS: constrained_set1_flag" , s);
+ sps->constrained_set2_flag = u_1 ( "SPS: constrained_set2_flag" , s);
+ sps->constrained_set3_flag = u_1 ( "SPS: constrained_set3_flag" , s);
+ reserved_zero = u_v (4, "SPS: reserved_zero_4bits" , s);
+ assert (reserved_zero==0);
+
+ sps->level_idc = u_v (8, "SPS: level_idc" , s);
+
+ sps->seq_parameter_set_id = ue_v ("SPS: seq_parameter_set_id" , s);
+
+ // Fidelity Range Extensions stuff
+ sps->chroma_format_idc = 1;
+ sps->bit_depth_luma_minus8 = 0;
+ sps->bit_depth_chroma_minus8 = 0;
+ img->lossless_qpprime_flag = 0;
+
+ if((sps->profile_idc==FREXT_HP ) ||
+ (sps->profile_idc==FREXT_Hi10P) ||
+ (sps->profile_idc==FREXT_Hi422) ||
+ (sps->profile_idc==FREXT_Hi444))
+ {
+ sps->chroma_format_idc = ue_v ("SPS: chroma_format_idc" , s);
+
+ // Residue Color Transform
+ if(sps->chroma_format_idc == 3)
+ {
+ i = u_1 ("SPS: residue_transform_flag" , s);
+ if (i==1)
+ {
+ error ("[Deprecated High444 Profile] residue_transform_flag = 1 is no longer supported", 1000);
+ }
+ }
+
+ sps->bit_depth_luma_minus8 = ue_v ("SPS: bit_depth_luma_minus8" , s);
+ sps->bit_depth_chroma_minus8 = ue_v ("SPS: bit_depth_chroma_minus8" , s);
+ img->lossless_qpprime_flag = u_1 ("SPS: lossless_qpprime_y_zero_flag" , s);
+
+ sps->seq_scaling_matrix_present_flag = u_1 ( "SPS: seq_scaling_matrix_present_flag" , s);
+
+ if(sps->seq_scaling_matrix_present_flag)
+ {
+ for(i=0; i<8; i++)
+ {
+ sps->seq_scaling_list_present_flag[i] = u_1 ( "SPS: seq_scaling_list_present_flag" , s);
+ if(sps->seq_scaling_list_present_flag[i])
+ {
+ if(i<6)
+ Scaling_List(sps->ScalingList4x4[i], 16, &sps->UseDefaultScalingMatrix4x4Flag[i], s);
+ else
+ Scaling_List(sps->ScalingList8x8[i-6], 64, &sps->UseDefaultScalingMatrix8x8Flag[i-6], s);
+ }
+ }
+ }
+ }
+
+ sps->log2_max_frame_num_minus4 = ue_v ("SPS: log2_max_frame_num_minus4" , s);
+ sps->pic_order_cnt_type = ue_v ("SPS: pic_order_cnt_type" , s);
+
+ if (sps->pic_order_cnt_type == 0)
+ sps->log2_max_pic_order_cnt_lsb_minus4 = ue_v ("SPS: log2_max_pic_order_cnt_lsb_minus4" , s);
+ else if (sps->pic_order_cnt_type == 1)
+ {
+ sps->delta_pic_order_always_zero_flag = u_1 ("SPS: delta_pic_order_always_zero_flag" , s);
+ sps->offset_for_non_ref_pic = se_v ("SPS: offset_for_non_ref_pic" , s);
+ sps->offset_for_top_to_bottom_field = se_v ("SPS: offset_for_top_to_bottom_field" , s);
+ sps->num_ref_frames_in_pic_order_cnt_cycle = ue_v ("SPS: num_ref_frames_in_pic_order_cnt_cycle" , s);
+ for(i=0; i<sps->num_ref_frames_in_pic_order_cnt_cycle; i++)
+ sps->offset_for_ref_frame[i] = se_v ("SPS: offset_for_ref_frame[i]" , s);
+ }
+ sps->num_ref_frames = ue_v ("SPS: num_ref_frames" , s);
+ sps->gaps_in_frame_num_value_allowed_flag = u_1 ("SPS: gaps_in_frame_num_value_allowed_flag" , s);
+ sps->pic_width_in_mbs_minus1 = ue_v ("SPS: pic_width_in_mbs_minus1" , s);
+ sps->pic_height_in_map_units_minus1 = ue_v ("SPS: pic_height_in_map_units_minus1" , s);
+ sps->frame_mbs_only_flag = u_1 ("SPS: frame_mbs_only_flag" , s);
+ if (!sps->frame_mbs_only_flag)
+ {
+ sps->mb_adaptive_frame_field_flag = u_1 ("SPS: mb_adaptive_frame_field_flag" , s);
+ }
+ sps->direct_8x8_inference_flag = u_1 ("SPS: direct_8x8_inference_flag" , s);
+ sps->frame_cropping_flag = u_1 ("SPS: frame_cropping_flag" , s);
+
+ if (sps->frame_cropping_flag)
+ {
+ sps->frame_cropping_rect_left_offset = ue_v ("SPS: frame_cropping_rect_left_offset" , s);
+ sps->frame_cropping_rect_right_offset = ue_v ("SPS: frame_cropping_rect_right_offset" , s);
+ sps->frame_cropping_rect_top_offset = ue_v ("SPS: frame_cropping_rect_top_offset" , s);
+ sps->frame_cropping_rect_bottom_offset = ue_v ("SPS: frame_cropping_rect_bottom_offset" , s);
+ }
+ sps->vui_parameters_present_flag = (Boolean) u_1 ("SPS: vui_parameters_present_flag" , s);
+
+ InitVUI(sps);
+ ReadVUI(p, sps);
+
+ sps->Valid = TRUE;
+
+ return UsedBits;
+}
+
+
+void InitVUI(seq_parameter_set_rbsp_t *sps)
+{
+ sps->vui_seq_parameters.matrix_coefficients = 2;
+}
+
+
+int ReadVUI(DataPartition *p, seq_parameter_set_rbsp_t *sps)
+{
+ Bitstream *s = p->bitstream;
+ if (sps->vui_parameters_present_flag)
+ {
+ sps->vui_seq_parameters.aspect_ratio_info_present_flag = u_1 ("VUI: aspect_ratio_info_present_flag" , s);
+ if (sps->vui_seq_parameters.aspect_ratio_info_present_flag)
+ {
+ sps->vui_seq_parameters.aspect_ratio_idc = u_v ( 8, "VUI: aspect_ratio_idc" , s);
+ if (255==sps->vui_seq_parameters.aspect_ratio_idc)
+ {
+ sps->vui_seq_parameters.sar_width = u_v (16, "VUI: sar_width" , s);
+ sps->vui_seq_parameters.sar_height = u_v (16, "VUI: sar_height" , s);
+ }
+ }
+
+ sps->vui_seq_parameters.overscan_info_present_flag = u_1 ("VUI: overscan_info_present_flag" , s);
+ if (sps->vui_seq_parameters.overscan_info_present_flag)
+ {
+ sps->vui_seq_parameters.overscan_appropriate_flag = u_1 ("VUI: overscan_appropriate_flag" , s);
+ }
+
+ sps->vui_seq_parameters.video_signal_type_present_flag = u_1 ("VUI: video_signal_type_present_flag" , s);
+ if (sps->vui_seq_parameters.video_signal_type_present_flag)
+ {
+ sps->vui_seq_parameters.video_format = u_v ( 3,"VUI: video_format" , s);
+ sps->vui_seq_parameters.video_full_range_flag = u_1 ( "VUI: video_full_range_flag" , s);
+ sps->vui_seq_parameters.colour_description_present_flag = u_1 ( "VUI: color_description_present_flag" , s);
+ if(sps->vui_seq_parameters.colour_description_present_flag)
+ {
+ sps->vui_seq_parameters.colour_primaries = u_v ( 8,"VUI: colour_primaries" , s);
+ sps->vui_seq_parameters.transfer_characteristics = u_v ( 8,"VUI: transfer_characteristics" , s);
+ sps->vui_seq_parameters.matrix_coefficients = u_v ( 8,"VUI: matrix_coefficients" , s);
+ }
+ }
+ sps->vui_seq_parameters.chroma_location_info_present_flag = u_1 ( "VUI: chroma_loc_info_present_flag" , s);
+ if(sps->vui_seq_parameters.chroma_location_info_present_flag)
+ {
+ sps->vui_seq_parameters.chroma_sample_loc_type_top_field = ue_v ( "VUI: chroma_sample_loc_type_top_field" , s);
+ sps->vui_seq_parameters.chroma_sample_loc_type_bottom_field = ue_v ( "VUI: chroma_sample_loc_type_bottom_field" , s);
+ }
+ sps->vui_seq_parameters.timing_info_present_flag = u_1 ("VUI: timing_info_present_flag" , s);
+ if (sps->vui_seq_parameters.timing_info_present_flag)
+ {
+ sps->vui_seq_parameters.num_units_in_tick = u_v (32,"VUI: num_units_in_tick" , s);
+ sps->vui_seq_parameters.time_scale = u_v (32,"VUI: time_scale" , s);
+ sps->vui_seq_parameters.fixed_frame_rate_flag = u_1 ( "VUI: fixed_frame_rate_flag" , s);
+ }
+ sps->vui_seq_parameters.nal_hrd_parameters_present_flag = u_1 ("VUI: nal_hrd_parameters_present_flag" , s);
+ if (sps->vui_seq_parameters.nal_hrd_parameters_present_flag)
+ {
+ ReadHRDParameters(p, &(sps->vui_seq_parameters.nal_hrd_parameters));
+ }
+ sps->vui_seq_parameters.vcl_hrd_parameters_present_flag = u_1 ("VUI: vcl_hrd_parameters_present_flag" , s);
+ if (sps->vui_seq_parameters.vcl_hrd_parameters_present_flag)
+ {
+ ReadHRDParameters(p, &(sps->vui_seq_parameters.vcl_hrd_parameters));
+ }
+ if (sps->vui_seq_parameters.nal_hrd_parameters_present_flag || sps->vui_seq_parameters.vcl_hrd_parameters_present_flag)
+ {
+ sps->vui_seq_parameters.low_delay_hrd_flag = u_1 ("VUI: low_delay_hrd_flag" , s);
+ }
+ sps->vui_seq_parameters.pic_struct_present_flag = u_1 ("VUI: pic_struct_present_flag " , s);
+ sps->vui_seq_parameters.bitstream_restriction_flag = u_1 ("VUI: bitstream_restriction_flag" , s);
+ if (sps->vui_seq_parameters.bitstream_restriction_flag)
+ {
+ sps->vui_seq_parameters.motion_vectors_over_pic_boundaries_flag = u_1 ("VUI: motion_vectors_over_pic_boundaries_flag", s);
+ sps->vui_seq_parameters.max_bytes_per_pic_denom = ue_v ("VUI: max_bytes_per_pic_denom" , s);
+ sps->vui_seq_parameters.max_bits_per_mb_denom = ue_v ("VUI: max_bits_per_mb_denom" , s);
+ sps->vui_seq_parameters.log2_max_mv_length_horizontal = ue_v ("VUI: log2_max_mv_length_horizontal" , s);
+ sps->vui_seq_parameters.log2_max_mv_length_vertical = ue_v ("VUI: log2_max_mv_length_vertical" , s);
+ sps->vui_seq_parameters.num_reorder_frames = ue_v ("VUI: num_reorder_frames" , s);
+ sps->vui_seq_parameters.max_dec_frame_buffering = ue_v ("VUI: max_dec_frame_buffering" , s);
+ }
+ }
+
+ return 0;
+}
+
+
+int ReadHRDParameters(DataPartition *p, hrd_parameters_t *hrd)
+{
+ Bitstream *s = p->bitstream;
+ unsigned int SchedSelIdx;
+
+ hrd->cpb_cnt_minus1 = ue_v ( "VUI: cpb_cnt_minus1" , s);
+ hrd->bit_rate_scale = u_v ( 4,"VUI: bit_rate_scale" , s);
+ hrd->cpb_size_scale = u_v ( 4,"VUI: cpb_size_scale" , s);
+
+ for( SchedSelIdx = 0; SchedSelIdx <= hrd->cpb_cnt_minus1; SchedSelIdx++ )
+ {
+ hrd->bit_rate_value_minus1[ SchedSelIdx ] = ue_v ( "VUI: bit_rate_value_minus1" , s);
+ hrd->cpb_size_value_minus1[ SchedSelIdx ] = ue_v ( "VUI: cpb_size_value_minus1" , s);
+ hrd->cbr_flag[ SchedSelIdx ] = u_1 ( "VUI: cbr_flag" , s);
+ }
+
+ hrd->initial_cpb_removal_delay_length_minus1 = u_v ( 5,"VUI: initial_cpb_removal_delay_length_minus1" , s);
+ hrd->cpb_removal_delay_length_minus1 = u_v ( 5,"VUI: cpb_removal_delay_length_minus1" , s);
+ hrd->dpb_output_delay_length_minus1 = u_v ( 5,"VUI: dpb_output_delay_length_minus1" , s);
+ hrd->time_offset_length = u_v ( 5,"VUI: time_offset_length" , s);
+
+ return 0;
+}
+
+
+int InterpretPPS (DataPartition *p, pic_parameter_set_rbsp_t *pps)
+{
+ unsigned i;
+ int NumberBitsPerSliceGroupId;
+ Bitstream *s = p->bitstream;
+
+ assert (p != NULL);
+ assert (p->bitstream != NULL);
+ assert (p->bitstream->streamBuffer != 0);
+ assert (pps != NULL);
+
+ UsedBits = 0;
+
+ pps->pic_parameter_set_id = ue_v ("PPS: pic_parameter_set_id" , s);
+ pps->seq_parameter_set_id = ue_v ("PPS: seq_parameter_set_id" , s);
+ pps->entropy_coding_mode_flag = u_1 ("PPS: entropy_coding_mode_flag" , s);
+
+ //! Note: as per JVT-F078 the following bit is unconditional. If F078 is not accepted, then
+ //! one has to fetch the correct SPS to check whether the bit is present (hopefully there is
+ //! no consistency problem :-(
+ //! The current encoder code handles this in the same way. When you change this, don't forget
+ //! the encoder! StW, 12/8/02
+ pps->pic_order_present_flag = u_1 ("PPS: pic_order_present_flag" , s);
+
+ pps->num_slice_groups_minus1 = ue_v ("PPS: num_slice_groups_minus1" , s);
+
+ // FMO stuff begins here
+ if (pps->num_slice_groups_minus1 > 0)
+ {
+ pps->slice_group_map_type = ue_v ("PPS: slice_group_map_type" , s);
+ if (pps->slice_group_map_type == 0)
+ {
+ for (i=0; i<=pps->num_slice_groups_minus1; i++)
+ pps->run_length_minus1 [i] = ue_v ("PPS: run_length_minus1 [i]" , s);
+ }
+ else if (pps->slice_group_map_type == 2)
+ {
+ for (i=0; i<pps->num_slice_groups_minus1; i++)
+ {
+ //! JVT-F078: avoid reference of SPS by using ue(v) instead of u(v)
+ pps->top_left [i] = ue_v ("PPS: top_left [i]" , s);
+ pps->bottom_right [i] = ue_v ("PPS: bottom_right [i]" , s);
+ }
+ }
+ else if (pps->slice_group_map_type == 3 ||
+ pps->slice_group_map_type == 4 ||
+ pps->slice_group_map_type == 5)
+ {
+ pps->slice_group_change_direction_flag = u_1 ("PPS: slice_group_change_direction_flag" , s);
+ pps->slice_group_change_rate_minus1 = ue_v ("PPS: slice_group_change_rate_minus1" , s);
+ }
+ else if (pps->slice_group_map_type == 6)
+ {
+ if (pps->num_slice_groups_minus1+1 >4)
+ NumberBitsPerSliceGroupId = 3;
+ else if (pps->num_slice_groups_minus1+1 > 2)
+ NumberBitsPerSliceGroupId = 2;
+ else
+ NumberBitsPerSliceGroupId = 1;
+ //! JVT-F078, exlicitly signal number of MBs in the map
+ pps->num_slice_group_map_units_minus1 = ue_v ("PPS: num_slice_group_map_units_minus1" , s);
+ for (i=0; i<=pps->num_slice_group_map_units_minus1; i++)
+ pps->slice_group_id[i] = u_v (NumberBitsPerSliceGroupId, "slice_group_id[i]", s);
+ }
+ }
+
+ // End of FMO stuff
+
+ pps->num_ref_idx_l0_active_minus1 = ue_v ("PPS: num_ref_idx_l0_active_minus1" , s);
+ pps->num_ref_idx_l1_active_minus1 = ue_v ("PPS: num_ref_idx_l1_active_minus1" , s);
+ pps->weighted_pred_flag = u_1 ("PPS: weighted_pred_flag" , s);
+ pps->weighted_bipred_idc = u_v ( 2, "PPS: weighted_bipred_idc" , s);
+ pps->pic_init_qp_minus26 = se_v ("PPS: pic_init_qp_minus26" , s);
+ pps->pic_init_qs_minus26 = se_v ("PPS: pic_init_qs_minus26" , s);
+
+ pps->chroma_qp_index_offset = se_v ("PPS: chroma_qp_index_offset" , s);
+
+ pps->deblocking_filter_control_present_flag = u_1 ("PPS: deblocking_filter_control_present_flag" , s);
+ pps->constrained_intra_pred_flag = u_1 ("PPS: constrained_intra_pred_flag" , s);
+ pps->redundant_pic_cnt_present_flag = u_1 ("PPS: redundant_pic_cnt_present_flag" , s);
+
+ if(more_rbsp_data(s->streamBuffer, s->frame_bitoffset,s->bitstream_length)) // more_data_in_rbsp()
+ {
+ //Fidelity Range Extensions Stuff
+ pps->transform_8x8_mode_flag = u_1 ("PPS: transform_8x8_mode_flag" , s);
+ pps->pic_scaling_matrix_present_flag = u_1 ("PPS: pic_scaling_matrix_present_flag" , s);
+
+ if(pps->pic_scaling_matrix_present_flag)
+ {
+ for(i=0; i<(6+((unsigned)pps->transform_8x8_mode_flag<<1)); i++)
+ {
+ pps->pic_scaling_list_present_flag[i]= u_1 ("PPS: pic_scaling_list_present_flag" , s);
+
+ if(pps->pic_scaling_list_present_flag[i])
+ {
+ if(i<6)
+ Scaling_List(pps->ScalingList4x4[i], 16, &pps->UseDefaultScalingMatrix4x4Flag[i], s);
+ else
+ Scaling_List(pps->ScalingList8x8[i-6], 64, &pps->UseDefaultScalingMatrix8x8Flag[i-6], s);
+ }
+ }
+ }
+ pps->second_chroma_qp_index_offset = se_v ("PPS: second_chroma_qp_index_offset" , s);
+ }
+ else
+ {
+ pps->second_chroma_qp_index_offset = pps->chroma_qp_index_offset;
+ }
+
+ pps->Valid = TRUE;
+ return UsedBits;
+}
+
+
+void PPSConsistencyCheck (pic_parameter_set_rbsp_t *pps)
+{
+ printf ("Consistency checking a picture parset, to be implemented\n");
+// if (pps->seq_parameter_set_id invalid then do something)
+}
+
+void SPSConsistencyCheck (seq_parameter_set_rbsp_t *sps)
+{
+ printf ("Consistency checking a sequence parset, to be implemented\n");
+}
+
+void MakePPSavailable (int id, pic_parameter_set_rbsp_t *pps)
+{
+ assert (pps->Valid == TRUE);
+
+ if (PicParSet[id].Valid == TRUE && PicParSet[id].slice_group_id != NULL)
+ free (PicParSet[id].slice_group_id);
+
+ memcpy (&PicParSet[id], pps, sizeof (pic_parameter_set_rbsp_t));
+
+ // we can simply use the memory provided with the pps. the PPS is destroyed after this function
+ // call and will not try to free if pps->slice_group_id == NULL
+ PicParSet[id].slice_group_id = pps->slice_group_id;
+ pps->slice_group_id = NULL;
+}
+
+void CleanUpPPS()
+{
+ int i;
+
+ for (i=0; i<MAXPPS; i++)
+ {
+ if (PicParSet[i].Valid == TRUE && PicParSet[i].slice_group_id != NULL)
+ free (PicParSet[i].slice_group_id);
+
+ PicParSet[i].Valid = FALSE;
+ }
+}
+
+
+void MakeSPSavailable (int id, seq_parameter_set_rbsp_t *sps)
+{
+ assert (sps->Valid == TRUE);
+ memcpy (&SeqParSet[id], sps, sizeof (seq_parameter_set_rbsp_t));
+}
+
+
+void ProcessSPS (NALU_t *nalu)
+{
+ DataPartition *dp = AllocPartition(1);
+ seq_parameter_set_rbsp_t *sps = AllocSPS();
+ int dummy;
+
+ memcpy (dp->bitstream->streamBuffer, &nalu->buf[1], nalu->len-1);
+ dp->bitstream->code_len = dp->bitstream->bitstream_length = RBSPtoSODB (dp->bitstream->streamBuffer, nalu->len-1);
+ dp->bitstream->ei_flag = 0;
+ dp->bitstream->read_len = dp->bitstream->frame_bitoffset = 0;
+ dummy = InterpretSPS (dp, sps);
+
+ if (sps->Valid)
+ {
+ if (active_sps)
+ {
+ if (sps->seq_parameter_set_id == active_sps->seq_parameter_set_id)
+ {
+ if (!sps_is_equal(sps, active_sps))
+ {
+ if (dec_picture)
+ {
+ // this may only happen on slice loss
+ exit_picture();
+ }
+ active_sps=NULL;
+ }
+ }
+ }
+ // SPSConsistencyCheck (pps);
+ MakeSPSavailable (sps->seq_parameter_set_id, sps);
+ img->profile_idc = sps->profile_idc; //ADD-VG
+ }
+
+ FreePartition (dp, 1);
+ FreeSPS (sps);
+}
+
+
+void ProcessPPS (NALU_t *nalu)
+{
+ DataPartition *dp;
+ pic_parameter_set_rbsp_t *pps;
+ int dummy;
+
+ dp = AllocPartition(1);
+ pps = AllocPPS();
+ memcpy (dp->bitstream->streamBuffer, &nalu->buf[1], nalu->len-1);
+ dp->bitstream->code_len = dp->bitstream->bitstream_length = RBSPtoSODB (dp->bitstream->streamBuffer, nalu->len-1);
+ dp->bitstream->ei_flag = 0;
+ dp->bitstream->read_len = dp->bitstream->frame_bitoffset = 0;
+ dummy = InterpretPPS (dp, pps);
+ // PPSConsistencyCheck (pps);
+ if (active_pps)
+ {
+ if (pps->pic_parameter_set_id == active_pps->pic_parameter_set_id)
+ {
+ if (!pps_is_equal(pps, active_pps))
+ {
+ if (dec_picture)
+ {
+ // this may only happen on slice loss
+ exit_picture();
+ }
+ active_pps = NULL;
+ }
+ }
+ }
+ MakePPSavailable (pps->pic_parameter_set_id, pps);
+ FreePartition (dp, 1);
+ FreePPS (pps);
+}
+
+void activate_sps (seq_parameter_set_rbsp_t *sps)
+{
+ if (active_sps != sps)
+ {
+ if (dec_picture)
+ {
+ // this may only happen on slice loss
+ exit_picture();
+ }
+ active_sps = sps;
+
+ img->bitdepth_chroma = 0;
+ img->width_cr = 0;
+ img->height_cr = 0;
+
+ // Fidelity Range Extensions stuff (part 1)
+ img->bitdepth_luma = sps->bit_depth_luma_minus8 + 8;
+ if (sps->chroma_format_idc != YUV400)
+ img->bitdepth_chroma = sps->bit_depth_chroma_minus8 + 8;
+
+ img->MaxFrameNum = 1<<(sps->log2_max_frame_num_minus4+4);
+ img->PicWidthInMbs = (sps->pic_width_in_mbs_minus1 +1);
+ img->PicHeightInMapUnits = (sps->pic_height_in_map_units_minus1 +1);
+ img->FrameHeightInMbs = ( 2 - sps->frame_mbs_only_flag ) * img->PicHeightInMapUnits;
+ img->FrameSizeInMbs = img->PicWidthInMbs * img->FrameHeightInMbs;
+
+ img->yuv_format=sps->chroma_format_idc;
+
+ img->width = img->PicWidthInMbs * MB_BLOCK_SIZE;
+ img->height = img->FrameHeightInMbs * MB_BLOCK_SIZE;
+
+ if (sps->chroma_format_idc == YUV420)
+ {
+ img->width_cr = img->width >>1;
+ img->height_cr = img->height >>1;
+ }
+ else if (sps->chroma_format_idc == YUV422)
+ {
+ img->width_cr = img->width >>1;
+ img->height_cr = img->height;
+ }
+ else if (sps->chroma_format_idc == YUV444)
+ {
+ //YUV444
+ img->width_cr = img->width;
+ img->height_cr = img->height;
+ }
+
+ img->width_cr_m1 = img->width_cr - 1;
+ init_frext(img);
+ init_global_buffers();
+ if (!img->no_output_of_prior_pics_flag)
+ {
+ flush_dpb();
+ }
+ init_dpb();
+
+ if (NULL!=Co_located)
+ {
+ free_colocated(Co_located);
+ }
+ Co_located = alloc_colocated (img->width, img->height,sps->mb_adaptive_frame_field_flag);
+ ercInit(img->width, img->height, 1);
+ }
+}
+
+void activate_pps(pic_parameter_set_rbsp_t *pps)
+{
+ if (active_pps != pps)
+ {
+ if (dec_picture)
+ {
+ // this may only happen on slice loss
+ exit_picture();
+ }
+
+ active_pps = pps;
+
+ // Fidelity Range Extensions stuff (part 2)
+ img->Transform8x8Mode = pps->transform_8x8_mode_flag;
+
+ }
+}
+
+void UseParameterSet (int PicParsetId)
+{
+ seq_parameter_set_rbsp_t *sps = &SeqParSet[PicParSet[PicParsetId].seq_parameter_set_id];
+ pic_parameter_set_rbsp_t *pps = &PicParSet[PicParsetId];
+ int i;
+
+
+ if (PicParSet[PicParsetId].Valid != TRUE)
+ printf ("Trying to use an invalid (uninitialized) Picture Parameter Set with ID %d, expect the unexpected...\n", PicParsetId);
+ if (SeqParSet[PicParSet[PicParsetId].seq_parameter_set_id].Valid != TRUE)
+ printf ("PicParset %d references an invalid (uninitialized) Sequence Parameter Set with ID %d, expect the unexpected...\n", PicParsetId, PicParSet[PicParsetId].seq_parameter_set_id);
+
+ sps = &SeqParSet[PicParSet[PicParsetId].seq_parameter_set_id];
+
+
+ // In theory, and with a well-designed software, the lines above
+ // are everything necessary. In practice, we need to patch many values
+ // in img-> (but no more in inp-> -- these have been taken care of)
+
+ // Sequence Parameter Set Stuff first
+
+// printf ("Using Picture Parameter set %d and associated Sequence Parameter Set %d\n", PicParsetId, PicParSet[PicParsetId].seq_parameter_set_id);
+
+ if ((int) sps->pic_order_cnt_type < 0 || sps->pic_order_cnt_type > 2) // != 1
+ {
+ printf ("invalid sps->pic_order_cnt_type = %d\n", sps->pic_order_cnt_type);
+ error ("pic_order_cnt_type != 1", -1000);
+ }
+
+ if (sps->pic_order_cnt_type == 1)
+ {
+ if(sps->num_ref_frames_in_pic_order_cnt_cycle >= MAXnum_ref_frames_in_pic_order_cnt_cycle)
+ {
+ error("num_ref_frames_in_pic_order_cnt_cycle too large",-1011);
+ }
+ }
+
+ activate_sps(sps);
+ activate_pps(pps);
+
+
+ // currSlice->dp_mode is set by read_new_slice (NALU first byte available there)
+ if (pps->entropy_coding_mode_flag == UVLC)
+ {
+ nal_startcode_follows = uvlc_startcode_follows;
+ for (i=0; i<3; i++)
+ {
+ img->currentSlice->partArr[i].readSyntaxElement = readSyntaxElement_UVLC;
+ }
+ }
+ else
+ {
+ nal_startcode_follows = cabac_startcode_follows;
+ for (i=0; i<3; i++)
+ {
+ img->currentSlice->partArr[i].readSyntaxElement = readSyntaxElement_CABAC;
+ }
+ }
+}
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/parset.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/parset.h:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/parset.h Sun Feb 4 08:38:32 2007
@@ -0,0 +1,44 @@
+
+/*!
+ **************************************************************************************
+ * \file
+ * parset.h
+ * \brief
+ * Picture and Sequence Parameter Sets, decoder operations
+ * This code reflects JVT version xxx
+ * \date 25 November 2002
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Stephan Wenger <stewe at cs.tu-berlin.de>
+ ***************************************************************************************
+ */
+#ifndef _PARSET_H_
+#define _PARSET_H_
+
+
+#include "parsetcommon.h"
+#include "nalucommon.h"
+
+void Scaling_List(int *scalingList, int sizeOfScalingList, Boolean *UseDefaultScalingMatrix, Bitstream *s);
+
+void InitVUI(seq_parameter_set_rbsp_t *sps);
+int ReadVUI(DataPartition *p, seq_parameter_set_rbsp_t *sps);
+int ReadHRDParameters(DataPartition *p, hrd_parameters_t *hrd);
+
+void PPSConsistencyCheck (pic_parameter_set_rbsp_t *pps);
+void SPSConsistencyCheck (seq_parameter_set_rbsp_t *sps);
+
+void MakePPSavailable (int id, pic_parameter_set_rbsp_t *pps);
+void MakeSPSavailable (int id, seq_parameter_set_rbsp_t *sps);
+
+void ProcessSPS (NALU_t *nalu);
+void ProcessPPS (NALU_t *nalu);
+
+void UseParameterSet (int PicParsetId);
+
+void CleanUpPPS();
+
+void activate_sps (seq_parameter_set_rbsp_t *sps);
+void activate_pps (pic_parameter_set_rbsp_t *pps);
+
+#endif
Index: llvm-test/MultiSource/Applications/JM/ldecod/parsetcommon.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/parsetcommon.c:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/parsetcommon.c Sun Feb 4 08:38:32 2007
@@ -0,0 +1,218 @@
+
+/*!
+ **************************************************************************************
+ * \file
+ * parset.c
+ * \brief
+ * Picture and Sequence Parameter set generation and handling
+ * \date 25 November 2002
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Stephan Wenger <stewe at cs.tu-berlin.de>
+ *
+ **************************************************************************************
+ */
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "parsetcommon.h"
+#include "memalloc.h"
+/*!
+ *************************************************************************************
+ * \brief
+ * Allocates memory for a picture paramater set
+ *
+ * \return
+ * pointer to a pps
+ *************************************************************************************
+ */
+
+pic_parameter_set_rbsp_t *AllocPPS ()
+ {
+ pic_parameter_set_rbsp_t *p;
+
+ if ((p=calloc (sizeof (pic_parameter_set_rbsp_t), 1)) == NULL)
+ no_mem_exit ("AllocPPS: PPS");
+ if ((p->slice_group_id = calloc (SIZEslice_group_id, 1)) == NULL)
+ no_mem_exit ("AllocPPS: slice_group_id");
+ return p;
+ }
+
+
+/*!
+ *************************************************************************************
+ * \brief
+ * Allocates memory for am sequence paramater set
+ *
+ * \return
+ * pointer to a sps
+ *************************************************************************************
+ */
+
+seq_parameter_set_rbsp_t *AllocSPS ()
+ {
+ seq_parameter_set_rbsp_t *p;
+
+ if ((p=calloc (sizeof (seq_parameter_set_rbsp_t), 1)) == NULL)
+ no_mem_exit ("AllocSPS: SPS");
+ return p;
+ }
+
+
+/*!
+ *************************************************************************************
+ * \brief
+ * Frees a picture parameter set
+ *
+ * \param pps to be freed
+ * Picture parameter set to be freed
+ *************************************************************************************
+ */
+
+ void FreePPS (pic_parameter_set_rbsp_t *pps)
+ {
+ assert (pps != NULL);
+ if (pps->slice_group_id != NULL) free (pps->slice_group_id);
+ free (pps);
+ }
+
+
+ /*!
+ *************************************************************************************
+ * \brief
+ * Frees a sps
+ *
+ * \param sps
+ * Sequence parameter set to be freed
+ *************************************************************************************
+ */
+
+ void FreeSPS (seq_parameter_set_rbsp_t *sps)
+ {
+ assert (sps != NULL);
+ free (sps);
+ }
+
+
+int sps_is_equal(seq_parameter_set_rbsp_t *sps1, seq_parameter_set_rbsp_t *sps2)
+{
+ unsigned i;
+ int equal = 1;
+
+ if ((!sps1->Valid) || (!sps2->Valid))
+ return 0;
+
+ equal &= (sps1->profile_idc == sps2->profile_idc);
+ equal &= (sps1->constrained_set0_flag == sps2->constrained_set0_flag);
+ equal &= (sps1->constrained_set1_flag == sps2->constrained_set1_flag);
+ equal &= (sps1->constrained_set2_flag == sps2->constrained_set2_flag);
+ equal &= (sps1->level_idc == sps2->level_idc);
+ equal &= (sps1->seq_parameter_set_id == sps2->seq_parameter_set_id);
+ equal &= (sps1->log2_max_frame_num_minus4 == sps2->log2_max_frame_num_minus4);
+ equal &= (sps1->pic_order_cnt_type == sps2->pic_order_cnt_type);
+
+ if (!equal) return equal;
+
+ if( sps1->pic_order_cnt_type == 0 )
+ {
+ equal &= (sps1->log2_max_pic_order_cnt_lsb_minus4 == sps2->log2_max_pic_order_cnt_lsb_minus4);
+ }
+
+ else if( sps1->pic_order_cnt_type == 1 )
+ {
+ equal &= (sps1->delta_pic_order_always_zero_flag == sps2->delta_pic_order_always_zero_flag);
+ equal &= (sps1->offset_for_non_ref_pic == sps2->offset_for_non_ref_pic);
+ equal &= (sps1->offset_for_top_to_bottom_field == sps2->offset_for_top_to_bottom_field);
+ equal &= (sps1->num_ref_frames_in_pic_order_cnt_cycle == sps2->num_ref_frames_in_pic_order_cnt_cycle);
+ if (!equal) return equal;
+
+ for ( i = 0 ; i< sps1->num_ref_frames_in_pic_order_cnt_cycle ;i ++)
+ equal &= (sps1->offset_for_ref_frame[i] == sps2->offset_for_ref_frame[i]);
+ }
+
+ equal &= (sps1->num_ref_frames == sps2->num_ref_frames);
+ equal &= (sps1->gaps_in_frame_num_value_allowed_flag == sps2->gaps_in_frame_num_value_allowed_flag);
+ equal &= (sps1->pic_width_in_mbs_minus1 == sps2->pic_width_in_mbs_minus1);
+ equal &= (sps1->pic_height_in_map_units_minus1 == sps2->pic_height_in_map_units_minus1);
+ equal &= (sps1->frame_mbs_only_flag == sps2->frame_mbs_only_flag);
+
+ if (!equal) return equal;
+ if( !sps1->frame_mbs_only_flag )
+ equal &= (sps1->mb_adaptive_frame_field_flag == sps2->mb_adaptive_frame_field_flag);
+
+ equal &= (sps1->direct_8x8_inference_flag == sps2->direct_8x8_inference_flag);
+ equal &= (sps1->frame_cropping_flag == sps2->frame_cropping_flag);
+ if (!equal) return equal;
+ if (sps1->frame_cropping_flag)
+ {
+ equal &= (sps1->frame_cropping_rect_left_offset == sps2->frame_cropping_rect_left_offset);
+ equal &= (sps1->frame_cropping_rect_right_offset == sps2->frame_cropping_rect_right_offset);
+ equal &= (sps1->frame_cropping_rect_top_offset == sps2->frame_cropping_rect_top_offset);
+ equal &= (sps1->frame_cropping_rect_bottom_offset == sps2->frame_cropping_rect_bottom_offset);
+ }
+ equal &= (sps1->vui_parameters_present_flag == sps2->vui_parameters_present_flag);
+
+ return equal;
+}
+
+int pps_is_equal(pic_parameter_set_rbsp_t *pps1, pic_parameter_set_rbsp_t *pps2)
+{
+ unsigned i;
+ int equal = 1;
+
+ if ((!pps1->Valid) || (!pps2->Valid))
+ return 0;
+
+ equal &= (pps1->pic_parameter_set_id == pps2->pic_parameter_set_id);
+ equal &= (pps1->seq_parameter_set_id == pps2->seq_parameter_set_id);
+ equal &= (pps1->entropy_coding_mode_flag == pps2->entropy_coding_mode_flag);
+ equal &= (pps1->pic_order_present_flag == pps2->pic_order_present_flag);
+ equal &= (pps1->num_slice_groups_minus1 == pps2->num_slice_groups_minus1);
+
+ if (!equal) return equal;
+
+ if (pps1->num_slice_groups_minus1>0)
+ {
+ equal &= (pps1->slice_group_map_type == pps2->slice_group_map_type);
+ if (!equal) return equal;
+ if (pps1->slice_group_map_type == 0)
+ {
+ for (i=0; i<=pps1->num_slice_groups_minus1; i++)
+ equal &= (pps1->run_length_minus1[i] == pps2->run_length_minus1[i]);
+ }
+ else if( pps1->slice_group_map_type == 2 )
+ {
+ for (i=0; i<pps1->num_slice_groups_minus1; i++)
+ {
+ equal &= (pps1->top_left[i] == pps2->top_left[i]);
+ equal &= (pps1->bottom_right[i] == pps2->bottom_right[i]);
+ }
+ }
+ else if( pps1->slice_group_map_type == 3 || pps1->slice_group_map_type==4 || pps1->slice_group_map_type==5 )
+ {
+ equal &= (pps1->slice_group_change_direction_flag == pps2->slice_group_change_direction_flag);
+ equal &= (pps1->slice_group_change_rate_minus1 == pps2->slice_group_change_rate_minus1);
+ }
+ else if( pps1->slice_group_map_type == 6 )
+ {
+ equal &= (pps1->num_slice_group_map_units_minus1 == pps2->num_slice_group_map_units_minus1);
+ if (!equal) return equal;
+ for (i=0; i<=pps1->num_slice_group_map_units_minus1; i++)
+ equal &= (pps1->slice_group_id[i] == pps2->slice_group_id[i]);
+ }
+ }
+
+ equal &= (pps1->num_ref_idx_l0_active_minus1 == pps2->num_ref_idx_l0_active_minus1);
+ equal &= (pps1->num_ref_idx_l1_active_minus1 == pps2->num_ref_idx_l1_active_minus1);
+ equal &= (pps1->weighted_pred_flag == pps2->weighted_pred_flag);
+ equal &= (pps1->weighted_bipred_idc == pps2->weighted_bipred_idc);
+ equal &= (pps1->pic_init_qp_minus26 == pps2->pic_init_qp_minus26);
+ equal &= (pps1->pic_init_qs_minus26 == pps2->pic_init_qs_minus26);
+ equal &= (pps1->chroma_qp_index_offset == pps2->chroma_qp_index_offset);
+ equal &= (pps1->deblocking_filter_control_present_flag == pps2->deblocking_filter_control_present_flag);
+ equal &= (pps1->constrained_intra_pred_flag == pps2->constrained_intra_pred_flag);
+ equal &= (pps1->redundant_pic_cnt_present_flag == pps2->redundant_pic_cnt_present_flag);
+
+ return equal;
+}
Index: llvm-test/MultiSource/Applications/JM/ldecod/parsetcommon.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/parsetcommon.h:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/parsetcommon.h Sun Feb 4 08:38:32 2007
@@ -0,0 +1,214 @@
+
+/*!
+ **************************************************************************************
+ * \file
+ * parsetcommon.h
+ * \brief
+ * Picture and Sequence Parameter Sets, structures common to encoder and decoder
+ * This code reflects JVT version xxx
+ * \date 25 November 2002
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Stephan Wenger <stewe at cs.tu-berlin.de>
+ ***************************************************************************************
+ */
+
+
+
+// In the JVT syntax, frequently flags are used that indicate the presence of
+// certain pieces of information in the NALU. Here, these flags are also
+// present. In the encoder, those bits indicate that the values signalled to
+// be present are meaningful and that this part of the syntax should be
+// written to the NALU. In the decoder, the flag indicates that information
+// was received from the decoded NALU and should be used henceforth.
+// The structure names were chosen as indicated in the JVT syntax
+
+#ifndef _PARSETCOMMON_H_
+#define _PARSETCOMMON_H_
+
+#include "defines.h"
+
+#define MAXIMUMPARSETRBSPSIZE 1500
+#define MAXIMUMPARSETNALUSIZE 1500
+#define SIZEslice_group_id (sizeof (int) * 60000) // should be sufficient for HUGE pictures, need one int per MB in a picture
+
+#define MAXSPS 32
+#define MAXPPS 256
+
+//! Boolean Type
+#ifdef FALSE
+# define Boolean int
+#else
+typedef enum {
+ FALSE,
+ TRUE
+} Boolean;
+#endif
+
+#define MAXIMUMVALUEOFcpb_cnt 32
+typedef struct
+{
+ unsigned int cpb_cnt_minus1; // ue(v)
+ unsigned int bit_rate_scale; // u(4)
+ unsigned int cpb_size_scale; // u(4)
+ unsigned int bit_rate_value_minus1 [MAXIMUMVALUEOFcpb_cnt]; // ue(v)
+ unsigned int cpb_size_value_minus1 [MAXIMUMVALUEOFcpb_cnt]; // ue(v)
+ unsigned int cbr_flag [MAXIMUMVALUEOFcpb_cnt]; // u(1)
+ unsigned int initial_cpb_removal_delay_length_minus1; // u(5)
+ unsigned int cpb_removal_delay_length_minus1; // u(5)
+ unsigned int dpb_output_delay_length_minus1; // u(5)
+ unsigned int time_offset_length; // u(5)
+} hrd_parameters_t;
+
+
+typedef struct
+{
+ Boolean aspect_ratio_info_present_flag; // u(1)
+ unsigned int aspect_ratio_idc; // u(8)
+ unsigned int sar_width; // u(16)
+ unsigned int sar_height; // u(16)
+ Boolean overscan_info_present_flag; // u(1)
+ Boolean overscan_appropriate_flag; // u(1)
+ Boolean video_signal_type_present_flag; // u(1)
+ unsigned video_format; // u(3)
+ Boolean video_full_range_flag; // u(1)
+ Boolean colour_description_present_flag; // u(1)
+ unsigned int colour_primaries; // u(8)
+ unsigned int transfer_characteristics; // u(8)
+ unsigned int matrix_coefficients; // u(8)
+ Boolean chroma_location_info_present_flag; // u(1)
+ unsigned int chroma_sample_loc_type_top_field; // ue(v)
+ unsigned int chroma_sample_loc_type_bottom_field; // ue(v)
+ Boolean timing_info_present_flag; // u(1)
+ unsigned int num_units_in_tick; // u(32)
+ unsigned int time_scale; // u(32)
+ Boolean fixed_frame_rate_flag; // u(1)
+ Boolean nal_hrd_parameters_present_flag; // u(1)
+ hrd_parameters_t nal_hrd_parameters; // hrd_paramters_t
+ Boolean vcl_hrd_parameters_present_flag; // u(1)
+ hrd_parameters_t vcl_hrd_parameters; // hrd_paramters_t
+ // if ((nal_hrd_parameters_present_flag || (vcl_hrd_parameters_present_flag))
+ Boolean low_delay_hrd_flag; // u(1)
+ Boolean pic_struct_present_flag; // u(1)
+ Boolean bitstream_restriction_flag; // u(1)
+ Boolean motion_vectors_over_pic_boundaries_flag; // u(1)
+ unsigned int max_bytes_per_pic_denom; // ue(v)
+ unsigned int max_bits_per_mb_denom; // ue(v)
+ unsigned int log2_max_mv_length_vertical; // ue(v)
+ unsigned int log2_max_mv_length_horizontal; // ue(v)
+ unsigned int num_reorder_frames; // ue(v)
+ unsigned int max_dec_frame_buffering; // ue(v)
+} vui_seq_parameters_t;
+
+
+#define MAXnum_slice_groups_minus1 8
+typedef struct
+{
+ Boolean Valid; // indicates the parameter set is valid
+ unsigned int pic_parameter_set_id; // ue(v)
+ unsigned int seq_parameter_set_id; // ue(v)
+ Boolean entropy_coding_mode_flag; // u(1)
+
+ Boolean transform_8x8_mode_flag; // u(1)
+
+ Boolean pic_scaling_matrix_present_flag; // u(1)
+ int pic_scaling_list_present_flag[8]; // u(1)
+ int ScalingList4x4[6][16]; // se(v)
+ int ScalingList8x8[2][64]; // se(v)
+ Boolean UseDefaultScalingMatrix4x4Flag[6];
+ Boolean UseDefaultScalingMatrix8x8Flag[2];
+
+ // if( pic_order_cnt_type < 2 ) in the sequence parameter set
+ Boolean pic_order_present_flag; // u(1)
+ unsigned int num_slice_groups_minus1; // ue(v)
+ unsigned int slice_group_map_type; // ue(v)
+ // if( slice_group_map_type = = 0 )
+ unsigned int run_length_minus1[MAXnum_slice_groups_minus1]; // ue(v)
+ // else if( slice_group_map_type = = 2 )
+ unsigned int top_left[MAXnum_slice_groups_minus1]; // ue(v)
+ unsigned int bottom_right[MAXnum_slice_groups_minus1]; // ue(v)
+ // else if( slice_group_map_type = = 3 || 4 || 5
+ Boolean slice_group_change_direction_flag; // u(1)
+ unsigned int slice_group_change_rate_minus1; // ue(v)
+ // else if( slice_group_map_type = = 6 )
+ unsigned int num_slice_group_map_units_minus1; // ue(v)
+ unsigned int *slice_group_id; // complete MBAmap u(v)
+ unsigned int num_ref_idx_l0_active_minus1; // ue(v)
+ unsigned int num_ref_idx_l1_active_minus1; // ue(v)
+ Boolean weighted_pred_flag; // u(1)
+ unsigned int weighted_bipred_idc; // u(2)
+ int pic_init_qp_minus26; // se(v)
+ int pic_init_qs_minus26; // se(v)
+ int chroma_qp_index_offset; // se(v)
+
+ int second_chroma_qp_index_offset; // se(v)
+
+ Boolean deblocking_filter_control_present_flag; // u(1)
+ Boolean constrained_intra_pred_flag; // u(1)
+ Boolean redundant_pic_cnt_present_flag; // u(1)
+} pic_parameter_set_rbsp_t;
+
+
+#define MAXnum_ref_frames_in_pic_order_cnt_cycle 256
+typedef struct
+{
+ Boolean Valid; // indicates the parameter set is valid
+
+ unsigned int profile_idc; // u(8)
+ Boolean constrained_set0_flag; // u(1)
+ Boolean constrained_set1_flag; // u(1)
+ Boolean constrained_set2_flag; // u(1)
+ Boolean constrained_set3_flag; // u(1)
+ unsigned int level_idc; // u(8)
+ unsigned int seq_parameter_set_id; // ue(v)
+ unsigned int chroma_format_idc; // ue(v)
+
+ Boolean seq_scaling_matrix_present_flag; // u(1)
+ int seq_scaling_list_present_flag[8]; // u(1)
+ int ScalingList4x4[6][16]; // se(v)
+ int ScalingList8x8[2][64]; // se(v)
+ Boolean UseDefaultScalingMatrix4x4Flag[6];
+ Boolean UseDefaultScalingMatrix8x8Flag[2];
+
+ unsigned int bit_depth_luma_minus8; // ue(v)
+ unsigned int bit_depth_chroma_minus8; // ue(v)
+
+ unsigned int log2_max_frame_num_minus4; // ue(v)
+ unsigned int pic_order_cnt_type;
+ // if( pic_order_cnt_type == 0 )
+ unsigned log2_max_pic_order_cnt_lsb_minus4; // ue(v)
+ // else if( pic_order_cnt_type == 1 )
+ Boolean delta_pic_order_always_zero_flag; // u(1)
+ int offset_for_non_ref_pic; // se(v)
+ int offset_for_top_to_bottom_field; // se(v)
+ unsigned int num_ref_frames_in_pic_order_cnt_cycle; // ue(v)
+ // for( i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++ )
+ int offset_for_ref_frame[MAXnum_ref_frames_in_pic_order_cnt_cycle]; // se(v)
+ unsigned int num_ref_frames; // ue(v)
+ Boolean gaps_in_frame_num_value_allowed_flag; // u(1)
+ unsigned int pic_width_in_mbs_minus1; // ue(v)
+ unsigned int pic_height_in_map_units_minus1; // ue(v)
+ Boolean frame_mbs_only_flag; // u(1)
+ // if( !frame_mbs_only_flag )
+ Boolean mb_adaptive_frame_field_flag; // u(1)
+ Boolean direct_8x8_inference_flag; // u(1)
+ Boolean frame_cropping_flag; // u(1)
+ unsigned int frame_cropping_rect_left_offset; // ue(v)
+ unsigned int frame_cropping_rect_right_offset; // ue(v)
+ unsigned int frame_cropping_rect_top_offset; // ue(v)
+ unsigned int frame_cropping_rect_bottom_offset; // ue(v)
+ Boolean vui_parameters_present_flag; // u(1)
+ vui_seq_parameters_t vui_seq_parameters; // vui_seq_parameters_t
+} seq_parameter_set_rbsp_t;
+
+
+pic_parameter_set_rbsp_t *AllocPPS ();
+seq_parameter_set_rbsp_t *AllocSPS ();
+
+void FreePPS (pic_parameter_set_rbsp_t *pps);
+void FreeSPS (seq_parameter_set_rbsp_t *sps);
+
+int sps_is_equal(seq_parameter_set_rbsp_t *sps1, seq_parameter_set_rbsp_t *sps2);
+int pps_is_equal(pic_parameter_set_rbsp_t *pps1, pic_parameter_set_rbsp_t *pps2);
+
+#endif
Index: llvm-test/MultiSource/Applications/JM/ldecod/rtp.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/rtp.c:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/rtp.c Sun Feb 4 08:38:32 2007
@@ -0,0 +1,372 @@
+
+/*!
+ ************************************************************************
+ * \file rtp.c
+ *
+ * \brief
+ * Network Adaptation layer for RTP packets
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Stephan Wenger <stewe at cs.tu-berlin.de>
+ ************************************************************************
+ */
+
+
+/*!
+
+ A quick guide to the basics of the RTP decoder implementation
+
+ This module contains the RTP packetization, de-packetization, and the
+ handling of Parameter Sets, see VCEG-N52 and accompanying documents.
+ Note: Compound packets are not yet implemented!
+
+ The interface between every NAL (including the RTP NAL) and the VCL is
+ based on Slices. The slice data structure on which the VCL is working
+ is defined in the type Slice (in defines.h). This type contains the
+ various fields of the slice header and a partition array, which itself
+ contains the data partitions the slice consists of. When data
+ partitioning is not used, then the whole slice bit string is stored
+ in partition #0. When individual partitions are missing, this is
+ indicated by the size of the bit strings in the partition array.
+ A complete missing slice (e.g. if a Full Slice packet was lost) is
+ indicated in a similar way.
+
+ part of the slice structure is the error indication (ei-flag). The
+ Ei-flag is set in such cases in which at least one partition of a slice
+ is damaged or missing.When data partitioning is used, it can happen that
+ one partition does not contain any symbols but the ei_flag is cleared,
+ which indicates the intentional missing of symbols of that partition.
+ A typical example for this behaviour is the Intra Slice, which does not
+ have symnbols in its type C partition.
+
+ The VCL requests new data to work on through the call of readSliceRTP().
+ This function calls the main state machine of this module in ReadRTPpaacket().
+
+ ReadRTPpacket assumes, when called, that in an error free environment
+ a complete slice, consisting of one Full Slice RTP packet, or three Partition
+ packets of types A, B, C with consecutive sequence numbers, can be read.
+ It first interprets any trailing SUPP and Parameter Update (Header) packets.
+ Then it reads one video data packet. Two cases have to be distinguished:
+
+ 1. Type A, or Full Slice packet
+ In this case, the PictureID and the macroblock mumbers are used to
+ identify the potential loss of a slice. A slice is lost, when the
+ StartMB of the newly read slice header is not equal to the current
+ state of the decoder
+ 1.1 Loss detected
+ In this case the last packet is unread (fseek back), and a dummy slice
+ containing the missing macroblocks is conveyed to the VCL. At the next
+ call of the NAL, the same packet is read again, but this time no packet
+ loss is detected by the above algorithm,
+ 1.2. No loss
+ In this case it is checked whether a Full Slice packet or a type A data
+ partition was read
+ 1.2.1 Full Slice
+ The Full Slice packet is conveyed to the NAL
+ 1.2.2 Type A Partition
+ The function RTPReadDataPartitionedSlice() is called, which collects
+ the remaining type B, C partitions and handles them appropriately.
+
+ Paraneter Update Packets (aka Header packets) are in an SDP-like syntax
+ and are interpreted by a simple parser in the function
+ RTPInterpretParameterSetPacket()
+
+ Each Slice header contaions the information on which parameter set to be used.
+ The function RTPSetImgInp() copies the information of the relevant parameter
+ set in the VCL's global variables img-> and inp-> IMPORTANT: any changes
+ in the semantics of the img-> and inp-> structure members must be represented
+ in this function as well!
+
+ A note to the stream-buffer data structure: The stream buffer always contains
+ only the contents of the partition in question, and not the slice/partition
+ header. Decoding has to start at bitoffset 0 (UVLC) or bytreoffset 0 (CABAC).
+
+ The remaining functions should be self-explanatory.
+
+*/
+
+#include "contributors.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "global.h"
+#include "errorconcealment.h"
+#include "rtp.h"
+#include "fmo.h"
+#include "sei.h"
+#include "memalloc.h"
+
+#ifdef WIN32
+#include <Winsock2.h>
+#else
+#include <netinet/in.h>
+#endif
+
+FILE *bits;
+
+int RTPReadPacket (RTPpacket_t *p, FILE *bits);
+
+/*!
+ ************************************************************************
+ * \brief
+ * Opens the bit stream file named fn
+ * \return
+ * none
+ ************************************************************************
+ */
+void OpenRTPFile (char *fn)
+{
+ if (NULL == (bits=fopen(fn, "rb")))
+ {
+ snprintf (errortext, ET_SIZE, "Cannot open RTP file '%s'", input->infile);
+ error(errortext,500);
+ }
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Closes the bit stream file
+ ************************************************************************
+ */
+void CloseRTPFile()
+{
+ fclose (bits);
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Fills nalu->buf and nalu->len with the payload of an RTP packet.
+ * Other fields in nalu-> remain uninitialized (will be taken care of
+ * by NALUtoRBSP.
+ *
+ * \return
+ * 4 in case of ok (for compatibility with GetAnnexbNALU)
+ * 0 if there is nothing any more to read (EOF)
+ * -1 in case of any error
+ *
+ ************************************************************************
+ */
+
+int GetRTPNALU (NALU_t *nalu)
+{
+ RTPpacket_t *p;
+ int ret;
+
+ if ((p=malloc (sizeof (RTPpacket_t)))== NULL)
+ no_mem_exit ("GetRTPNALU-1");
+ if ((p->packet=malloc (MAXRTPPACKETSIZE))== NULL)
+ no_mem_exit ("GetRTPNALU-2");
+ if ((p->payload=malloc (MAXRTPPACKETSIZE))== NULL)
+ no_mem_exit ("GetRTPNALU-3");
+
+ ret = RTPReadPacket (p, bits);
+ nalu->forbidden_bit = 1;
+ nalu->len = 0;
+
+ if (ret < 0)
+ return -1;
+ if (ret == 0)
+ return 0;
+
+ assert (p->paylen < nalu->max_size);
+
+ nalu->len = p->paylen;
+ memcpy (nalu->buf, p->payload, p->paylen);
+ nalu->forbidden_bit = (nalu->buf[0]>>7) & 1;
+ nalu->nal_reference_idc = (nalu->buf[0]>>5) & 3;
+ nalu->nal_unit_type = (nalu->buf[0]) & 0x1f;
+
+ free (p->payload);
+ free (p->packet);
+ free (p);
+// printf ("Got an RTP NALU, len %d, first byte %x\n", nalu->len, nalu->buf[0]);
+ return nalu->len;
+}
+
+
+
+/*!
+ *****************************************************************************
+ *
+ * \brief
+ * DecomposeRTPpacket interprets the RTP packet and writes the various
+ * structure members of the RTPpacket_t structure
+ *
+ * \return
+ * 0 in case of success
+ * negative error code in case of failure
+ *
+ * \param p
+ * Caller is responsible to allocate enough memory for the generated payload
+ * in parameter->payload. Typically a malloc of paclen-12 bytes is sufficient
+ *
+ * \par Side effects
+ * none
+ *
+ * \date
+ * 30 Spetember 2001
+ *
+ * \author
+ * Stephan Wenger stewe at cs.tu-berlin.de
+ *****************************************************************************/
+
+int DecomposeRTPpacket (RTPpacket_t *p)
+
+{
+ // consistency check
+ assert (p->packlen < 65536 - 28); // IP, UDP headers
+ assert (p->packlen >= 12); // at least a complete RTP header
+ assert (p->payload != NULL);
+ assert (p->packet != NULL);
+
+ // Extract header information
+
+ p->v = (p->packet[0] >> 6) & 0x03;
+ p->p = (p->packet[0] >> 5) & 0x01;
+ p->x = (p->packet[0] >> 4) & 0x01;
+ p->cc = (p->packet[0] >> 0) & 0x0F;
+
+ p->m = (p->packet[1] >> 7) & 0x01;
+ p->pt = (p->packet[1] >> 0) & 0x7F;
+
+ memcpy (&p->seq, &p->packet[2], 2);
+ p->seq = ntohs((unsigned short)p->seq);
+
+ memcpy (&p->timestamp, &p->packet[4], 4);// change to shifts for unified byte sex
+ p->timestamp = ntohl(p->timestamp);
+ memcpy (&p->ssrc, &p->packet[8], 4);// change to shifts for unified byte sex
+ p->ssrc = ntohl(p->ssrc);
+
+ // header consistency checks
+ if ( (p->v != 2)
+ || (p->p != 0)
+ || (p->x != 0)
+ || (p->cc != 0) )
+ {
+ printf ("DecomposeRTPpacket, RTP header consistency problem, header follows\n");
+ DumpRTPHeader (p);
+ return -1;
+ }
+ p->paylen = p->packlen-12;
+ memcpy (p->payload, &p->packet[12], p->paylen);
+ return 0;
+}
+
+/*!
+ *****************************************************************************
+ *
+ * \brief
+ * DumpRTPHeader is a debug tool that dumps a human-readable interpretation
+ * of the RTP header
+ *
+ * \return
+ * n.a.
+ * \param p
+ * the RTP packet to be dumped, after DecompositeRTPpacket()
+ *
+ * \par Side effects
+ * Debug output to stdout
+ *
+ * \date
+ * 30 Spetember 2001
+ *
+ * \author
+ * Stephan Wenger stewe at cs.tu-berlin.de
+ *****************************************************************************/
+
+void DumpRTPHeader (RTPpacket_t *p)
+
+{
+ int i;
+ for (i=0; i< 30; i++)
+ printf ("%02x ", p->packet[i]);
+ printf ("Version (V): %d\n", p->v);
+ printf ("Padding (P): %d\n", p->p);
+ printf ("Extension (X): %d\n", p->x);
+ printf ("CSRC count (CC): %d\n", p->cc);
+ printf ("Marker bit (M): %d\n", p->m);
+ printf ("Payload Type (PT): %d\n", p->pt);
+ printf ("Sequence Number: %d\n", p->seq);
+ printf ("Timestamp: %d\n", p->timestamp);
+ printf ("SSRC: %d\n", p->ssrc);
+}
+
+
+/*!
+ *****************************************************************************
+ *
+ * \brief
+ * RTPReadPacket reads one packet from file
+ *
+ * \return
+ * 0: EOF
+ * negative: error
+ * positive: size of RTP packet in bytes
+ *
+ * \param p
+ * packet data structure, with memory for p->packet allocated
+ *
+ * \param bits
+ * target file
+ *
+ * \par Side effects:
+ * - File pointer in bits moved
+ * - p->xxx filled by reading and Decomposepacket()
+ *
+ * \date
+ * 04 November, 2001
+ *
+ * \author
+ * Stephan Wenger, stewe at cs.tu-berlin.de
+ *****************************************************************************/
+
+int RTPReadPacket (RTPpacket_t *p, FILE *bits)
+{
+ int Filepos, intime;
+
+ assert (p != NULL);
+ assert (p->packet != NULL);
+ assert (p->payload != NULL);
+
+ Filepos = ftell (bits);
+ if (4 != fread (&p->packlen,1, 4, bits))
+ {
+ return 0;
+ }
+
+ if (4 != fread (&intime, 1, 4, bits))
+ {
+ fseek (bits, Filepos, SEEK_SET);
+ printf ("RTPReadPacket: File corruption, could not read Timestamp, exit\n");
+ exit (-1);
+ }
+
+ assert (p->packlen < MAXRTPPACKETSIZE);
+
+ if (p->packlen != fread (p->packet, 1, p->packlen, bits))
+ {
+ printf ("RTPReadPacket: File corruption, could not read %d bytes\n", p->packlen);
+ exit (-1); // EOF inidication
+ }
+
+ if (DecomposeRTPpacket (p) < 0)
+ {
+ // this should never happen, hence exit() is ok. We probably do not want to attempt
+ // to decode a packet that obviously wasn't generated by RTP
+ printf ("Errors reported by DecomposePacket(), exit\n");
+ exit (-700);
+ }
+ assert (p->pt == H264PAYLOADTYPE);
+ assert (p->ssrc == H264SSRC);
+ return p->packlen;
+}
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/rtp.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/rtp.h:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/rtp.h Sun Feb 4 08:38:32 2007
@@ -0,0 +1,48 @@
+
+/*!
+ *************************************************************************************
+ * \file rtp.h
+ *
+ * \brief
+ * Prototypes for rtp.c
+ *************************************************************************************
+ */
+
+#ifndef _RTP_H_
+#define _RTP_H_
+
+#include "nalucommon.h"
+
+#define MAXRTPPAYLOADLEN (65536 - 40) //!< Maximum payload size of an RTP packet */
+#define MAXRTPPACKETSIZE (65536 - 28) //!< Maximum size of an RTP packet incl. header */
+#define H264PAYLOADTYPE 105 //!< RTP paylaod type fixed here for simplicity*/
+#define H264SSRC 0x12345678 //!< SSRC, chosen to simplify debugging */
+#define RTP_TR_TIMESTAMP_MULT 1000 //!< should be something like 27 Mhz / 29.97 Hz */
+
+typedef struct
+{
+ unsigned int v; //!< Version, 2 bits, MUST be 0x2
+ unsigned int p; //!< Padding bit, Padding MUST NOT be used
+ unsigned int x; //!< Extension, MUST be zero
+ unsigned int cc; /*!< CSRC count, normally 0 in the absence
+ of RTP mixers */
+ unsigned int m; //!< Marker bit
+ unsigned int pt; //!< 7 bits, Payload Type, dynamically established
+ unsigned int seq; /*!< RTP sequence number, incremented by one for
+ each sent packet */
+ unsigned int old_seq; //!< to detect wether packets were lost
+ unsigned int timestamp; //!< timestamp, 27 MHz for H.264
+ unsigned int ssrc; //!< Synchronization Source, chosen randomly
+ byte * payload; //!< the payload including payload headers
+ unsigned int paylen; //!< length of payload in bytes
+ byte * packet; //!< complete packet including header and payload
+ unsigned int packlen; //!< length of packet, typically paylen+12
+} RTPpacket_t;
+
+void DumpRTPHeader (RTPpacket_t *p);
+
+int GetRTPNALU (NALU_t *nalu);
+void OpenRTPFile (char *fn);
+void CloseRTPFile();
+
+#endif
Index: llvm-test/MultiSource/Applications/JM/ldecod/sei.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/sei.c:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/sei.c Sun Feb 4 08:38:32 2007
@@ -0,0 +1,1825 @@
+/*!
+ ************************************************************************
+ * \file sei.c
+ *
+ * \brief
+ * Functions to implement SEI messages
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Dong Tian <tian at cs.tut.fi>
+ * - Karsten Suehring <suehring at hhi.de>
+ ************************************************************************
+ */
+
+#include "contributors.h"
+
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include "global.h"
+#include "memalloc.h"
+#include "sei.h"
+#include "vlc.h"
+#include "header.h"
+#include "mbuffer.h"
+#include "parset.h"
+
+extern int UsedBits;
+
+extern seq_parameter_set_rbsp_t SeqParSet[MAXSPS];
+
+
+// #define PRINT_BUFFERING_PERIOD_INFO // uncomment to print buffering period SEI info
+// #define PRINT_PCITURE_TIMING_INFO // uncomment to print picture timing SEI info
+// #define WRITE_MAP_IMAGE // uncomment to write spare picture map
+// #define PRINT_SUBSEQUENCE_INFO // uncomment to print sub-sequence SEI info
+// #define PRINT_SUBSEQUENCE_LAYER_CHAR // uncomment to print sub-sequence layer characteristics SEI info
+// #define PRINT_SUBSEQUENCE_CHAR // uncomment to print sub-sequence characteristics SEI info
+// #define PRINT_SCENE_INFORMATION // uncomment to print scene information SEI info
+// #define PRINT_PAN_SCAN_RECT // uncomment to print pan-scan rectangle SEI info
+// #define PRINT_RECOVERY_POINT // uncomment to print random access point SEI info
+// #define PRINT_FILLER_PAYLOAD_INFO // uncomment to print filler payload SEI info
+// #define PRINT_DEC_REF_PIC_MARKING // uncomment to print decoded picture buffer management repetition SEI info
+// #define PRINT_RESERVED_INFO // uncomment to print reserved SEI info
+// #define PRINT_USER_DATA_UNREGISTERED_INFO // uncomment to print unregistered user data SEI info
+// #define PRINT_USER_DATA_REGISTERED_ITU_T_T35_INFO // uncomment to print ITU-T T.35 user data SEI info
+// #define PRINT_FULL_FRAME_FREEZE_INFO // uncomment to print full-frame freeze SEI info
+// #define PRINT_FULL_FRAME_FREEZE_RELEASE_INFO // uncomment to print full-frame freeze release SEI info
+// #define PRINT_FULL_FRAME_SNAPSHOT_INFO // uncomment to print full-frame snapshot SEI info
+// #define PRINT_PROGRESSIVE_REFINEMENT_END_INFO // uncomment to print Progressive refinement segment start SEI info
+// #define PRINT_PROGRESSIVE_REFINEMENT_END_INFO // uncomment to print Progressive refinement segment end SEI info
+// #define PRINT_MOTION_CONST_SLICE_GROUP_SET_INFO // uncomment to print Motion-constrained slice group set SEI info
+// #define PRINT_FILM_GRAIN_CHARACTERISTICS_INFO // uncomment to print Film grain characteristics SEI info
+// #define PRINT_DEBLOCKING_FILTER_DISPLAY_PREFERENCE_INFO // uncomment to print deblocking filter display preference SEI info
+// #define PRINT_STEREO_VIDEO_INFO_INFO // uncomment to print stero video SEI info
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the SEI rbsp
+ * \param msg
+ * a pointer that point to the sei message.
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void InterpretSEIMessage(byte* msg, int size, ImageParameters *img)
+{
+ int payload_type = 0;
+ int payload_size = 0;
+ int offset = 1;
+ byte tmp_byte;
+ do
+ {
+ // sei_message();
+ payload_type = 0;
+ tmp_byte = msg[offset++];
+ while (tmp_byte == 0xFF)
+ {
+ payload_type += 255;
+ tmp_byte = msg[offset++];
+ }
+ payload_type += tmp_byte; // this is the last byte
+
+ payload_size = 0;
+ tmp_byte = msg[offset++];
+ while (tmp_byte == 0xFF)
+ {
+ payload_size += 255;
+ tmp_byte = msg[offset++];
+ }
+ payload_size += tmp_byte; // this is the last byte
+
+ switch ( payload_type ) // sei_payload( type, size );
+ {
+ case SEI_BUFFERING_PERIOD:
+ interpret_buffering_period_info( msg+offset, payload_size, img );
+ break;
+ case SEI_PIC_TIMING:
+ interpret_picture_timing_info( msg+offset, payload_size, img );
+ break;
+ case SEI_PAN_SCAN_RECT:
+ interpret_pan_scan_rect_info( msg+offset, payload_size, img );
+ break;
+ case SEI_FILLER_PAYLOAD:
+ interpret_filler_payload_info( msg+offset, payload_size, img );
+ break;
+ case SEI_USER_DATA_REGISTERED_ITU_T_T35:
+ interpret_user_data_registered_itu_t_t35_info( msg+offset, payload_size, img );
+ break;
+ case SEI_USER_DATA_UNREGISTERED:
+ interpret_user_data_unregistered_info( msg+offset, payload_size, img );
+ break;
+ case SEI_RECOVERY_POINT:
+ interpret_recovery_point_info( msg+offset, payload_size, img );
+ break;
+ case SEI_DEC_REF_PIC_MARKING_REPETITION:
+ interpret_dec_ref_pic_marking_repetition_info( msg+offset, payload_size, img );
+ break;
+ case SEI_SPARE_PIC:
+ interpret_spare_pic( msg+offset, payload_size, img );
+ break;
+ case SEI_SCENE_INFO:
+ interpret_scene_information( msg+offset, payload_size, img );
+ break;
+ case SEI_SUB_SEQ_INFO:
+ interpret_subsequence_info( msg+offset, payload_size, img );
+ break;
+ case SEI_SUB_SEQ_LAYER_CHARACTERISTICS:
+ interpret_subsequence_layer_characteristics_info( msg+offset, payload_size, img );
+ break;
+ case SEI_SUB_SEQ_CHARACTERISTICS:
+ interpret_subsequence_characteristics_info( msg+offset, payload_size, img );
+ break;
+ case SEI_FULL_FRAME_FREEZE:
+ interpret_full_frame_freeze_info( msg+offset, payload_size, img );
+ break;
+ case SEI_FULL_FRAME_FREEZE_RELEASE:
+ interpret_full_frame_freeze_release_info( msg+offset, payload_size, img );
+ break;
+ case SEI_FULL_FRAME_SNAPSHOT:
+ interpret_full_frame_snapshot_info( msg+offset, payload_size, img );
+ break;
+ case SEI_PROGRESSIVE_REFINEMENT_SEGMENT_START:
+ interpret_progressive_refinement_end_info( msg+offset, payload_size, img );
+ break;
+ case SEI_PROGRESSIVE_REFINEMENT_SEGMENT_END:
+ interpret_progressive_refinement_end_info( msg+offset, payload_size, img );
+ break;
+ case SEI_MOTION_CONSTRAINED_SLICE_GROUP_SET:
+ interpret_motion_constrained_slice_group_set_info( msg+offset, payload_size, img );
+ case SEI_FILM_GRAIN_CHARACTERISTICS:
+ interpret_film_grain_characteristics_info ( msg+offset, payload_size, img );
+ break;
+ case SEI_DEBLOCKING_FILTER_DISPLAY_PREFERENCE:
+ interpret_deblocking_filter_display_preference_info ( msg+offset, payload_size, img );
+ break;
+ case SEI_STEREO_VIDEO_INFO:
+ interpret_stereo_video_info_info ( msg+offset, payload_size, img );
+ break;
+ default:
+ interpret_reserved_info( msg+offset, payload_size, img );
+ break;
+ }
+ offset += payload_size;
+
+ } while( msg[offset] != 0x80 ); // more_rbsp_data() msg[offset] != 0x80
+ // ignore the trailing bits rbsp_trailing_bits();
+ assert(msg[offset] == 0x80); // this is the trailing bits
+ assert( offset+1 == size );
+}
+
+
+/*!
+************************************************************************
+* \brief
+* Interpret the spare picture SEI message
+* \param payload
+* a pointer that point to the sei payload
+* \param size
+* the size of the sei message
+* \param img
+* the image pointer
+*
+************************************************************************
+*/
+void interpret_spare_pic( byte* payload, int size, ImageParameters *img )
+{
+ int i,x,y;
+ Bitstream* buf;
+ int bit0, bit1, bitc, no_bit0;
+ int target_frame_num = 0;
+ int num_spare_pics;
+ int delta_spare_frame_num, CandidateSpareFrameNum, SpareFrameNum = 0;
+ int ref_area_indicator;
+
+ int m, n, left, right, top, bottom,directx, directy;
+ byte ***map;
+
+#ifdef WRITE_MAP_IMAGE
+ int symbol_size_in_bytes = img->pic_unit_bitsize_on_disk/8;
+ int j, k, i0, j0, tmp, kk;
+ char filename[20] = "map_dec.yuv";
+ FILE *fp;
+ imgpel** Y;
+ static int old_pn=-1;
+ static int first = 1;
+
+ printf("Spare picture SEI message\n");
+#endif
+
+ UsedBits = 0;
+
+ assert( payload!=NULL);
+ assert( img!=NULL);
+
+ buf = malloc(sizeof(Bitstream));
+ buf->bitstream_length = size;
+ buf->streamBuffer = payload;
+ buf->frame_bitoffset = 0;
+
+ target_frame_num = ue_v("SEI: target_frame_num", buf);
+
+#ifdef WRITE_MAP_IMAGE
+ printf( "target_frame_num is %d\n", target_frame_num );
+#endif
+
+ num_spare_pics = 1 + ue_v("SEI: num_spare_pics_minus1", buf);
+
+#ifdef WRITE_MAP_IMAGE
+ printf( "num_spare_pics is %d\n", num_spare_pics );
+#endif
+
+ get_mem3D(&map, num_spare_pics, img->height/16, img->width/16);
+
+ for (i=0; i<num_spare_pics; i++)
+ {
+ if (i==0)
+ {
+ CandidateSpareFrameNum = target_frame_num - 1;
+ if ( CandidateSpareFrameNum < 0 ) CandidateSpareFrameNum = MAX_FN - 1;
+ }
+ else
+ CandidateSpareFrameNum = SpareFrameNum;
+
+ delta_spare_frame_num = ue_v("SEI: delta_spare_frame_num", buf);
+
+ SpareFrameNum = CandidateSpareFrameNum - delta_spare_frame_num;
+ if( SpareFrameNum < 0 )
+ SpareFrameNum = MAX_FN + SpareFrameNum;
+
+ ref_area_indicator = ue_v("SEI: ref_area_indicator", buf);
+
+ switch ( ref_area_indicator )
+ {
+ case 0: // The whole frame can serve as spare picture
+ for (y=0; y<img->height/16; y++)
+ for (x=0; x<img->width/16; x++)
+ map[i][y][x] = 0;
+ break;
+ case 1: // The map is not compressed
+ for (y=0; y<img->height/16; y++)
+ for (x=0; x<img->width/16; x++)
+ {
+ map[i][y][x] = u_1("SEI: ref_mb_indicator", buf);
+ }
+ break;
+ case 2: // The map is compressed
+ //!KS: could not check this function, description is unclear (as stated in Ed. Note)
+ bit0 = 0;
+ bit1 = 1;
+ bitc = bit0;
+ no_bit0 = -1;
+
+ x = ( img->width/16 - 1 ) / 2;
+ y = ( img->height/16 - 1 ) / 2;
+ left = right = x;
+ top = bottom = y;
+ directx = 0;
+ directy = 1;
+
+ for (m=0; m<img->height/16; m++)
+ for (n=0; n<img->width/16; n++)
+ {
+
+ if (no_bit0<0)
+ {
+ no_bit0 = ue_v("SEI: zero_run_length", buf);
+ }
+ if (no_bit0>0) map[i][y][x] = bit0;
+ else map[i][y][x] = bit1;
+ no_bit0--;
+
+ // go to the next mb:
+ if ( directx == -1 && directy == 0 )
+ {
+ if (x > left) x--;
+ else if (x == 0)
+ {
+ y = bottom + 1;
+ bottom++;
+ directx = 1;
+ directy = 0;
+ }
+ else if (x == left)
+ {
+ x--;
+ left--;
+ directx = 0;
+ directy = 1;
+ }
+ }
+ else if ( directx == 1 && directy == 0 )
+ {
+ if (x < right) x++;
+ else if (x == img->width/16 - 1)
+ {
+ y = top - 1;
+ top--;
+ directx = -1;
+ directy = 0;
+ }
+ else if (x == right)
+ {
+ x++;
+ right++;
+ directx = 0;
+ directy = -1;
+ }
+ }
+ else if ( directx == 0 && directy == -1 )
+ {
+ if ( y > top) y--;
+ else if (y == 0)
+ {
+ x = left - 1;
+ left--;
+ directx = 0;
+ directy = 1;
+ }
+ else if (y == top)
+ {
+ y--;
+ top--;
+ directx = -1;
+ directy = 0;
+ }
+ }
+ else if ( directx == 0 && directy == 1 )
+ {
+ if (y < bottom) y++;
+ else if (y == img->height/16 - 1)
+ {
+ x = right+1;
+ right++;
+ directx = 0;
+ directy = -1;
+ }
+ else if (y == bottom)
+ {
+ y++;
+ bottom++;
+ directx = 1;
+ directy = 0;
+ }
+ }
+
+
+ }
+ break;
+ default:
+ printf( "Wrong ref_area_indicator %d!\n", ref_area_indicator );
+ exit(0);
+ break;
+ }
+
+ } // end of num_spare_pics
+
+#ifdef WRITE_MAP_IMAGE
+ // begin to write map seq
+ if ( old_pn != img->number )
+ {
+ old_pn = img->number;
+ get_mem2Dpel(&Y, img->height, img->width);
+ if (first)
+ {
+ fp = fopen( filename, "wb" );
+ first = 0;
+ }
+ else
+ fp = fopen( filename, "ab" );
+ assert( fp != NULL );
+ for (kk=0; kk<num_spare_pics; kk++)
+ {
+ for (i=0; i < img->height/16; i++)
+ for (j=0; j < img->width/16; j++)
+ {
+ tmp=map[kk][i][j]==0? img->max_imgpel_value : 0;
+ for (i0=0; i0<16; i0++)
+ for (j0=0; j0<16; j0++)
+ Y[i*16+i0][j*16+j0]=tmp;
+ }
+
+ // write the map image
+ for (i=0; i < img->height; i++)
+ for (j=0; j < img->width; j++)
+ fwrite(&(Y[i][j]), symbol_size_in_bytes, 1, p_out);
+
+ for (k=0; k < 2; k++)
+ for (i=0; i < img->height/2; i++)
+ for (j=0; j < img->width/2; j++)
+ fwrite(&(img->dc_pred_value_chroma), symbol_size_in_bytes, 1, p_out);
+ }
+ fclose( fp );
+ free_mem2Dpel( Y );
+ }
+ // end of writing map image
+#undef WRITE_MAP_IMAGE
+#endif
+
+ free_mem3D( map, num_spare_pics );
+
+ free(buf);
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the Sub-sequence information SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_subsequence_info( byte* payload, int size, ImageParameters *img )
+{
+ Bitstream* buf;
+ int sub_seq_layer_num, sub_seq_id, first_ref_pic_flag, leading_non_ref_pic_flag, last_pic_flag,
+ sub_seq_frame_num_flag, sub_seq_frame_num;
+
+ buf = malloc(sizeof(Bitstream));
+ buf->bitstream_length = size;
+ buf->streamBuffer = payload;
+ buf->frame_bitoffset = 0;
+
+ UsedBits = 0;
+
+ sub_seq_layer_num = ue_v("SEI: sub_seq_layer_num" , buf);
+ sub_seq_id = ue_v("SEI: sub_seq_id" , buf);
+ first_ref_pic_flag = u_1 ("SEI: first_ref_pic_flag" , buf);
+ leading_non_ref_pic_flag = u_1 ("SEI: leading_non_ref_pic_flag", buf);
+ last_pic_flag = u_1 ("SEI: last_pic_flag" , buf);
+ sub_seq_frame_num_flag = u_1 ("SEI: sub_seq_frame_num_flag" , buf);
+ if (sub_seq_frame_num_flag)
+ {
+ sub_seq_frame_num = ue_v("SEI: sub_seq_frame_num" , buf);
+ }
+
+#ifdef PRINT_SUBSEQUENCE_INFO
+ printf("Sub-sequence information SEI message\n");
+ printf("sub_seq_layer_num = %d\n", sub_seq_layer_num );
+ printf("sub_seq_id = %d\n", sub_seq_id);
+ printf("first_ref_pic_flag = %d\n", first_ref_pic_flag);
+ printf("leading_non_ref_pic_flag = %d\n", leading_non_ref_pic_flag);
+ printf("last_pic_flag = %d\n", last_pic_flag);
+ printf("sub_seq_frame_num_flag = %d\n", sub_seq_frame_num_flag);
+ if (sub_seq_frame_num_flag)
+ {
+ printf("sub_seq_frame_num = %d\n", sub_seq_frame_num);
+ }
+#endif
+
+ free(buf);
+#ifdef PRINT_SUBSEQUENCE_INFO
+#undef PRINT_SUBSEQUENCE_INFO
+#endif
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the Sub-sequence layer characteristics SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_subsequence_layer_characteristics_info( byte* payload, int size, ImageParameters *img )
+{
+ Bitstream* buf;
+ long num_sub_layers, accurate_statistics_flag, average_bit_rate, average_frame_rate;
+ int i;
+
+ buf = malloc(sizeof(Bitstream));
+ buf->bitstream_length = size;
+ buf->streamBuffer = payload;
+ buf->frame_bitoffset = 0;
+
+ UsedBits = 0;
+
+ num_sub_layers = 1 + ue_v("SEI: num_sub_layers_minus1", buf);
+
+#ifdef PRINT_SUBSEQUENCE_LAYER_CHAR
+ printf("Sub-sequence layer characteristics SEI message\n");
+ printf("num_sub_layers_minus1 = %d\n", num_sub_layers - 1);
+#endif
+
+ for (i=0; i<num_sub_layers; i++)
+ {
+ accurate_statistics_flag = u_1( "SEI: accurate_statistics_flag", buf);
+ average_bit_rate = u_v(16,"SEI: average_bit_rate" , buf);
+ average_frame_rate = u_v(16,"SEI: average_frame_rate" , buf);
+
+#ifdef PRINT_SUBSEQUENCE_LAYER_CHAR
+ printf("layer %d: accurate_statistics_flag = %ld \n", i, accurate_statistics_flag);
+ printf("layer %d: average_bit_rate = %ld \n", i, average_bit_rate);
+ printf("layer %d: average_frame_rate = %ld \n", i, average_frame_rate);
+#endif
+ }
+ free (buf);
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the Sub-sequence characteristics SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_subsequence_characteristics_info( byte* payload, int size, ImageParameters *img )
+{
+ Bitstream* buf;
+ int i;
+ int sub_seq_layer_num, sub_seq_id, duration_flag, average_rate_flag, accurate_statistics_flag;
+ unsigned long sub_seq_duration, average_bit_rate, average_frame_rate;
+ int num_referenced_subseqs, ref_sub_seq_layer_num, ref_sub_seq_id, ref_sub_seq_direction;
+
+ buf = malloc(sizeof(Bitstream));
+ buf->bitstream_length = size;
+ buf->streamBuffer = payload;
+ buf->frame_bitoffset = 0;
+
+ UsedBits = 0;
+
+ sub_seq_layer_num = ue_v("SEI: sub_seq_layer_num", buf);
+ sub_seq_id = ue_v("SEI: sub_seq_id", buf);
+ duration_flag = u_1 ("SEI: duration_flag", buf);
+
+#ifdef PRINT_SUBSEQUENCE_CHAR
+ printf("Sub-sequence characteristics SEI message\n");
+ printf("sub_seq_layer_num = %d\n", sub_seq_layer_num );
+ printf("sub_seq_id = %d\n", sub_seq_id);
+ printf("duration_flag = %d\n", duration_flag);
+#endif
+
+ if ( duration_flag )
+ {
+ sub_seq_duration = u_v (32, "SEI: duration_flag", buf);
+#ifdef PRINT_SUBSEQUENCE_CHAR
+ printf("sub_seq_duration = %ld\n", sub_seq_duration);
+#endif
+ }
+
+ average_rate_flag = u_1 ("SEI: average_rate_flag", buf);
+
+#ifdef PRINT_SUBSEQUENCE_CHAR
+ printf("average_rate_flag = %d\n", average_rate_flag);
+#endif
+
+ if ( average_rate_flag )
+ {
+ accurate_statistics_flag = u_1 ( "SEI: accurate_statistics_flag", buf);
+ average_bit_rate = u_v (16, "SEI: average_bit_rate", buf);
+ average_frame_rate = u_v (16, "SEI: average_frame_rate", buf);
+
+#ifdef PRINT_SUBSEQUENCE_CHAR
+ printf("accurate_statistics_flag = %d\n", accurate_statistics_flag);
+ printf("average_bit_rate = %ld\n", average_bit_rate);
+ printf("average_frame_rate = %ld\n", average_frame_rate);
+#endif
+ }
+
+ num_referenced_subseqs = ue_v("SEI: num_referenced_subseqs", buf);
+
+#ifdef PRINT_SUBSEQUENCE_CHAR
+ printf("num_referenced_subseqs = %d\n", num_referenced_subseqs);
+#endif
+
+ for (i=0; i<num_referenced_subseqs; i++)
+ {
+ ref_sub_seq_layer_num = ue_v("SEI: ref_sub_seq_layer_num", buf);
+ ref_sub_seq_id = ue_v("SEI: ref_sub_seq_id", buf);
+ ref_sub_seq_direction = u_1 ("SEI: ref_sub_seq_direction", buf);
+
+#ifdef PRINT_SUBSEQUENCE_CHAR
+ printf("ref_sub_seq_layer_num = %d\n", ref_sub_seq_layer_num);
+ printf("ref_sub_seq_id = %d\n", ref_sub_seq_id);
+ printf("ref_sub_seq_direction = %d\n", ref_sub_seq_direction);
+#endif
+ }
+
+ free( buf );
+#ifdef PRINT_SUBSEQUENCE_CHAR
+#undef PRINT_SUBSEQUENCE_CHAR
+#endif
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the Scene information SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_scene_information( byte* payload, int size, ImageParameters *img )
+{
+ Bitstream* buf;
+ int scene_id, scene_transition_type, second_scene_id;
+
+ buf = malloc(sizeof(Bitstream));
+ buf->bitstream_length = size;
+ buf->streamBuffer = payload;
+ buf->frame_bitoffset = 0;
+
+ UsedBits = 0;
+
+ scene_id = ue_v("SEI: scene_id" , buf);
+ scene_transition_type = ue_v("SEI: scene_transition_type", buf);
+ if ( scene_transition_type > 3 )
+ {
+ second_scene_id = ue_v("SEI: scene_transition_type", buf);;
+ }
+
+#ifdef PRINT_SCENE_INFORMATION
+ printf("Scene information SEI message\n");
+ printf("scene_transition_type = %d\n", scene_transition_type);
+ printf("scene_id = %d\n", scene_id);
+ if ( scene_transition_type > 3 )
+ {
+ printf("second_scene_id = %d\n", second_scene_id);
+ }
+#endif
+ free( buf );
+#ifdef PRINT_SCENE_INFORMATION
+#undef PRINT_SCENE_INFORMATION
+#endif
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the Filler payload SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_filler_payload_info( byte* payload, int size, ImageParameters *img )
+{
+ int payload_cnt = 0;
+
+ while (payload_cnt<size)
+ {
+ if (payload[payload_cnt] == 0xFF)
+ {
+ payload_cnt++;
+ }
+ }
+
+
+#ifdef PRINT_FILLER_PAYLOAD_INFO
+ printf("Filler payload SEI message\n");
+ if (payload_cnt==size)
+ {
+ printf("read %d bytes of filler payload\n", payload_cnt);
+ }
+ else
+ {
+ printf("error reading filler payload: not all bytes are 0xFF (%d of %d)\n", payload_cnt, size);
+ }
+#endif
+
+#ifdef PRINT_FILLER_PAYLOAD_INFO
+#undef PRINT_FILLER_PAYLOAD_INFO
+#endif
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the User data unregistered SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_user_data_unregistered_info( byte* payload, int size, ImageParameters *img )
+{
+ int offset = 0;
+ byte payload_byte;
+
+#ifdef PRINT_USER_DATA_UNREGISTERED_INFO
+ printf("User data unregistered SEI message\n");
+ printf("uuid_iso_11578 = 0x");
+#endif
+ assert (size>=16);
+
+ for (offset = 0; offset < 16; offset++)
+ {
+#ifdef PRINT_USER_DATA_UNREGISTERED_INFO
+ printf("%02x",payload[offset]);
+#endif
+ }
+
+#ifdef PRINT_USER_DATA_UNREGISTERED_INFO
+ printf("\n");
+#endif
+
+ while (offset < size)
+ {
+ payload_byte = payload[offset];
+ offset ++;
+#ifdef PRINT_USER_DATA_UNREGISTERED_INFO
+ printf("Unreg data payload_byte = %d\n", payload_byte);
+#endif
+ }
+#ifdef PRINT_USER_DATA_UNREGISTERED_INFO
+#undef PRINT_USER_DATA_UNREGISTERED_INFO
+#endif
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the User data registered by ITU-T T.35 SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_user_data_registered_itu_t_t35_info( byte* payload, int size, ImageParameters *img )
+{
+ int offset = 0;
+ byte itu_t_t35_country_code, itu_t_t35_country_code_extension_byte, payload_byte;
+
+ itu_t_t35_country_code = payload[offset];
+ offset++;
+#ifdef PRINT_USER_DATA_REGISTERED_ITU_T_T35_INFO
+ printf("User data registered by ITU-T T.35 SEI message\n");
+ printf(" itu_t_t35_country_code = %d \n", itu_t_t35_country_code);
+#endif
+ if(itu_t_t35_country_code == 0xFF)
+ {
+ itu_t_t35_country_code_extension_byte = payload[offset];
+ offset++;
+#ifdef PRINT_USER_DATA_REGISTERED_ITU_T_T35_INFO
+ printf(" ITU_T_T35_COUNTRY_CODE_EXTENSION_BYTE %d \n", itu_t_t35_country_code_extension_byte);
+#endif
+ }
+ while (offset < size)
+ {
+ payload_byte = payload[offset];
+ offset ++;
+#ifdef PRINT_USER_DATA_REGISTERED_ITU_T_T35_INFO
+ printf("itu_t_t35 payload_byte = %d\n", payload_byte);
+#endif
+ }
+#ifdef PRINT_USER_DATA_REGISTERED_ITU_T_T35_INFO
+#undef PRINT_USER_DATA_REGISTERED_ITU_T_T35_INFO
+#endif
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the Pan scan rectangle SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_pan_scan_rect_info( byte* payload, int size, ImageParameters *img )
+{
+ int pan_scan_rect_cancel_flag;
+ int pan_scan_cnt_minus1, i;
+ int pan_scan_rect_repetition_period;
+ int pan_scan_rect_id, pan_scan_rect_left_offset, pan_scan_rect_right_offset;
+ int pan_scan_rect_top_offset, pan_scan_rect_bottom_offset;
+
+ Bitstream* buf;
+
+ buf = malloc(sizeof(Bitstream));
+ buf->bitstream_length = size;
+ buf->streamBuffer = payload;
+ buf->frame_bitoffset = 0;
+
+ UsedBits = 0;
+
+ pan_scan_rect_id = ue_v("SEI: pan_scan_rect_id", buf);
+
+ pan_scan_rect_cancel_flag = u_1("SEI: pan_scan_rect_cancel_flag", buf);
+ if (!pan_scan_rect_cancel_flag) {
+ pan_scan_cnt_minus1 = ue_v("SEI: pan_scan_cnt_minus1", buf);
+ for (i = 0; i <= pan_scan_cnt_minus1; i++) {
+ pan_scan_rect_left_offset = se_v("SEI: pan_scan_rect_left_offset" , buf);
+ pan_scan_rect_right_offset = se_v("SEI: pan_scan_rect_right_offset" , buf);
+ pan_scan_rect_top_offset = se_v("SEI: pan_scan_rect_top_offset" , buf);
+ pan_scan_rect_bottom_offset = se_v("SEI: pan_scan_rect_bottom_offset", buf);
+#ifdef PRINT_PAN_SCAN_RECT
+ printf("Pan scan rectangle SEI message %d/%d\n", i, pan_scan_cnt_minus1);
+ printf("pan_scan_rect_id = %d\n", pan_scan_rect_id);
+ printf("pan_scan_rect_left_offset = %d\n", pan_scan_rect_left_offset);
+ printf("pan_scan_rect_right_offset = %d\n", pan_scan_rect_right_offset);
+ printf("pan_scan_rect_top_offset = %d\n", pan_scan_rect_top_offset);
+ printf("pan_scan_rect_bottom_offset = %d\n", pan_scan_rect_bottom_offset);
+#endif
+ }
+ pan_scan_rect_repetition_period = ue_v("SEI: pan_scan_rect_repetition_period", buf);
+ }
+
+ free (buf);
+#ifdef PRINT_PAN_SCAN_RECT
+#undef PRINT_PAN_SCAN_RECT
+#endif
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the Random access point SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_recovery_point_info( byte* payload, int size, ImageParameters *img )
+{
+ int recovery_frame_cnt, exact_match_flag, broken_link_flag, changing_slice_group_idc;
+
+
+ Bitstream* buf;
+
+
+ buf = malloc(sizeof(Bitstream));
+ buf->bitstream_length = size;
+ buf->streamBuffer = payload;
+ buf->frame_bitoffset = 0;
+
+ UsedBits = 0;
+
+ recovery_frame_cnt = ue_v( "SEI: recovery_frame_cnt" , buf);
+ exact_match_flag = u_1 ( "SEI: exact_match_flag" , buf);
+ broken_link_flag = u_1 ( "SEI: broken_link_flag" , buf);
+ changing_slice_group_idc = u_v ( 2, "SEI: changing_slice_group_idc", buf);
+
+ img->recovery_point = 1;
+ img->recovery_frame_cnt = recovery_frame_cnt;
+
+#ifdef PRINT_RECOVERY_POINT
+ printf("Recovery point SEI message\n");
+ printf("recovery_frame_cnt = %d\n", recovery_frame_cnt);
+ printf("exact_match_flag = %d\n", exact_match_flag);
+ printf("broken_link_flag = %d\n", broken_link_flag);
+ printf("changing_slice_group_idc = %d\n", changing_slice_group_idc);
+#endif
+ free (buf);
+#ifdef PRINT_RECOVERY_POINT
+#undef PRINT_RECOVERY_POINT
+#endif
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the Decoded Picture Buffer Management Repetition SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_dec_ref_pic_marking_repetition_info( byte* payload, int size, ImageParameters *img )
+{
+ int original_idr_flag, original_frame_num;
+
+ DecRefPicMarking_t *tmp_drpm;
+
+ DecRefPicMarking_t *old_drpm;
+ int old_idr_flag , old_no_output_of_prior_pics_flag, old_long_term_reference_flag , old_adaptive_ref_pic_buffering_flag;
+
+
+ Bitstream* buf;
+
+ buf = malloc(sizeof(Bitstream));
+ buf->bitstream_length = size;
+ buf->streamBuffer = payload;
+ buf->frame_bitoffset = 0;
+
+ UsedBits = 0;
+
+ original_idr_flag = u_1 ( "SEI: original_idr_flag" , buf);
+ original_frame_num = ue_v( "SEI: original_frame_num" , buf);
+
+#ifdef PRINT_DEC_REF_PIC_MARKING
+ printf("Decoded Picture Buffer Management Repetition SEI message\n");
+ printf("original_idr_flag = %d\n", original_idr_flag);
+ printf("original_frame_num = %d\n", original_frame_num);
+#endif
+
+ // we need to save everything that is probably overwritten in dec_ref_pic_marking()
+ old_drpm = img->dec_ref_pic_marking_buffer;
+ old_idr_flag = img->idr_flag;
+
+ old_no_output_of_prior_pics_flag = img->no_output_of_prior_pics_flag;
+ old_long_term_reference_flag = img->long_term_reference_flag;
+ old_adaptive_ref_pic_buffering_flag = img->adaptive_ref_pic_buffering_flag;
+
+ // set new initial values
+ img->idr_flag = original_idr_flag;
+ img->dec_ref_pic_marking_buffer = NULL;
+
+ dec_ref_pic_marking(buf);
+
+ // print out decoded values
+#ifdef PRINT_DEC_REF_PIC_MARKING
+ if (img->idr_flag)
+ {
+ printf("no_output_of_prior_pics_flag = %d\n", img->no_output_of_prior_pics_flag);
+ printf("long_term_reference_flag = %d\n", img->long_term_reference_flag);
+ }
+ else
+ {
+ printf("adaptive_ref_pic_buffering_flag = %d\n", img->adaptive_ref_pic_buffering_flag);
+ if (img->adaptive_ref_pic_buffering_flag)
+ {
+ tmp_drpm=img->dec_ref_pic_marking_buffer;
+ while (tmp_drpm != NULL)
+ {
+ printf("memory_management_control_operation = %d\n", tmp_drpm->memory_management_control_operation);
+
+ if ((tmp_drpm->memory_management_control_operation==1)||(tmp_drpm->memory_management_control_operation==3))
+ {
+ printf("difference_of_pic_nums_minus1 = %d\n", tmp_drpm->difference_of_pic_nums_minus1);
+ }
+ if (tmp_drpm->memory_management_control_operation==2)
+ {
+ printf("long_term_pic_num = %d\n", tmp_drpm->long_term_pic_num);
+ }
+ if ((tmp_drpm->memory_management_control_operation==3)||(tmp_drpm->memory_management_control_operation==6))
+ {
+ printf("long_term_frame_idx = %d\n", tmp_drpm->long_term_frame_idx);
+ }
+ if (tmp_drpm->memory_management_control_operation==4)
+ {
+ printf("max_long_term_pic_idx_plus1 = %d\n", tmp_drpm->max_long_term_frame_idx_plus1);
+ }
+ tmp_drpm = tmp_drpm->Next;
+ }
+ }
+ }
+#endif
+
+ while (img->dec_ref_pic_marking_buffer)
+ {
+ tmp_drpm=img->dec_ref_pic_marking_buffer;
+
+ img->dec_ref_pic_marking_buffer=tmp_drpm->Next;
+ free (tmp_drpm);
+ }
+
+ // restore old values in img
+ img->dec_ref_pic_marking_buffer = old_drpm;
+ img->idr_flag = old_idr_flag;
+ img->no_output_of_prior_pics_flag = old_no_output_of_prior_pics_flag;
+ img->long_term_reference_flag = old_long_term_reference_flag;
+ img->adaptive_ref_pic_buffering_flag = old_adaptive_ref_pic_buffering_flag;
+
+ free (buf);
+#ifdef PRINT_DEC_REF_PIC_MARKING
+#undef PRINT_DEC_REF_PIC_MARKING
+#endif
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the Full-frame freeze SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_full_frame_freeze_info( byte* payload, int size, ImageParameters *img )
+{
+#ifdef PRINT_FULL_FRAME_FREEZE_INFO
+ printf("Full-frame freeze SEI message\n");
+ if (size)
+ {
+ printf("payload size of this message should be zero, but is %d bytes.\n", size);
+ }
+#endif
+
+#ifdef PRINT_FULL_FRAME_FREEZE_INFO
+#undef PRINT_FULL_FRAME_FREEZE_INFO
+#endif
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the Full-frame freeze release SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_full_frame_freeze_release_info( byte* payload, int size, ImageParameters *img )
+{
+#ifdef PRINT_FULL_FRAME_FREEZE_RELEASE_INFO
+ printf("Full-frame freeze release SEI message\n");
+ if (size)
+ {
+ printf("payload size of this message should be zero, but is %d bytes.\n", size);
+ }
+#endif
+
+#ifdef PRINT_FULL_FRAME_FREEZE_RELEASE_INFO
+#undef PRINT_FULL_FRAME_FREEZE_RELEASE_INFO
+#endif
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the Full-frame snapshot SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_full_frame_snapshot_info( byte* payload, int size, ImageParameters *img )
+{
+ int snapshot_id;
+
+ Bitstream* buf;
+
+ buf = malloc(sizeof(Bitstream));
+ buf->bitstream_length = size;
+ buf->streamBuffer = payload;
+ buf->frame_bitoffset = 0;
+
+ UsedBits = 0;
+
+ snapshot_id = ue_v("SEI: snapshot_id", buf);
+
+#ifdef PRINT_FULL_FRAME_SNAPSHOT_INFO
+ printf("Full-frame snapshot SEI message\n");
+ printf("snapshot_id = %d\n", snapshot_id);
+#endif
+ free (buf);
+#ifdef PRINT_FULL_FRAME_SNAPSHOT_INFO
+#undef PRINT_FULL_FRAME_SNAPSHOT_INFO
+#endif
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the Progressive refinement segment start SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_progressive_refinement_start_info( byte* payload, int size, ImageParameters *img )
+{
+ int progressive_refinement_id, num_refinement_steps_minus1;
+
+ Bitstream* buf;
+
+ buf = malloc(sizeof(Bitstream));
+ buf->bitstream_length = size;
+ buf->streamBuffer = payload;
+ buf->frame_bitoffset = 0;
+
+ UsedBits = 0;
+
+ progressive_refinement_id = ue_v("SEI: progressive_refinement_id" , buf);
+ num_refinement_steps_minus1 = ue_v("SEI: num_refinement_steps_minus1", buf);
+
+#ifdef PRINT_PROGRESSIVE_REFINEMENT_START_INFO
+ printf("Progressive refinement segment start SEI message\n");
+ printf("progressive_refinement_id = %d\n", progressive_refinement_id);
+ printf("num_refinement_steps_minus1 = %d\n", num_refinement_steps_minus1);
+#endif
+ free (buf);
+#ifdef PRINT_PROGRESSIVE_REFINEMENT_START_INFO
+#undef PRINT_PROGRESSIVE_REFINEMENT_START_INFO
+#endif
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the Progressive refinement segment end SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_progressive_refinement_end_info( byte* payload, int size, ImageParameters *img )
+{
+ int progressive_refinement_id;
+
+ Bitstream* buf;
+
+ buf = malloc(sizeof(Bitstream));
+ buf->bitstream_length = size;
+ buf->streamBuffer = payload;
+ buf->frame_bitoffset = 0;
+
+ UsedBits = 0;
+
+ progressive_refinement_id = ue_v("SEI: progressive_refinement_id" , buf);
+
+#ifdef PRINT_PROGRESSIVE_REFINEMENT_END_INFO
+ printf("Progressive refinement segment end SEI message\n");
+ printf("progressive_refinement_id = %d\n", progressive_refinement_id);
+#endif
+ free (buf);
+#ifdef PRINT_PROGRESSIVE_REFINEMENT_END_INFO
+#undef PRINT_PROGRESSIVE_REFINEMENT_END_INFO
+#endif
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the Motion-constrained slice group set SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_motion_constrained_slice_group_set_info( byte* payload, int size, ImageParameters *img )
+{
+ int num_slice_groups_minus1, slice_group_id, exact_match_flag, pan_scan_rect_flag, pan_scan_rect_id;
+ int i;
+ int sliceGroupSize;
+
+ Bitstream* buf;
+
+ buf = malloc(sizeof(Bitstream));
+ buf->bitstream_length = size;
+ buf->streamBuffer = payload;
+ buf->frame_bitoffset = 0;
+
+ UsedBits = 0;
+
+ num_slice_groups_minus1 = ue_v("SEI: num_slice_groups_minus1" , buf);
+ sliceGroupSize = CeilLog2( num_slice_groups_minus1 + 1 );
+#ifdef PRINT_MOTION_CONST_SLICE_GROUP_SET_INFO
+ printf("Motion-constrained slice group set SEI message\n");
+ printf("num_slice_groups_minus1 = %d\n", num_slice_groups_minus1);
+#endif
+
+ for (i=0; i<=num_slice_groups_minus1;i++)
+ {
+
+ slice_group_id = u_v (sliceGroupSize, "SEI: slice_group_id" , buf) ;
+#ifdef PRINT_MOTION_CONST_SLICE_GROUP_SET_INFO
+ printf("slice_group_id = %d\n", slice_group_id);
+#endif
+ }
+
+ exact_match_flag = u_1("SEI: exact_match_flag" , buf);
+ pan_scan_rect_flag = u_1("SEI: pan_scan_rect_flag" , buf);
+
+#ifdef PRINT_MOTION_CONST_SLICE_GROUP_SET_INFO
+ printf("exact_match_flag = %d\n", exact_match_flag);
+ printf("pan_scan_rect_flag = %d\n", pan_scan_rect_flag);
+#endif
+
+ if (pan_scan_rect_flag)
+ {
+ pan_scan_rect_id = ue_v("SEI: pan_scan_rect_id" , buf);
+#ifdef PRINT_MOTION_CONST_SLICE_GROUP_SET_INFO
+ printf("pan_scan_rect_id = %d\n", pan_scan_rect_id);
+#endif
+ }
+
+ free (buf);
+#ifdef PRINT_MOTION_CONST_SLICE_GROUP_SET_INFO
+#undef PRINT_MOTION_CONST_SLICE_GROUP_SET_INFO
+#endif
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the film grain characteristics SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_film_grain_characteristics_info( byte* payload, int size, ImageParameters *img )
+{
+ int film_grain_characteristics_cancel_flag;
+ int model_id, separate_colour_description_present_flag;
+ int film_grain_bit_depth_luma_minus8, film_grain_bit_depth_chroma_minus8, film_grain_full_range_flag, film_grain_colour_primaries, film_grain_transfer_characteristics, film_grain_matrix_coefficients;
+ int blending_mode_id, log2_scale_factor, comp_model_present_flag[3];
+ int num_intensity_intervals_minus1, num_model_values_minus1;
+ int intensity_interval_lower_bound, intensity_interval_upper_bound;
+ int comp_model_value;
+ int film_grain_characteristics_repetition_period;
+
+ int c, i, j;
+
+ Bitstream* buf;
+
+ buf = malloc(sizeof(Bitstream));
+ buf->bitstream_length = size;
+ buf->streamBuffer = payload;
+ buf->frame_bitoffset = 0;
+
+ film_grain_characteristics_cancel_flag = u_1("SEI: film_grain_characteristics_cancel_flag", buf);
+#ifdef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO
+ printf("film_grain_characteristics_cancel_flag = %d\n", film_grain_characteristics_cancel_flag);
+#endif
+ if(!film_grain_characteristics_cancel_flag)
+ {
+
+ model_id = u_v(2, "SEI: model_id", buf);
+ separate_colour_description_present_flag = u_1("SEI: separate_colour_description_present_flag", buf);
+#ifdef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO
+ printf("model_id = %d\n", model_id);
+ printf("separate_colour_description_present_flag = %d\n", separate_colour_description_present_flag);
+#endif
+ if (separate_colour_description_present_flag)
+ {
+ film_grain_bit_depth_luma_minus8 = u_v(3, "SEI: film_grain_bit_depth_luma_minus8", buf);
+ film_grain_bit_depth_chroma_minus8 = u_v(3, "SEI: film_grain_bit_depth_chroma_minus8", buf);
+ film_grain_full_range_flag = u_v(1, "SEI: film_grain_full_range_flag", buf);
+ film_grain_colour_primaries = u_v(8, "SEI: film_grain_colour_primaries", buf);
+ film_grain_transfer_characteristics = u_v(8, "SEI: film_grain_transfer_characteristics", buf);
+ film_grain_matrix_coefficients = u_v(8, "SEI: film_grain_matrix_coefficients", buf);
+#ifdef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO
+ printf("film_grain_bit_depth_luma_minus8 = %d\n", film_grain_bit_depth_luma_minus8);
+ printf("film_grain_bit_depth_chroma_minus8 = %d\n", film_grain_bit_depth_chroma_minus8);
+ printf("film_grain_full_range_flag = %d\n", film_grain_full_range_flag);
+ printf("film_grain_colour_primaries = %d\n", film_grain_colour_primaries);
+ printf("film_grain_transfer_characteristics = %d\n", film_grain_transfer_characteristics);
+ printf("film_grain_matrix_coefficients = %d\n", film_grain_matrix_coefficients);
+#endif
+ }
+ blending_mode_id = u_v(2, "SEI: blending_mode_id", buf);
+ log2_scale_factor = u_v(4, "SEI: log2_scale_factor", buf);
+#ifdef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO
+ printf("blending_mode_id = %d\n", blending_mode_id);
+ printf("log2_scale_factor = %d\n", log2_scale_factor);
+#endif
+ for (c = 0; c < 3; c ++)
+ {
+ comp_model_present_flag[c] = u_1("SEI: comp_model_present_flag", buf);
+#ifdef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO
+ printf("comp_model_present_flag = %d\n", comp_model_present_flag[c]);
+#endif
+ }
+ for (c = 0; c < 3; c ++)
+ if (comp_model_present_flag[c])
+ {
+ num_intensity_intervals_minus1 = u_v(8, "SEI: num_intensity_intervals_minus1", buf);
+ num_model_values_minus1 = u_v(3, "SEI: num_model_values_minus1", buf);
+#ifdef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO
+ printf("num_intensity_intervals_minus1 = %d\n", num_intensity_intervals_minus1);
+ printf("num_model_values_minus1 = %d\n", num_model_values_minus1);
+#endif
+ for (i = 0; i <= num_intensity_intervals_minus1; i ++)
+ {
+ intensity_interval_lower_bound = u_v(8, "SEI: intensity_interval_lower_bound", buf);
+ intensity_interval_upper_bound = u_v(8, "SEI: intensity_interval_upper_bound", buf);
+#ifdef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO
+ printf("intensity_interval_lower_bound = %d\n", intensity_interval_lower_bound);
+ printf("intensity_interval_upper_bound = %d\n", intensity_interval_upper_bound);
+#endif
+ for (j = 0; j <= num_model_values_minus1; j++)
+ {
+ comp_model_value = se_v("SEI: comp_model_value", buf);
+#ifdef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO
+ printf("comp_model_value = %d\n", comp_model_value);
+#endif
+ }
+ }
+ }
+ film_grain_characteristics_repetition_period = ue_v("SEI: film_grain_characteristics_repetition_period", buf);
+#ifdef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO
+ printf("film_grain_characteristics_repetition_period = %d\n", film_grain_characteristics_repetition_period);
+#endif
+ }
+
+ free (buf);
+#ifdef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO
+#undef PRINT_FILM_GRAIN_CHARACTERISTICS_INFO
+#endif
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the deblocking filter display preference SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_deblocking_filter_display_preference_info( byte* payload, int size, ImageParameters *img )
+{
+ int deblocking_display_preference_cancel_flag;
+ int display_prior_to_deblocking_preferred_flag, dec_frame_buffering_constraint_flag, deblocking_display_preference_repetition_period;
+
+ Bitstream* buf;
+
+ buf = malloc(sizeof(Bitstream));
+ buf->bitstream_length = size;
+ buf->streamBuffer = payload;
+ buf->frame_bitoffset = 0;
+
+ deblocking_display_preference_cancel_flag = u_1("SEI: deblocking_display_preference_cancel_flag", buf);
+#ifdef PRINT_DEBLOCKING_FILTER_DISPLAY_PREFERENCE_INFO
+ printf("deblocking_display_preference_cancel_flag = %d\n", deblocking_display_preference_cancel_flag);
+#endif
+ if(!deblocking_display_preference_cancel_flag)
+ {
+ display_prior_to_deblocking_preferred_flag = u_1("SEI: display_prior_to_deblocking_preferred_flag", buf);
+ dec_frame_buffering_constraint_flag = u_1("SEI: dec_frame_buffering_constraint_flag", buf);
+ deblocking_display_preference_repetition_period = ue_v("SEI: deblocking_display_preference_repetition_period", buf);
+#ifdef PRINT_DEBLOCKING_FILTER_DISPLAY_PREFERENCE_INFO
+ printf("display_prior_to_deblocking_preferred_flag = %d\n", display_prior_to_deblocking_preferred_flag);
+ printf("dec_frame_buffering_constraint_flag = %d\n", dec_frame_buffering_constraint_flag);
+ printf("deblocking_display_preference_repetition_period = %d\n", deblocking_display_preference_repetition_period);
+#endif
+ }
+
+ free (buf);
+#ifdef PRINT_DEBLOCKING_FILTER_DISPLAY_PREFERENCE_INFO
+#undef PRINT_DEBLOCKING_FILTER_DISPLAY_PREFERENCE_INFO
+#endif
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the stereo video info SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_stereo_video_info_info( byte* payload, int size, ImageParameters *img )
+{
+ int field_views_flags;
+ int top_field_is_left_view_flag, current_frame_is_left_view_flag, next_frame_is_second_view_flag;
+ int left_view_self_contained_flag;
+ int right_view_self_contained_flag;
+
+ Bitstream* buf;
+
+ buf = malloc(sizeof(Bitstream));
+ buf->bitstream_length = size;
+ buf->streamBuffer = payload;
+ buf->frame_bitoffset = 0;
+
+ field_views_flags = u_1("SEI: field_views_flags", buf);
+#ifdef PRINT_STEREO_VIDEO_INFO_INFO
+ printf("field_views_flags = %d\n", field_views_flags);
+#endif
+ if (field_views_flags)
+ {
+ top_field_is_left_view_flag = u_1("SEI: top_field_is_left_view_flag", buf);
+#ifdef PRINT_STEREO_VIDEO_INFO_INFO
+ printf("top_field_is_left_view_flag = %d\n", top_field_is_left_view_flag);
+#endif
+ }
+ else
+ {
+ current_frame_is_left_view_flag = u_1("SEI: current_frame_is_left_view_flag", buf);
+ next_frame_is_second_view_flag = u_1("SEI: next_frame_is_second_view_flag", buf);
+#ifdef PRINT_STEREO_VIDEO_INFO_INFO
+ printf("current_frame_is_left_view_flag = %d\n", current_frame_is_left_view_flag);
+ printf("next_frame_is_second_view_flag = %d\n", next_frame_is_second_view_flag);
+#endif
+ }
+
+ left_view_self_contained_flag = u_1("SEI: left_view_self_contained_flag", buf);
+ right_view_self_contained_flag = u_1("SEI: right_view_self_contained_flag", buf);
+#ifdef PRINT_STEREO_VIDEO_INFO_INFO
+ printf("left_view_self_contained_flag = %d\n", left_view_self_contained_flag);
+ printf("right_view_self_contained_flag = %d\n", right_view_self_contained_flag);
+#endif
+
+ free (buf);
+#ifdef PRINT_STEREO_VIDEO_INFO_INFO
+#undef PRINT_STEREO_VIDEO_INFO_INFO
+#endif
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the Reserved SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_reserved_info( byte* payload, int size, ImageParameters *img )
+{
+ int offset = 0;
+ byte payload_byte;
+
+#ifdef PRINT_RESERVED_INFO
+ printf("Reserved SEI message\n");
+#endif
+
+ while (offset < size)
+ {
+ payload_byte = payload[offset];
+ offset ++;
+#ifdef PRINT_RESERVED_INFO
+ printf("reserved_sei_message_payload_byte = %d\n", payload_byte);
+#endif
+ }
+#ifdef PRINT_RESERVED_INFO
+#undef PRINT_RESERVED_INFO
+#endif
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the Buffering period SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_buffering_period_info( byte* payload, int size, ImageParameters *img )
+{
+ int seq_parameter_set_id, initial_cpb_removal_delay, initial_cpb_removal_delay_offset;
+ unsigned int k;
+
+ Bitstream* buf;
+ seq_parameter_set_rbsp_t *sps;
+
+
+ buf = malloc(sizeof(Bitstream));
+ buf->bitstream_length = size;
+ buf->streamBuffer = payload;
+ buf->frame_bitoffset = 0;
+
+ UsedBits = 0;
+
+ seq_parameter_set_id = ue_v("SEI: seq_parameter_set_id" , buf);
+
+ sps = &SeqParSet[seq_parameter_set_id];
+
+ activate_sps(sps);
+
+#ifdef PRINT_BUFFERING_PERIOD_INFO
+ printf("Buffering period SEI message\n");
+ printf("seq_parameter_set_id = %d\n", seq_parameter_set_id);
+#endif
+
+ // Note: NalHrdBpPresentFlag and CpbDpbDelaysPresentFlag can also be set "by some means not specified in this Recommendation | International Standard"
+ if (sps->vui_parameters_present_flag)
+ {
+
+ if (sps->vui_seq_parameters.nal_hrd_parameters_present_flag)
+ {
+ for (k=0; k<sps->vui_seq_parameters.nal_hrd_parameters.cpb_cnt_minus1+1; k++)
+ {
+ initial_cpb_removal_delay = u_v(sps->vui_seq_parameters.nal_hrd_parameters.initial_cpb_removal_delay_length_minus1+1, "SEI: initial_cpb_removal_delay" , buf);
+ initial_cpb_removal_delay_offset = u_v(sps->vui_seq_parameters.nal_hrd_parameters.initial_cpb_removal_delay_length_minus1+1, "SEI: initial_cpb_removal_delay_offset" , buf);
+
+#ifdef PRINT_BUFFERING_PERIOD_INFO
+ printf("nal initial_cpb_removal_delay[%d] = %d\n", k, initial_cpb_removal_delay);
+ printf("nal initial_cpb_removal_delay_offset[%d] = %d\n", k, initial_cpb_removal_delay_offset);
+#endif
+ }
+ }
+
+ if (sps->vui_seq_parameters.vcl_hrd_parameters_present_flag)
+ {
+ for (k=0; k<sps->vui_seq_parameters.vcl_hrd_parameters.cpb_cnt_minus1+1; k++)
+ {
+ initial_cpb_removal_delay = u_v(sps->vui_seq_parameters.vcl_hrd_parameters.initial_cpb_removal_delay_length_minus1+1, "SEI: initial_cpb_removal_delay" , buf);
+ initial_cpb_removal_delay_offset = u_v(sps->vui_seq_parameters.vcl_hrd_parameters.initial_cpb_removal_delay_length_minus1+1, "SEI: initial_cpb_removal_delay_offset" , buf);
+
+#ifdef PRINT_BUFFERING_PERIOD_INFO
+ printf("vcl initial_cpb_removal_delay[%d] = %d\n", k, initial_cpb_removal_delay);
+ printf("vcl initial_cpb_removal_delay_offset[%d] = %d\n", k, initial_cpb_removal_delay_offset);
+#endif
+ }
+ }
+ }
+
+ free (buf);
+#ifdef PRINT_BUFFERING_PERIOD_INFO
+#undef PRINT_BUFFERING_PERIOD_INFO
+#endif
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Interpret the Picture timing SEI message
+ * \param payload
+ * a pointer that point to the sei payload
+ * \param size
+ * the size of the sei message
+ * \param img
+ * the image pointer
+ *
+ ************************************************************************
+ */
+void interpret_picture_timing_info( byte* payload, int size, ImageParameters *img )
+{
+ int cpb_removal_delay, dpb_output_delay, picture_structure_present_flag, picture_structure;
+ int clock_time_stamp_flag;
+ int ct_type, nuit_field_based_flag, counting_type, full_timestamp_flag, discontinuity_flag, cnt_dropped_flag, nframes;
+ int seconds_value, minutes_value, hours_value, seconds_flag, minutes_flag, hours_flag, time_offset;
+ int NumClockTs = 0;
+ int i;
+
+ int cpb_removal_len = 24;
+ int dpb_output_len = 24;
+
+ Boolean CpbDpbDelaysPresentFlag;
+
+ Bitstream* buf;
+
+ if (NULL==active_sps)
+ {
+ fprintf (stderr, "Warning: no active SPS, timing SEI cannot be parsed\n");
+ return;
+ }
+
+ buf = malloc(sizeof(Bitstream));
+ buf->bitstream_length = size;
+ buf->streamBuffer = payload;
+ buf->frame_bitoffset = 0;
+
+ UsedBits = 0;
+
+
+#ifdef PRINT_PCITURE_TIMING_INFO
+ printf("Picture timing SEI message\n");
+#endif
+
+ // CpbDpbDelaysPresentFlag can also be set "by some means not specified in this Recommendation | International Standard"
+ CpbDpbDelaysPresentFlag = (Boolean) (active_sps->vui_parameters_present_flag
+ && ( (active_sps->vui_seq_parameters.nal_hrd_parameters_present_flag != 0)
+ ||(active_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag != 0)));
+
+ if (CpbDpbDelaysPresentFlag )
+ {
+ if (active_sps->vui_parameters_present_flag)
+ {
+ if (active_sps->vui_seq_parameters.nal_hrd_parameters_present_flag)
+ {
+ cpb_removal_len = active_sps->vui_seq_parameters.nal_hrd_parameters.cpb_removal_delay_length_minus1 + 1;
+ dpb_output_len = active_sps->vui_seq_parameters.nal_hrd_parameters.dpb_output_delay_length_minus1 + 1;
+ }
+ else if (active_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag)
+ {
+ cpb_removal_len = active_sps->vui_seq_parameters.vcl_hrd_parameters.cpb_removal_delay_length_minus1 + 1;
+ dpb_output_len = active_sps->vui_seq_parameters.vcl_hrd_parameters.dpb_output_delay_length_minus1 + 1;
+ }
+ }
+
+ if ((active_sps->vui_seq_parameters.nal_hrd_parameters_present_flag)||
+ (active_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag))
+ {
+ cpb_removal_delay = u_v(cpb_removal_len, "SEI: cpb_removal_delay" , buf);
+ dpb_output_delay = u_v(dpb_output_len, "SEI: dpb_output_delay" , buf);
+#ifdef PRINT_PCITURE_TIMING_INFO
+ printf("cpb_removal_delay = %d\n",cpb_removal_delay);
+ printf("dpb_output_delay = %d\n",dpb_output_delay);
+#endif
+ }
+ }
+
+ if (!active_sps->vui_parameters_present_flag)
+ {
+ picture_structure_present_flag = 0;
+ }
+ else
+ {
+ picture_structure_present_flag = active_sps->vui_seq_parameters.pic_struct_present_flag;
+ }
+
+ if (picture_structure_present_flag)
+ {
+ picture_structure = u_v(4, "SEI: pic_struct" , buf);
+#ifdef PRINT_PCITURE_TIMING_INFO
+ printf("picture_structure = %d\n",picture_structure);
+#endif
+ switch (picture_structure)
+ {
+ case 0:
+ case 1:
+ case 2:
+ NumClockTs = 1;
+ break;
+ case 3:
+ case 4:
+ case 7:
+ NumClockTs = 2;
+ break;
+ case 5:
+ case 6:
+ case 8:
+ NumClockTs = 3;
+ break;
+ default:
+ error("reserved picture_structure used (can't determine NumClockTs)", 500);
+ }
+ for (i=0; i<NumClockTs; i++)
+ {
+ clock_time_stamp_flag = u_1("SEI: clock_time_stamp_flag" , buf);
+#ifdef PRINT_PCITURE_TIMING_INFO
+ printf("clock_time_stamp_flag = %d\n",clock_time_stamp_flag);
+#endif
+ if (clock_time_stamp_flag)
+ {
+ ct_type = u_v(2, "SEI: ct_type" , buf);
+ nuit_field_based_flag = u_1( "SEI: nuit_field_based_flag" , buf);
+ counting_type = u_v(5, "SEI: counting_type" , buf);
+ full_timestamp_flag = u_1( "SEI: full_timestamp_flag" , buf);
+ discontinuity_flag = u_1( "SEI: discontinuity_flag" , buf);
+ cnt_dropped_flag = u_1( "SEI: cnt_dropped_flag" , buf);
+ nframes = u_v(8, "SEI: nframes" , buf);
+
+#ifdef PRINT_PCITURE_TIMING_INFO
+ printf("ct_type = %d\n",ct_type);
+ printf("nuit_field_based_flag = %d\n",nuit_field_based_flag);
+ printf("full_timestamp_flag = %d\n",full_timestamp_flag);
+ printf("discontinuity_flag = %d\n",discontinuity_flag);
+ printf("cnt_dropped_flag = %d\n",cnt_dropped_flag);
+ printf("nframes = %d\n",nframes);
+#endif
+ if (full_timestamp_flag)
+ {
+ seconds_value = u_v(6, "SEI: seconds_value" , buf);
+ minutes_value = u_v(6, "SEI: minutes_value" , buf);
+ hours_value = u_v(5, "SEI: hours_value" , buf);
+#ifdef PRINT_PCITURE_TIMING_INFO
+ printf("seconds_value = %d\n",seconds_value);
+ printf("minutes_value = %d\n",minutes_value);
+ printf("hours_value = %d\n",hours_value);
+#endif
+ }
+ else
+ {
+ seconds_flag = u_1( "SEI: seconds_flag" , buf);
+#ifdef PRINT_PCITURE_TIMING_INFO
+ printf("seconds_flag = %d\n",seconds_flag);
+#endif
+ if (seconds_flag)
+ {
+ seconds_value = u_v(6, "SEI: seconds_value" , buf);
+ minutes_flag = u_1( "SEI: minutes_flag" , buf);
+#ifdef PRINT_PCITURE_TIMING_INFO
+ printf("seconds_value = %d\n",seconds_value);
+ printf("minutes_flag = %d\n",minutes_flag);
+#endif
+ if(minutes_flag)
+ {
+ minutes_value = u_v(6, "SEI: minutes_value" , buf);
+ hours_flag = u_1( "SEI: hours_flag" , buf);
+#ifdef PRINT_PCITURE_TIMING_INFO
+ printf("minutes_value = %d\n",minutes_value);
+ printf("hours_flag = %d\n",hours_flag);
+#endif
+ if(hours_flag)
+ {
+ hours_value = u_v(5, "SEI: hours_value" , buf);
+#ifdef PRINT_PCITURE_TIMING_INFO
+ printf("hours_value = %d\n",hours_value);
+#endif
+ }
+ }
+ }
+ }
+ {
+ int time_offset_length;
+ if (active_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag)
+ time_offset_length = active_sps->vui_seq_parameters.vcl_hrd_parameters.time_offset_length;
+ else if (active_sps->vui_seq_parameters.nal_hrd_parameters_present_flag)
+ time_offset_length = active_sps->vui_seq_parameters.nal_hrd_parameters.time_offset_length;
+ else
+ time_offset_length = 24;
+ if (time_offset_length)
+ time_offset = u_v(time_offset_length, "SEI: time_offset" , buf); // TODO interpretation is unsigned, need signed interpretation (i_v)
+ else
+ time_offset = 0;
+#ifdef PRINT_PCITURE_TIMING_INFO
+ printf("time_offset = %d\n",time_offset);
+#endif
+ }
+ }
+ }
+ }
+
+ free (buf);
+#ifdef PRINT_PCITURE_TIMING_INFO
+#undef PRINT_PCITURE_TIMING_INFO
+#endif
+}
Index: llvm-test/MultiSource/Applications/JM/ldecod/sei.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/sei.h:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/sei.h Sun Feb 4 08:38:32 2007
@@ -0,0 +1,68 @@
+
+/*!
+ *************************************************************************************
+ * \file sei.h
+ *
+ * \brief
+ * Prototypes for sei.c
+ *************************************************************************************
+ */
+
+#ifndef SEI_H
+#define SEI_H
+
+typedef enum {
+ SEI_BUFFERING_PERIOD = 0,
+ SEI_PIC_TIMING,
+ SEI_PAN_SCAN_RECT,
+ SEI_FILLER_PAYLOAD,
+ SEI_USER_DATA_REGISTERED_ITU_T_T35,
+ SEI_USER_DATA_UNREGISTERED,
+ SEI_RECOVERY_POINT,
+ SEI_DEC_REF_PIC_MARKING_REPETITION,
+ SEI_SPARE_PIC,
+ SEI_SCENE_INFO,
+ SEI_SUB_SEQ_INFO,
+ SEI_SUB_SEQ_LAYER_CHARACTERISTICS,
+ SEI_SUB_SEQ_CHARACTERISTICS,
+ SEI_FULL_FRAME_FREEZE,
+ SEI_FULL_FRAME_FREEZE_RELEASE,
+ SEI_FULL_FRAME_SNAPSHOT,
+ SEI_PROGRESSIVE_REFINEMENT_SEGMENT_START,
+ SEI_PROGRESSIVE_REFINEMENT_SEGMENT_END,
+ SEI_MOTION_CONSTRAINED_SLICE_GROUP_SET,
+ SEI_FILM_GRAIN_CHARACTERISTICS,
+ SEI_DEBLOCKING_FILTER_DISPLAY_PREFERENCE,
+ SEI_STEREO_VIDEO_INFO,
+
+ SEI_MAX_ELEMENTS //!< number of maximum syntax elements
+} SEI_type;
+
+#define MAX_FN 256
+
+void InterpretSEIMessage(byte* msg, int size, ImageParameters *img);
+void interpret_spare_pic( byte* payload, int size, ImageParameters *img );
+void interpret_subsequence_info( byte* payload, int size, ImageParameters *img );
+void interpret_subsequence_layer_characteristics_info( byte* payload, int size, ImageParameters *img );
+void interpret_subsequence_characteristics_info( byte* payload, int size, ImageParameters *img );
+void interpret_scene_information( byte* payload, int size, ImageParameters *img ); // JVT-D099
+void interpret_user_data_registered_itu_t_t35_info( byte* payload, int size, ImageParameters *img );
+void interpret_user_data_unregistered_info( byte* payload, int size, ImageParameters *img );
+void interpret_pan_scan_rect_info( byte* payload, int size, ImageParameters *img );
+void interpret_recovery_point_info( byte* payload, int size, ImageParameters *img );
+void interpret_filler_payload_info( byte* payload, int size, ImageParameters *img );
+void interpret_dec_ref_pic_marking_repetition_info( byte* payload, int size, ImageParameters *img );
+void interpret_full_frame_freeze_info( byte* payload, int size, ImageParameters *img );
+void interpret_full_frame_freeze_release_info( byte* payload, int size, ImageParameters *img );
+void interpret_full_frame_snapshot_info( byte* payload, int size, ImageParameters *img );
+void interpret_progressive_refinement_start_info( byte* payload, int size, ImageParameters *img );
+void interpret_progressive_refinement_end_info( byte* payload, int size, ImageParameters *img );
+void interpret_motion_constrained_slice_group_set_info( byte* payload, int size, ImageParameters *img );
+void interpret_reserved_info( byte* payload, int size, ImageParameters *img );
+void interpret_buffering_period_info( byte* payload, int size, ImageParameters *img );
+void interpret_picture_timing_info( byte* payload, int size, ImageParameters *img );
+void interpret_film_grain_characteristics_info( byte* payload, int size, ImageParameters *img );
+void interpret_deblocking_filter_display_preference_info( byte* payload, int size, ImageParameters *img );
+void interpret_stereo_video_info_info( byte* payload, int size, ImageParameters *img );
+
+#endif
Index: llvm-test/MultiSource/Applications/JM/ldecod/transform8x8.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/transform8x8.c:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/transform8x8.c Sun Feb 4 08:38:32 2007
@@ -0,0 +1,1034 @@
+
+/*!
+ ***************************************************************************
+ * \file transform8x8.c
+ *
+ * \brief
+ * 8x8 transform functions
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Yuri Vatis <vatis at hhi.de>
+ * - Jan Muenster <muenster at hhi.de>
+ *
+ * \date
+ * 12. October 2003
+ **************************************************************************
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "transform8x8.h"
+
+#define Q_BITS_8 16
+#define DQ_BITS_8 6
+
+const int quant_coef8[6][8][8] =
+{
+ {
+ {13107, 12222, 16777, 12222, 13107, 12222, 16777, 12222},
+ {12222, 11428, 15481, 11428, 12222, 11428, 15481, 11428},
+ {16777, 15481, 20972, 15481, 16777, 15481, 20972, 15481},
+ {12222, 11428, 15481, 11428, 12222, 11428, 15481, 11428},
+ {13107, 12222, 16777, 12222, 13107, 12222, 16777, 12222},
+ {12222, 11428, 15481, 11428, 12222, 11428, 15481, 11428},
+ {16777, 15481, 20972, 15481, 16777, 15481, 20972, 15481},
+ {12222, 11428, 15481, 11428, 12222, 11428, 15481, 11428}
+ },
+ {
+ {11916, 11058, 14980, 11058, 11916, 11058, 14980, 11058},
+ {11058, 10826, 14290, 10826, 11058, 10826, 14290, 10826},
+ {14980, 14290, 19174, 14290, 14980, 14290, 19174, 14290},
+ {11058, 10826, 14290, 10826, 11058, 10826, 14290, 10826},
+ {11916, 11058, 14980, 11058, 11916, 11058, 14980, 11058},
+ {11058, 10826, 14290, 10826, 11058, 10826, 14290, 10826},
+ {14980, 14290, 19174, 14290, 14980, 14290, 19174, 14290},
+ {11058, 10826, 14290, 10826, 11058, 10826, 14290, 10826}
+ },
+ {
+ {10082, 9675, 12710, 9675, 10082, 9675, 12710, 9675},
+ {9675, 8943, 11985, 8943, 9675, 8943, 11985, 8943},
+ {12710, 11985, 15978, 11985, 12710, 11985, 15978, 11985},
+ {9675, 8943, 11985, 8943, 9675, 8943, 11985, 8943},
+ {10082, 9675, 12710, 9675, 10082, 9675, 12710, 9675},
+ {9675, 8943, 11985, 8943, 9675, 8943, 11985, 8943},
+ {12710, 11985, 15978, 11985, 12710, 11985, 15978, 11985},
+ {9675, 8943, 11985, 8943, 9675, 8943, 11985, 8943}
+ },
+ {
+ {9362, 8931, 11984, 8931, 9362, 8931, 11984, 8931},
+ {8931, 8228, 11259, 8228, 8931, 8228, 11259, 8228},
+ {11984, 11259, 14913, 11259, 11984, 11259, 14913, 11259},
+ {8931, 8228, 11259, 8228, 8931, 8228, 11259, 8228},
+ {9362, 8931, 11984, 8931, 9362, 8931, 11984, 8931},
+ {8931, 8228, 11259, 8228, 8931, 8228, 11259, 8228},
+ {11984, 11259, 14913, 11259, 11984, 11259, 14913, 11259},
+ {8931, 8228, 11259, 8228, 8931, 8228, 11259, 8228}
+ },
+ {
+ {8192, 7740, 10486, 7740, 8192, 7740, 10486, 7740},
+ {7740, 7346, 9777, 7346, 7740, 7346, 9777, 7346},
+ {10486, 9777, 13159, 9777, 10486, 9777, 13159, 9777},
+ {7740, 7346, 9777, 7346, 7740, 7346, 9777, 7346},
+ {8192, 7740, 10486, 7740, 8192, 7740, 10486, 7740},
+ {7740, 7346, 9777, 7346, 7740, 7346, 9777, 7346},
+ {10486, 9777, 13159, 9777, 10486, 9777, 13159, 9777},
+ {7740, 7346, 9777, 7346, 7740, 7346, 9777, 7346}
+ },
+ {
+ {7282, 6830, 9118, 6830, 7282, 6830, 9118, 6830},
+ {6830, 6428, 8640, 6428, 6830, 6428, 8640, 6428},
+ {9118, 8640, 11570, 8640, 9118, 8640, 11570, 8640},
+ {6830, 6428, 8640, 6428, 6830, 6428, 8640, 6428},
+ {7282, 6830, 9118, 6830, 7282, 6830, 9118, 6830},
+ {6830, 6428, 8640, 6428, 6830, 6428, 8640, 6428},
+ {9118, 8640, 11570, 8640, 9118, 8640, 11570, 8640},
+ {6830, 6428, 8640, 6428, 6830, 6428, 8640, 6428}
+ }
+};
+
+
+
+const int dequant_coef8[6][8][8] =
+{
+ {
+ {20, 19, 25, 19, 20, 19, 25, 19},
+ {19, 18, 24, 18, 19, 18, 24, 18},
+ {25, 24, 32, 24, 25, 24, 32, 24},
+ {19, 18, 24, 18, 19, 18, 24, 18},
+ {20, 19, 25, 19, 20, 19, 25, 19},
+ {19, 18, 24, 18, 19, 18, 24, 18},
+ {25, 24, 32, 24, 25, 24, 32, 24},
+ {19, 18, 24, 18, 19, 18, 24, 18}
+ },
+ {
+ {22, 21, 28, 21, 22, 21, 28, 21},
+ {21, 19, 26, 19, 21, 19, 26, 19},
+ {28, 26, 35, 26, 28, 26, 35, 26},
+ {21, 19, 26, 19, 21, 19, 26, 19},
+ {22, 21, 28, 21, 22, 21, 28, 21},
+ {21, 19, 26, 19, 21, 19, 26, 19},
+ {28, 26, 35, 26, 28, 26, 35, 26},
+ {21, 19, 26, 19, 21, 19, 26, 19}
+ },
+ {
+ {26, 24, 33, 24, 26, 24, 33, 24},
+ {24, 23, 31, 23, 24, 23, 31, 23},
+ {33, 31, 42, 31, 33, 31, 42, 31},
+ {24, 23, 31, 23, 24, 23, 31, 23},
+ {26, 24, 33, 24, 26, 24, 33, 24},
+ {24, 23, 31, 23, 24, 23, 31, 23},
+ {33, 31, 42, 31, 33, 31, 42, 31},
+ {24, 23, 31, 23, 24, 23, 31, 23}
+ },
+ {
+ {28, 26, 35, 26, 28, 26, 35, 26},
+ {26, 25, 33, 25, 26, 25, 33, 25},
+ {35, 33, 45, 33, 35, 33, 45, 33},
+ {26, 25, 33, 25, 26, 25, 33, 25},
+ {28, 26, 35, 26, 28, 26, 35, 26},
+ {26, 25, 33, 25, 26, 25, 33, 25},
+ {35, 33, 45, 33, 35, 33, 45, 33},
+ {26, 25, 33, 25, 26, 25, 33, 25}
+ },
+ {
+ {32, 30, 40, 30, 32, 30, 40, 30},
+ {30, 28, 38, 28, 30, 28, 38, 28},
+ {40, 38, 51, 38, 40, 38, 51, 38},
+ {30, 28, 38, 28, 30, 28, 38, 28},
+ {32, 30, 40, 30, 32, 30, 40, 30},
+ {30, 28, 38, 28, 30, 28, 38, 28},
+ {40, 38, 51, 38, 40, 38, 51, 38},
+ {30, 28, 38, 28, 30, 28, 38, 28}
+ },
+ {
+ {36, 34, 46, 34, 36, 34, 46, 34},
+ {34, 32, 43, 32, 34, 32, 43, 32},
+ {46, 43, 58, 43, 46, 43, 58, 43},
+ {34, 32, 43, 32, 34, 32, 43, 32},
+ {36, 34, 46, 34, 36, 34, 46, 34},
+ {34, 32, 43, 32, 34, 32, 43, 32},
+ {46, 43, 58, 43, 46, 43, 58, 43},
+ {34, 32, 43, 32, 34, 32, 43, 32}
+ }
+
+};
+
+
+
+#ifdef _NEW_8x8_ARRAYS_INCLUDED_
+//! single scan pattern
+const byte SNGL_SCAN8x8[64][2] = {
+ {0,0}, {1,0}, {0,1}, {0,2}, {1,1}, {2,0}, {3,0}, {2,1}, {1,2}, {0,3}, {0,4}, {1,3}, {2,2}, {3,1}, {4,0}, {5,0},
+ {4,1}, {3,2}, {2,3}, {1,4}, {0,5}, {0,6}, {1,5}, {2,4}, {3,3}, {4,2}, {5,1}, {6,0}, {7,0}, {6,1}, {5,2}, {4,3},
+ {3,4}, {2,5}, {1,6}, {0,7}, {1,7}, {2,6}, {3,5}, {4,4}, {5,3}, {6,2}, {7,1}, {7,2}, {6,3}, {5,4}, {4,5}, {3,6},
+ {2,7}, {3,7}, {4,6}, {5,5}, {6,4}, {7,3}, {7,4}, {6,5}, {5,6}, {4,7}, {5,7}, {6,6}, {7,5}, {7,6}, {6,7}, {7,7}
+};
+
+//! field scan pattern
+const byte FIELD_SCAN8x8[64][2] = {
+ {0,0}, {0,1}, {0,2}, {1,0}, {1,1}, {0,3}, {0,4}, {1,2}, {2,0}, {2,1}, {1,3}, {0,5}, {0,6}, {1,4}, {2,2}, {3,0},
+ {3,1}, {2,3}, {1,5}, {0,7}, {1,6}, {2,4}, {3,2}, {4,0}, {4,1}, {3,3}, {2,5}, {1,7}, {2,6}, {3,4}, {4,2}, {5,0},
+ {5,1}, {4,3}, {3,5}, {2,7}, {3,6}, {4,4}, {5,2}, {6,0}, {6,1}, {5,3}, {4,5}, {3,7}, {4,6}, {5,4}, {6,2}, {7,0},
+ {7,1}, {6,3}, {5,5}, {4,7}, {5,6}, {6,4}, {7,2}, {7,3}, {6,5}, {5,7}, {6,6}, {7,4}, {7,5}, {6,7}, {7,6}, {7,7}
+};
+
+
+//! array used to find expencive coefficients
+const byte COEFF_COST8x8[64] =
+{
+ 3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,
+ 1,1,1,1,1,1,1,1,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
+};
+
+#endif
+
+// 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:
+//
+// Z A B C D E F G H I J K L M N O P
+// Q a1 b1 c1 d1 e1 f1 g1 h1
+// R a2 b2 c2 d2 e2 f2 g2 h2
+// S a3 b3 c3 d3 e3 f3 g3 h3
+// T a4 b4 c4 d4 e4 f4 g4 h4
+// U a5 b5 c5 d5 e5 f5 g5 h5
+// V a6 b6 c6 d6 e6 f6 g6 h6
+// W a7 b7 c7 d7 e7 f7 g7 h7
+// X a8 b8 c8 d8 e8 f8 g8 h8
+
+
+// Predictor array index definitions
+#define P_Z (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])
+#define P_M (PredPel[13])
+#define P_N (PredPel[14])
+#define P_O (PredPel[15])
+#define P_P (PredPel[16])
+#define P_Q (PredPel[17])
+#define P_R (PredPel[18])
+#define P_S (PredPel[19])
+#define P_T (PredPel[20])
+#define P_U (PredPel[21])
+#define P_V (PredPel[22])
+#define P_W (PredPel[23])
+#define P_X (PredPel[24])
+
+/*!
+ ************************************************************************
+ * \brief
+ * Make intra 8x8 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 8x8 block image posision
+ *
+ ************************************************************************
+ */
+int intrapred8x8( struct img_par *img, //!< image parameters
+ int b8)
+
+{
+ int i,j;
+ int s0;
+ imgpel PredPel[25]; // array of predictor pels
+ imgpel **imgY = dec_picture->imgY; // For MB level frame/field coding tools -- set default to imgY
+
+ int mb_nr=img->current_mb_nr;
+
+ PixelPos pix_a[8];
+ 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;
+ int img_block_x = (img->mb_x)*4 + 2*(b8%2);
+ int img_block_y = (img->mb_y)*4 + 2*(b8/2);
+ int ioff = (b8%2)*8;
+ int joff = (b8/2)*8;
+ int jpos0 = joff , jpos1 = joff + 1, jpos2 = joff + 2, jpos3 = joff + 3;
+ int jpos4 = joff + 4, jpos5 = joff + 5, jpos6 = joff + 6, jpos7 = joff + 7;
+ int ipos0 = ioff , ipos1 = ioff + 1, ipos2 = ioff + 2, ipos3 = ioff + 3;
+ int ipos4 = ioff + 4, ipos5 = ioff + 5, ipos6 = ioff + 6, ipos7 = ioff + 7;
+ int jpos, ipos;
+ imgpel *pred_pels;
+
+ byte predmode = img->ipredmode[img_block_y][img_block_x];
+
+ for (i=0;i<8;i++)
+ {
+ getNeighbour(mb_nr, ioff -1 , joff +i , IS_LUMA, &pix_a[i]);
+ }
+
+ getNeighbour(mb_nr, ioff , joff -1 , IS_LUMA, &pix_b);
+ getNeighbour(mb_nr, ioff +8 , joff -1 , IS_LUMA, &pix_c);
+ getNeighbour(mb_nr, ioff -1 , joff -1 , IS_LUMA, &pix_d);
+
+ pix_c.available = pix_c.available &&!(ioff == 8 && joff == 8);
+
+ if (active_pps->constrained_intra_pred_flag)
+ {
+ for (i=0, block_available_left=1; i<8;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;
+
+ // form predictor pels
+ // form predictor pels
+ if (block_available_up)
+ {
+ pred_pels = &imgY[pix_b.pos_y][pix_b.pos_x];
+ P_A = pred_pels[0];
+ P_B = pred_pels[1];
+ P_C = pred_pels[2];
+ P_D = pred_pels[3];
+ P_E = pred_pels[4];
+ P_F = pred_pels[5];
+ P_G = pred_pels[6];
+ P_H = pred_pels[7];
+ }
+ else
+ {
+ P_A = P_B = P_C = P_D = P_E = P_F = P_G = P_H = img->dc_pred_value_luma;
+ }
+
+ if (block_available_up_right)
+ {
+ pred_pels = &imgY[pix_c.pos_y][pix_c.pos_x];
+ P_I = pred_pels[0];
+ P_J = pred_pels[1];
+ P_K = pred_pels[2];
+ P_L = pred_pels[3];
+ P_M = pred_pels[4];
+ P_N = pred_pels[5];
+ P_O = pred_pels[6];
+ P_P = pred_pels[7];
+
+ }
+ else
+ {
+ P_I = P_J = P_K = P_L = P_M = P_N = P_O = P_P = P_H;
+ }
+
+ if (block_available_left)
+ {
+ P_Q = imgY[pix_a[0].pos_y][pix_a[0].pos_x];
+ P_R = imgY[pix_a[1].pos_y][pix_a[1].pos_x];
+ P_S = imgY[pix_a[2].pos_y][pix_a[2].pos_x];
+ P_T = imgY[pix_a[3].pos_y][pix_a[3].pos_x];
+ P_U = imgY[pix_a[4].pos_y][pix_a[4].pos_x];
+ P_V = imgY[pix_a[5].pos_y][pix_a[5].pos_x];
+ P_W = imgY[pix_a[6].pos_y][pix_a[6].pos_x];
+ P_X = imgY[pix_a[7].pos_y][pix_a[7].pos_x];
+ }
+ else
+ {
+ P_Q = P_R = P_S = P_T = P_U = P_V = P_W = P_X = img->dc_pred_value_luma;
+ }
+
+ if (block_available_up_left)
+ {
+ P_Z = imgY[pix_d.pos_y][pix_d.pos_x];
+ }
+ else
+ {
+ P_Z = img->dc_pred_value_luma;
+ }
+
+ LowPassForIntra8x8Pred(&(P_Z), block_available_up_left, block_available_up, block_available_left);
+
+//img->mpr[y][x]
+ switch(predmode)
+ {
+ case DC_PRED:
+ s0 = 0;
+ if (block_available_up && block_available_left)
+ {
+ // no edge
+ s0 = (P_A + P_B + P_C + P_D + P_E + P_F + P_G + P_H + P_Q + P_R + P_S + P_T + P_U + P_V + P_W + P_X + 8) >> 4;
+ }
+ else if (!block_available_up && block_available_left)
+ {
+ // upper edge
+ s0 = (P_Q + P_R + P_S + P_T + P_U + P_V + P_W + P_X + 4) >> 3;
+ }
+ else if (block_available_up && !block_available_left)
+ {
+ // left edge
+ s0 = (P_A + P_B + P_C + P_D + P_E + P_F + P_G + P_H + 4) >> 3;
+ }
+ else //if (!block_available_up && !block_available_left)
+ {
+ // top left corner, nothing to predict from
+ s0 = img->dc_pred_value_luma;
+ }
+ for(j = joff; j < joff + 2*BLOCK_SIZE; j++)
+ for(i = ioff; i < ioff + 2*BLOCK_SIZE; i++)
+ img->mpr[j][i] = (imgpel) s0;
+ break;
+
+ case VERT_PRED:
+ if (!block_available_up)
+ printf ("warning: Intra_8x8_Vertical prediction mode not allowed at mb %d\n",img->current_mb_nr);
+
+ for (i=0; i < 2*BLOCK_SIZE; i++)
+ {
+ ipos = i+ioff;
+ img->mpr[jpos0][ipos] =
+ img->mpr[jpos1][ipos] =
+ img->mpr[jpos2][ipos] =
+ img->mpr[jpos3][ipos] =
+ img->mpr[jpos4][ipos] =
+ img->mpr[jpos5][ipos] =
+ img->mpr[jpos6][ipos] =
+ img->mpr[jpos7][ipos] = (imgpel) (&P_A)[i];
+ }
+ break;
+ case HOR_PRED:
+ if (!block_available_left)
+ printf ("warning: Intra_8x8_Horizontal prediction mode not allowed at mb %d\n",img->current_mb_nr);
+
+ for (j=0; j < 2*BLOCK_SIZE; j++)
+ {
+ jpos = j + joff;
+ img->mpr[jpos][ipos0] =
+ img->mpr[jpos][ipos1] =
+ img->mpr[jpos][ipos2] =
+ img->mpr[jpos][ipos3] =
+ img->mpr[jpos][ipos4] =
+ img->mpr[jpos][ipos5] =
+ img->mpr[jpos][ipos6] =
+ img->mpr[jpos][ipos7] = (imgpel) (&P_Q)[j];
+ }
+ break;
+
+ case DIAG_DOWN_LEFT_PRED:
+ if (!block_available_up)
+ printf ("warning: Intra_8x8_Diagonal_Down_Left prediction mode not allowed at mb %d\n",img->current_mb_nr);
+ // Mode DIAG_DOWN_LEFT_PRED
+ img->mpr[jpos0][ipos0] = (imgpel) ((P_A + P_C + 2*(P_B) + 2) >> 2);
+ img->mpr[jpos1][ipos0] =
+ img->mpr[jpos0][ipos1] = (imgpel) ((P_B + P_D + 2*(P_C) + 2) >> 2);
+ img->mpr[jpos2][ipos0] =
+ img->mpr[jpos1][ipos1] =
+ img->mpr[jpos0][ipos2] = (imgpel) ((P_C + P_E + 2*(P_D) + 2) >> 2);
+ img->mpr[jpos3][ipos0] =
+ img->mpr[jpos2][ipos1] =
+ img->mpr[jpos1][ipos2] =
+ img->mpr[jpos0][ipos3] = (imgpel) ((P_D + P_F + 2*(P_E) + 2) >> 2);
+ img->mpr[jpos4][ipos0] =
+ img->mpr[jpos3][ipos1] =
+ img->mpr[jpos2][ipos2] =
+ img->mpr[jpos1][ipos3] =
+ img->mpr[jpos0][ipos4] = (imgpel) ((P_E + P_G + 2*(P_F) + 2) >> 2);
+ img->mpr[jpos5][ipos0] =
+ img->mpr[jpos4][ipos1] =
+ img->mpr[jpos3][ipos2] =
+ img->mpr[jpos2][ipos3] =
+ img->mpr[jpos1][ipos4] =
+ img->mpr[jpos0][ipos5] = (imgpel) ((P_F + P_H + 2*(P_G) + 2) >> 2);
+ img->mpr[jpos6][ipos0] =
+ img->mpr[jpos5][ipos1] =
+ img->mpr[jpos4][ipos2] =
+ img->mpr[jpos3][ipos3] =
+ img->mpr[jpos2][ipos4] =
+ img->mpr[jpos1][ipos5] =
+ img->mpr[jpos0][ipos6] = (imgpel) ((P_G + P_I + 2*(P_H) + 2) >> 2);
+ img->mpr[jpos7][ipos0] =
+ img->mpr[jpos6][ipos1] =
+ img->mpr[jpos5][ipos2] =
+ img->mpr[jpos4][ipos3] =
+ img->mpr[jpos3][ipos4] =
+ img->mpr[jpos2][ipos5] =
+ img->mpr[jpos1][ipos6] =
+ img->mpr[jpos0][ipos7] = (imgpel) ((P_H + P_J + 2*(P_I) + 2) >> 2);
+ img->mpr[jpos7][ipos1] =
+ img->mpr[jpos6][ipos2] =
+ img->mpr[jpos5][ipos3] =
+ img->mpr[jpos4][ipos4] =
+ img->mpr[jpos3][ipos5] =
+ img->mpr[jpos2][ipos6] =
+ img->mpr[jpos1][ipos7] = (imgpel) ((P_I + P_K + 2*(P_J) + 2) >> 2);
+ img->mpr[jpos7][ipos2] =
+ img->mpr[jpos6][ipos3] =
+ img->mpr[jpos5][ipos4] =
+ img->mpr[jpos4][ipos5] =
+ img->mpr[jpos3][ipos6] =
+ img->mpr[jpos2][ipos7] = (imgpel) ((P_J + P_L + 2*(P_K) + 2) >> 2);
+ img->mpr[jpos7][ipos3] =
+ img->mpr[jpos6][ipos4] =
+ img->mpr[jpos5][ipos5] =
+ img->mpr[jpos4][ipos6] =
+ img->mpr[jpos3][ipos7] = (imgpel) ((P_K + P_M + 2*(P_L) + 2) >> 2);
+ img->mpr[jpos7][ipos4] =
+ img->mpr[jpos6][ipos5] =
+ img->mpr[jpos5][ipos6] =
+ img->mpr[jpos4][ipos7] = (imgpel) ((P_L + P_N + 2*(P_M) + 2) >> 2);
+ img->mpr[jpos7][ipos5] =
+ img->mpr[jpos6][ipos6] =
+ img->mpr[jpos5][ipos7] = (imgpel) ((P_M + P_O + 2*(P_N) + 2) >> 2);
+ img->mpr[jpos7][ipos6] =
+ img->mpr[jpos6][ipos7] = (imgpel) ((P_N + P_P + 2*(P_O) + 2) >> 2);
+ img->mpr[jpos7][ipos7] = (imgpel) ((P_O + 3*(P_P) + 2) >> 2);
+ break;
+
+ case VERT_LEFT_PRED:
+ if (!block_available_up)
+ printf ("warning: Intra_4x4_Vertical_Left prediction mode not allowed at mb %d\n",img->current_mb_nr);
+
+ img->mpr[jpos0][ipos0] = (imgpel) ((P_A + P_B + 1) >> 1);
+ img->mpr[jpos0][ipos1] =
+ img->mpr[jpos2][ipos0] = (imgpel) ((P_B + P_C + 1) >> 1);
+ img->mpr[jpos0][ipos2] =
+ img->mpr[jpos2][ipos1] =
+ img->mpr[jpos4][ipos0] = (imgpel) ((P_C + P_D + 1) >> 1);
+ img->mpr[jpos0][ipos3] =
+ img->mpr[jpos2][ipos2] =
+ img->mpr[jpos4][ipos1] =
+ img->mpr[jpos6][ipos0] = (imgpel) ((P_D + P_E + 1) >> 1);
+ img->mpr[jpos0][ipos4] =
+ img->mpr[jpos2][ipos3] =
+ img->mpr[jpos4][ipos2] =
+ img->mpr[jpos6][ipos1] = (imgpel) ((P_E + P_F + 1) >> 1);
+ img->mpr[jpos0][ipos5] =
+ img->mpr[jpos2][ipos4] =
+ img->mpr[jpos4][ipos3] =
+ img->mpr[jpos6][ipos2] = (imgpel) ((P_F + P_G + 1) >> 1);
+ img->mpr[jpos0][ipos6] =
+ img->mpr[jpos2][ipos5] =
+ img->mpr[jpos4][ipos4] =
+ img->mpr[jpos6][ipos3] = (imgpel) ((P_G + P_H + 1) >> 1);
+ img->mpr[jpos0][ipos7] =
+ img->mpr[jpos2][ipos6] =
+ img->mpr[jpos4][ipos5] =
+ img->mpr[jpos6][ipos4] = (imgpel) ((P_H + P_I + 1) >> 1);
+ img->mpr[jpos2][ipos7] =
+ img->mpr[jpos4][ipos6] =
+ img->mpr[jpos6][ipos5] = (imgpel) ((P_I + P_J + 1) >> 1);
+ img->mpr[jpos4][ipos7] =
+ img->mpr[jpos6][ipos6] = (imgpel) ((P_J + P_K + 1) >> 1);
+ img->mpr[jpos6][ipos7] = (imgpel) ((P_K + P_L + 1) >> 1);
+ img->mpr[jpos1][ipos0] = (imgpel) ((P_A + P_C + 2*P_B + 2) >> 2);
+ img->mpr[jpos1][ipos1] =
+ img->mpr[jpos3][ipos0] = (imgpel) ((P_B + P_D + 2*P_C + 2) >> 2);
+ img->mpr[jpos1][ipos2] =
+ img->mpr[jpos3][ipos1] =
+ img->mpr[jpos5][ipos0] = (imgpel) ((P_C + P_E + 2*P_D + 2) >> 2);
+ img->mpr[jpos1][ipos3] =
+ img->mpr[jpos3][ipos2] =
+ img->mpr[jpos5][ipos1] =
+ img->mpr[jpos7][ipos0] = (imgpel) ((P_D + P_F + 2*P_E + 2) >> 2);
+ img->mpr[jpos1][ipos4] =
+ img->mpr[jpos3][ipos3] =
+ img->mpr[jpos5][ipos2] =
+ img->mpr[jpos7][ipos1] = (imgpel) ((P_E + P_G + 2*P_F + 2) >> 2);
+ img->mpr[jpos1][ipos5] =
+ img->mpr[jpos3][ipos4] =
+ img->mpr[jpos5][ipos3] =
+ img->mpr[jpos7][ipos2] = (imgpel) ((P_F + P_H + 2*P_G + 2) >> 2);
+ img->mpr[jpos1][ipos6] =
+ img->mpr[jpos3][ipos5] =
+ img->mpr[jpos5][ipos4] =
+ img->mpr[jpos7][ipos3] = (imgpel) ((P_G + P_I + 2*P_H + 2) >> 2);
+ img->mpr[jpos1][ipos7] =
+ img->mpr[jpos3][ipos6] =
+ img->mpr[jpos5][ipos5] =
+ img->mpr[jpos7][ipos4] = (imgpel) ((P_H + P_J + 2*P_I + 2) >> 2);
+ img->mpr[jpos3][ipos7] =
+ img->mpr[jpos5][ipos6] =
+ img->mpr[jpos7][ipos5] = (imgpel) ((P_I + P_K + 2*P_J + 2) >> 2);
+ img->mpr[jpos5][ipos7] =
+ img->mpr[jpos7][ipos6] = (imgpel) ((P_J + P_L + 2*P_K + 2) >> 2);
+ img->mpr[jpos7][ipos7] = (imgpel) ((P_K + P_M + 2*P_L + 2) >> 2);
+ break;
+
+
+ case DIAG_DOWN_RIGHT_PRED:
+ if ((!block_available_up)||(!block_available_left)||(!block_available_up_left))
+ printf ("warning: Intra_8x8_Diagonal_Down_Right prediction mode not allowed at mb %d\n",img->current_mb_nr);
+
+ // Mode DIAG_DOWN_RIGHT_PRED
+ img->mpr[jpos7][ipos0] = (imgpel) ((P_X + P_V + 2*(P_W) + 2) >> 2);
+ img->mpr[jpos6][ipos0] =
+ img->mpr[jpos7][ipos1] = (imgpel) ((P_W + P_U + 2*(P_V) + 2) >> 2);
+ img->mpr[jpos5][ipos0] =
+ img->mpr[jpos6][ipos1] =
+ img->mpr[jpos7][ipos2] = (imgpel) ((P_V + P_T + 2*(P_U) + 2) >> 2);
+ img->mpr[jpos4][ipos0] =
+ img->mpr[jpos5][ipos1] =
+ img->mpr[jpos6][ipos2] =
+ img->mpr[jpos7][ipos3] = (imgpel) ((P_U + P_S + 2*(P_T) + 2) >> 2);
+ img->mpr[jpos3][ipos0] =
+ img->mpr[jpos4][ipos1] =
+ img->mpr[jpos5][ipos2] =
+ img->mpr[jpos6][ipos3] =
+ img->mpr[jpos7][ipos4] = (imgpel) ((P_T + P_R + 2*(P_S) + 2) >> 2);
+ img->mpr[jpos2][ipos0] =
+ img->mpr[jpos3][ipos1] =
+ img->mpr[jpos4][ipos2] =
+ img->mpr[jpos5][ipos3] =
+ img->mpr[jpos6][ipos4] =
+ img->mpr[jpos7][ipos5] = (imgpel) ((P_S + P_Q + 2*(P_R) + 2) >> 2);
+ img->mpr[jpos1][ipos0] =
+ img->mpr[jpos2][ipos1] =
+ img->mpr[jpos3][ipos2] =
+ img->mpr[jpos4][ipos3] =
+ img->mpr[jpos5][ipos4] =
+ img->mpr[jpos6][ipos5] =
+ img->mpr[jpos7][ipos6] = (imgpel) ((P_R + P_Z + 2*(P_Q) + 2) >> 2);
+ img->mpr[jpos0][ipos0] =
+ img->mpr[jpos1][ipos1] =
+ img->mpr[jpos2][ipos2] =
+ img->mpr[jpos3][ipos3] =
+ img->mpr[jpos4][ipos4] =
+ img->mpr[jpos5][ipos5] =
+ img->mpr[jpos6][ipos6] =
+ img->mpr[jpos7][ipos7] = (imgpel) ((P_Q + P_A + 2*(P_Z) + 2) >> 2);
+ img->mpr[jpos0][ipos1] =
+ img->mpr[jpos1][ipos2] =
+ img->mpr[jpos2][ipos3] =
+ img->mpr[jpos3][ipos4] =
+ img->mpr[jpos4][ipos5] =
+ img->mpr[jpos5][ipos6] =
+ img->mpr[jpos6][ipos7] = (imgpel) ((P_Z + P_B + 2*(P_A) + 2) >> 2);
+ img->mpr[jpos0][ipos2] =
+ img->mpr[jpos1][ipos3] =
+ img->mpr[jpos2][ipos4] =
+ img->mpr[jpos3][ipos5] =
+ img->mpr[jpos4][ipos6] =
+ img->mpr[jpos5][ipos7] = (imgpel) ((P_A + P_C + 2*(P_B) + 2) >> 2);
+ img->mpr[jpos0][ipos3] =
+ img->mpr[jpos1][ipos4] =
+ img->mpr[jpos2][ipos5] =
+ img->mpr[jpos3][ipos6] =
+ img->mpr[jpos4][ipos7] = (imgpel) ((P_B + P_D + 2*(P_C) + 2) >> 2);
+ img->mpr[jpos0][ipos4] =
+ img->mpr[jpos1][ipos5] =
+ img->mpr[jpos2][ipos6] =
+ img->mpr[jpos3][ipos7] = (imgpel) ((P_C + P_E + 2*(P_D) + 2) >> 2);
+ img->mpr[jpos0][ipos5] =
+ img->mpr[jpos1][ipos6] =
+ img->mpr[jpos2][ipos7] = (imgpel) ((P_D + P_F + 2*(P_E) + 2) >> 2);
+ img->mpr[jpos0][ipos6] =
+ img->mpr[jpos1][ipos7] = (imgpel) ((P_E + P_G + 2*(P_F) + 2) >> 2);
+ img->mpr[jpos0][ipos7] = (imgpel) ((P_F + P_H + 2*(P_G) + 2) >> 2);
+ break;
+
+ case VERT_RIGHT_PRED:/* diagonal prediction -22.5 deg to horizontal plane */
+ if ((!block_available_up)||(!block_available_left)||(!block_available_up_left))
+ printf ("warning: Intra_8x8_Vertical_Right prediction mode not allowed at mb %d\n",img->current_mb_nr);
+
+ img->mpr[jpos0][ipos0] =
+ img->mpr[jpos2][ipos1] =
+ img->mpr[jpos4][ipos2] =
+ img->mpr[jpos6][ipos3] = (imgpel) ((P_Z + P_A + 1) >> 1);
+ img->mpr[jpos0][ipos1] =
+ img->mpr[jpos2][ipos2] =
+ img->mpr[jpos4][ipos3] =
+ img->mpr[jpos6][ipos4] = (imgpel) ((P_A + P_B + 1) >> 1);
+ img->mpr[jpos0][ipos2] =
+ img->mpr[jpos2][ipos3] =
+ img->mpr[jpos4][ipos4] =
+ img->mpr[jpos6][ipos5] = (imgpel) ((P_B + P_C + 1) >> 1);
+ img->mpr[jpos0][ipos3] =
+ img->mpr[jpos2][ipos4] =
+ img->mpr[jpos4][ipos5] =
+ img->mpr[jpos6][ipos6] = (imgpel) ((P_C + P_D + 1) >> 1);
+ img->mpr[jpos0][ipos4] =
+ img->mpr[jpos2][ipos5] =
+ img->mpr[jpos4][ipos6] =
+ img->mpr[jpos6][ipos7] = (imgpel) ((P_D + P_E + 1) >> 1);
+ img->mpr[jpos0][ipos5] =
+ img->mpr[jpos2][ipos6] =
+ img->mpr[jpos4][ipos7] = (imgpel) ((P_E + P_F + 1) >> 1);
+ img->mpr[jpos0][ipos6] =
+ img->mpr[jpos2][ipos7] = (imgpel) ((P_F + P_G + 1) >> 1);
+ img->mpr[jpos0][ipos7] = (imgpel) ((P_G + P_H + 1) >> 1);
+ img->mpr[jpos1][ipos0] =
+ img->mpr[jpos3][ipos1] =
+ img->mpr[jpos5][ipos2] =
+ img->mpr[jpos7][ipos3] = (imgpel) ((P_Q + P_A + 2*P_Z + 2) >> 2);
+ img->mpr[jpos1][ipos1] =
+ img->mpr[jpos3][ipos2] =
+ img->mpr[jpos5][ipos3] =
+ img->mpr[jpos7][ipos4] = (imgpel) ((P_Z + P_B + 2*P_A + 2) >> 2);
+ img->mpr[jpos1][ipos2] =
+ img->mpr[jpos3][ipos3] =
+ img->mpr[jpos5][ipos4] =
+ img->mpr[jpos7][ipos5] = (imgpel) ((P_A + P_C + 2*P_B + 2) >> 2);
+ img->mpr[jpos1][ipos3] =
+ img->mpr[jpos3][ipos4] =
+ img->mpr[jpos5][ipos5] =
+ img->mpr[jpos7][ipos6] = (imgpel) ((P_B + P_D + 2*P_C + 2) >> 2);
+ img->mpr[jpos1][ipos4] =
+ img->mpr[jpos3][ipos5] =
+ img->mpr[jpos5][ipos6] =
+ img->mpr[jpos7][ipos7] = (imgpel) ((P_C + P_E + 2*P_D + 2) >> 2);
+ img->mpr[jpos1][ipos5] =
+ img->mpr[jpos3][ipos6] =
+ img->mpr[jpos5][ipos7] = (imgpel) ((P_D + P_F + 2*P_E + 2) >> 2);
+ img->mpr[jpos1][ipos6] =
+ img->mpr[jpos3][ipos7] = (imgpel) ((P_E + P_G + 2*P_F + 2) >> 2);
+ img->mpr[jpos1][ipos7] = (imgpel) ((P_F + P_H + 2*P_G + 2) >> 2);
+ img->mpr[jpos2][ipos0] =
+ img->mpr[jpos4][ipos1] =
+ img->mpr[jpos6][ipos2] = (imgpel) ((P_R + P_Z + 2*P_Q + 2) >> 2);
+ img->mpr[jpos3][ipos0] =
+ img->mpr[jpos5][ipos1] =
+ img->mpr[jpos7][ipos2] = (imgpel) ((P_S + P_Q + 2*P_R + 2) >> 2);
+ img->mpr[jpos4][ipos0] =
+ img->mpr[jpos6][ipos1] = (imgpel) ((P_T + P_R + 2*P_S + 2) >> 2);
+ img->mpr[jpos5][ipos0] =
+ img->mpr[jpos7][ipos1] = (imgpel) ((P_U + P_S + 2*P_T + 2) >> 2);
+ img->mpr[jpos6][ipos0] = (imgpel) ((P_V + P_T + 2*P_U + 2) >> 2);
+ img->mpr[jpos7][ipos0] = (imgpel) ((P_W + P_U + 2*P_V + 2) >> 2);
+ break;
+
+ case HOR_DOWN_PRED:/* diagonal prediction -22.5 deg to horizontal plane */
+ if ((!block_available_up)||(!block_available_left)||(!block_available_up_left))
+ printf ("warning: Intra_8x8_Horizontal_Down prediction mode not allowed at mb %d\n",img->current_mb_nr);
+
+ img->mpr[jpos0][ipos0] =
+ img->mpr[jpos1][ipos2] =
+ img->mpr[jpos2][ipos4] =
+ img->mpr[jpos3][ipos6] = (imgpel) ((P_Q + P_Z + 1) >> 1);
+ img->mpr[jpos1][ipos0] =
+ img->mpr[jpos2][ipos2] =
+ img->mpr[jpos3][ipos4] =
+ img->mpr[jpos4][ipos6] = (imgpel) ((P_R + P_Q + 1) >> 1);
+ img->mpr[jpos2][ipos0] =
+ img->mpr[jpos3][ipos2] =
+ img->mpr[jpos4][ipos4] =
+ img->mpr[jpos5][ipos6] = (imgpel) ((P_S + P_R + 1) >> 1);
+ img->mpr[jpos3][ipos0] =
+ img->mpr[jpos4][ipos2] =
+ img->mpr[jpos5][ipos4] =
+ img->mpr[jpos6][ipos6] = (imgpel) ((P_T + P_S + 1) >> 1);
+ img->mpr[jpos4][ipos0] =
+ img->mpr[jpos5][ipos2] =
+ img->mpr[jpos6][ipos4] =
+ img->mpr[jpos7][ipos6] = (imgpel) ((P_U + P_T + 1) >> 1);
+ img->mpr[jpos5][ipos0] =
+ img->mpr[jpos6][ipos2] =
+ img->mpr[jpos7][ipos4] = (imgpel) ((P_V + P_U + 1) >> 1);
+ img->mpr[jpos6][ipos0] =
+ img->mpr[jpos7][ipos2] = (imgpel) ((P_W + P_V + 1) >> 1);
+ img->mpr[jpos7][ipos0] = (imgpel) ((P_X + P_W + 1) >> 1);
+ img->mpr[jpos0][ipos1] =
+ img->mpr[jpos1][ipos3] =
+ img->mpr[jpos2][ipos5] =
+ img->mpr[jpos3][ipos7] = (imgpel) ((P_Q + P_A + 2*P_Z + 2) >> 2);
+ img->mpr[jpos1][ipos1] =
+ img->mpr[jpos2][ipos3] =
+ img->mpr[jpos3][ipos5] =
+ img->mpr[jpos4][ipos7] = (imgpel) ((P_Z + P_R + 2*P_Q + 2) >> 2);
+ img->mpr[jpos2][ipos1] =
+ img->mpr[jpos3][ipos3] =
+ img->mpr[jpos4][ipos5] =
+ img->mpr[jpos5][ipos7] = (imgpel) ((P_Q + P_S + 2*P_R + 2) >> 2);
+ img->mpr[jpos3][ipos1] =
+ img->mpr[jpos4][ipos3] =
+ img->mpr[jpos5][ipos5] =
+ img->mpr[jpos6][ipos7] = (imgpel) ((P_R + P_T + 2*P_S + 2) >> 2);
+ img->mpr[jpos4][ipos1] =
+ img->mpr[jpos5][ipos3] =
+ img->mpr[jpos6][ipos5] =
+ img->mpr[jpos7][ipos7] = (imgpel) ((P_S + P_U + 2*P_T + 2) >> 2);
+ img->mpr[jpos5][ipos1] =
+ img->mpr[jpos6][ipos3] =
+ img->mpr[jpos7][ipos5] = (imgpel) ((P_T + P_V + 2*P_U + 2) >> 2);
+ img->mpr[jpos6][ipos1] =
+ img->mpr[jpos7][ipos3] = (imgpel) ((P_U + P_W + 2*P_V + 2) >> 2);
+ img->mpr[jpos7][ipos1] = (imgpel) ((P_V + P_X + 2*P_W + 2) >> 2);
+ img->mpr[jpos0][ipos2] =
+ img->mpr[jpos1][ipos4] =
+ img->mpr[jpos2][ipos6] = (imgpel) ((P_Z + P_B + 2*P_A + 2) >> 2);
+ img->mpr[jpos0][ipos3] =
+ img->mpr[jpos1][ipos5] =
+ img->mpr[jpos2][ipos7] = (imgpel) ((P_A + P_C + 2*P_B + 2) >> 2);
+ img->mpr[jpos0][ipos4] =
+ img->mpr[jpos1][ipos6] = (imgpel) ((P_B + P_D + 2*P_C + 2) >> 2);
+ img->mpr[jpos0][ipos5] =
+ img->mpr[jpos1][ipos7] = (imgpel) ((P_C + P_E + 2*P_D + 2) >> 2);
+ img->mpr[jpos0][ipos6] = (imgpel) ((P_D + P_F + 2*P_E + 2) >> 2);
+ img->mpr[jpos0][ipos7] = (imgpel) ((P_E + P_G + 2*P_F + 2) >> 2);
+ break;
+
+ case HOR_UP_PRED:/* diagonal prediction -22.5 deg to horizontal plane */
+ if (!block_available_left)
+ printf ("warning: Intra_8x8_Horizontal_Up prediction mode not allowed at mb %d\n",img->current_mb_nr);
+
+ img->mpr[jpos0][ipos0] = (imgpel) ((P_Q + P_R + 1) >> 1);
+ img->mpr[jpos1][ipos0] =
+ img->mpr[jpos0][ipos2] = (imgpel) ((P_R + P_S + 1) >> 1);
+ img->mpr[jpos2][ipos0] =
+ img->mpr[jpos1][ipos2] =
+ img->mpr[jpos0][ipos4] = (imgpel) ((P_S + P_T + 1) >> 1);
+ img->mpr[jpos3][ipos0] =
+ img->mpr[jpos2][ipos2] =
+ img->mpr[jpos1][ipos4] =
+ img->mpr[jpos0][ipos6] = (imgpel) ((P_T + P_U + 1) >> 1);
+ img->mpr[jpos4][ipos0] =
+ img->mpr[jpos3][ipos2] =
+ img->mpr[jpos2][ipos4] =
+ img->mpr[jpos1][ipos6] = (imgpel) ((P_U + P_V + 1) >> 1);
+ img->mpr[jpos5][ipos0] =
+ img->mpr[jpos4][ipos2] =
+ img->mpr[jpos3][ipos4] =
+ img->mpr[jpos2][ipos6] = (imgpel) ((P_V + P_W + 1) >> 1);
+ img->mpr[jpos6][ipos0] =
+ img->mpr[jpos5][ipos2] =
+ img->mpr[jpos4][ipos4] =
+ img->mpr[jpos3][ipos6] = (imgpel) ((P_W + P_X + 1) >> 1);
+ img->mpr[jpos4][ipos6] =
+ img->mpr[jpos4][ipos7] =
+ img->mpr[jpos5][ipos4] =
+ img->mpr[jpos5][ipos5] =
+ img->mpr[jpos5][ipos6] =
+ img->mpr[jpos5][ipos7] =
+ img->mpr[jpos6][ipos2] =
+ img->mpr[jpos6][ipos3] =
+ img->mpr[jpos6][ipos4] =
+ img->mpr[jpos6][ipos5] =
+ img->mpr[jpos6][ipos6] =
+ img->mpr[jpos6][ipos7] =
+ img->mpr[jpos7][ipos0] =
+ img->mpr[jpos7][ipos1] =
+ img->mpr[jpos7][ipos2] =
+ img->mpr[jpos7][ipos3] =
+ img->mpr[jpos7][ipos4] =
+ img->mpr[jpos7][ipos5] =
+ img->mpr[jpos7][ipos6] =
+ img->mpr[jpos7][ipos7] = (imgpel) P_X;
+ img->mpr[jpos6][ipos1] =
+ img->mpr[jpos5][ipos3] =
+ img->mpr[jpos4][ipos5] =
+ img->mpr[jpos3][ipos7] = (imgpel) ((P_W + 3*P_X + 2) >> 2);
+ img->mpr[jpos5][ipos1] =
+ img->mpr[jpos4][ipos3] =
+ img->mpr[jpos3][ipos5] =
+ img->mpr[jpos2][ipos7] = (imgpel) ((P_X + P_V + 2*P_W + 2) >> 2);
+ img->mpr[jpos4][ipos1] =
+ img->mpr[jpos3][ipos3] =
+ img->mpr[jpos2][ipos5] =
+ img->mpr[jpos1][ipos7] = (imgpel) ((P_W + P_U + 2*P_V + 2) >> 2);
+ img->mpr[jpos3][ipos1] =
+ img->mpr[jpos2][ipos3] =
+ img->mpr[jpos1][ipos5] =
+ img->mpr[jpos0][ipos7] = (imgpel) ((P_V + P_T + 2*P_U + 2) >> 2);
+ img->mpr[jpos2][ipos1] =
+ img->mpr[jpos1][ipos3] =
+ img->mpr[jpos0][ipos5] = (imgpel) ((P_U + P_S + 2*P_T + 2) >> 2);
+ img->mpr[jpos1][ipos1] =
+ img->mpr[jpos0][ipos3] = (imgpel) ((P_T + P_R + 2*P_S + 2) >> 2);
+ img->mpr[jpos0][ipos1] = (imgpel) ((P_S + P_Q + 2*P_R + 2) >> 2);
+ break;
+
+ default:
+ printf("Error: illegal intra_4x4 prediction mode: %d\n",predmode);
+ return SEARCH_SYNC;
+ break;
+ }
+ return DECODING_OK;
+}
+
+
+
+/*!
+ *************************************************************************************
+ * \brief
+ * Prefiltering for Intra8x8 prediction
+ *************************************************************************************
+ */
+void LowPassForIntra8x8Pred(imgpel *PredPel, int block_up_left, int block_up, int block_left)
+{
+ int i;
+ imgpel LoopArray[25];
+
+ memcpy(&LoopArray[0], &PredPel[0], 25 * sizeof(imgpel));
+
+ if(block_up)
+ {
+ if(block_up_left)
+ {
+ LoopArray[1] = (((&P_Z)[0] + ((&P_Z)[1]<<1) + (&P_Z)[2] + 2)>>2);
+ }
+ else
+ LoopArray[1] = (((&P_Z)[1] + ((&P_Z)[1]<<1) + (&P_Z)[2] + 2)>>2);
+
+
+ for(i = 2; i <16; i++)
+ {
+ LoopArray[i] = (((&P_Z)[i-1] + ((&P_Z)[i]<<1) + (&P_Z)[i+1] + 2)>>2);
+ }
+ LoopArray[16] = ((P_P + (P_P<<1) + P_O + 2)>>2);
+ }
+
+ if(block_up_left)
+ {
+
+ if(block_up && block_left)
+ {
+ LoopArray[0] = ((P_Q + (P_Z<<1) + P_A +2)>>2);
+ }
+ else
+ {
+ if(block_up)
+ LoopArray[0] = ((P_Z + (P_Z<<1) + P_A +2)>>2);
+ else
+ if(block_left)
+ LoopArray[0] = ((P_Z + (P_Z<<1) + P_Q +2)>>2);
+ }
+
+ }
+
+ if(block_left)
+ {
+ if(block_up_left)
+ LoopArray[17] = ((P_Z + (P_Q<<1) + P_R + 2)>>2);
+ else
+ LoopArray[17] = ((P_Q + (P_Q<<1) + P_R + 2)>>2);
+
+ for(i = 18; i <24; i++)
+ {
+ LoopArray[i] = (((&P_Z)[i-1] + ((&P_Z)[i]<<1) + (&P_Z)[i+1] + 2)>>2);
+ }
+ LoopArray[24] = ((P_W + (P_X<<1) + P_X + 2)>>2);
+ }
+
+ memcpy(&PredPel[0], &LoopArray[0], 25 * sizeof(imgpel));
+}
+
+
+
+/*!
+ ***********************************************************************
+ * \brief
+ * Inverse 8x8 transformation
+ ***********************************************************************
+ */
+void itrans8x8(struct img_par *img, //!< image parameters
+ int ioff, //!< index to 4x4 block
+ int joff) //!<
+{
+ int i,j;
+ int m6[8][8];
+ Boolean lossless_qpprime = (Boolean) ((img->qp + img->bitdepth_luma_qp_scale)==0 && img->lossless_qpprime_flag==1);
+ static int ipos;
+ static int a[8], b[8];
+
+ if(lossless_qpprime)
+ {
+ for( j = joff; j < joff + 8; j++)
+ {
+ for( i = ioff; i < ioff + 8; i++)
+ img->m7[j][i] = iClip1(img->max_imgpel_value, (img->m7[j][i]+(long)img->mpr[j][i]));
+ }
+ }
+ else
+ {
+ int *m7;
+ for( i = 0; i < 8; i++)
+ {
+ m7 = &img->m7[joff + i][ioff];
+ a[0] = m7[0] + m7[4];
+ a[4] = m7[0] - m7[4];
+ a[2] = (m7[2]>>1) - m7[6];
+ a[6] = m7[2] + (m7[6]>>1);
+
+ b[0] = a[0] + a[6];
+ b[2] = a[4] + a[2];
+ b[4] = a[4] - a[2];
+ b[6] = a[0] - a[6];
+
+ a[1] = -m7[3] + m7[5] - m7[7] - (m7[7]>>1);
+ a[3] = m7[1] + m7[7] - m7[3] - (m7[3]>>1);
+ a[5] = -m7[1] + m7[7] + m7[5] + (m7[5]>>1);
+ a[7] = m7[3] + m7[5] + m7[1] + (m7[1]>>1);
+
+ b[1] = a[1] + (a[7]>>2);
+ b[7] = -(a[1]>>2) + a[7];
+ b[3] = a[3] + (a[5]>>2);
+ b[5] = (a[3]>>2) - a[5];
+
+ m6[0][i] = b[0] + b[7];
+ m6[1][i] = b[2] + b[5];
+ m6[2][i] = b[4] + b[3];
+ m6[3][i] = b[6] + b[1];
+ m6[4][i] = b[6] - b[1];
+ m6[5][i] = b[4] - b[3];
+ m6[6][i] = b[2] - b[5];
+ m6[7][i] = b[0] - b[7];
+ }
+ for( i = 0; i < 8; i++)
+ {
+ ipos = ioff + i;
+ m7 = m6[i];
+ a[0] = m7[0] + m7[4];
+ a[4] = m7[0] - m7[4];
+ a[2] = (m7[2]>>1) - m7[6];
+ a[6] = m7[2] + (m7[6]>>1);
+
+ b[0] = a[0] + a[6];
+ b[2] = a[4] + a[2];
+ b[4] = a[4] - a[2];
+ b[6] = a[0] - a[6];
+
+ a[1] = -m7[3] + m7[5] - m7[7] - (m7[7]>>1);
+ a[3] = m7[1] + m7[7] - m7[3] - (m7[3]>>1);
+ a[5] = -m7[1] + m7[7] + m7[5] + (m7[5]>>1);
+ a[7] = m7[3] + m7[5] + m7[1] + (m7[1]>>1);
+
+ b[1] = a[1] + (a[7]>>2);
+ b[7] = -(a[1]>>2) + a[7];
+ b[3] = a[3] + (a[5]>>2);
+ b[5] = (a[3]>>2) - a[5];
+
+ img->m7[joff + 0][ipos] = b[0] + b[7];
+ img->m7[joff + 1][ipos] = b[2] + b[5];
+ img->m7[joff + 2][ipos] = b[4] + b[3];
+ img->m7[joff + 3][ipos] = b[6] + b[1];
+ img->m7[joff + 4][ipos] = b[6] - b[1];
+ img->m7[joff + 5][ipos] = b[4] - b[3];
+ img->m7[joff + 6][ipos] = b[2] - b[5];
+ img->m7[joff + 7][ipos] = b[0] - b[7];
+ }
+
+ for( j = joff; j < joff + 8; j++)
+ {
+ for( i = ioff; i < ioff + 8; i++)
+ img->m7[j][i] = iClip1(img->max_imgpel_value,
+ rshift_rnd_sf((img->m7[j][i]+((long)img->mpr[j][i] << DQ_BITS_8)),DQ_BITS_8));
+ }
+ }
+}
Index: llvm-test/MultiSource/Applications/JM/ldecod/transform8x8.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/transform8x8.h:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/transform8x8.h Sun Feb 4 08:38:32 2007
@@ -0,0 +1,38 @@
+/*!
+ ***************************************************************************
+ *
+ * \file transform8x8.h
+ *
+ * \brief
+ * prototypes of 8x8 transform functions
+ *
+ * \date
+ * 9. October 2003
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Yuri Vatis vatis at hhi.de
+ **************************************************************************/
+
+#ifndef _TRANSFORM8X8_H_
+#define _TRANSFORM8X8_H_
+
+#include "global.h"
+#include "image.h"
+#include "mb_access.h"
+#include "elements.h"
+#include <math.h>
+
+
+int **cofAC8x8_intra, ****cofAC8x8_iintra; // [level/run][scan_pos]
+
+
+void intrapred_luma8x8(int img_x,int img_y, int *left_available, int *up_available, int *all_available);
+int intrapred8x8(struct img_par *img, int b8);
+void itrans8x8(struct img_par *img, int ioff, int joff);
+double RDCost_for_8x8IntraBlocks(int *c_nz, int b8, int ipmode, double lambda, double min_rdcost, int mostProbableMode);
+int dct_luma8x8(int block_x,int block_y,int *coeff_cost);
+void LowPassForIntra8x8Pred(imgpel *PredPel, int block_up_left, int block_up, int block_left);
+
+
+#endif
Index: llvm-test/MultiSource/Applications/JM/ldecod/vlc.c
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/vlc.c:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/vlc.c Sun Feb 4 08:38:32 2007
@@ -0,0 +1,1369 @@
+
+/*!
+ ************************************************************************
+ * \file vlc.c
+ *
+ * \brief
+ * VLC support functions
+ *
+ * \author
+ * Main contributors (see contributors.h for copyright, address and affiliation details)
+ * - Inge Lille-Langøy <inge.lille-langoy at telenor.com>
+ * - Detlev Marpe <marpe at hhi.de>
+ * - Gabi Blaettermann <blaetter at hhi.de>
+ ************************************************************************
+ */
+#include "contributors.h"
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include <assert.h>
+
+#include "global.h"
+#include "vlc.h"
+#include "elements.h"
+
+
+// A little trick to avoid those horrible #if TRACE all over the source code
+#if TRACE
+#define SYMTRACESTRING(s) strncpy(symbol.tracestring,s,TRACESTRING_SIZE)
+#else
+#define SYMTRACESTRING(s) // do nothing
+#endif
+
+extern void tracebits(const char *trace_str, int len, int info,int value1);
+
+
+int UsedBits; // for internal statistics, is adjusted by se_v, ue_v, u_1
+
+// Note that all NA values are filled with 0
+
+//! for the linfo_levrun_inter routine
+const byte NTAB1[4][8][2] =
+{
+ {{1,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}},
+ {{1,1},{1,2},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}},
+ {{2,0},{1,3},{1,4},{1,5},{0,0},{0,0},{0,0},{0,0}},
+ {{3,0},{2,1},{2,2},{1,6},{1,7},{1,8},{1,9},{4,0}},
+};
+const byte LEVRUN1[16]=
+{
+ 4,2,2,1,1,1,1,1,1,1,0,0,0,0,0,0,
+};
+
+
+const byte NTAB2[4][8][2] =
+{
+ {{1,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}},
+ {{1,1},{2,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}},
+ {{1,2},{3,0},{4,0},{5,0},{0,0},{0,0},{0,0},{0,0}},
+ {{1,3},{1,4},{2,1},{3,1},{6,0},{7,0},{8,0},{9,0}},
+};
+
+//! for the linfo_levrun__c2x2 routine
+const byte LEVRUN3[4] =
+{
+ 2,1,0,0
+};
+const byte NTAB3[2][2][2] =
+{
+ {{1,0},{0,0}},
+ {{2,0},{1,1}},
+};
+
+/*!
+ *************************************************************************************
+ * \brief
+ * ue_v, reads an ue(v) syntax element, the length in bits is stored in
+ * the global UsedBits variable
+ *
+ * \param tracestring
+ * the string for the trace file
+ *
+ * \param bitstream
+ * the stream to be read from
+ *
+ * \return
+ * the value of the coded syntax element
+ *
+ *************************************************************************************
+ */
+int ue_v (char *tracestring, Bitstream *bitstream)
+{
+ SyntaxElement symbol;
+
+ assert (bitstream->streamBuffer != NULL);
+ symbol.type = SE_HEADER;
+ symbol.mapping = linfo_ue; // Mapping rule
+ SYMTRACESTRING(tracestring);
+ readSyntaxElement_VLC (&symbol, bitstream);
+ UsedBits+=symbol.len;
+ return symbol.value1;
+}
+
+
+/*!
+ *************************************************************************************
+ * \brief
+ * ue_v, reads an se(v) syntax element, the length in bits is stored in
+ * the global UsedBits variable
+ *
+ * \param tracestring
+ * the string for the trace file
+ *
+ * \param bitstream
+ * the stream to be read from
+ *
+ * \return
+ * the value of the coded syntax element
+ *
+ *************************************************************************************
+ */
+int se_v (char *tracestring, Bitstream *bitstream)
+{
+ SyntaxElement symbol;
+
+ assert (bitstream->streamBuffer != NULL);
+ symbol.type = SE_HEADER;
+ symbol.mapping = linfo_se; // Mapping rule: signed integer
+ SYMTRACESTRING(tracestring);
+ readSyntaxElement_VLC (&symbol, bitstream);
+ UsedBits+=symbol.len;
+ return symbol.value1;
+}
+
+
+/*!
+ *************************************************************************************
+ * \brief
+ * ue_v, reads an u(v) syntax element, the length in bits is stored in
+ * the global UsedBits variable
+ *
+ * \param LenInBits
+ * length of the syntax element
+ *
+ * \param tracestring
+ * the string for the trace file
+ *
+ * \param bitstream
+ * the stream to be read from
+ *
+ * \return
+ * the value of the coded syntax element
+ *
+ *************************************************************************************
+ */
+int u_v (int LenInBits, char*tracestring, Bitstream *bitstream)
+{
+ SyntaxElement symbol;
+ symbol.inf = 0;
+
+ assert (bitstream->streamBuffer != NULL);
+ symbol.type = SE_HEADER;
+ symbol.mapping = linfo_ue; // Mapping rule
+ symbol.len = LenInBits;
+ SYMTRACESTRING(tracestring);
+ readSyntaxElement_FLC (&symbol, bitstream);
+ UsedBits+=symbol.len;
+ return symbol.inf;
+}
+
+
+/*!
+ *************************************************************************************
+ * \brief
+ * ue_v, reads an u(1) syntax element, the length in bits is stored in
+ * the global UsedBits variable
+ *
+ * \param tracestring
+ * the string for the trace file
+ *
+ * \param bitstream
+ * the stream to be read from
+ *
+ * \return
+ * the value of the coded syntax element
+ *
+ *************************************************************************************
+ */
+Boolean u_1 (char *tracestring, Bitstream *bitstream)
+{
+ return (Boolean) u_v (1, tracestring, bitstream);
+}
+
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * mapping rule for ue(v) syntax elements
+ * \par Input:
+ * lenght and info
+ * \par Output:
+ * number in the code table
+ ************************************************************************
+ */
+void linfo_ue(int len, int info, int *value1, int *dummy)
+{
+ assert ((len>>1)<32);
+ *value1 = (1<<(len>>1))+info-1;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * mapping rule for se(v) syntax elements
+ * \par Input:
+ * lenght and info
+ * \par Output:
+ * signed mvd
+ ************************************************************************
+ */
+void linfo_se(int len, int info, int *value1, int *dummy)
+{
+ int n;
+ assert ((len>>1)<32);
+ n = (1 << (len>>1))+info-1;
+ *value1 = (n+1)>>1;
+ if((n & 0x01)==0) // lsb is signed bit
+ *value1 = -*value1;
+}
+
+
+/*!
+ ************************************************************************
+ * \par Input:
+ * length and info
+ * \par Output:
+ * cbp (intra)
+ ************************************************************************
+ */
+void linfo_cbp_intra(int len,int info,int *cbp, int *dummy)
+{
+ extern const byte NCBP[2][48][2];
+ int cbp_idx;
+
+ linfo_ue(len,info,&cbp_idx,dummy);
+ *cbp=NCBP[active_sps->chroma_format_idc?1:0][cbp_idx][0];
+}
+
+/*!
+ ************************************************************************
+ * \par Input:
+ * length and info
+ * \par Output:
+ * cbp (inter)
+ ************************************************************************
+ */
+void linfo_cbp_inter(int len,int info,int *cbp, int *dummy)
+{
+ extern const byte NCBP[2][48][2];
+ int cbp_idx;
+
+ linfo_ue(len,info,&cbp_idx,dummy);
+ *cbp=NCBP[active_sps->chroma_format_idc?1:0][cbp_idx][1];
+}
+
+/*!
+ ************************************************************************
+ * \par Input:
+ * length and info
+ * \par Output:
+ * level, run
+ ************************************************************************
+ */
+void linfo_levrun_inter(int len, int info, int *level, int *irun)
+{
+ int l2;
+ int inf;
+ assert (((len>>1)-5)<32);
+ if (len<=9)
+ {
+ l2=imax(0,(len>>1)-1);
+ inf=info>>1;
+ *level=NTAB1[l2][inf][0];
+ *irun=NTAB1[l2][inf][1];
+ if ((info&0x01)==1)
+ *level=-*level; // make sign
+ }
+ else // if len > 9, skip using the array
+ {
+ *irun=(info&0x1e)>>1;
+ *level = LEVRUN1[*irun] + (info>>5) + ( 1<< ((len>>1) - 5));
+ if ((info&0x01)==1)
+ *level=-*level;
+ }
+ if (len == 1) // EOB
+ *level = 0;
+}
+
+
+/*!
+ ************************************************************************
+ * \par Input:
+ * length and info
+ * \par Output:
+ * level, run
+ ************************************************************************
+ */
+void linfo_levrun_c2x2(int len, int info, int *level, int *irun)
+{
+ int l2;
+ int inf;
+
+ if (len<=5)
+ {
+ l2=imax(0,(len>>1)-1);
+ inf=info>>1;
+ *level=NTAB3[l2][inf][0];
+ *irun=NTAB3[l2][inf][1];
+ if ((info&0x01)==1)
+ *level=-*level; // make sign
+ }
+ else // if len > 5, skip using the array
+ {
+ *irun=(info&0x06)>>1;
+ *level = LEVRUN3[*irun] + (info>>3) + (1 << ((len>>1) - 3));
+ if ((info&0x01)==1)
+ *level=-*level;
+ }
+ if (len == 1) // EOB
+ *level = 0;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * read next UVLC codeword from UVLC-partition and
+ * map it to the corresponding syntax element
+ ************************************************************************
+ */
+int readSyntaxElement_VLC(SyntaxElement *sym, Bitstream *currStream)
+{
+ int frame_bitoffset = currStream->frame_bitoffset;
+ byte *buf = currStream->streamBuffer;
+ int BitstreamLengthInBytes = currStream->bitstream_length;
+
+ sym->len = GetVLCSymbol (buf, frame_bitoffset, &(sym->inf), BitstreamLengthInBytes);
+ if (sym->len == -1)
+ return -1;
+ currStream->frame_bitoffset += sym->len;
+ sym->mapping(sym->len,sym->inf,&(sym->value1),&(sym->value2));
+
+#if TRACE
+ tracebits(sym->tracestring, sym->len, sym->inf, sym->value1);
+#endif
+
+ return 1;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * read next UVLC codeword from UVLC-partition and
+ * map it to the corresponding syntax element
+ ************************************************************************
+ */
+int readSyntaxElement_UVLC(SyntaxElement *sym, struct img_par *img, struct datapartition *dP)
+{
+ Bitstream *currStream = dP->bitstream;
+
+ return (readSyntaxElement_VLC(sym, currStream));
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * read next VLC codeword for 4x4 Intra Prediction Mode and
+ * map it to the corresponding Intra Prediction Direction
+ ************************************************************************
+ */
+int readSyntaxElement_Intra4x4PredictionMode(SyntaxElement *sym, struct img_par *img,struct datapartition *dP)
+{
+ Bitstream *currStream = dP->bitstream;
+ int frame_bitoffset = currStream->frame_bitoffset;
+ byte *buf = currStream->streamBuffer;
+ int BitstreamLengthInBytes = currStream->bitstream_length;
+
+ sym->len = GetVLCSymbol_IntraMode (buf, frame_bitoffset, &(sym->inf), BitstreamLengthInBytes);
+
+ if (sym->len == -1)
+ return -1;
+
+ currStream->frame_bitoffset += sym->len;
+ sym->value1 = sym->len == 1 ? -1 : sym->inf;
+
+#if TRACE
+ tracebits2(sym->tracestring, sym->len, sym->value1);
+#endif
+
+ return 1;
+}
+
+int GetVLCSymbol_IntraMode (byte buffer[],int totbitoffset,int *info, int bytecount)
+{
+
+ register int inf;
+ long byteoffset; // byte from start of buffer
+ int bitoffset; // bit from start of byte
+ int ctr_bit=0; // control bit for current bit posision
+ int bitcounter=1;
+ int len;
+ int info_bit;
+
+ byteoffset = totbitoffset>>3;
+ bitoffset = 7-(totbitoffset&0x07);
+ ctr_bit = (buffer[byteoffset] & (0x01<<bitoffset)); // set up control bit
+ len = 1;
+
+ //First bit
+ if (ctr_bit)
+ {
+ *info = 0;
+ return bitcounter;
+ }
+ else
+ len=4;
+
+ // make infoword
+ inf=0; // shortest possible code is 1, then info is always 0
+ for(info_bit=0;(info_bit<(len-1)); info_bit++)
+ {
+ bitcounter++;
+ bitoffset-=1;
+ if (bitoffset<0)
+ { // finished with current byte ?
+ bitoffset=bitoffset+8;
+ byteoffset++;
+ }
+ if (byteoffset > bytecount)
+ {
+ return -1;
+ }
+ inf=(inf<<1);
+ if(buffer[byteoffset] & (0x01<<(bitoffset)))
+ inf |=1;
+ }
+
+ *info = inf;
+ return bitcounter; // return absolute offset in bit from start of frame
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * test if bit buffer contains only stop bit
+ *
+ * \param buffer
+ * buffer containing VLC-coded data bits
+ * \param totbitoffset
+ * bit offset from start of partition
+ * \param bytecount
+ * buffer length
+ * \return
+ * true if more bits available
+ ************************************************************************
+ */
+int more_rbsp_data (byte buffer[],int totbitoffset,int bytecount)
+{
+
+ long byteoffset; // byte from start of buffer
+ int bitoffset; // bit from start of byte
+ int ctr_bit=0; // control bit for current bit posision
+
+ int cnt=0;
+
+
+ byteoffset= totbitoffset>>3;
+ bitoffset= 7-(totbitoffset&0x07);
+
+ assert (byteoffset<bytecount);
+
+ // there is more until we're in the last byte
+ if (byteoffset<(bytecount-1)) return TRUE;
+
+ // read one bit
+ ctr_bit = (buffer[byteoffset] & (0x01<<bitoffset));
+
+ // a stop bit has to be one
+ if (ctr_bit==0) return TRUE;
+
+ bitoffset--;
+
+ while (bitoffset>=0)
+ {
+ ctr_bit = (buffer[byteoffset] & (0x01<<bitoffset)); // set up control bit
+ if (ctr_bit>0) cnt++;
+ bitoffset--;
+ }
+
+ return (0!=cnt);
+
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Check if there are symbols for the next MB
+ ************************************************************************
+ */
+int uvlc_startcode_follows(struct img_par *img, int dummy)
+{
+ int dp_Nr = assignSE2partition[img->currentSlice->dp_mode][SE_MBTYPE];
+ DataPartition *dP = &(img->currentSlice->partArr[dp_Nr]);
+ Bitstream *currStream = dP->bitstream;
+ byte *buf = currStream->streamBuffer;
+
+ //KS: new function test for End of Buffer
+ return (!(more_rbsp_data(buf, currStream->frame_bitoffset,currStream->bitstream_length)));
+}
+
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * read one exp-golomb VLC symbol
+ *
+ * \param buffer
+ * containing VLC-coded data bits
+ * \param totbitoffset
+ * bit offset from start of partition
+ * \param info
+ * returns the value of the symbol
+ * \param bytecount
+ * buffer length
+ * \return
+ * bits read
+ ************************************************************************
+ */
+int GetVLCSymbol (byte buffer[],int totbitoffset,int *info, int bytecount)
+{
+
+ register int inf;
+ long byteoffset; // byte from start of buffer
+ int bitoffset; // bit from start of byte
+ int ctr_bit=0; // control bit for current bit posision
+ int bitcounter=1;
+ int len;
+ int info_bit;
+
+ byteoffset= totbitoffset>>3;
+ bitoffset= 7-(totbitoffset&0x07);
+ ctr_bit = (buffer[byteoffset] & (0x01<<bitoffset)); // set up control bit
+
+ len=1;
+ while (ctr_bit==0)
+ { // find leading 1 bit
+ len++;
+ bitoffset-=1;
+ bitcounter++;
+ if (bitoffset<0)
+ { // finish with current byte ?
+ bitoffset=bitoffset+8;
+ byteoffset++;
+ }
+ ctr_bit=buffer[byteoffset] & (0x01<<(bitoffset));
+ }
+ // make infoword
+ inf=0; // shortest possible code is 1, then info is always 0
+ for(info_bit=0;(info_bit<(len-1)); info_bit++)
+ {
+ bitcounter++;
+ bitoffset-=1;
+ if (bitoffset<0)
+ { // finished with current byte ?
+ bitoffset=bitoffset+8;
+ byteoffset++;
+ }
+ if (byteoffset > bytecount)
+ {
+ return -1;
+ }
+ inf=(inf<<1);
+ if(buffer[byteoffset] & (0x01<<(bitoffset)))
+ inf |=1;
+ }
+
+ *info = inf;
+ return bitcounter; // return absolute offset in bit from start of frame
+}
+
+extern void tracebits2(const char *trace_str, int len, int info) ;
+
+/*!
+ ************************************************************************
+ * \brief
+ * code from bitstream (2d tables)
+ ************************************************************************
+ */
+
+int code_from_bitstream_2d(SyntaxElement *sym,
+ DataPartition *dP,
+ const int *lentab,
+ const int *codtab,
+ int tabwidth,
+ int tabheight,
+ int *code)
+{
+ Bitstream *currStream = dP->bitstream;
+ int frame_bitoffset = currStream->frame_bitoffset;
+ byte *buf = currStream->streamBuffer;
+ int BitstreamLengthInBytes = currStream->bitstream_length;
+
+ int i,j;
+ int len, cod;
+
+ // this VLC decoding method is not optimized for speed
+ for (j = 0; j < tabheight; j++) {
+ for (i = 0; i < tabwidth; i++)
+ {
+ len = lentab[i];
+ if (!len)
+ continue;
+ cod = codtab[i];
+
+ if ((ShowBits(buf, frame_bitoffset, BitstreamLengthInBytes, len) == cod))
+ {
+ sym->value1 = i;
+ sym->value2 = j;
+ currStream->frame_bitoffset += len; // move bitstream pointer
+ sym->len = len;
+ goto found_code;
+ }
+ }
+ lentab += tabwidth;
+ codtab += tabwidth;
+ }
+
+ return -1; // failed to find code
+
+found_code:
+
+ *code = cod;
+
+ return 0;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * read FLC codeword from UVLC-partition
+ ************************************************************************
+ */
+int readSyntaxElement_FLC(SyntaxElement *sym, Bitstream *currStream)
+{
+ int frame_bitoffset = currStream->frame_bitoffset;
+ byte *buf = currStream->streamBuffer;
+ int BitstreamLengthInBytes = currStream->bitstream_length;
+
+ if ((GetBits(buf, frame_bitoffset, &(sym->inf), BitstreamLengthInBytes, sym->len)) < 0)
+ return -1;
+
+ currStream->frame_bitoffset += sym->len; // move bitstream pointer
+ sym->value1 = sym->inf;
+
+#if TRACE
+ tracebits2(sym->tracestring, sym->len, sym->inf);
+#endif
+
+ return 1;
+}
+
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * read NumCoeff/TrailingOnes codeword from UVLC-partition
+ ************************************************************************
+ */
+
+int readSyntaxElement_NumCoeffTrailingOnes(SyntaxElement *sym, DataPartition *dP,
+ char *type)
+{
+ Bitstream *currStream = dP->bitstream;
+ int frame_bitoffset = currStream->frame_bitoffset;
+ byte *buf = currStream->streamBuffer;
+ int BitstreamLengthInBytes = currStream->bitstream_length;
+
+ int vlcnum, retval;
+ int code;
+
+ static const int lentab[3][4][17] =
+ {
+ { // 0702
+ { 1, 6, 8, 9,10,11,13,13,13,14,14,15,15,16,16,16,16},
+ { 0, 2, 6, 8, 9,10,11,13,13,14,14,15,15,15,16,16,16},
+ { 0, 0, 3, 7, 8, 9,10,11,13,13,14,14,15,15,16,16,16},
+ { 0, 0, 0, 5, 6, 7, 8, 9,10,11,13,14,14,15,15,16,16},
+ },
+ {
+ { 2, 6, 6, 7, 8, 8, 9,11,11,12,12,12,13,13,13,14,14},
+ { 0, 2, 5, 6, 6, 7, 8, 9,11,11,12,12,13,13,14,14,14},
+ { 0, 0, 3, 6, 6, 7, 8, 9,11,11,12,12,13,13,13,14,14},
+ { 0, 0, 0, 4, 4, 5, 6, 6, 7, 9,11,11,12,13,13,13,14},
+ },
+ {
+ { 4, 6, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 9,10,10,10,10},
+ { 0, 4, 5, 5, 5, 5, 6, 6, 7, 8, 8, 9, 9, 9,10,10,10},
+ { 0, 0, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10,10},
+ { 0, 0, 0, 4, 4, 4, 4, 4, 5, 6, 7, 8, 8, 9,10,10,10},
+ },
+
+ };
+
+ static const int codtab[3][4][17] =
+ {
+ {
+ { 1, 5, 7, 7, 7, 7,15,11, 8,15,11,15,11,15,11, 7,4},
+ { 0, 1, 4, 6, 6, 6, 6,14,10,14,10,14,10, 1,14,10,6},
+ { 0, 0, 1, 5, 5, 5, 5, 5,13, 9,13, 9,13, 9,13, 9,5},
+ { 0, 0, 0, 3, 3, 4, 4, 4, 4, 4,12,12, 8,12, 8,12,8},
+ },
+ {
+ { 3,11, 7, 7, 7, 4, 7,15,11,15,11, 8,15,11, 7, 9,7},
+ { 0, 2, 7,10, 6, 6, 6, 6,14,10,14,10,14,10,11, 8,6},
+ { 0, 0, 3, 9, 5, 5, 5, 5,13, 9,13, 9,13, 9, 6,10,5},
+ { 0, 0, 0, 5, 4, 6, 8, 4, 4, 4,12, 8,12,12, 8, 1,4},
+ },
+ {
+ {15,15,11, 8,15,11, 9, 8,15,11,15,11, 8,13, 9, 5,1},
+ { 0,14,15,12,10, 8,14,10,14,14,10,14,10, 7,12, 8,4},
+ { 0, 0,13,14,11, 9,13, 9,13,10,13, 9,13, 9,11, 7,3},
+ { 0, 0, 0,12,11,10, 9, 8,13,12,12,12, 8,12,10, 6,2},
+ },
+ };
+
+ vlcnum = sym->value1;
+ // vlcnum is the index of Table used to code coeff_token
+ // vlcnum==3 means (8<=nC) which uses 6bit FLC
+
+ if (vlcnum == 3)
+ {
+ // read 6 bit FLC
+ code = ShowBits(buf, frame_bitoffset, BitstreamLengthInBytes, 6);
+ currStream->frame_bitoffset += 6;
+ sym->value2 = code & 3;
+ sym->value1 = (code >> 2);
+
+ if (!sym->value1 && sym->value2 == 3)
+ {
+ // #c = 0, #t1 = 3 => #c = 0
+ sym->value2 = 0;
+ }
+ else
+ sym->value1++;
+
+ sym->len = 6;
+
+ retval = 0;
+ }
+ else
+
+ {
+ const int *lt = &lentab[vlcnum][0][0];
+ const int *ct = &codtab[vlcnum][0][0];
+ retval = code_from_bitstream_2d(sym, dP, lt, ct, 17, 4, &code);
+ }
+
+ if (retval)
+ {
+ printf("ERROR: failed to find NumCoeff/TrailingOnes\n");
+ exit(-1);
+ }
+
+#if TRACE
+ snprintf(sym->tracestring,
+ TRACESTRING_SIZE, "%s # c & tr.1s vlc=%d #c=%d #t1=%d",
+ type, vlcnum, sym->value1, sym->value2);
+ tracebits2(sym->tracestring, sym->len, code);
+
+#endif
+
+ return retval;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * read NumCoeff/TrailingOnes codeword from UVLC-partition ChromaDC
+ ************************************************************************
+ */
+int readSyntaxElement_NumCoeffTrailingOnesChromaDC(SyntaxElement *sym, DataPartition *dP)
+{
+ int retval;
+ int code;
+
+ static const int lentab[3][4][17] =
+ {
+ //YUV420
+ {{ 2, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 1, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 3, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+ //YUV422
+ {{ 1, 7, 7, 9, 9,10,11,12,13, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 2, 7, 7, 9,10,11,12,12, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 3, 7, 7, 9,10,11,12, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 5, 6, 7, 7,10,11, 0, 0, 0, 0, 0, 0, 0, 0}},
+ //YUV444
+ {{ 1, 6, 8, 9,10,11,13,13,13,14,14,15,15,16,16,16,16},
+ { 0, 2, 6, 8, 9,10,11,13,13,14,14,15,15,15,16,16,16},
+ { 0, 0, 3, 7, 8, 9,10,11,13,13,14,14,15,15,16,16,16},
+ { 0, 0, 0, 5, 6, 7, 8, 9,10,11,13,14,14,15,15,16,16}}
+ };
+
+ static const int codtab[3][4][17] =
+ {
+ //YUV420
+ {{ 1, 7, 4, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 1, 6, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+ //YUV422
+ {{ 1,15,14, 7, 6, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 1,13,12, 5, 6, 6, 6, 5, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 1,11,10, 4, 5, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 1, 1, 9, 8, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0}},
+ //YUV444
+ {{ 1, 5, 7, 7, 7, 7,15,11, 8,15,11,15,11,15,11, 7, 4},
+ { 0, 1, 4, 6, 6, 6, 6,14,10,14,10,14,10, 1,14,10, 6},
+ { 0, 0, 1, 5, 5, 5, 5, 5,13, 9,13, 9,13, 9,13, 9, 5},
+ { 0, 0, 0, 3, 3, 4, 4, 4, 4, 4,12,12, 8,12, 8,12, 8}}
+
+ };
+ int yuv = active_sps->chroma_format_idc - 1;
+
+ const int *lt = &lentab[yuv][0][0];
+ const int *ct = &codtab[yuv][0][0];
+
+ retval = code_from_bitstream_2d(sym, dP, lt, ct, 17, 4, &code);
+
+ if (retval)
+ {
+ printf("ERROR: failed to find NumCoeff/TrailingOnes ChromaDC\n");
+ exit(-1);
+ }
+
+
+#if TRACE
+ snprintf(sym->tracestring,
+ TRACESTRING_SIZE, "ChrDC # c & tr.1s #c=%d #t1=%d",
+ sym->value1, sym->value2);
+ tracebits2(sym->tracestring, sym->len, code);
+
+#endif
+
+ return retval;
+}
+
+
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * read Level VLC0 codeword from UVLC-partition
+ ************************************************************************
+ */
+int readSyntaxElement_Level_VLC0(SyntaxElement *sym, struct datapartition *dP)
+{
+ Bitstream *currStream = dP->bitstream;
+ int frame_bitoffset = currStream->frame_bitoffset;
+ byte *buf = currStream->streamBuffer;
+ int BitstreamLengthInBytes = currStream->bitstream_length;
+ int len, sign=0, level=0, code;
+ int offset, addbit;
+
+ len = 0;
+ while (!ShowBits(buf, frame_bitoffset+len, BitstreamLengthInBytes, 1))
+ len++;
+
+ len++;
+ code = 1;
+ frame_bitoffset += len;
+
+ if (len < 15)
+ {
+ sign = (len - 1) & 1;
+ level = (len-1) / 2 + 1;
+ }
+ else if (len == 15)
+ {
+ // escape code
+ code = (code << 4) | ShowBits(buf, frame_bitoffset, BitstreamLengthInBytes, 4);
+ len += 4;
+ frame_bitoffset += 4;
+ sign = (code & 1);
+ level = ((code >> 1) & 0x7) + 8;
+ }
+ else if (len >= 16)
+ {
+ // escape code
+ addbit=len-16;
+ code = ShowBits(buf, frame_bitoffset, BitstreamLengthInBytes, (len-4));
+ len = (len-4);
+ frame_bitoffset += len;
+ sign = (code & 1);
+
+ offset=(2048<<addbit)+16-2048;
+ level = (code >> 1) + offset;
+ code |= (1 << (len)); // for display purpose only
+ len += addbit + 16;
+ }
+
+ if (sign)
+ level = -level;
+
+ sym->inf = level;
+ sym->len = len;
+
+#if TRACE
+ tracebits2(sym->tracestring, sym->len, code);
+#endif
+ currStream->frame_bitoffset = frame_bitoffset;
+ return 0;
+
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * read Level VLC codeword from UVLC-partition
+ ************************************************************************
+ */
+int readSyntaxElement_Level_VLCN(SyntaxElement *sym, int vlc, struct datapartition *dP)
+{
+
+ Bitstream *currStream = dP->bitstream;
+ int frame_bitoffset = currStream->frame_bitoffset;
+ byte *buf = currStream->streamBuffer;
+ int BitstreamLengthInBytes = currStream->bitstream_length;
+
+ int levabs, sign;
+ int len = 0;
+ int code, sb;
+
+ int numPrefix;
+ int shift = vlc-1;
+ int escape = (15<<shift)+1;
+ int addbit, offset;
+
+ // read pre zeros
+ numPrefix = 0;
+ while (!ShowBits(buf, frame_bitoffset+numPrefix, BitstreamLengthInBytes, 1))
+ numPrefix++;
+
+
+ len = numPrefix+1;
+ code = 1;
+
+ if (numPrefix < 15)
+ {
+ levabs = (numPrefix<<shift) + 1;
+
+ // read (vlc-1) bits -> suffix
+ if (vlc-1)
+ {
+ sb = ShowBits(buf, frame_bitoffset+len, BitstreamLengthInBytes, vlc-1);
+ code = (code << (vlc-1) )| sb;
+ levabs += sb;
+ len += (vlc-1);
+ }
+
+ // read 1 bit -> sign
+ sign = ShowBits(buf, frame_bitoffset+len, BitstreamLengthInBytes, 1);
+ code = (code << 1)| sign;
+ len ++;
+ }
+ else // escape
+ {
+ addbit = numPrefix - 15;
+
+ sb = ShowBits(buf, frame_bitoffset+len, BitstreamLengthInBytes, (11+addbit));
+ code = (code << (11+addbit) )| sb;
+
+ len += (11+addbit);
+ offset = (2048<<addbit)+escape-2048;
+ levabs = sb + offset;
+
+ // read 1 bit -> sign
+ sign = ShowBits(buf, frame_bitoffset+len, BitstreamLengthInBytes, 1);
+ code = (code << 1)| sign;
+ len++;
+ }
+
+ sym->inf = (sign)?-levabs:levabs;
+ sym->len = len;
+
+ currStream->frame_bitoffset = frame_bitoffset+len;
+
+#if TRACE
+ tracebits2(sym->tracestring, sym->len, code);
+#endif
+
+ return 0;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * read Total Zeros codeword from UVLC-partition
+ ************************************************************************
+ */
+int readSyntaxElement_TotalZeros(SyntaxElement *sym, DataPartition *dP)
+{
+ int retval;
+ int code;
+
+ static const int lentab[TOTRUN_NUM][16] =
+ {
+
+ { 1,3,3,4,4,5,5,6,6,7,7,8,8,9,9,9},
+ { 3,3,3,3,3,4,4,4,4,5,5,6,6,6,6},
+ { 4,3,3,3,4,4,3,3,4,5,5,6,5,6},
+ { 5,3,4,4,3,3,3,4,3,4,5,5,5},
+ { 4,4,4,3,3,3,3,3,4,5,4,5},
+ { 6,5,3,3,3,3,3,3,4,3,6},
+ { 6,5,3,3,3,2,3,4,3,6},
+ { 6,4,5,3,2,2,3,3,6},
+ { 6,6,4,2,2,3,2,5},
+ { 5,5,3,2,2,2,4},
+ { 4,4,3,3,1,3},
+ { 4,4,2,1,3},
+ { 3,3,1,2},
+ { 2,2,1},
+ { 1,1},
+ };
+
+ static const int codtab[TOTRUN_NUM][16] =
+ {
+ {1,3,2,3,2,3,2,3,2,3,2,3,2,3,2,1},
+ {7,6,5,4,3,5,4,3,2,3,2,3,2,1,0},
+ {5,7,6,5,4,3,4,3,2,3,2,1,1,0},
+ {3,7,5,4,6,5,4,3,3,2,2,1,0},
+ {5,4,3,7,6,5,4,3,2,1,1,0},
+ {1,1,7,6,5,4,3,2,1,1,0},
+ {1,1,5,4,3,3,2,1,1,0},
+ {1,1,1,3,3,2,2,1,0},
+ {1,0,1,3,2,1,1,1,},
+ {1,0,1,3,2,1,1,},
+ {0,1,1,2,1,3},
+ {0,1,1,1,1},
+ {0,1,1,1},
+ {0,1,1},
+ {0,1},
+ };
+
+ int vlcnum = sym->value1;
+
+ const int *lt = &lentab[vlcnum][0];
+ const int *ct = &codtab[vlcnum][0];
+
+ retval = code_from_bitstream_2d(sym, dP, lt, ct, 16, 1, &code);
+
+ if (retval)
+ {
+ printf("ERROR: failed to find Total Zeros\n");
+ exit(-1);
+ }
+
+
+#if TRACE
+ tracebits2(sym->tracestring, sym->len, code);
+
+#endif
+
+ return retval;
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * read Total Zeros Chroma DC codeword from UVLC-partition
+ ************************************************************************
+ */
+int readSyntaxElement_TotalZerosChromaDC(SyntaxElement *sym, DataPartition *dP)
+{
+ int retval;
+ int code;
+
+ static const int lentab[3][TOTRUN_NUM][16] =
+ {
+ //YUV420
+ {{ 1,2,3,3},
+ { 1,2,2},
+ { 1,1}},
+ //YUV422
+ {{ 1,3,3,4,4,4,5,5},
+ { 3,2,3,3,3,3,3},
+ { 3,3,2,2,3,3},
+ { 3,2,2,2,3},
+ { 2,2,2,2},
+ { 2,2,1},
+ { 1,1}},
+ //YUV444
+ {{ 1,3,3,4,4,5,5,6,6,7,7,8,8,9,9,9},
+ { 3,3,3,3,3,4,4,4,4,5,5,6,6,6,6},
+ { 4,3,3,3,4,4,3,3,4,5,5,6,5,6},
+ { 5,3,4,4,3,3,3,4,3,4,5,5,5},
+ { 4,4,4,3,3,3,3,3,4,5,4,5},
+ { 6,5,3,3,3,3,3,3,4,3,6},
+ { 6,5,3,3,3,2,3,4,3,6},
+ { 6,4,5,3,2,2,3,3,6},
+ { 6,6,4,2,2,3,2,5},
+ { 5,5,3,2,2,2,4},
+ { 4,4,3,3,1,3},
+ { 4,4,2,1,3},
+ { 3,3,1,2},
+ { 2,2,1},
+ { 1,1}}
+ };
+
+ static const int codtab[3][TOTRUN_NUM][16] =
+ {
+ //YUV420
+ {{ 1,1,1,0},
+ { 1,1,0},
+ { 1,0}},
+ //YUV422
+ {{ 1,2,3,2,3,1,1,0},
+ { 0,1,1,4,5,6,7},
+ { 0,1,1,2,6,7},
+ { 6,0,1,2,7},
+ { 0,1,2,3},
+ { 0,1,1},
+ { 0,1}},
+ //YUV444
+ {{1,3,2,3,2,3,2,3,2,3,2,3,2,3,2,1},
+ {7,6,5,4,3,5,4,3,2,3,2,3,2,1,0},
+ {5,7,6,5,4,3,4,3,2,3,2,1,1,0},
+ {3,7,5,4,6,5,4,3,3,2,2,1,0},
+ {5,4,3,7,6,5,4,3,2,1,1,0},
+ {1,1,7,6,5,4,3,2,1,1,0},
+ {1,1,5,4,3,3,2,1,1,0},
+ {1,1,1,3,3,2,2,1,0},
+ {1,0,1,3,2,1,1,1,},
+ {1,0,1,3,2,1,1,},
+ {0,1,1,2,1,3},
+ {0,1,1,1,1},
+ {0,1,1,1},
+ {0,1,1},
+ {0,1}}
+ };
+ int yuv = active_sps->chroma_format_idc - 1;
+
+ int vlcnum = sym->value1;
+
+ const int *lt = &lentab[yuv][vlcnum][0];
+ const int *ct = &codtab[yuv][vlcnum][0];
+
+ retval = code_from_bitstream_2d(sym, dP, lt, ct, 16, 1, &code);
+
+ if (retval)
+ {
+ printf("ERROR: failed to find Total Zeros\n");
+ exit(-1);
+ }
+
+
+#if TRACE
+ tracebits2(sym->tracestring, sym->len, code);
+
+#endif
+
+ return retval;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * read Run codeword from UVLC-partition
+ ************************************************************************
+ */
+int readSyntaxElement_Run(SyntaxElement *sym, DataPartition *dP)
+{
+ int retval;
+ int code;
+
+ static const int lentab[TOTRUN_NUM][16] =
+ {
+ {1,1},
+ {1,2,2},
+ {2,2,2,2},
+ {2,2,2,3,3},
+ {2,2,3,3,3,3},
+ {2,3,3,3,3,3,3},
+ {3,3,3,3,3,3,3,4,5,6,7,8,9,10,11},
+ };
+
+ static const int codtab[TOTRUN_NUM][16] =
+ {
+ {1,0},
+ {1,1,0},
+ {3,2,1,0},
+ {3,2,1,1,0},
+ {3,2,3,2,1,0},
+ {3,0,1,3,2,5,4},
+ {7,6,5,4,3,2,1,1,1,1,1,1,1,1,1},
+ };
+
+ int vlcnum = sym->value1;
+
+ const int *lt = &lentab[vlcnum][0];
+ const int *ct = &codtab[vlcnum][0];
+
+ retval = code_from_bitstream_2d(sym, dP, lt, ct, 16, 1, &code);
+
+ if (retval)
+ {
+ printf("ERROR: failed to find Run\n");
+ exit(-1);
+ }
+
+
+#if TRACE
+ tracebits2(sym->tracestring, sym->len, code);
+#endif
+
+ return retval;
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * Reads bits from the bitstream buffer
+ *
+ * \param buffer
+ * containing VLC-coded data bits
+ * \param totbitoffset
+ * bit offset from start of partition
+ * \param info
+ * returns value of the read bits
+ * \param bytecount
+ * total bytes in bitstream
+ * \param numbits
+ * number of bits to read
+ *
+ ************************************************************************
+ */
+int GetBits (byte buffer[],int totbitoffset,int *info, int bytecount,
+ int numbits)
+{
+
+ register int inf;
+ long byteoffset; // byte from start of buffer
+ int bitoffset; // bit from start of byte
+
+ int bitcounter=numbits;
+
+ byteoffset= totbitoffset>>3;
+ bitoffset= 7-(totbitoffset&0x07);
+
+ inf=0;
+ while (numbits)
+ {
+ inf <<=1;
+ inf |= (buffer[byteoffset] & (0x01<<bitoffset))>>bitoffset;
+ numbits--;
+ bitoffset--;
+ if (bitoffset < 0)
+ {
+ byteoffset++;
+ bitoffset += 8;
+ if (byteoffset > bytecount)
+ {
+ return -1;
+ }
+ }
+ }
+
+ *info = inf;
+ return bitcounter; // return absolute offset in bit from start of frame
+}
+
+/*!
+ ************************************************************************
+ * \brief
+ * Reads bits from the bitstream buffer
+ *
+ * \param buffer
+ * buffer containing VLC-coded data bits
+ * \param totbitoffset
+ * bit offset from start of partition
+ * \param bytecount
+ * total bytes in bitstream
+ * \param numbits
+ * number of bits to read
+ *
+ ************************************************************************
+ */
+
+int ShowBits (byte buffer[],int totbitoffset,int bytecount, int numbits)
+{
+
+ register int inf;
+ long byteoffset = totbitoffset>>3; // byte from start of buffer
+ int bitoffset = 7-(totbitoffset&0x07); // bit from start of byte
+
+ inf=0;
+ while (numbits)
+ {
+ inf <<=1;
+ inf |= (buffer[byteoffset] & (0x01<<bitoffset))>>bitoffset;
+ numbits--;
+ bitoffset--;
+ if (bitoffset < 0)
+ {
+ byteoffset++;
+ bitoffset += 8;
+ if (byteoffset > bytecount)
+ {
+ return -1;
+ }
+ }
+ }
+
+ return inf; // return absolute offset in bit from start of frame
+}
+
+
+/*!
+ ************************************************************************
+ * \brief
+ * peek at the next 2 UVLC codeword from UVLC-partition to determine
+ * if a skipped MB is field/frame
+ ************************************************************************
+ */
+int peekSyntaxElement_UVLC(SyntaxElement *sym, struct img_par *img, struct datapartition *dP)
+{
+ Bitstream *currStream = dP->bitstream;
+ int frame_bitoffset = currStream->frame_bitoffset;
+ byte *buf = currStream->streamBuffer;
+ int BitstreamLengthInBytes = currStream->bitstream_length;
+
+
+ sym->len = GetVLCSymbol (buf, frame_bitoffset, &(sym->inf), BitstreamLengthInBytes);
+ if (sym->len == -1)
+ return -1;
+ frame_bitoffset += sym->len;
+ sym->mapping(sym->len,sym->inf,&(sym->value1),&(sym->value2));
+
+
+#if TRACE
+ tracebits(sym->tracestring, sym->len, sym->inf, sym->value1);
+#endif
+
+ return 1;
+}
+
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/vlc.h
diff -u /dev/null llvm-test/MultiSource/Applications/JM/ldecod/vlc.h:1.3
--- /dev/null Sun Feb 4 08:38:53 2007
+++ llvm-test/MultiSource/Applications/JM/ldecod/vlc.h Sun Feb 4 08:38:32 2007
@@ -0,0 +1,56 @@
+
+/*!
+ ************************************************************************
+ * \file vlc.h
+ *
+ * \brief
+ * header for (CA)VLC coding functions
+ *
+ * \author
+ * Karsten Suehring
+ *
+ ************************************************************************
+ */
+
+#ifndef _VLC_H_
+#define _VLC_H_
+
+int se_v (char *tracestring, Bitstream *bitstream);
+int ue_v (char *tracestring, Bitstream *bitstream);
+Boolean u_1 (char *tracestring, Bitstream *bitstream);
+int u_v (int LenInBits, char *tracestring, Bitstream *bitstream);
+
+// UVLC mapping
+void linfo_ue(int len, int info, int *value1, int *dummy);
+void linfo_se(int len, int info, int *value1, int *dummy);
+
+void linfo_cbp_intra(int len,int info,int *cbp, int *dummy);
+void linfo_cbp_inter(int len,int info,int *cbp, int *dummy);
+void linfo_levrun_inter(int len,int info,int *level,int *irun);
+void linfo_levrun_c2x2(int len,int info,int *level,int *irun);
+
+int readSyntaxElement_VLC (SyntaxElement *sym, Bitstream *currStream);
+int readSyntaxElement_UVLC(SyntaxElement *sym, struct img_par *img, struct datapartition *dp);
+int readSyntaxElement_Intra4x4PredictionMode(SyntaxElement *sym, struct img_par *img, struct datapartition *dp);
+
+int GetVLCSymbol (byte buffer[],int totbitoffset,int *info, int bytecount);
+int GetVLCSymbol_IntraMode (byte buffer[],int totbitoffset,int *info, int bytecount);
+
+int readSyntaxElement_FLC(SyntaxElement *sym, Bitstream *currStream);
+int readSyntaxElement_NumCoeffTrailingOnes(SyntaxElement *sym, DataPartition *dP,
+ char *type);
+int readSyntaxElement_NumCoeffTrailingOnesChromaDC(SyntaxElement *sym, DataPartition *dP);
+int readSyntaxElement_Level_VLC0(SyntaxElement *sym, struct datapartition *dP);
+int readSyntaxElement_Level_VLCN(SyntaxElement *sym, int vlc, struct datapartition *dP);
+int readSyntaxElement_TotalZeros(SyntaxElement *sym, DataPartition *dP);
+int readSyntaxElement_TotalZerosChromaDC(SyntaxElement *sym, DataPartition *dP);
+int readSyntaxElement_Run(SyntaxElement *sym, DataPartition *dP);
+int GetBits (byte buffer[],int totbitoffset,int *info, int bytecount,
+ int numbits);
+int ShowBits (byte buffer[],int totbitoffset,int bytecount, int numbits);
+
+int more_rbsp_data (byte buffer[],int totbitoffset,int bytecount);
+
+
+#endif
+
Index: llvm-test/MultiSource/Applications/JM/ldecod/win32.h
diff -c /dev/null llvm-test/MultiSource/Applications/JM/ldecod/win32.h:1.1
*** /dev/null Sun Feb 4 08:38:53 2007
--- llvm-test/MultiSource/Applications/JM/ldecod/win32.h Sun Feb 4 08:38:32 2007
***************
*** 0 ****
--- 1,68 ----
+
+ /*!
+ ************************************************************************
+ * \file
+ * win32.h
+ *
+ * \brief
+ * win32 definitions for H.264 encoder.
+ *
+ * \author
+ *
+ ************************************************************************
+ */
+ #ifndef _WIN32_H_
+ #define _WIN32_H_
+
+ # include <fcntl.h>
+ # include <stdio.h>
+
+ #if defined(WIN32)
+ # include <io.h>
+ # include <sys/types.h>
+ # include <sys/stat.h>
+ # define strcasecmp strcmpi
+
+ # define snprintf _snprintf
+ # define open _open
+ # define close _close
+ # define read _read
+ # define write _write
+ # define lseek _lseeki64
+ # define fsync _commit
+ # define tell _tell
+ # define TIMEB _timeb
+ # define ftime _ftime
+ # 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
+ # define inline _inline
+ #else
+ # include <unistd.h>
+ # define TIMEB timeb
+ # define OPENFLAGS_WRITE O_WRONLY|O_CREAT|O_TRUNC
+ # define OPENFLAGS_READ O_RDONLY
+ # define OPEN_PERMISSIONS S_IRUSR | S_IWUSR
+
+ # if __STDC_VERSION__ >= 199901L
+ /* "inline" is a keyword */
+ # else
+ # define inline /* nothing */
+ # endif
+ #endif
+
+ #if defined(WIN32) && !defined(__GNUC__)
+ typedef __int64 int64;
+ # define FORMAT_OFF_T "I64d"
+ # ifndef INT64_MIN
+ # define INT64_MIN (-9223372036854775807i64 - 1i64)
+ # endif
+ #else
+ typedef long long int64;
+ # define FORMAT_OFF_T "lld"
+ # ifndef INT64_MIN
+ # define INT64_MIN (-9223372036854775807LL - 1LL)
+ # endif
+ #endif
+
+ #endif
More information about the llvm-commits
mailing list