ref: 4e6482e168b7476774e983121f8762016cd45d07
author: Sam Leitch <[email protected]>
date: Wed Nov 27 10:07:35 EST 2013
Initial commit
--- /dev/null
+++ b/.gitignore
@@ -1,0 +1,5 @@
+win/Debug/
+win/Release/
+win/_ReSharper.h264bsd/
+win/ipch/
+win/*.sdf
--- /dev/null
+++ b/README.md
@@ -1,0 +1,12 @@
+# h264bsd
+
+This is a software-based library that was extracted from the Android project with the intention of being used elsewhere.
+
+The only modification that have been made are to remove the top-level API and add an opaque pointer for encoder storage.
+
+The intention is to provide a simple H.264 decoder that can be easily invoked from [ffi](http://en.wikipedia.org/wiki/Foreign_function_interface) systems.
+
+## Directories
+
+*src* Contains the modified source.
+*win* Contains Visual Studio project files for building.
--- /dev/null
+++ b/src/basetype.h
@@ -1,0 +1,53 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BASETYPE_H_INCLUDED
+#define BASETYPE_H_INCLUDED
+
+
+#ifdef __arm
+#define VOLATILE volatile
+#else
+#define VOLATILE
+#endif
+
+typedef unsigned char u8;
+typedef signed char i8;
+typedef unsigned short u16;
+typedef signed short i16;
+typedef unsigned int u32;
+typedef signed int i32;
+
+#if defined(VC1SWDEC_16BIT) || defined(MP4ENC_ARM11)
+typedef unsigned short u16x;
+typedef signed short i16x;
+#else
+typedef unsigned int u16x;
+typedef signed int i16x;
+#endif
+
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+#endif
+
+#endif /* BASETYPE_H_INCLUDED */
--- /dev/null
+++ b/src/h264bsd_byte_stream.c
@@ -1,0 +1,238 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ ExtractNalUnit
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_byte_stream.h"
+#include "h264bsd_util.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+#define BYTE_STREAM_ERROR 0xFFFFFFFF
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ Function name: ExtractNalUnit
+
+ Functional description:
+ Extracts one NAL unit from the byte stream buffer. Removes
+ emulation prevention bytes if present. The original stream buffer
+ is used directly and is therefore modified if emulation prevention
+ bytes are present in the stream.
+
+ Stream buffer is assumed to contain either exactly one NAL unit
+ and nothing else, or one or more NAL units embedded in byte
+ stream format described in the Annex B of the standard. Function
+ detects which one is used based on the first bytes in the buffer.
+
+ Inputs:
+ pByteStream pointer to byte stream buffer
+ len length of the stream buffer (in bytes)
+
+ Outputs:
+ pStrmData stream information is stored here
+ readBytes number of bytes "consumed" from the stream buffer
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK error in byte stream
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdExtractNalUnit(u8 *pByteStream, u32 len, strmData_t *pStrmData,
+ u32 *readBytes)
+{
+
+/* Variables */
+
+ u32 i, tmp;
+ u32 byteCount,initByteCount;
+ u32 zeroCount;
+ u8 byte;
+ u32 hasEmulation = HANTRO_FALSE;
+ u32 invalidStream = HANTRO_FALSE;
+ u8 *readPtr, *writePtr;
+
+/* Code */
+
+ ASSERT(pByteStream);
+ ASSERT(len);
+ ASSERT(len < BYTE_STREAM_ERROR);
+ ASSERT(pStrmData);
+
+ /* byte stream format if starts with 0x000001 or 0x000000 */
+ if (len > 3 && pByteStream[0] == 0x00 && pByteStream[1] == 0x00 &&
+ (pByteStream[2]&0xFE) == 0x00)
+ {
+ /* search for NAL unit start point, i.e. point after first start code
+ * prefix in the stream */
+ zeroCount = byteCount = 2;
+ readPtr = pByteStream + 2;
+ /*lint -e(716) while(1) used consciously */
+ while (1)
+ {
+ byte = *readPtr++;
+ byteCount++;
+
+ if (byteCount == len)
+ {
+ /* no start code prefix found -> error */
+ *readBytes = len;
+ return(HANTRO_NOK);
+ }
+
+ if (!byte)
+ zeroCount++;
+ else if ((byte == 0x01) && (zeroCount >= 2))
+ break;
+ else
+ zeroCount = 0;
+ }
+
+ initByteCount = byteCount;
+
+ /* determine size of the NAL unit. Search for next start code prefix
+ * or end of stream and ignore possible trailing zero bytes */
+ zeroCount = 0;
+ /*lint -e(716) while(1) used consciously */
+ while (1)
+ {
+ byte = *readPtr++;
+ byteCount++;
+ if (!byte)
+ zeroCount++;
+
+ if ( (byte == 0x03) && (zeroCount == 2) )
+ {
+ hasEmulation = HANTRO_TRUE;
+ }
+
+ if ( (byte == 0x01) && (zeroCount >= 2 ) )
+ {
+ pStrmData->strmBuffSize =
+ byteCount - initByteCount - zeroCount - 1;
+ zeroCount -= MIN(zeroCount, 3);
+ break;
+ }
+ else if (byte)
+ {
+ if (zeroCount >= 3)
+ invalidStream = HANTRO_TRUE;
+ zeroCount = 0;
+ }
+
+ if (byteCount == len)
+ {
+ pStrmData->strmBuffSize = byteCount - initByteCount - zeroCount;
+ break;
+ }
+
+ }
+ }
+ /* separate NAL units as input -> just set stream params */
+ else
+ {
+ initByteCount = 0;
+ zeroCount = 0;
+ pStrmData->strmBuffSize = len;
+ hasEmulation = HANTRO_TRUE;
+ }
+
+ pStrmData->pStrmBuffStart = pByteStream + initByteCount;
+ pStrmData->pStrmCurrPos = pStrmData->pStrmBuffStart;
+ pStrmData->bitPosInWord = 0;
+ pStrmData->strmBuffReadBits = 0;
+
+ /* return number of bytes "consumed" */
+ *readBytes = pStrmData->strmBuffSize + initByteCount + zeroCount;
+
+ if (invalidStream)
+ {
+ return(HANTRO_NOK);
+ }
+
+ /* remove emulation prevention bytes before rbsp processing */
+ if (hasEmulation)
+ {
+ tmp = pStrmData->strmBuffSize;
+ readPtr = writePtr = pStrmData->pStrmBuffStart;
+ zeroCount = 0;
+ for (i = tmp; i--;)
+ {
+ if ((zeroCount == 2) && (*readPtr == 0x03))
+ {
+ /* emulation prevention byte shall be followed by one of the
+ * following bytes: 0x00, 0x01, 0x02, 0x03. This implies that
+ * emulation prevention 0x03 byte shall not be the last byte
+ * of the stream. */
+ if ( (i == 0) || (*(readPtr+1) > 0x03) )
+ return(HANTRO_NOK);
+
+ /* do not write emulation prevention byte */
+ readPtr++;
+ zeroCount = 0;
+ }
+ else
+ {
+ /* NAL unit shall not contain byte sequences 0x000000,
+ * 0x000001 or 0x000002 */
+ if ( (zeroCount == 2) && (*readPtr <= 0x02) )
+ return(HANTRO_NOK);
+
+ if (*readPtr == 0)
+ zeroCount++;
+ else
+ zeroCount = 0;
+
+ *writePtr++ = *readPtr++;
+ }
+ }
+
+ /* (readPtr - writePtr) indicates number of "removed" emulation
+ * prevention bytes -> subtract from stream buffer size */
+ pStrmData->strmBuffSize -= (u32)(readPtr - writePtr);
+ }
+
+ return(HANTRO_OK);
+
+}
+
--- /dev/null
+++ b/src/h264bsd_byte_stream.h
@@ -1,0 +1,55 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_BYTE_STREAM_H
+#define H264SWDEC_BYTE_STREAM_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdExtractNalUnit(u8 *pByteStream, u32 len, strmData_t *pStrmData,
+ u32 *readBytes);
+
+#endif /* #ifdef H264SWDEC_BYTE_STREAM_H */
+
--- /dev/null
+++ b/src/h264bsd_cavlc.c
@@ -1,0 +1,917 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ DecodeCoeffToken
+ DecodeLevelPrefix
+ DecodeTotalZeros
+ DecodeRunBefore
+ DecodeResidualBlockCavlc
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_cavlc.h"
+#include "h264bsd_util.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* Following descriptions use term "information field" to represent combination
+ * of certain decoded symbol value and the length of the corresponding variable
+ * length code word. For example, total_zeros information field consists of
+ * 4 bits symbol value (bits [4,7]) along with four bits to represent length
+ * of the VLC code word (bits [0,3]) */
+
+/* macro to obtain length of the coeff token information field, bits [0,4] */
+#define LENGTH_TC(vlc) ((vlc) & 0x1F)
+/* macro to obtain length of the other information fields, bits [0,3] */
+#define LENGTH(vlc) ((vlc) & 0xF)
+/* macro to obtain code word from the information fields, bits [4,7] */
+#define INFO(vlc) (((vlc) >> 4) & 0xF) /* 4 MSB bits contain information */
+/* macro to obtain trailing ones from the coeff token information word,
+ * bits [5,10] */
+#define TRAILING_ONES(coeffToken) ((coeffToken>>5) & 0x3F)
+/* macro to obtain total coeff from the coeff token information word,
+ * bits [11,15] */
+#define TOTAL_COEFF(coeffToken) (((coeffToken) >> 11) & 0x1F)
+
+#define VLC_NOT_FOUND 0xFFFFFFFEU
+
+/* VLC tables for coeff_token. Because of long codes (max. 16 bits) some of the
+ * tables have been splitted into multiple separate tables. Each array/table
+ * element has the following structure:
+ * [5 bits for tot.coeff.] [6 bits for tr.ones] [5 bits for VLC length]
+ * If there is a 0x0000 value, it means that there is not corresponding VLC
+ * codeword for that index. */
+
+/* VLC lengths up to 6 bits, 0 <= nC < 2 */
+static const u16 coeffToken0_0[32] = {
+ 0x0000,0x0000,0x0000,0x2066,0x1026,0x0806,0x1865,0x1865,
+ 0x1043,0x1043,0x1043,0x1043,0x1043,0x1043,0x1043,0x1043,
+ 0x0822,0x0822,0x0822,0x0822,0x0822,0x0822,0x0822,0x0822,
+ 0x0822,0x0822,0x0822,0x0822,0x0822,0x0822,0x0822,0x0822};
+
+/* VLC lengths up to 10 bits, 0 <= nC < 2 */
+static const u16 coeffToken0_1[48] = {
+ 0x0000,0x0000,0x0000,0x0000,0x406a,0x304a,0x282a,0x200a,
+ 0x3869,0x3869,0x2849,0x2849,0x2029,0x2029,0x1809,0x1809,
+ 0x3068,0x3068,0x3068,0x3068,0x2048,0x2048,0x2048,0x2048,
+ 0x1828,0x1828,0x1828,0x1828,0x1008,0x1008,0x1008,0x1008,
+ 0x2867,0x2867,0x2867,0x2867,0x2867,0x2867,0x2867,0x2867,
+ 0x1847,0x1847,0x1847,0x1847,0x1847,0x1847,0x1847,0x1847};
+
+/* VLC lengths up to 14 bits, 0 <= nC < 2 */
+static const u16 coeffToken0_2[56] = {
+ 0x606e,0x584e,0x502e,0x500e,0x586e,0x504e,0x482e,0x480e,
+ 0x400d,0x400d,0x484d,0x484d,0x402d,0x402d,0x380d,0x380d,
+ 0x506d,0x506d,0x404d,0x404d,0x382d,0x382d,0x300d,0x300d,
+ 0x486b,0x486b,0x486b,0x486b,0x486b,0x486b,0x486b,0x486b,
+ 0x384b,0x384b,0x384b,0x384b,0x384b,0x384b,0x384b,0x384b,
+ 0x302b,0x302b,0x302b,0x302b,0x302b,0x302b,0x302b,0x302b,
+ 0x280b,0x280b,0x280b,0x280b,0x280b,0x280b,0x280b,0x280b};
+
+/* VLC lengths up to 16 bits, 0 <= nC < 2 */
+static const u16 coeffToken0_3[32] = {
+ 0x0000,0x0000,0x682f,0x682f,0x8010,0x8050,0x8030,0x7810,
+ 0x8070,0x7850,0x7830,0x7010,0x7870,0x7050,0x7030,0x6810,
+ 0x706f,0x706f,0x684f,0x684f,0x602f,0x602f,0x600f,0x600f,
+ 0x686f,0x686f,0x604f,0x604f,0x582f,0x582f,0x580f,0x580f};
+
+/* VLC lengths up to 6 bits, 2 <= nC < 4 */
+static const u16 coeffToken2_0[32] = {
+ 0x0000,0x0000,0x0000,0x0000,0x3866,0x2046,0x2026,0x1006,
+ 0x3066,0x1846,0x1826,0x0806,0x2865,0x2865,0x1025,0x1025,
+ 0x2064,0x2064,0x2064,0x2064,0x1864,0x1864,0x1864,0x1864,
+ 0x1043,0x1043,0x1043,0x1043,0x1043,0x1043,0x1043,0x1043};
+
+/* VLC lengths up to 9 bits, 2 <= nC < 4 */
+static const u16 coeffToken2_1[32] = {
+ 0x0000,0x0000,0x0000,0x0000,0x4869,0x3849,0x3829,0x3009,
+ 0x2808,0x2808,0x3048,0x3048,0x3028,0x3028,0x2008,0x2008,
+ 0x4067,0x4067,0x4067,0x4067,0x2847,0x2847,0x2847,0x2847,
+ 0x2827,0x2827,0x2827,0x2827,0x1807,0x1807,0x1807,0x1807};
+
+/* VLC lengths up to 14 bits, 2 <= nC < 4 */
+static const u16 coeffToken2_2[128] = {
+ 0x0000,0x0000,0x786d,0x786d,0x806e,0x804e,0x802e,0x800e,
+ 0x782e,0x780e,0x784e,0x702e,0x704d,0x704d,0x700d,0x700d,
+ 0x706d,0x706d,0x684d,0x684d,0x682d,0x682d,0x680d,0x680d,
+ 0x686d,0x686d,0x604d,0x604d,0x602d,0x602d,0x600d,0x600d,
+ 0x580c,0x580c,0x580c,0x580c,0x584c,0x584c,0x584c,0x584c,
+ 0x582c,0x582c,0x582c,0x582c,0x500c,0x500c,0x500c,0x500c,
+ 0x606c,0x606c,0x606c,0x606c,0x504c,0x504c,0x504c,0x504c,
+ 0x502c,0x502c,0x502c,0x502c,0x480c,0x480c,0x480c,0x480c,
+ 0x586b,0x586b,0x586b,0x586b,0x586b,0x586b,0x586b,0x586b,
+ 0x484b,0x484b,0x484b,0x484b,0x484b,0x484b,0x484b,0x484b,
+ 0x482b,0x482b,0x482b,0x482b,0x482b,0x482b,0x482b,0x482b,
+ 0x400b,0x400b,0x400b,0x400b,0x400b,0x400b,0x400b,0x400b,
+ 0x506b,0x506b,0x506b,0x506b,0x506b,0x506b,0x506b,0x506b,
+ 0x404b,0x404b,0x404b,0x404b,0x404b,0x404b,0x404b,0x404b,
+ 0x402b,0x402b,0x402b,0x402b,0x402b,0x402b,0x402b,0x402b,
+ 0x380b,0x380b,0x380b,0x380b,0x380b,0x380b,0x380b,0x380b};
+
+/* VLC lengths up to 6 bits, 4 <= nC < 8 */
+static const u16 coeffToken4_0[64] = {
+ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
+ 0x1806,0x3846,0x3826,0x1006,0x4866,0x3046,0x3026,0x0806,
+ 0x2825,0x2825,0x2845,0x2845,0x2025,0x2025,0x2045,0x2045,
+ 0x1825,0x1825,0x4065,0x4065,0x1845,0x1845,0x1025,0x1025,
+ 0x3864,0x3864,0x3864,0x3864,0x3064,0x3064,0x3064,0x3064,
+ 0x2864,0x2864,0x2864,0x2864,0x2064,0x2064,0x2064,0x2064,
+ 0x1864,0x1864,0x1864,0x1864,0x1044,0x1044,0x1044,0x1044,
+ 0x0824,0x0824,0x0824,0x0824,0x0004,0x0004,0x0004,0x0004};
+
+/* VLC lengths up to 10 bits, 4 <= nC < 8 */
+static const u16 coeffToken4_1[128] = {
+ 0x0000,0x800a,0x806a,0x804a,0x802a,0x780a,0x786a,0x784a,
+ 0x782a,0x700a,0x706a,0x704a,0x702a,0x680a,0x6829,0x6829,
+ 0x6009,0x6009,0x6849,0x6849,0x6029,0x6029,0x5809,0x5809,
+ 0x6869,0x6869,0x6049,0x6049,0x5829,0x5829,0x5009,0x5009,
+ 0x6068,0x6068,0x6068,0x6068,0x5848,0x5848,0x5848,0x5848,
+ 0x5028,0x5028,0x5028,0x5028,0x4808,0x4808,0x4808,0x4808,
+ 0x5868,0x5868,0x5868,0x5868,0x5048,0x5048,0x5048,0x5048,
+ 0x4828,0x4828,0x4828,0x4828,0x4008,0x4008,0x4008,0x4008,
+ 0x3807,0x3807,0x3807,0x3807,0x3807,0x3807,0x3807,0x3807,
+ 0x3007,0x3007,0x3007,0x3007,0x3007,0x3007,0x3007,0x3007,
+ 0x4847,0x4847,0x4847,0x4847,0x4847,0x4847,0x4847,0x4847,
+ 0x2807,0x2807,0x2807,0x2807,0x2807,0x2807,0x2807,0x2807,
+ 0x5067,0x5067,0x5067,0x5067,0x5067,0x5067,0x5067,0x5067,
+ 0x4047,0x4047,0x4047,0x4047,0x4047,0x4047,0x4047,0x4047,
+ 0x4027,0x4027,0x4027,0x4027,0x4027,0x4027,0x4027,0x4027,
+ 0x2007,0x2007,0x2007,0x2007,0x2007,0x2007,0x2007,0x2007};
+
+/* fixed 6 bit length VLC, nC <= 8 */
+static const u16 coeffToken8[64] = {
+ 0x0806,0x0826,0x0000,0x0006,0x1006,0x1026,0x1046,0x0000,
+ 0x1806,0x1826,0x1846,0x1866,0x2006,0x2026,0x2046,0x2066,
+ 0x2806,0x2826,0x2846,0x2866,0x3006,0x3026,0x3046,0x3066,
+ 0x3806,0x3826,0x3846,0x3866,0x4006,0x4026,0x4046,0x4066,
+ 0x4806,0x4826,0x4846,0x4866,0x5006,0x5026,0x5046,0x5066,
+ 0x5806,0x5826,0x5846,0x5866,0x6006,0x6026,0x6046,0x6066,
+ 0x6806,0x6826,0x6846,0x6866,0x7006,0x7026,0x7046,0x7066,
+ 0x7806,0x7826,0x7846,0x7866,0x8006,0x8026,0x8046,0x8066};
+
+/* VLC lengths up to 3 bits, nC == -1 */
+static const u16 coeffTokenMinus1_0[8] = {
+ 0x0000,0x1043,0x0002,0x0002,0x0821,0x0821,0x0821,0x0821};
+
+/* VLC lengths up to 8 bits, nC == -1 */
+static const u16 coeffTokenMinus1_1[32] = {
+ 0x2067,0x2067,0x2048,0x2028,0x1847,0x1847,0x1827,0x1827,
+ 0x2006,0x2006,0x2006,0x2006,0x1806,0x1806,0x1806,0x1806,
+ 0x1006,0x1006,0x1006,0x1006,0x1866,0x1866,0x1866,0x1866,
+ 0x1026,0x1026,0x1026,0x1026,0x0806,0x0806,0x0806,0x0806};
+
+/* VLC tables for total_zeros. One table containing longer code, totalZeros_1,
+ * has been broken into two separate tables. Table elements have the
+ * following structure:
+ * [4 bits for info] [4 bits for VLC length] */
+
+/* VLC lengths up to 5 bits */
+static const u8 totalZeros_1_0[32] = {
+ 0x00,0x00,0x65,0x55,0x44,0x44,0x34,0x34,
+ 0x23,0x23,0x23,0x23,0x13,0x13,0x13,0x13,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01};
+
+/* VLC lengths up to 9 bits */
+static const u8 totalZeros_1_1[32] = {
+ 0x00,0xf9,0xe9,0xd9,0xc8,0xc8,0xb8,0xb8,
+ 0xa7,0xa7,0xa7,0xa7,0x97,0x97,0x97,0x97,
+ 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,
+ 0x76,0x76,0x76,0x76,0x76,0x76,0x76,0x76};
+
+static const u8 totalZeros_2[64] = {
+ 0xe6,0xd6,0xc6,0xb6,0xa5,0xa5,0x95,0x95,
+ 0x84,0x84,0x84,0x84,0x74,0x74,0x74,0x74,
+ 0x64,0x64,0x64,0x64,0x54,0x54,0x54,0x54,
+ 0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03};
+
+static const u8 totalZeros_3[64] = {
+ 0xd6,0xb6,0xc5,0xc5,0xa5,0xa5,0x95,0x95,
+ 0x84,0x84,0x84,0x84,0x54,0x54,0x54,0x54,
+ 0x44,0x44,0x44,0x44,0x04,0x04,0x04,0x04,
+ 0x73,0x73,0x73,0x73,0x73,0x73,0x73,0x73,
+ 0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13};
+
+static const u8 totalZeros_4[32] = {
+ 0xc5,0xb5,0xa5,0x05,0x94,0x94,0x74,0x74,
+ 0x34,0x34,0x24,0x24,0x83,0x83,0x83,0x83,
+ 0x63,0x63,0x63,0x63,0x53,0x53,0x53,0x53,
+ 0x43,0x43,0x43,0x43,0x13,0x13,0x13,0x13};
+
+static const u8 totalZeros_5[32] = {
+ 0xb5,0x95,0xa4,0xa4,0x84,0x84,0x24,0x24,
+ 0x14,0x14,0x04,0x04,0x73,0x73,0x73,0x73,
+ 0x63,0x63,0x63,0x63,0x53,0x53,0x53,0x53,
+ 0x43,0x43,0x43,0x43,0x33,0x33,0x33,0x33};
+
+static const u8 totalZeros_6[64] = {
+ 0xa6,0x06,0x15,0x15,0x84,0x84,0x84,0x84,
+ 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+ 0x73,0x73,0x73,0x73,0x73,0x73,0x73,0x73,
+ 0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,
+ 0x53,0x53,0x53,0x53,0x53,0x53,0x53,0x53,
+ 0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23};
+
+static const u8 totalZeros_7[64] = {
+ 0x96,0x06,0x15,0x15,0x74,0x74,0x74,0x74,
+ 0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,
+ 0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,
+ 0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52};
+
+static const u8 totalZeros_8[64] = {
+ 0x86,0x06,0x25,0x25,0x14,0x14,0x14,0x14,
+ 0x73,0x73,0x73,0x73,0x73,0x73,0x73,0x73,
+ 0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,
+ 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42};
+
+static const u8 totalZeros_9[64] = {
+ 0x16,0x06,0x75,0x75,0x24,0x24,0x24,0x24,
+ 0x53,0x53,0x53,0x53,0x53,0x53,0x53,0x53,
+ 0x62,0x62,0x62,0x62,0x62,0x62,0x62,0x62,
+ 0x62,0x62,0x62,0x62,0x62,0x62,0x62,0x62,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32};
+
+static const u8 totalZeros_10[32] = {
+ 0x15,0x05,0x64,0x64,0x23,0x23,0x23,0x23,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,
+ 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32};
+
+static const u8 totalZeros_11[16] = {
+ 0x04,0x14,0x23,0x23,0x33,0x33,0x53,0x53,
+ 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41};
+
+static const u8 totalZeros_12[16] = {
+ 0x04,0x14,0x43,0x43,0x22,0x22,0x22,0x22,
+ 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31};
+
+static const u8 totalZeros_13[8] = {0x03,0x13,0x32,0x32,0x21,0x21,0x21,0x21};
+
+static const u8 totalZeros_14[4] = {0x02,0x12,0x21,0x21};
+
+/* VLC tables for run_before. Table elements have the following structure:
+ * [4 bits for info] [4bits for VLC length]
+ */
+
+static const u8 runBefore_6[8] = {0x13,0x23,0x43,0x33,0x63,0x53,0x02,0x02};
+
+static const u8 runBefore_5[8] = {0x53,0x43,0x33,0x23,0x12,0x12,0x02,0x02};
+
+static const u8 runBefore_4[8] = {0x43,0x33,0x22,0x22,0x12,0x12,0x02,0x02};
+
+static const u8 runBefore_3[4] = {0x32,0x22,0x12,0x02};
+
+static const u8 runBefore_2[4] = {0x22,0x12,0x01,0x01};
+
+static const u8 runBefore_1[2] = {0x11,0x01};
+
+/* following four macros are used to handle stream buffer "cache" in the CAVLC
+ * decoding function */
+
+/* macro to initialize stream buffer cache, fills the buffer (32 bits) */
+#define BUFFER_INIT(value, bits) \
+{ \
+ bits = 32; \
+ value = h264bsdShowBits32(pStrmData); \
+}
+
+/* macro to read numBits bits from the buffer, bits will be written to
+ * outVal. Refills the buffer if not enough bits left */
+#define BUFFER_SHOW(value, bits, outVal, numBits) \
+{ \
+ if (bits < (numBits)) \
+ { \
+ if(h264bsdFlushBits(pStrmData,32-bits) == END_OF_STREAM) \
+ return(HANTRO_NOK); \
+ value = h264bsdShowBits32(pStrmData); \
+ bits = 32; \
+ } \
+ (outVal) = value >> (32 - (numBits)); \
+}
+
+/* macro to flush numBits bits from the buffer */
+#define BUFFER_FLUSH(value, bits, numBits) \
+{ \
+ value <<= (numBits); \
+ bits -= (numBits); \
+}
+
+/* macro to read and flush numBits bits from the buffer, bits will be written
+ * to outVal. Refills the buffer if not enough bits left */
+#define BUFFER_GET(value, bits, outVal, numBits) \
+{ \
+ if (bits < (numBits)) \
+ { \
+ if(h264bsdFlushBits(pStrmData,32-bits) == END_OF_STREAM) \
+ return(HANTRO_NOK); \
+ value = h264bsdShowBits32(pStrmData); \
+ bits = 32; \
+ } \
+ (outVal) = value >> (32 - (numBits)); \
+ value <<= (numBits); \
+ bits -= (numBits); \
+}
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 DecodeCoeffToken(u32 bits, u32 nc);
+
+static u32 DecodeLevelPrefix(u32 bits);
+
+static u32 DecodeTotalZeros(u32 bits, u32 totalCoeff, u32 isChromaDC);
+
+static u32 DecodeRunBefore(u32 bits,u32 zerosLeft);
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeCoeffToken
+
+ Functional description:
+ Function to decode coeff_token information field from the stream.
+
+ Inputs:
+ u32 bits next 16 stream bits
+ u32 nc nC, see standard for details
+
+ Outputs:
+ u32 information field (11 bits for value, 5 bits for length)
+
+------------------------------------------------------------------------------*/
+
+u32 DecodeCoeffToken(u32 bits, u32 nc)
+{
+
+/* Variables */
+
+ u32 value;
+
+/* Code */
+
+ /* standard defines that nc for decoding of chroma dc coefficients is -1,
+ * represented by u32 here -> -1 maps to 2^32 - 1 */
+ ASSERT(nc <= 16 || nc == (u32)(-1));
+
+ if (nc < 2)
+ {
+ if (bits >= 0x8000)
+ {
+ value = 0x0001;
+ }
+ else if (bits >= 0x0C00)
+ value = coeffToken0_0[bits >> 10];
+ else if (bits >= 0x0100)
+ value = coeffToken0_1[bits >> 6];
+ else if (bits >= 0x0020)
+ value = coeffToken0_2[(bits>>2)-8];
+ else
+ value = coeffToken0_3[bits];
+ }
+ else if (nc < 4)
+ {
+ if (bits >= 0x8000)
+ {
+ value = bits & 0x4000 ? 0x0002 : 0x0822;
+ }
+ else if (bits >= 0x1000)
+ value = coeffToken2_0[bits >> 10];
+ else if (bits >= 0x0200)
+ value = coeffToken2_1[bits >> 7];
+ else
+ value = coeffToken2_2[bits>>2];
+ }
+ else if (nc < 8)
+ {
+ value = coeffToken4_0[bits >> 10];
+ if (!value)
+ value = coeffToken4_1[bits>>6];
+ }
+ else if (nc <= 16)
+ {
+ value = coeffToken8[bits>>10];
+ }
+ else
+ {
+ value = coeffTokenMinus1_0[bits >> 13];
+ if (!value)
+ value = coeffTokenMinus1_1[bits>>8];
+ }
+
+ return(value);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeLevelPrefix
+
+ Functional description:
+ Function to decode level_prefix information field from the stream
+
+ Inputs:
+ u32 bits next 16 stream bits
+
+ Outputs:
+ u32 level_prefix information field or VLC_NOT_FOUND
+
+------------------------------------------------------------------------------*/
+
+u32 DecodeLevelPrefix(u32 bits)
+{
+
+/* Variables */
+
+ u32 numZeros;
+
+/* Code */
+
+ if (bits >= 0x8000)
+ numZeros = 0;
+ else if (bits >= 0x4000)
+ numZeros = 1;
+ else if (bits >= 0x2000)
+ numZeros = 2;
+ else if (bits >= 0x1000)
+ numZeros = 3;
+ else if (bits >= 0x0800)
+ numZeros = 4;
+ else if (bits >= 0x0400)
+ numZeros = 5;
+ else if (bits >= 0x0200)
+ numZeros = 6;
+ else if (bits >= 0x0100)
+ numZeros = 7;
+ else if (bits >= 0x0080)
+ numZeros = 8;
+ else if (bits >= 0x0040)
+ numZeros = 9;
+ else if (bits >= 0x0020)
+ numZeros = 10;
+ else if (bits >= 0x0010)
+ numZeros = 11;
+ else if (bits >= 0x0008)
+ numZeros = 12;
+ else if (bits >= 0x0004)
+ numZeros = 13;
+ else if (bits >= 0x0002)
+ numZeros = 14;
+ else if (bits >= 0x0001)
+ numZeros = 15;
+ else /* more than 15 zeros encountered which is an error */
+ return(VLC_NOT_FOUND);
+
+ return(numZeros);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeTotalZeros
+
+ Functional description:
+ Function to decode total_zeros information field from the stream
+
+ Inputs:
+ u32 bits next 9 stream bits
+ u32 totalCoeff total number of coefficients for the block
+ being decoded
+ u32 isChromaDC flag to indicate chroma DC block
+
+ Outputs:
+ u32 information field (4 bits value, 4 bits length)
+
+------------------------------------------------------------------------------*/
+
+u32 DecodeTotalZeros(u32 bits, u32 totalCoeff, u32 isChromaDC)
+{
+
+/* Variables */
+
+ u32 value = 0x0;
+
+/* Code */
+
+ ASSERT(totalCoeff);
+
+ if (!isChromaDC)
+ {
+ ASSERT(totalCoeff < 16);
+ switch (totalCoeff)
+ {
+ case 1:
+ value = totalZeros_1_0[bits >> 4];
+ if (!value)
+ value = totalZeros_1_1[bits];
+ break;
+
+ case 2:
+ value = totalZeros_2[bits >> 3];
+ break;
+
+ case 3:
+ value = totalZeros_3[bits >> 3];
+ break;
+
+ case 4:
+ value = totalZeros_4[bits >> 4];
+ break;
+
+ case 5:
+ value = totalZeros_5[bits >> 4];
+ break;
+
+ case 6:
+ value = totalZeros_6[bits >> 3];
+ break;
+
+ case 7:
+ value = totalZeros_7[bits >> 3];
+ break;
+
+ case 8:
+ value = totalZeros_8[bits >> 3];
+ break;
+
+ case 9:
+ value = totalZeros_9[bits >> 3];
+ break;
+
+ case 10:
+ value = totalZeros_10[bits >> 4];
+ break;
+
+ case 11:
+ value = totalZeros_11[bits >> 5];
+ break;
+
+ case 12:
+ value = totalZeros_12[bits >> 5];
+ break;
+
+ case 13:
+ value = totalZeros_13[bits >> 6];
+ break;
+
+ case 14:
+ value = totalZeros_14[bits >> 7];
+ break;
+
+ default: /* case 15 */
+ value = (bits >> 8) ? 0x11 : 0x01;
+ break;
+ }
+ }
+ else
+ {
+ ASSERT(totalCoeff < 4);
+ bits >>= 6;
+ if (bits > 3)
+ value = 0x01;
+ else
+ {
+ if (totalCoeff == 3)
+ value = 0x11;
+ else if (bits > 1)
+ {
+ value = 0x12;
+ }
+ else if (totalCoeff == 2)
+ value = 0x22;
+ else if (bits)
+ value = 0x23;
+ else
+ value = 0x33;
+ }
+ }
+
+ return(value);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeRunBefore
+
+ Functional description:
+ Function to decode run_before information field from the stream
+
+ Inputs:
+ u32 bits next 11 stream bits
+ u32 zerosLeft number of zeros left for the current block
+
+ Outputs:
+ u32 information field (4 bits value, 4 bits length)
+
+------------------------------------------------------------------------------*/
+
+u32 DecodeRunBefore(u32 bits, u32 zerosLeft)
+{
+
+/* Variables */
+
+ u32 value = 0x0;
+
+/* Code */
+
+ switch (zerosLeft)
+ {
+ case 1:
+ value = runBefore_1[bits>>10];
+ break;
+
+ case 2:
+ value = runBefore_2[bits>>9];
+ break;
+
+ case 3:
+ value = runBefore_3[bits>>9];
+ break;
+
+ case 4:
+ value = runBefore_4[bits>>8];
+ break;
+
+ case 5:
+ value = runBefore_5[bits>>8];
+ break;
+
+ case 6:
+ value = runBefore_6[bits>>8];
+ break;
+
+ default:
+ if (bits >= 0x100)
+ value = ((7-(bits>>8))<<4)+0x3;
+ else if (bits >= 0x80)
+ value = 0x74;
+ else if (bits >= 0x40)
+ value = 0x85;
+ else if (bits >= 0x20)
+ value = 0x96;
+ else if (bits >= 0x10)
+ value = 0xa7;
+ else if (bits >= 0x8)
+ value = 0xb8;
+ else if (bits >= 0x4)
+ value = 0xc9;
+ else if (bits >= 0x2)
+ value = 0xdA;
+ else if (bits)
+ value = 0xeB;
+ if (INFO(value) > zerosLeft)
+ value = 0;
+ break;
+ }
+
+ return(value);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeResidualBlockCavlc
+
+ Functional description:
+ Function to decode one CAVLC coded block. This corresponds to
+ syntax elements residual_block_cavlc() in the standard.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ nc nC value
+ maxNumCoeff maximum number of residual coefficients
+
+ Outputs:
+ coeffLevel stores decoded coefficient levels
+
+ Returns:
+ numCoeffs on bits [4,11] if successful
+ coeffMap on bits [16,31] if successful, this is bit map
+ where each bit indicates if the corresponding
+ coefficient was zero (0) or non-zero (1)
+ HANTRO_NOK end of stream or error in stream
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeResidualBlockCavlc(
+ strmData_t *pStrmData,
+ i32 *coeffLevel,
+ i32 nc,
+ u32 maxNumCoeff)
+{
+
+/* Variables */
+
+ u32 i, tmp, totalCoeff, trailingOnes, suffixLength, levelPrefix;
+ u32 levelSuffix, zerosLeft, bit;
+ i32 level[16];
+ u32 run[16];
+ /* stream "cache" */
+ u32 bufferValue;
+ u32 bufferBits;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(coeffLevel);
+ ASSERT(nc > -2);
+ ASSERT(maxNumCoeff == 4 || maxNumCoeff == 15 || maxNumCoeff == 16);
+ ASSERT(VLC_NOT_FOUND != END_OF_STREAM);
+
+ /* assume that coeffLevel array has been "cleaned" by caller */
+
+ BUFFER_INIT(bufferValue, bufferBits);
+
+ /*lint -e774 disable lint warning on always false comparison */
+ BUFFER_SHOW(bufferValue, bufferBits, bit, 16);
+ /*lint +e774 */
+ tmp = DecodeCoeffToken(bit, (u32)nc);
+ if (!tmp)
+ return(HANTRO_NOK);
+ BUFFER_FLUSH(bufferValue, bufferBits, LENGTH_TC(tmp));
+
+ totalCoeff = TOTAL_COEFF(tmp);
+ if (totalCoeff > maxNumCoeff)
+ return(HANTRO_NOK);
+ trailingOnes = TRAILING_ONES(tmp);
+
+ if (totalCoeff != 0)
+ {
+ i = 0;
+ /* nonzero coefficients: +/- 1 */
+ if (trailingOnes)
+ {
+ BUFFER_GET(bufferValue, bufferBits, bit, trailingOnes);
+ tmp = 1 << (trailingOnes - 1);
+ for (; tmp; i++)
+ {
+ level[i] = bit & tmp ? -1 : 1;
+ tmp >>= 1;
+ }
+ }
+
+ /* other levels */
+ if (totalCoeff > 10 && trailingOnes < 3)
+ suffixLength = 1;
+ else
+ suffixLength = 0;
+
+ for (; i < totalCoeff; i++)
+ {
+ BUFFER_SHOW(bufferValue, bufferBits, bit, 16);
+ levelPrefix = DecodeLevelPrefix(bit);
+ if (levelPrefix == VLC_NOT_FOUND)
+ return(HANTRO_NOK);
+ BUFFER_FLUSH(bufferValue, bufferBits, levelPrefix+1);
+
+ if (levelPrefix < 14)
+ tmp = suffixLength;
+ else if (levelPrefix == 14)
+ {
+ tmp = suffixLength ? suffixLength : 4;
+ }
+ else
+ {
+ /* setting suffixLength to 1 here corresponds to adding 15
+ * to levelCode value if levelPrefix == 15 and
+ * suffixLength == 0 */
+ if (!suffixLength)
+ suffixLength = 1;
+ tmp = 12;
+ }
+
+ if (suffixLength)
+ levelPrefix <<= suffixLength;
+
+ if (tmp)
+ {
+ BUFFER_GET(bufferValue, bufferBits, levelSuffix, tmp);
+ levelPrefix += levelSuffix;
+ }
+
+ tmp = levelPrefix;
+
+ if (i == trailingOnes && trailingOnes < 3)
+ tmp += 2;
+
+ level[i] = (tmp+2)>>1;
+
+ if (suffixLength == 0)
+ suffixLength = 1;
+
+ if ((level[i] > (3 << (suffixLength - 1))) && suffixLength < 6)
+ suffixLength++;
+
+ if (tmp & 0x1)
+ level[i] = -level[i];
+ }
+
+ /* zero runs */
+ if (totalCoeff < maxNumCoeff)
+ {
+ BUFFER_SHOW(bufferValue, bufferBits, bit,9);
+ zerosLeft = DecodeTotalZeros(bit, totalCoeff,
+ (u32)(maxNumCoeff == 4));
+ if (!zerosLeft)
+ return(HANTRO_NOK);
+ BUFFER_FLUSH(bufferValue, bufferBits, LENGTH(zerosLeft));
+ zerosLeft = INFO(zerosLeft);
+ }
+ else
+ zerosLeft = 0;
+
+ for (i = 0; i < totalCoeff - 1; i++)
+ {
+ if (zerosLeft > 0)
+ {
+ BUFFER_SHOW(bufferValue, bufferBits, bit,11);
+ tmp = DecodeRunBefore(bit, zerosLeft);
+ if (!tmp)
+ return(HANTRO_NOK);
+ BUFFER_FLUSH(bufferValue, bufferBits, LENGTH(tmp));
+ run[i] = INFO(tmp);
+ zerosLeft -= run[i]++;
+ }
+ else
+ {
+ run[i] = 1;
+ }
+ }
+
+ /* combining level and run, levelSuffix variable used to hold coeffMap,
+ * i.e. bit map indicating which coefficients had non-zero value. */
+
+ /*lint -esym(771,level,run) level and run are always initialized */
+ tmp = zerosLeft;
+ coeffLevel[tmp] = level[totalCoeff-1];
+ levelSuffix = 1 << tmp;
+ for (i = totalCoeff-1; i--;)
+ {
+ tmp += run[i];
+ levelSuffix |= 1 << tmp;
+ coeffLevel[tmp] = level[i];
+ }
+
+ }
+ else
+ levelSuffix = 0;
+
+ if (h264bsdFlushBits(pStrmData, 32-bufferBits) != HANTRO_OK)
+ return(HANTRO_NOK);
+
+ return((totalCoeff << 4) | (levelSuffix << 16));
+}
+
--- /dev/null
+++ b/src/h264bsd_cavlc.h
@@ -1,0 +1,59 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_CAVLC_H
+#define H264SWDEC_CAVLC_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeResidualBlockCavlc(
+ strmData_t *pStrmData,
+ i32 *coeffLevel,
+ i32 nc,
+ u32 maxNumCoeff);
+
+#endif /* #ifdef H264SWDEC_CAVLC_H */
+
--- /dev/null
+++ b/src/h264bsd_cfg.h
@@ -1,0 +1,62 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_CFG_H
+#define H264SWDEC_CFG_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include <stdlib.h>
+#include <memory.h>
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+#define MAX_NUM_REF_PICS 16
+#define MAX_NUM_SLICE_GROUPS 8
+#define MAX_NUM_SEQ_PARAM_SETS 32
+#define MAX_NUM_PIC_PARAM_SETS 256
+
+#define _ERROR_PRINT
+#define _DEBUG_PRINT
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+#endif /* #ifdef H264SWDEC_CFG_H */
+
--- /dev/null
+++ b/src/h264bsd_conceal.c
@@ -1,0 +1,627 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdConceal
+ ConcealMb
+ Transform
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_conceal.h"
+#include "h264bsd_util.h"
+#include "h264bsd_reconstruct.h"
+#include "h264bsd_dpb.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*lint -e702 disable lint warning on right shift of signed quantity */
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 ConcealMb(mbStorage_t *pMb, image_t *currImage, u32 row, u32 col,
+ u32 sliceType, u8 *data);
+
+static void Transform(i32 *data);
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdConceal
+
+ Functional description:
+ Perform error concealment for a picture. Two types of concealment
+ is performed based on sliceType:
+ 1) copy from previous picture for P-slices.
+ 2) concealment from neighbour pixels for I-slices
+
+ I-type concealment is based on ideas presented by Jarno Tulkki.
+ The concealment algorithm determines frequency domain coefficients
+ from the neighbour pixels, applies integer transform (the same
+ transform used in the residual processing) and uses the results as
+ pixel values for concealed macroblocks. Transform produces 4x4
+ array and one pixel value has to be used for 4x4 luma blocks and
+ 2x2 chroma blocks.
+
+ Similar concealment is performed for whole picture (the choise
+ of the type is based on last successfully decoded slice header of
+ the picture but it is handled by the calling function). It is
+ acknowledged that this may result in wrong type of concealment
+ when a picture contains both types of slices. However,
+ determination of slice type macroblock-by-macroblock cannot
+ be done due to the fact that it is impossible to know to which
+ slice each corrupted (not successfully decoded) macroblock
+ belongs.
+
+ The error concealment is started by searching the first propoerly
+ decoded macroblock and concealing the row containing the macroblock
+ in question. After that all macroblocks above the row in question
+ are concealed. Finally concealment of rows below is performed.
+ The order of concealment for 4x4 picture where macroblock 9 is the
+ first properly decoded one is as follows (properly decoded
+ macroblocks marked with 'x', numbers indicating the order of
+ concealment):
+
+ 4 6 8 10
+ 3 5 7 9
+ 1 x x 2
+ 11 12 13 14
+
+ If all macroblocks of the picture are lost, the concealment is
+ copy of previous picture for P-type and setting the image to
+ constant gray (pixel value 128) for I-type.
+
+ Concealment sets quantization parameter of the concealed
+ macroblocks to value 40 and macroblock type to intra to enable
+ deblocking filter to smooth the edges of the concealed areas.
+
+ Inputs:
+ pStorage pointer to storage structure
+ currImage pointer to current image structure
+ sliceType type of the slice
+
+ Outputs:
+ currImage concealed macroblocks will be written here
+
+ Returns:
+ HANTRO_OK
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdConceal(storage_t *pStorage, image_t *currImage, u32 sliceType)
+{
+
+/* Variables */
+
+ u32 i, j;
+ u32 row, col;
+ u32 width, height;
+ u8 *refData;
+ mbStorage_t *mb;
+
+/* Code */
+
+ ASSERT(pStorage);
+ ASSERT(currImage);
+
+ DEBUG(("Concealing %s slice\n", IS_I_SLICE(sliceType) ?
+ "intra" : "inter"));
+
+ width = currImage->width;
+ height = currImage->height;
+ refData = NULL;
+ /* use reference picture with smallest available index */
+ if (IS_P_SLICE(sliceType) || (pStorage->intraConcealmentFlag != 0))
+ {
+ i = 0;
+ do
+ {
+ refData = h264bsdGetRefPicData(pStorage->dpb, i);
+ i++;
+ if (i >= 16)
+ break;
+ } while (refData == NULL);
+ }
+
+ i = row = col = 0;
+ /* find first properly decoded macroblock -> start point for concealment */
+ while (i < pStorage->picSizeInMbs && !pStorage->mb[i].decoded)
+ {
+ i++;
+ col++;
+ if (col == width)
+ {
+ row++;
+ col = 0;
+ }
+ }
+
+ /* whole picture lost -> copy previous or set grey */
+ if (i == pStorage->picSizeInMbs)
+ {
+ if ( (IS_I_SLICE(sliceType) && (pStorage->intraConcealmentFlag == 0)) ||
+ refData == NULL)
+ memset(currImage->data, 128, width*height*384);
+ else
+ memcpy(currImage->data, refData, width*height*384);
+
+ pStorage->numConcealedMbs = pStorage->picSizeInMbs;
+
+ /* no filtering if whole picture concealed */
+ for (i = 0; i < pStorage->picSizeInMbs; i++)
+ pStorage->mb[i].disableDeblockingFilterIdc = 1;
+
+ return(HANTRO_OK);
+ }
+
+ /* start from the row containing the first correct macroblock, conceal the
+ * row in question, all rows above that row and then continue downwards */
+ mb = pStorage->mb + row * width;
+ for (j = col; j--;)
+ {
+ ConcealMb(mb+j, currImage, row, j, sliceType, refData);
+ mb[j].decoded = 1;
+ pStorage->numConcealedMbs++;
+ }
+ for (j = col + 1; j < width; j++)
+ {
+ if (!mb[j].decoded)
+ {
+ ConcealMb(mb+j, currImage, row, j, sliceType, refData);
+ mb[j].decoded = 1;
+ pStorage->numConcealedMbs++;
+ }
+ }
+ /* if previous row(s) could not be concealed -> conceal them now */
+ if (row)
+ {
+ for (j = 0; j < width; j++)
+ {
+ i = row - 1;
+ mb = pStorage->mb + i*width + j;
+ do
+ {
+ ConcealMb(mb, currImage, i, j, sliceType, refData);
+ mb->decoded = 1;
+ pStorage->numConcealedMbs++;
+ mb -= width;
+ } while(i--);
+ }
+ }
+
+ /* process rows below the one containing the first correct macroblock */
+ for (i = row + 1; i < height; i++)
+ {
+ mb = pStorage->mb + i * width;
+
+ for (j = 0; j < width; j++)
+ {
+ if (!mb[j].decoded)
+ {
+ ConcealMb(mb+j, currImage, i, j, sliceType, refData);
+ mb[j].decoded = 1;
+ pStorage->numConcealedMbs++;
+ }
+ }
+ }
+
+ return(HANTRO_OK);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: ConcealMb
+
+ Functional description:
+ Perform error concealment for one macroblock, location of the
+ macroblock in the picture indicated by row and col
+
+------------------------------------------------------------------------------*/
+
+u32 ConcealMb(mbStorage_t *pMb, image_t *currImage, u32 row, u32 col,
+ u32 sliceType, u8 *refData)
+{
+
+/* Variables */
+
+ u32 i, j, comp;
+ u32 hor, ver;
+ u32 mbNum;
+ u32 width, height;
+ u8 *mbPos;
+ u8 data[384];
+ u8 *pData;
+ i32 tmp;
+ i32 firstPhase[16];
+ i32 *pTmp;
+ /* neighbours above, below, left and right */
+ i32 a[4], b[4], l[4], r[4];
+ u32 A, B, L, R;
+#ifdef H264DEC_OMXDL
+ u8 fillBuff[32*21 + 15 + 32];
+ u8 *pFill;
+#endif
+/* Code */
+
+ ASSERT(pMb);
+ ASSERT(!pMb->decoded);
+ ASSERT(currImage);
+ ASSERT(col < currImage->width);
+ ASSERT(row < currImage->height);
+
+#ifdef H264DEC_OMXDL
+ pFill = ALIGN(fillBuff, 16);
+#endif
+ width = currImage->width;
+ height = currImage->height;
+ mbNum = row * width + col;
+
+ h264bsdSetCurrImageMbPointers(currImage, mbNum);
+
+ mbPos = currImage->data + row * 16 * width * 16 + col * 16;
+ A = B = L = R = HANTRO_FALSE;
+
+ /* set qpY to 40 to enable some filtering in deblocking (stetson value) */
+ pMb->qpY = 40;
+ pMb->disableDeblockingFilterIdc = 0;
+ /* mbType set to intra to perform filtering despite the values of other
+ * boundary strength determination fields */
+ pMb->mbType = I_4x4;
+ pMb->filterOffsetA = 0;
+ pMb->filterOffsetB = 0;
+ pMb->chromaQpIndexOffset = 0;
+
+ if (IS_I_SLICE(sliceType))
+ memset(data, 0, sizeof(data));
+ else
+ {
+ mv_t mv = {0,0};
+ image_t refImage;
+ refImage.width = width;
+ refImage.height = height;
+ refImage.data = refData;
+ if (refImage.data)
+ {
+#ifndef H264DEC_OMXDL
+ h264bsdPredictSamples(data, &mv, &refImage, col*16, row*16,
+ 0, 0, 16, 16);
+#else
+ h264bsdPredictSamples(data, &mv, &refImage,
+ ((row*16) + ((col*16)<<16)),
+ 0x00001010, pFill);
+#endif
+ h264bsdWriteMacroblock(currImage, data);
+
+ return(HANTRO_OK);
+ }
+ else
+ memset(data, 0, sizeof(data));
+ }
+
+ memset(firstPhase, 0, sizeof(firstPhase));
+
+ /* counter for number of neighbours used */
+ j = 0;
+ hor = ver = 0;
+ if (row && (pMb-width)->decoded)
+ {
+ A = HANTRO_TRUE;
+ pData = mbPos - width*16;
+ a[0] = *pData++; a[0] += *pData++; a[0] += *pData++; a[0] += *pData++;
+ a[1] = *pData++; a[1] += *pData++; a[1] += *pData++; a[1] += *pData++;
+ a[2] = *pData++; a[2] += *pData++; a[2] += *pData++; a[2] += *pData++;
+ a[3] = *pData++; a[3] += *pData++; a[3] += *pData++; a[3] += *pData++;
+ j++;
+ hor++;
+ firstPhase[0] += a[0] + a[1] + a[2] + a[3];
+ firstPhase[1] += a[0] + a[1] - a[2] - a[3];
+ }
+ if ((row != height - 1) && (pMb+width)->decoded)
+ {
+ B = HANTRO_TRUE;
+ pData = mbPos + 16*width*16;
+ b[0] = *pData++; b[0] += *pData++; b[0] += *pData++; b[0] += *pData++;
+ b[1] = *pData++; b[1] += *pData++; b[1] += *pData++; b[1] += *pData++;
+ b[2] = *pData++; b[2] += *pData++; b[2] += *pData++; b[2] += *pData++;
+ b[3] = *pData++; b[3] += *pData++; b[3] += *pData++; b[3] += *pData++;
+ j++;
+ hor++;
+ firstPhase[0] += b[0] + b[1] + b[2] + b[3];
+ firstPhase[1] += b[0] + b[1] - b[2] - b[3];
+ }
+ if (col && (pMb-1)->decoded)
+ {
+ L = HANTRO_TRUE;
+ pData = mbPos - 1;
+ l[0] = pData[0]; l[0] += pData[16*width];
+ l[0] += pData[32*width]; l[0] += pData[48*width];
+ pData += 64*width;
+ l[1] = pData[0]; l[1] += pData[16*width];
+ l[1] += pData[32*width]; l[1] += pData[48*width];
+ pData += 64*width;
+ l[2] = pData[0]; l[2] += pData[16*width];
+ l[2] += pData[32*width]; l[2] += pData[48*width];
+ pData += 64*width;
+ l[3] = pData[0]; l[3] += pData[16*width];
+ l[3] += pData[32*width]; l[3] += pData[48*width];
+ j++;
+ ver++;
+ firstPhase[0] += l[0] + l[1] + l[2] + l[3];
+ firstPhase[4] += l[0] + l[1] - l[2] - l[3];
+ }
+ if ((col != width - 1) && (pMb+1)->decoded)
+ {
+ R = HANTRO_TRUE;
+ pData = mbPos + 16;
+ r[0] = pData[0]; r[0] += pData[16*width];
+ r[0] += pData[32*width]; r[0] += pData[48*width];
+ pData += 64*width;
+ r[1] = pData[0]; r[1] += pData[16*width];
+ r[1] += pData[32*width]; r[1] += pData[48*width];
+ pData += 64*width;
+ r[2] = pData[0]; r[2] += pData[16*width];
+ r[2] += pData[32*width]; r[2] += pData[48*width];
+ pData += 64*width;
+ r[3] = pData[0]; r[3] += pData[16*width];
+ r[3] += pData[32*width]; r[3] += pData[48*width];
+ j++;
+ ver++;
+ firstPhase[0] += r[0] + r[1] + r[2] + r[3];
+ firstPhase[4] += r[0] + r[1] - r[2] - r[3];
+ }
+
+ /* at least one properly decoded neighbour available */
+ ASSERT(j);
+
+ /*lint -esym(644,l,r,a,b) variable initialized above */
+ if (!hor && L && R)
+ firstPhase[1] = (l[0]+l[1]+l[2]+l[3]-r[0]-r[1]-r[2]-r[3]) >> 5;
+ else if (hor)
+ firstPhase[1] >>= (3+hor);
+
+ if (!ver && A && B)
+ firstPhase[4] = (a[0]+a[1]+a[2]+a[3]-b[0]-b[1]-b[2]-b[3]) >> 5;
+ else if (ver)
+ firstPhase[4] >>= (3+ver);
+
+ switch (j)
+ {
+ case 1:
+ firstPhase[0] >>= 4;
+ break;
+
+ case 2:
+ firstPhase[0] >>= 5;
+ break;
+
+ case 3:
+ /* approximate (firstPhase[0]*4/3)>>6 */
+ firstPhase[0] = (21 * firstPhase[0]) >> 10;
+ break;
+
+ default: /* 4 */
+ firstPhase[0] >>= 6;
+ break;
+
+ }
+
+
+ Transform(firstPhase);
+
+ for (i = 0, pData = data, pTmp = firstPhase; i < 256;)
+ {
+ tmp = pTmp[(i & 0xF)>>2];
+ /*lint -e734 CLIP1 macro results in value that fits into 8 bits */
+ *pData++ = CLIP1(tmp);
+ /*lint +e734 */
+
+ i++;
+ if (!(i & 0x3F))
+ pTmp += 4;
+ }
+
+ /* chroma components */
+ mbPos = currImage->data + width * height * 256 +
+ row * 8 * width * 8 + col * 8;
+ for (comp = 0; comp < 2; comp++)
+ {
+
+ memset(firstPhase, 0, sizeof(firstPhase));
+
+ /* counter for number of neighbours used */
+ j = 0;
+ hor = ver = 0;
+ if (A)
+ {
+ pData = mbPos - width*8;
+ a[0] = *pData++; a[0] += *pData++;
+ a[1] = *pData++; a[1] += *pData++;
+ a[2] = *pData++; a[2] += *pData++;
+ a[3] = *pData++; a[3] += *pData++;
+ j++;
+ hor++;
+ firstPhase[0] += a[0] + a[1] + a[2] + a[3];
+ firstPhase[1] += a[0] + a[1] - a[2] - a[3];
+ }
+ if (B)
+ {
+ pData = mbPos + 8*width*8;
+ b[0] = *pData++; b[0] += *pData++;
+ b[1] = *pData++; b[1] += *pData++;
+ b[2] = *pData++; b[2] += *pData++;
+ b[3] = *pData++; b[3] += *pData++;
+ j++;
+ hor++;
+ firstPhase[0] += b[0] + b[1] + b[2] + b[3];
+ firstPhase[1] += b[0] + b[1] - b[2] - b[3];
+ }
+ if (L)
+ {
+ pData = mbPos - 1;
+ l[0] = pData[0]; l[0] += pData[8*width];
+ pData += 16*width;
+ l[1] = pData[0]; l[1] += pData[8*width];
+ pData += 16*width;
+ l[2] = pData[0]; l[2] += pData[8*width];
+ pData += 16*width;
+ l[3] = pData[0]; l[3] += pData[8*width];
+ j++;
+ ver++;
+ firstPhase[0] += l[0] + l[1] + l[2] + l[3];
+ firstPhase[4] += l[0] + l[1] - l[2] - l[3];
+ }
+ if (R)
+ {
+ pData = mbPos + 8;
+ r[0] = pData[0]; r[0] += pData[8*width];
+ pData += 16*width;
+ r[1] = pData[0]; r[1] += pData[8*width];
+ pData += 16*width;
+ r[2] = pData[0]; r[2] += pData[8*width];
+ pData += 16*width;
+ r[3] = pData[0]; r[3] += pData[8*width];
+ j++;
+ ver++;
+ firstPhase[0] += r[0] + r[1] + r[2] + r[3];
+ firstPhase[4] += r[0] + r[1] - r[2] - r[3];
+ }
+ if (!hor && L && R)
+ firstPhase[1] = (l[0]+l[1]+l[2]+l[3]-r[0]-r[1]-r[2]-r[3]) >> 4;
+ else if (hor)
+ firstPhase[1] >>= (2+hor);
+
+ if (!ver && A && B)
+ firstPhase[4] = (a[0]+a[1]+a[2]+a[3]-b[0]-b[1]-b[2]-b[3]) >> 4;
+ else if (ver)
+ firstPhase[4] >>= (2+ver);
+
+ switch (j)
+ {
+ case 1:
+ firstPhase[0] >>= 3;
+ break;
+
+ case 2:
+ firstPhase[0] >>= 4;
+ break;
+
+ case 3:
+ /* approximate (firstPhase[0]*4/3)>>5 */
+ firstPhase[0] = (21 * firstPhase[0]) >> 9;
+ break;
+
+ default: /* 4 */
+ firstPhase[0] >>= 5;
+ break;
+
+ }
+
+ Transform(firstPhase);
+
+ pData = data + 256 + comp*64;
+ for (i = 0, pTmp = firstPhase; i < 64;)
+ {
+ tmp = pTmp[(i & 0x7)>>1];
+ /*lint -e734 CLIP1 macro results in value that fits into 8 bits */
+ *pData++ = CLIP1(tmp);
+ /*lint +e734 */
+
+ i++;
+ if (!(i & 0xF))
+ pTmp += 4;
+ }
+
+ /* increment pointers for cr */
+ mbPos += width * height * 64;
+ }
+
+ h264bsdWriteMacroblock(currImage, data);
+
+ return(HANTRO_OK);
+
+}
+
+
+/*------------------------------------------------------------------------------
+
+ Function name: Transform
+
+ Functional description:
+ Simplified transform, assuming that only dc component and lowest
+ horizontal and lowest vertical component may be non-zero
+
+------------------------------------------------------------------------------*/
+
+void Transform(i32 *data)
+{
+
+ u32 col;
+ i32 tmp0, tmp1;
+
+ if (!data[1] && !data[4])
+ {
+ data[1] = data[2] = data[3] = data[4] = data[5] =
+ data[6] = data[7] = data[8] = data[9] = data[10] =
+ data[11] = data[12] = data[13] = data[14] = data[15] = data[0];
+ return;
+ }
+ /* first horizontal transform for rows 0 and 1 */
+ tmp0 = data[0];
+ tmp1 = data[1];
+ data[0] = tmp0 + tmp1;
+ data[1] = tmp0 + (tmp1>>1);
+ data[2] = tmp0 - (tmp1>>1);
+ data[3] = tmp0 - tmp1;
+
+ tmp0 = data[4];
+ data[5] = tmp0;
+ data[6] = tmp0;
+ data[7] = tmp0;
+
+ /* then vertical transform */
+ for (col = 4; col--; data++)
+ {
+ tmp0 = data[0];
+ tmp1 = data[4];
+ data[0] = tmp0 + tmp1;
+ data[4] = tmp0 + (tmp1>>1);
+ data[8] = tmp0 - (tmp1>>1);
+ data[12] = tmp0 - tmp1;
+ }
+
+}
+/*lint +e702 */
+
--- /dev/null
+++ b/src/h264bsd_conceal.h
@@ -1,0 +1,55 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_CONCEAL_H
+#define H264SWDEC_CONCEAL_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_storage.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdConceal(storage_t *pStorage, image_t *currImage, u32 sliceType);
+
+#endif /* #ifdef H264SWDEC_CONCEAL_H */
+
--- /dev/null
+++ b/src/h264bsd_container.h
@@ -1,0 +1,70 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_CONTAINER_H
+#define H264SWDEC_CONTAINER_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_storage.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/* String length for tracing */
+#define H264DEC_TRACE_STR_LEN 100
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+typedef struct
+{
+ enum {
+ UNINITIALIZED,
+ INITIALIZED,
+ NEW_HEADERS
+ } decStat;
+
+ u32 picNumber;
+ storage_t storage;
+#ifdef H264DEC_TRACE
+ char str[H264DEC_TRACE_STR_LEN];
+#endif
+} decContainer_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+#endif /* #ifdef H264SWDEC_DECCONTAINER_H */
+
--- /dev/null
+++ b/src/h264bsd_deblocking.c
@@ -1,0 +1,2426 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdFilterPicture
+ FilterVerLumaEdge
+ FilterHorLumaEdge
+ FilterHorLuma
+ FilterVerChromaEdge
+ FilterHorChromaEdge
+ FilterHorChroma
+ InnerBoundaryStrength
+ EdgeBoundaryStrength
+ GetBoundaryStrengths
+ IsSliceBoundaryOnLeft
+ IsSliceBoundaryOnTop
+ GetMbFilteringFlags
+ GetLumaEdgeThresholds
+ GetChromaEdgeThresholds
+ FilterLuma
+ FilterChroma
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_util.h"
+#include "h264bsd_macroblock_layer.h"
+#include "h264bsd_deblocking.h"
+#include "h264bsd_dpb.h"
+
+#ifdef H264DEC_OMXDL
+#include "omxtypes.h"
+#include "omxVC.h"
+#include "armVC.h"
+#endif /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* Switch off the following Lint messages for this file:
+ * Info 701: Shift left of signed quantity (int)
+ * Info 702: Shift right of signed quantity (int)
+ */
+/*lint -e701 -e702 */
+
+/* array of alpha values, from the standard */
+static const u8 alphas[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};
+
+/* array of beta values, from the standard */
+static const u8 betas[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};
+
+
+
+#ifndef H264DEC_OMXDL
+/* array of tc0 values, from the standard, each triplet corresponds to a
+ * column in the table. Indexing goes as tc0[indexA][bS-1] */
+static const u8 tc0[52][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,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},{0,0,1},{0,0,1},{0,0,1},{0,1,1},{0,1,1},{1,1,1},
+ {1,1,1},{1,1,1},{1,1,1},{1,1,2},{1,1,2},{1,1,2},{1,1,2},{1,2,3},
+ {1,2,3},{2,2,3},{2,2,4},{2,3,4},{2,3,4},{3,3,5},{3,4,6},{3,4,6},
+ {4,5,7},{4,5,8},{4,6,9},{5,7,10},{6,8,11},{6,8,13},{7,10,14},{8,11,16},
+ {9,12,18},{10,13,20},{11,15,23},{13,17,25}
+};
+#else
+/* array of tc0 values, from the standard, each triplet corresponds to a
+ * column in the table. Indexing goes as tc0[indexA][bS] */
+static const u8 tc0[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, 0}, {0, 0, 0, 1, 0}, {0, 0, 0, 1, 0},
+ {0, 0, 0, 1, 0}, {0, 0, 1, 1, 0}, {0, 0, 1, 1, 0}, {0, 1, 1, 1, 0},
+ {0, 1, 1, 1, 0}, {0, 1, 1, 1, 0}, {0, 1, 1, 1, 0}, {0, 1, 1, 2, 0},
+ {0, 1, 1, 2, 0}, {0, 1, 1, 2, 0}, {0, 1, 1, 2, 0}, {0, 1, 2, 3, 0},
+ {0, 1, 2, 3, 0}, {0, 2, 2, 3, 0}, {0, 2, 2, 4, 0}, {0, 2, 3, 4, 0},
+ {0, 2, 3, 4, 0}, {0, 3, 3, 5, 0}, {0, 3, 4, 6, 0}, {0, 3, 4, 6, 0},
+ {0, 4, 5, 7, 0}, {0, 4, 5, 8, 0}, {0, 4, 6, 9, 0}, {0, 5, 7, 10, 0},
+ {0, 6, 8, 11, 0}, {0, 6, 8, 13, 0}, {0, 7, 10, 14, 0},
+ {0, 8, 11, 16, 0}, {0, 9, 12, 18, 0}, {0, 10, 13, 20, 0},
+ {0, 11, 15, 23, 0}, {0, 13, 17, 25, 0}
+};
+#endif
+
+
+#ifndef H264DEC_OMXDL
+/* mapping of raster scan block index to 4x4 block index */
+static const u32 mb4x4Index[16] =
+ {0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15};
+
+typedef struct {
+ const u8 *tc0;
+ u32 alpha;
+ u32 beta;
+} edgeThreshold_t;
+
+typedef struct {
+ u32 top;
+ u32 left;
+} bS_t;
+
+enum { TOP = 0, LEFT = 1, INNER = 2 };
+#endif /* H264DEC_OMXDL */
+
+#define FILTER_LEFT_EDGE 0x04
+#define FILTER_TOP_EDGE 0x02
+#define FILTER_INNER_EDGE 0x01
+
+
+/* clipping table defined in intra_prediction.c */
+extern const u8 h264bsdClip[];
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 InnerBoundaryStrength(mbStorage_t *mb1, u32 i1, u32 i2);
+
+#ifndef H264DEC_OMXDL
+static u32 EdgeBoundaryStrength(mbStorage_t *mb1, mbStorage_t *mb2,
+ u32 i1, u32 i2);
+#else
+static u32 InnerBoundaryStrength2(mbStorage_t *mb1, u32 i1, u32 i2);
+static u32 EdgeBoundaryStrengthLeft(mbStorage_t *mb1, mbStorage_t *mb2);
+static u32 EdgeBoundaryStrengthTop(mbStorage_t *mb1, mbStorage_t *mb2);
+#endif
+
+static u32 IsSliceBoundaryOnLeft(mbStorage_t *mb);
+
+static u32 IsSliceBoundaryOnTop(mbStorage_t *mb);
+
+static u32 GetMbFilteringFlags(mbStorage_t *mb);
+
+#ifndef H264DEC_OMXDL
+
+static u32 GetBoundaryStrengths(mbStorage_t *mb, bS_t *bs, u32 flags);
+
+static void FilterLuma(u8 *data, bS_t *bS, edgeThreshold_t *thresholds,
+ u32 imageWidth);
+
+static void FilterChroma(u8 *cb, u8 *cr, bS_t *bS, edgeThreshold_t *thresholds,
+ u32 imageWidth);
+
+static void FilterVerLumaEdge( u8 *data, u32 bS, edgeThreshold_t *thresholds,
+ u32 imageWidth);
+static void FilterHorLumaEdge( u8 *data, u32 bS, edgeThreshold_t *thresholds,
+ i32 imageWidth);
+static void FilterHorLuma( u8 *data, u32 bS, edgeThreshold_t *thresholds,
+ i32 imageWidth);
+
+static void FilterVerChromaEdge( u8 *data, u32 bS, edgeThreshold_t *thresholds,
+ u32 imageWidth);
+static void FilterHorChromaEdge( u8 *data, u32 bS, edgeThreshold_t *thresholds,
+ i32 imageWidth);
+static void FilterHorChroma( u8 *data, u32 bS, edgeThreshold_t *thresholds,
+ i32 imageWidth);
+
+static void GetLumaEdgeThresholds(
+ edgeThreshold_t *thresholds,
+ mbStorage_t *mb,
+ u32 filteringFlags);
+
+static void GetChromaEdgeThresholds(
+ edgeThreshold_t *thresholds,
+ mbStorage_t *mb,
+ u32 filteringFlags,
+ i32 chromaQpIndexOffset);
+
+#else /* H264DEC_OMXDL */
+
+static u32 GetBoundaryStrengths(mbStorage_t *mb, u8 (*bs)[16], u32 flags);
+
+static void GetLumaEdgeThresholds(
+ mbStorage_t *mb,
+ u8 (*alpha)[2],
+ u8 (*beta)[2],
+ u8 (*threshold)[16],
+ u8 (*bs)[16],
+ u32 filteringFlags );
+
+static void GetChromaEdgeThresholds(
+ mbStorage_t *mb,
+ u8 (*alpha)[2],
+ u8 (*beta)[2],
+ u8 (*threshold)[8],
+ u8 (*bs)[16],
+ u32 filteringFlags,
+ i32 chromaQpIndexOffset);
+
+#endif /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+
+ Function: IsSliceBoundaryOnLeft
+
+ Functional description:
+ Function to determine if there is a slice boundary on the left side
+ of a macroblock.
+
+------------------------------------------------------------------------------*/
+u32 IsSliceBoundaryOnLeft(mbStorage_t *mb)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(mb && mb->mbA);
+
+ if (mb->sliceId != mb->mbA->sliceId)
+ return(HANTRO_TRUE);
+ else
+ return(HANTRO_FALSE);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: IsSliceBoundaryOnTop
+
+ Functional description:
+ Function to determine if there is a slice boundary above the
+ current macroblock.
+
+------------------------------------------------------------------------------*/
+u32 IsSliceBoundaryOnTop(mbStorage_t *mb)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(mb && mb->mbB);
+
+ if (mb->sliceId != mb->mbB->sliceId)
+ return(HANTRO_TRUE);
+ else
+ return(HANTRO_FALSE);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: GetMbFilteringFlags
+
+ Functional description:
+ Function to determine which edges of a macroblock has to be
+ filtered. Output is a bit-wise OR of FILTER_LEFT_EDGE,
+ FILTER_TOP_EDGE and FILTER_INNER_EDGE, depending on which edges
+ shall be filtered.
+
+------------------------------------------------------------------------------*/
+u32 GetMbFilteringFlags(mbStorage_t *mb)
+{
+
+/* Variables */
+
+ u32 flags = 0;
+
+/* Code */
+
+ ASSERT(mb);
+
+ /* nothing will be filtered if disableDeblockingFilterIdc == 1 */
+ if (mb->disableDeblockingFilterIdc != 1)
+ {
+ flags |= FILTER_INNER_EDGE;
+
+ /* filterLeftMbEdgeFlag, left mb is MB_A */
+ if (mb->mbA &&
+ ((mb->disableDeblockingFilterIdc != 2) ||
+ !IsSliceBoundaryOnLeft(mb)))
+ flags |= FILTER_LEFT_EDGE;
+
+ /* filterTopMbEdgeFlag */
+ if (mb->mbB &&
+ ((mb->disableDeblockingFilterIdc != 2) ||
+ !IsSliceBoundaryOnTop(mb)))
+ flags |= FILTER_TOP_EDGE;
+ }
+
+ return(flags);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: InnerBoundaryStrength
+
+ Functional description:
+ Function to calculate boundary strength value bs for an inner
+ edge of a macroblock. Macroblock type is checked before this is
+ called -> no intra mb condition here.
+
+------------------------------------------------------------------------------*/
+u32 InnerBoundaryStrength(mbStorage_t *mb1, u32 ind1, u32 ind2)
+{
+ i32 tmp1, tmp2;
+ i32 mv1, mv2, mv3, mv4;
+
+ tmp1 = mb1->totalCoeff[ind1];
+ tmp2 = mb1->totalCoeff[ind2];
+ mv1 = mb1->mv[ind1].hor;
+ mv2 = mb1->mv[ind2].hor;
+ mv3 = mb1->mv[ind1].ver;
+ mv4 = mb1->mv[ind2].ver;
+
+ if (tmp1 || tmp2)
+ {
+ return 2;
+ }
+ else if ( ((u32)ABS(mv1 - mv2) >= 4) || ((u32)ABS(mv3 - mv4) >= 4) ||
+ (mb1->refAddr[ind1 >> 2] != mb1->refAddr[ind2 >> 2]) )
+ {
+ return 1;
+ }
+ else
+ return 0;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: InnerBoundaryStrength2
+
+ Functional description:
+ Function to calculate boundary strength value bs for an inner
+ edge of a macroblock. The function is the same as
+ InnerBoundaryStrength but without checking totalCoeff.
+
+------------------------------------------------------------------------------*/
+u32 InnerBoundaryStrength2(mbStorage_t *mb1, u32 ind1, u32 ind2)
+{
+ i32 tmp1, tmp2, tmp3, tmp4;
+
+ tmp1 = mb1->mv[ind1].hor;
+ tmp2 = mb1->mv[ind2].hor;
+ tmp3 = mb1->mv[ind1].ver;
+ tmp4 = mb1->mv[ind2].ver;
+
+ if ( ((u32)ABS(tmp1 - tmp2) >= 4) || ((u32)ABS(tmp3 - tmp4) >= 4) ||
+ (mb1->refAddr[ind1 >> 2] != mb1->refAddr[ind2 >> 2]))
+ {
+ return 1;
+ }
+ else
+ return 0;
+}
+#ifndef H264DEC_OMXDL
+/*------------------------------------------------------------------------------
+
+ Function: EdgeBoundaryStrength
+
+ Functional description:
+ Function to calculate boundary strength value bs for left- or
+ top-most edge of a macroblock. Macroblock types are checked
+ before this is called -> no intra mb conditions here.
+
+------------------------------------------------------------------------------*/
+u32 EdgeBoundaryStrength(mbStorage_t *mb1, mbStorage_t *mb2,
+ u32 ind1, u32 ind2)
+{
+
+ if (mb1->totalCoeff[ind1] || mb2->totalCoeff[ind2])
+ {
+ return 2;
+ }
+ else if ((mb1->refAddr[ind1 >> 2] != mb2->refAddr[ind2 >> 2]) ||
+ ((u32)ABS(mb1->mv[ind1].hor - mb2->mv[ind2].hor) >= 4) ||
+ ((u32)ABS(mb1->mv[ind1].ver - mb2->mv[ind2].ver) >= 4))
+ {
+ return 1;
+ }
+ else
+ return 0;
+}
+
+#else /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+
+ Function: EdgeBoundaryStrengthTop
+
+ Functional description:
+ Function to calculate boundary strength value bs for
+ top-most edge of a macroblock. Macroblock types are checked
+ before this is called -> no intra mb conditions here.
+
+------------------------------------------------------------------------------*/
+u32 EdgeBoundaryStrengthTop(mbStorage_t *mb1, mbStorage_t *mb2)
+{
+ u32 topBs = 0;
+ u32 tmp1, tmp2, tmp3, tmp4;
+
+ tmp1 = mb1->totalCoeff[0];
+ tmp2 = mb2->totalCoeff[10];
+ tmp3 = mb1->totalCoeff[1];
+ tmp4 = mb2->totalCoeff[11];
+ if (tmp1 || tmp2)
+ {
+ topBs = 2<<0;
+ }
+ else if (((u32)ABS(mb1->mv[0].hor - mb2->mv[10].hor) >= 4) ||
+ ((u32)ABS(mb1->mv[0].ver - mb2->mv[10].ver) >= 4) ||
+ (mb1->refAddr[0] != mb2->refAddr[10 >> 2]))
+ {
+ topBs = 1<<0;
+ }
+ tmp1 = mb1->totalCoeff[4];
+ tmp2 = mb2->totalCoeff[14];
+ if (tmp3 || tmp4)
+ {
+ topBs += 2<<8;
+ }
+ else if (((u32)ABS(mb1->mv[1].hor - mb2->mv[11].hor) >= 4) ||
+ ((u32)ABS(mb1->mv[1].ver - mb2->mv[11].ver) >= 4) ||
+ (mb1->refAddr[0] != mb2->refAddr[11 >> 2]))
+ {
+ topBs += 1<<8;
+ }
+ tmp3 = mb1->totalCoeff[5];
+ tmp4 = mb2->totalCoeff[15];
+ if (tmp1 || tmp2)
+ {
+ topBs += 2<<16;
+ }
+ else if (((u32)ABS(mb1->mv[4].hor - mb2->mv[14].hor) >= 4) ||
+ ((u32)ABS(mb1->mv[4].ver - mb2->mv[14].ver) >= 4) ||
+ (mb1->refAddr[4 >> 2] != mb2->refAddr[14 >> 2]))
+ {
+ topBs += 1<<16;
+ }
+ if (tmp3 || tmp4)
+ {
+ topBs += 2<<24;
+ }
+ else if (((u32)ABS(mb1->mv[5].hor - mb2->mv[15].hor) >= 4) ||
+ ((u32)ABS(mb1->mv[5].ver - mb2->mv[15].ver) >= 4) ||
+ (mb1->refAddr[5 >> 2] != mb2->refAddr[15 >> 2]))
+ {
+ topBs += 1<<24;
+ }
+
+ return topBs;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: EdgeBoundaryStrengthLeft
+
+ Functional description:
+ Function to calculate boundary strength value bs for left-
+ edge of a macroblock. Macroblock types are checked
+ before this is called -> no intra mb conditions here.
+
+------------------------------------------------------------------------------*/
+u32 EdgeBoundaryStrengthLeft(mbStorage_t *mb1, mbStorage_t *mb2)
+{
+ u32 leftBs = 0;
+ u32 tmp1, tmp2, tmp3, tmp4;
+
+ tmp1 = mb1->totalCoeff[0];
+ tmp2 = mb2->totalCoeff[5];
+ tmp3 = mb1->totalCoeff[2];
+ tmp4 = mb2->totalCoeff[7];
+
+ if (tmp1 || tmp2)
+ {
+ leftBs = 2<<0;
+ }
+ else if (((u32)ABS(mb1->mv[0].hor - mb2->mv[5].hor) >= 4) ||
+ ((u32)ABS(mb1->mv[0].ver - mb2->mv[5].ver) >= 4) ||
+ (mb1->refAddr[0] != mb2->refAddr[5 >> 2]))
+ {
+ leftBs = 1<<0;
+ }
+ tmp1 = mb1->totalCoeff[8];
+ tmp2 = mb2->totalCoeff[13];
+ if (tmp3 || tmp4)
+ {
+ leftBs += 2<<8;
+ }
+ else if (((u32)ABS(mb1->mv[2].hor - mb2->mv[7].hor) >= 4) ||
+ ((u32)ABS(mb1->mv[2].ver - mb2->mv[7].ver) >= 4) ||
+ (mb1->refAddr[0] != mb2->refAddr[7 >> 2]))
+ {
+ leftBs += 1<<8;
+ }
+ tmp3 = mb1->totalCoeff[10];
+ tmp4 = mb2->totalCoeff[15];
+ if (tmp1 || tmp2)
+ {
+ leftBs += 2<<16;
+ }
+ else if (((u32)ABS(mb1->mv[8].hor - mb2->mv[13].hor) >= 4) ||
+ ((u32)ABS(mb1->mv[8].ver - mb2->mv[13].ver) >= 4) ||
+ (mb1->refAddr[8 >> 2] != mb2->refAddr[13 >> 2]))
+ {
+ leftBs += 1<<16;
+ }
+ if (tmp3 || tmp4)
+ {
+ leftBs += 2<<24;
+ }
+ else if (((u32)ABS(mb1->mv[10].hor - mb2->mv[15].hor) >= 4) ||
+ ((u32)ABS(mb1->mv[10].ver - mb2->mv[15].ver) >= 4) ||
+ (mb1->refAddr[10 >> 2] != mb2->refAddr[15 >> 2]))
+ {
+ leftBs += 1<<24;
+ }
+
+ return leftBs;
+}
+#endif /* H264DEC_OMXDL */
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdFilterPicture
+
+ Functional description:
+ Perform deblocking filtering for a picture. Filter does not copy
+ the original picture anywhere but filtering is performed directly
+ on the original image. Parameters controlling the filtering process
+ are computed based on information in macroblock structures of the
+ filtered macroblock, macroblock above and macroblock on the left of
+ the filtered one.
+
+ Inputs:
+ image pointer to image to be filtered
+ mb pointer to macroblock data structure of the top-left
+ macroblock of the picture
+
+ Outputs:
+ image filtered image stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_OMXDL
+void h264bsdFilterPicture(
+ image_t *image,
+ mbStorage_t *mb)
+{
+
+/* Variables */
+
+ u32 flags;
+ u32 picSizeInMbs, mbRow, mbCol;
+ u32 picWidthInMbs;
+ u8 *data;
+ mbStorage_t *pMb;
+ bS_t bS[16];
+ edgeThreshold_t thresholds[3];
+
+/* Code */
+
+ ASSERT(image);
+ ASSERT(mb);
+ ASSERT(image->data);
+ ASSERT(image->width);
+ ASSERT(image->height);
+
+ picWidthInMbs = image->width;
+ data = image->data;
+ picSizeInMbs = picWidthInMbs * image->height;
+
+ pMb = mb;
+
+ for (mbRow = 0, mbCol = 0; mbRow < image->height; pMb++)
+ {
+ flags = GetMbFilteringFlags(pMb);
+
+ if (flags)
+ {
+ /* GetBoundaryStrengths function returns non-zero value if any of
+ * the bS values for the macroblock being processed was non-zero */
+ if (GetBoundaryStrengths(pMb, bS, flags))
+ {
+ /* luma */
+ GetLumaEdgeThresholds(thresholds, pMb, flags);
+ data = image->data + mbRow * picWidthInMbs * 256 + mbCol * 16;
+
+ FilterLuma((u8*)data, bS, thresholds, picWidthInMbs*16);
+
+ /* chroma */
+ GetChromaEdgeThresholds(thresholds, pMb, flags,
+ pMb->chromaQpIndexOffset);
+ data = image->data + picSizeInMbs * 256 +
+ mbRow * picWidthInMbs * 64 + mbCol * 8;
+
+ FilterChroma((u8*)data, data + 64*picSizeInMbs, bS,
+ thresholds, picWidthInMbs*8);
+
+ }
+ }
+
+ mbCol++;
+ if (mbCol == picWidthInMbs)
+ {
+ mbCol = 0;
+ mbRow++;
+ }
+ }
+
+}
+
+int sample = 0;
+unsigned int hashA = 0;
+unsigned int hashB = 0;
+unsigned int hashC = 0;
+unsigned int hashD = 0;
+
+/*------------------------------------------------------------------------------
+
+ Function: FilterVerLumaEdge
+
+ Functional description:
+ Filter one vertical 4-pixel luma edge.
+
+------------------------------------------------------------------------------*/
+void FilterVerLumaEdge(
+ u8 *data,
+ u32 bS,
+ edgeThreshold_t *thresholds,
+ u32 imageWidth)
+{
+
+/* Variables */
+
+ i32 delta, tc, tmp;
+ u32 i;
+ i32 p0, q0, p1, q1, p2, q2;
+ u32 tmpFlag;
+ const u8 *clp = h264bsdClip + 512;
+
+ u32 alpha = thresholds->alpha;
+ u32 beta = thresholds->beta;
+ i32 val;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(bS && bS <= 4);
+ ASSERT(thresholds);
+
+ if (bS < 4)
+ {
+ tc = thresholds->tc0[bS-1];
+ tmp = tc;
+ for (i = 4; i; i--, data += imageWidth)
+ {
+ p1 = data[-2]; p0 = data[-1];
+ q0 = data[0]; q1 = data[1];
+
+ if ( ((u32)ABS(p0 - q0) < alpha) &&
+ ((u32)ABS(p1 - p0) < beta) &&
+ ((u32)ABS(q1 - q0) < beta) )
+ {
+ p2 = data[-3];
+ q2 = data[2];
+
+ if ((u32)ABS(p2 - p0) < beta)
+ {
+ val = (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1;
+ data[-2] = (p1 + CLIP3(-tc, tc, val));
+ tmp++;
+ }
+
+ if ((u32)ABS(q2 - q0) < beta)
+ {
+ val = (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1;
+ data[1] = (q1 + CLIP3(-tc, tc, val));
+ tmp++;
+ }
+
+ val = (((q0 - p0) << 2) + (p1 - q1) + 4) >> 3;
+ delta = CLIP3(-tmp, tmp, val);
+
+ p0 = clp[p0 + delta];
+ q0 = clp[q0 - delta];
+ tmp = tc;
+ data[-1] = p0;
+ data[ 0] = q0;
+ }
+ // hashA += data[-2] + data[-1] + data[0] + data[1];
+ }
+ }
+ else
+ {
+ for (i = 4; i; i--, data += imageWidth)
+ {
+ p1 = data[-2]; p0 = data[-1];
+ q0 = data[0]; q1 = data[1];
+ if ( ((u32)ABS(p0-q0) < alpha) &&
+ ((u32)ABS(p1-p0) < beta) &&
+ ((u32)ABS(q1-q0) < beta) )
+ {
+ tmpFlag = ((u32)ABS(p0 - q0) < ((alpha >> 2) +2)) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ p2 = data[-3];
+ q2 = data[2];
+
+ if (tmpFlag && (u32)ABS(p2-p0) < beta)
+ {
+ tmp = p1 + p0 + q0;
+ data[-1] = ((p2 + 2 * tmp + q1 + 4) >> 3);
+ data[-2] = ((p2 + tmp + 2) >> 2);
+ data[-3] = ((2 * data[-4] + 3 * p2 + tmp + 4) >> 3);
+ }
+ else
+ data[-1] = (2 * p1 + p0 + q1 + 2) >> 2;
+
+ if (tmpFlag && (u32)ABS(q2-q0) < beta)
+ {
+ tmp = p0 + q0 + q1;
+ data[0] = ((p1 + 2 * tmp + q2 + 4) >> 3);
+ data[1] = ((tmp + q2 + 2) >> 2);
+ data[2] = ((2 * data[3] + 3 * q2 + tmp + 4) >> 3);
+ }
+ else
+ data[0] = ((2 * q1 + q0 + p1 + 2) >> 2);
+ }
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: FilterHorLumaEdge
+
+ Functional description:
+ Filter one horizontal 4-pixel luma edge
+
+------------------------------------------------------------------------------*/
+void FilterHorLumaEdge(
+ u8 *data,
+ u32 bS,
+ edgeThreshold_t *thresholds,
+ i32 imageWidth)
+{
+
+/* Variables */
+
+ i32 delta, tc, tmp;
+ u32 i;
+ u8 p0, q0, p1, q1, p2, q2;
+ const u8 *clp = h264bsdClip + 512;
+ i32 val;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(bS < 4);
+ ASSERT(thresholds);
+
+// if (sample ++ % (1024 * 128) == 0) {
+// printf("Hash A: %d, Hash B: %d\n", hashA, hashB);
+// }
+
+ tc = thresholds->tc0[bS-1];
+ tmp = tc;
+ for (i = 4; i; i--, data++)
+ {
+ p1 = data[-imageWidth*2]; p0 = data[-imageWidth];
+ q0 = data[0]; q1 = data[imageWidth];
+ if ( ((u32)ABS(p0-q0) < thresholds->alpha) &&
+ ((u32)ABS(p1-p0) < thresholds->beta) &&
+ ((u32)ABS(q1-q0) < thresholds->beta) )
+ {
+ p2 = data[-imageWidth*3];
+
+ if ((u32)ABS(p2-p0) < thresholds->beta)
+ {
+ val = (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1;
+ data[-imageWidth*2] = (p1 + CLIP3(-tc, tc, val));
+ tmp++;
+ }
+
+ q2 = data[imageWidth*2];
+
+ if ((u32)ABS(q2-q0) < thresholds->beta)
+ {
+ val = (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1;
+ data[imageWidth] = (q1 + CLIP3(-tc, tc, val));
+ tmp++;
+ }
+
+ val = ((((q0 - p0) << 2) + (p1 - q1) + 4) >> 3);
+ delta = CLIP3(-tmp, tmp, val);
+
+ p0 = clp[p0 + delta];
+ q0 = clp[q0 - delta];
+ tmp = tc;
+ data[-imageWidth] = p0;
+ data[ 0] = q0;
+ }
+
+ // hashB += data[-imageWidth*2] + data[-imageWidth] + data[0] + data[imageWidth];
+ }
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: FilterHorLuma
+
+ Functional description:
+ Filter all four successive horizontal 4-pixel luma edges. This can
+ be done when bS is equal to all four edges.
+
+------------------------------------------------------------------------------*/
+void FilterHorLuma(
+ u8 *data,
+ u32 bS,
+ edgeThreshold_t *thresholds,
+ i32 imageWidth)
+{
+/* Variables */
+
+ i32 delta, tc, tmp;
+ u32 i;
+ i32 p0, q0, p1, q1, p2, q2;
+ u32 tmpFlag;
+ const u8 *clp = h264bsdClip + 512;
+ u32 alpha = thresholds->alpha;
+ u32 beta = thresholds->beta;
+ i32 val;
+/* Code */
+
+ ASSERT(data);
+ ASSERT(bS <= 4);
+ ASSERT(thresholds);
+
+// if (sample ++ % (1024 * 64) == 0) {
+// printf("Hash A: %d, Hash B: %d\n", hashA, hashB);
+// }
+
+ if (bS < 4)
+ {
+ tc = thresholds->tc0[bS-1];
+ tmp = tc;
+ for (i = 16; i; i--, data++)
+ {
+ p1 = data[-imageWidth*2]; p0 = data[-imageWidth];
+ q0 = data[0]; q1 = data[imageWidth];
+ if ( ((u32)ABS(p0 - q0) < alpha) &&
+ ((u32)ABS(p1 - p0) < beta) &&
+ ((u32)ABS(q1 - q0) < beta) )
+ {
+ p2 = data[-imageWidth*3];
+
+ if ((u32)ABS(p2 - p0) < beta)
+ {
+ val = (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1;
+ data[-imageWidth*2] = (u8)(p1 + CLIP3(-tc, tc, val));
+ tmp++;
+ }
+
+ q2 = data[imageWidth*2];
+
+ if ((u32)ABS(q2-q0) < beta)
+ {
+ val = (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1;
+ data[imageWidth] = (u8)(q1 + CLIP3(-tc, tc, val));
+ tmp++;
+ }
+
+ val = ((((q0 - p0) << 2) + (p1 - q1) + 4) >> 3);
+ delta = CLIP3(-tmp, tmp, val);
+
+ p0 = clp[p0 + delta];
+ q0 = clp[q0 - delta];
+ tmp = tc;
+ data[-imageWidth] = p0;
+ data[ 0] = q0;
+ }
+ }
+ }
+ else
+ {
+ for (i = 16; i; i--, data++)
+ {
+ p1 = data[-imageWidth*2]; p0 = data[-imageWidth];
+ q0 = data[0]; q1 = data[imageWidth];
+ if ( ((u32)ABS(p0 - q0) < alpha) &&
+ ((u32)ABS(p1 - p0) < beta) &&
+ ((u32)ABS(q1 - q0) < beta) )
+ {
+ tmpFlag = ((u32)ABS(p0 - q0) < ((alpha >> 2) +2))
+ ? HANTRO_TRUE : HANTRO_FALSE;
+
+ p2 = data[-imageWidth*3];
+ q2 = data[imageWidth*2];
+
+ if (tmpFlag && (u32)ABS(p2 - p0) < beta)
+ {
+ tmp = p1 + p0 + q0;
+ data[-imageWidth] = (u8)((p2 + 2 * tmp + q1 + 4) >> 3);
+ data[-imageWidth*2] = (u8)((p2 + tmp + 2) >> 2);
+ data[-imageWidth*3] = (u8)((2 * data[-imageWidth*4] +
+ 3 * p2 + tmp + 4) >> 3);
+ }
+ else
+ data[-imageWidth] = (u8)((2 * p1 + p0 + q1 + 2) >> 2);
+
+ if (tmpFlag && (u32)ABS(q2 - q0) < beta)
+ {
+ tmp = p0 + q0 + q1;
+ data[ 0] = (u8)((p1 + 2 * tmp + q2 + 4) >> 3);
+ data[imageWidth] = (u8)((tmp + q2 + 2) >> 2);
+ data[imageWidth*2] = (u8)((2 * data[imageWidth*3] +
+ 3 * q2 + tmp + 4) >> 3);
+ }
+ else
+ data[0] = (2 * q1 + q0 + p1 + 2) >> 2;
+ }
+ }
+ }
+
+ // hashA += data[-imageWidth*2] + data[-imageWidth] + data[0] + data[imageWidth];
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: FilterVerChromaEdge
+
+ Functional description:
+ Filter one vertical 2-pixel chroma edge
+
+------------------------------------------------------------------------------*/
+void FilterVerChromaEdge(
+ u8 *data,
+ u32 bS,
+ edgeThreshold_t *thresholds,
+ u32 width)
+{
+
+/* Variables */
+
+ i32 delta, tc;
+ u8 p0, q0, p1, q1;
+ const u8 *clp = h264bsdClip + 512;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(bS <= 4);
+ ASSERT(thresholds);
+
+ p1 = data[-2]; p0 = data[-1];
+ q0 = data[0]; q1 = data[1];
+ if ( ((u32)ABS(p0-q0) < thresholds->alpha) &&
+ ((u32)ABS(p1-p0) < thresholds->beta) &&
+ ((u32)ABS(q1-q0) < thresholds->beta) )
+ {
+ if (bS < 4)
+ {
+ tc = thresholds->tc0[bS-1] + 1;
+ delta = CLIP3(-tc, tc, ((((q0 - p0) << 2) +
+ (p1 - q1) + 4) >> 3));
+ p0 = clp[p0 + delta];
+ q0 = clp[q0 - delta];
+ data[-1] = p0;
+ data[ 0] = q0;
+ }
+ else
+ {
+ data[-1] = (2 * p1 + p0 + q1 + 2) >> 2;
+ data[ 0] = (2 * q1 + q0 + p1 + 2) >> 2;
+ }
+ }
+ data += width;
+ p1 = data[-2]; p0 = data[-1];
+ q0 = data[0]; q1 = data[1];
+ if ( ((u32)ABS(p0-q0) < thresholds->alpha) &&
+ ((u32)ABS(p1-p0) < thresholds->beta) &&
+ ((u32)ABS(q1-q0) < thresholds->beta) )
+ {
+ if (bS < 4)
+ {
+ tc = thresholds->tc0[bS-1] + 1;
+ delta = CLIP3(-tc, tc, ((((q0 - p0) << 2) +
+ (p1 - q1) + 4) >> 3));
+ p0 = clp[p0 + delta];
+ q0 = clp[q0 - delta];
+ data[-1] = p0;
+ data[ 0] = q0;
+ }
+ else
+ {
+ data[-1] = (2 * p1 + p0 + q1 + 2) >> 2;
+ data[ 0] = (2 * q1 + q0 + p1 + 2) >> 2;
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: FilterHorChromaEdge
+
+ Functional description:
+ Filter one horizontal 2-pixel chroma edge
+
+------------------------------------------------------------------------------*/
+void FilterHorChromaEdge(
+ u8 *data,
+ u32 bS,
+ edgeThreshold_t *thresholds,
+ i32 width)
+{
+
+/* Variables */
+
+ i32 delta, tc;
+ u32 i;
+ u8 p0, q0, p1, q1;
+ const u8 *clp = h264bsdClip + 512;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(bS < 4);
+ ASSERT(thresholds);
+
+ tc = thresholds->tc0[bS-1] + 1;
+ for (i = 2; i; i--, data++)
+ {
+ p1 = data[-width*2]; p0 = data[-width];
+ q0 = data[0]; q1 = data[width];
+ if ( ((u32)ABS(p0-q0) < thresholds->alpha) &&
+ ((u32)ABS(p1-p0) < thresholds->beta) &&
+ ((u32)ABS(q1-q0) < thresholds->beta) )
+ {
+ delta = CLIP3(-tc, tc, ((((q0 - p0) << 2) +
+ (p1 - q1) + 4) >> 3));
+ p0 = clp[p0 + delta];
+ q0 = clp[q0 - delta];
+ data[-width] = p0;
+ data[ 0] = q0;
+ }
+ }
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: FilterHorChroma
+
+ Functional description:
+ Filter all four successive horizontal 2-pixel chroma edges. This
+ can be done if bS is equal for all four edges.
+
+------------------------------------------------------------------------------*/
+void FilterHorChroma(
+ u8 *data,
+ u32 bS,
+ edgeThreshold_t *thresholds,
+ i32 width)
+{
+
+/* Variables */
+
+ i32 delta, tc;
+ u32 i;
+ u8 p0, q0, p1, q1;
+ const u8 *clp = h264bsdClip + 512;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(bS <= 4);
+ ASSERT(thresholds);
+
+ if (bS < 4)
+ {
+ tc = thresholds->tc0[bS-1] + 1;
+ for (i = 8; i; i--, data++)
+ {
+ p1 = data[-width*2]; p0 = data[-width];
+ q0 = data[0]; q1 = data[width];
+ if ( ((u32)ABS(p0-q0) < thresholds->alpha) &&
+ ((u32)ABS(p1-p0) < thresholds->beta) &&
+ ((u32)ABS(q1-q0) < thresholds->beta) )
+ {
+ delta = CLIP3(-tc, tc, ((((q0 - p0) << 2) +
+ (p1 - q1) + 4) >> 3));
+ p0 = clp[p0 + delta];
+ q0 = clp[q0 - delta];
+ data[-width] = p0;
+ data[ 0] = q0;
+ }
+ }
+ }
+ else
+ {
+ for (i = 8; i; i--, data++)
+ {
+ p1 = data[-width*2]; p0 = data[-width];
+ q0 = data[0]; q1 = data[width];
+ if ( ((u32)ABS(p0-q0) < thresholds->alpha) &&
+ ((u32)ABS(p1-p0) < thresholds->beta) &&
+ ((u32)ABS(q1-q0) < thresholds->beta) )
+ {
+ data[-width] = (2 * p1 + p0 + q1 + 2) >> 2;
+ data[ 0] = (2 * q1 + q0 + p1 + 2) >> 2;
+ }
+ }
+ }
+
+}
+
+
+void GetBoundaryStrengthsA(mbStorage_t *mb, bS_t *bS) {
+ bS[4].top = mb->totalCoeff[2] || mb->totalCoeff[0] ? 2 : 0;
+ bS[5].top = mb->totalCoeff[3] || mb->totalCoeff[1] ? 2 : 0;
+ bS[6].top = mb->totalCoeff[6] || mb->totalCoeff[4] ? 2 : 0;
+ bS[7].top = mb->totalCoeff[7] || mb->totalCoeff[5] ? 2 : 0;
+ bS[8].top = mb->totalCoeff[8] || mb->totalCoeff[2] ? 2 : 0;
+ bS[9].top = mb->totalCoeff[9] || mb->totalCoeff[3] ? 2 : 0;
+ bS[10].top = mb->totalCoeff[12] || mb->totalCoeff[6] ? 2 : 0;
+ bS[11].top = mb->totalCoeff[13] || mb->totalCoeff[7] ? 2 : 0;
+ bS[12].top = mb->totalCoeff[10] || mb->totalCoeff[8] ? 2 : 0;
+ bS[13].top = mb->totalCoeff[11] || mb->totalCoeff[9] ? 2 : 0;
+ bS[14].top = mb->totalCoeff[14] || mb->totalCoeff[12] ? 2 : 0;
+ bS[15].top = mb->totalCoeff[15] || mb->totalCoeff[13] ? 2 : 0;
+
+ bS[1].left = mb->totalCoeff[1] || mb->totalCoeff[0] ? 2 : 0;
+ bS[2].left = mb->totalCoeff[4] || mb->totalCoeff[1] ? 2 : 0;
+ bS[3].left = mb->totalCoeff[5] || mb->totalCoeff[4] ? 2 : 0;
+ bS[5].left = mb->totalCoeff[3] || mb->totalCoeff[2] ? 2 : 0;
+ bS[6].left = mb->totalCoeff[6] || mb->totalCoeff[3] ? 2 : 0;
+ bS[7].left = mb->totalCoeff[7] || mb->totalCoeff[6] ? 2 : 0;
+ bS[9].left = mb->totalCoeff[9] || mb->totalCoeff[8] ? 2 : 0;
+ bS[10].left = mb->totalCoeff[12] || mb->totalCoeff[9] ? 2 : 0;
+ bS[11].left = mb->totalCoeff[13] || mb->totalCoeff[12] ? 2 : 0;
+ bS[13].left = mb->totalCoeff[11] || mb->totalCoeff[10] ? 2 : 0;
+ bS[14].left = mb->totalCoeff[14] || mb->totalCoeff[11] ? 2 : 0;
+ bS[15].left = mb->totalCoeff[15] || mb->totalCoeff[14] ? 2 : 0;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: GetBoundaryStrengths
+
+ Functional description:
+ Function to calculate boundary strengths for all edges of a
+ macroblock. Function returns HANTRO_TRUE if any of the bS values for
+ the macroblock had non-zero value, HANTRO_FALSE otherwise.
+
+------------------------------------------------------------------------------*/
+u32 GetBoundaryStrengths(mbStorage_t *mb, bS_t *bS, u32 flags)
+{
+
+/* Variables */
+
+ /* this flag is set HANTRO_TRUE as soon as any boundary strength value is
+ * non-zero */
+ u32 nonZeroBs = HANTRO_FALSE;
+
+/* Code */
+
+ ASSERT(mb);
+ ASSERT(bS);
+ ASSERT(flags);
+
+// if (sample ++ % (1024 * 128) == 0) {
+// printf("Hash A: %d, Hash B: %d, Hash C: %d, Hash D: %d\n", hashA, hashB, hashC, hashD);
+// }
+
+ /* top edges */
+ if (flags & FILTER_TOP_EDGE)
+ {
+ if (IS_INTRA_MB(*mb) || IS_INTRA_MB(*mb->mbB))
+ {
+ bS[0].top = bS[1].top = bS[2].top = bS[3].top = 4;
+ nonZeroBs = HANTRO_TRUE;
+ }
+ else
+ {
+ bS[0].top = EdgeBoundaryStrength(mb, mb->mbB, 0, 10);
+ bS[1].top = EdgeBoundaryStrength(mb, mb->mbB, 1, 11);
+ bS[2].top = EdgeBoundaryStrength(mb, mb->mbB, 4, 14);
+ bS[3].top = EdgeBoundaryStrength(mb, mb->mbB, 5, 15);
+ if (bS[0].top || bS[1].top || bS[2].top || bS[3].top)
+ nonZeroBs = HANTRO_TRUE;
+ }
+ }
+ else
+ {
+ bS[0].top = bS[1].top = bS[2].top = bS[3].top = 0;
+ }
+
+ /* left edges */
+ if (flags & FILTER_LEFT_EDGE)
+ {
+ if (IS_INTRA_MB(*mb) || IS_INTRA_MB(*mb->mbA))
+ {
+ bS[0].left = bS[4].left = bS[8].left = bS[12].left = 4;
+ nonZeroBs = HANTRO_TRUE;
+ }
+ else
+ {
+ bS[0].left = EdgeBoundaryStrength(mb, mb->mbA, 0, 5);
+ bS[4].left = EdgeBoundaryStrength(mb, mb->mbA, 2, 7);
+ bS[8].left = EdgeBoundaryStrength(mb, mb->mbA, 8, 13);
+ bS[12].left = EdgeBoundaryStrength(mb, mb->mbA, 10, 15);
+ if (!nonZeroBs &&
+ (bS[0].left || bS[4].left || bS[8].left || bS[12].left))
+ nonZeroBs = HANTRO_TRUE;
+ }
+ }
+ else
+ {
+ bS[0].left = bS[4].left = bS[8].left = bS[12].left = 0;
+ }
+
+ /* inner edges */
+ if (IS_INTRA_MB(*mb))
+ {
+ bS[4].top = bS[5].top = bS[6].top = bS[7].top =
+ bS[8].top = bS[9].top = bS[10].top = bS[11].top =
+ bS[12].top = bS[13].top = bS[14].top = bS[15].top = 3;
+
+ bS[1].left = bS[2].left = bS[3].left =
+ bS[5].left = bS[6].left = bS[7].left =
+ bS[9].left = bS[10].left = bS[11].left =
+ bS[13].left = bS[14].left = bS[15].left = 3;
+ nonZeroBs = HANTRO_TRUE;
+ }
+ else
+ {
+ /* 16x16 inter mb -> ref addresses or motion vectors cannot differ,
+ * only check if either of the blocks contain coefficients */
+ if (h264bsdNumMbPart(mb->mbType) == 1)
+ {
+ GetBoundaryStrengthsA(mb, bS);
+ }
+ /* 16x8 inter mb -> ref addresses and motion vectors can be different
+ * only for the middle horizontal edge, for the other top edges it is
+ * enough to check whether the blocks contain coefficients or not. The
+ * same applies to all internal left edges. */
+ else if (mb->mbType == P_L0_L0_16x8)
+ {
+ bS[4].top = mb->totalCoeff[2] || mb->totalCoeff[0] ? 2 : 0;
+ bS[5].top = mb->totalCoeff[3] || mb->totalCoeff[1] ? 2 : 0;
+ bS[6].top = mb->totalCoeff[6] || mb->totalCoeff[4] ? 2 : 0;
+ bS[7].top = mb->totalCoeff[7] || mb->totalCoeff[5] ? 2 : 0;
+ bS[12].top = mb->totalCoeff[10] || mb->totalCoeff[8] ? 2 : 0;
+ bS[13].top = mb->totalCoeff[11] || mb->totalCoeff[9] ? 2 : 0;
+ bS[14].top = mb->totalCoeff[14] || mb->totalCoeff[12] ? 2 : 0;
+ bS[15].top = mb->totalCoeff[15] || mb->totalCoeff[13] ? 2 : 0;
+ bS[8].top = InnerBoundaryStrength(mb, 8, 2);
+ bS[9].top = InnerBoundaryStrength(mb, 9, 3);
+ bS[10].top = InnerBoundaryStrength(mb, 12, 6);
+ bS[11].top = InnerBoundaryStrength(mb, 13, 7);
+
+ bS[1].left = mb->totalCoeff[1] || mb->totalCoeff[0] ? 2 : 0;
+ bS[2].left = mb->totalCoeff[4] || mb->totalCoeff[1] ? 2 : 0;
+ bS[3].left = mb->totalCoeff[5] || mb->totalCoeff[4] ? 2 : 0;
+ bS[5].left = mb->totalCoeff[3] || mb->totalCoeff[2] ? 2 : 0;
+ bS[6].left = mb->totalCoeff[6] || mb->totalCoeff[3] ? 2 : 0;
+ bS[7].left = mb->totalCoeff[7] || mb->totalCoeff[6] ? 2 : 0;
+ bS[9].left = mb->totalCoeff[9] || mb->totalCoeff[8] ? 2 : 0;
+ bS[10].left = mb->totalCoeff[12] || mb->totalCoeff[9] ? 2 : 0;
+ bS[11].left = mb->totalCoeff[13] || mb->totalCoeff[12] ? 2 : 0;
+ bS[13].left = mb->totalCoeff[11] || mb->totalCoeff[10] ? 2 : 0;
+ bS[14].left = mb->totalCoeff[14] || mb->totalCoeff[11] ? 2 : 0;
+ bS[15].left = mb->totalCoeff[15] || mb->totalCoeff[14] ? 2 : 0;
+ }
+ /* 8x16 inter mb -> ref addresses and motion vectors can be different
+ * only for the middle vertical edge, for the other left edges it is
+ * enough to check whether the blocks contain coefficients or not. The
+ * same applies to all internal top edges. */
+ else if (mb->mbType == P_L0_L0_8x16)
+ {
+ bS[4].top = mb->totalCoeff[2] || mb->totalCoeff[0] ? 2 : 0;
+ bS[5].top = mb->totalCoeff[3] || mb->totalCoeff[1] ? 2 : 0;
+ bS[6].top = mb->totalCoeff[6] || mb->totalCoeff[4] ? 2 : 0;
+ bS[7].top = mb->totalCoeff[7] || mb->totalCoeff[5] ? 2 : 0;
+ bS[8].top = mb->totalCoeff[8] || mb->totalCoeff[2] ? 2 : 0;
+ bS[9].top = mb->totalCoeff[9] || mb->totalCoeff[3] ? 2 : 0;
+ bS[10].top = mb->totalCoeff[12] || mb->totalCoeff[6] ? 2 : 0;
+ bS[11].top = mb->totalCoeff[13] || mb->totalCoeff[7] ? 2 : 0;
+ bS[12].top = mb->totalCoeff[10] || mb->totalCoeff[8] ? 2 : 0;
+ bS[13].top = mb->totalCoeff[11] || mb->totalCoeff[9] ? 2 : 0;
+ bS[14].top = mb->totalCoeff[14] || mb->totalCoeff[12] ? 2 : 0;
+ bS[15].top = mb->totalCoeff[15] || mb->totalCoeff[13] ? 2 : 0;
+
+ bS[1].left = mb->totalCoeff[1] || mb->totalCoeff[0] ? 2 : 0;
+ bS[3].left = mb->totalCoeff[5] || mb->totalCoeff[4] ? 2 : 0;
+ bS[5].left = mb->totalCoeff[3] || mb->totalCoeff[2] ? 2 : 0;
+ bS[7].left = mb->totalCoeff[7] || mb->totalCoeff[6] ? 2 : 0;
+ bS[9].left = mb->totalCoeff[9] || mb->totalCoeff[8] ? 2 : 0;
+ bS[11].left = mb->totalCoeff[13] || mb->totalCoeff[12] ? 2 : 0;
+ bS[13].left = mb->totalCoeff[11] || mb->totalCoeff[10] ? 2 : 0;
+ bS[15].left = mb->totalCoeff[15] || mb->totalCoeff[14] ? 2 : 0;
+ bS[2].left = InnerBoundaryStrength(mb, 4, 1);
+ bS[6].left = InnerBoundaryStrength(mb, 6, 3);
+ bS[10].left = InnerBoundaryStrength(mb, 12, 9);
+ bS[14].left = InnerBoundaryStrength(mb, 14, 11);
+ }
+ else
+ {
+ bS[4].top = InnerBoundaryStrength(mb, mb4x4Index[4], mb4x4Index[0]);
+ bS[5].top = InnerBoundaryStrength(mb, mb4x4Index[5], mb4x4Index[1]);
+ bS[6].top = InnerBoundaryStrength(mb, mb4x4Index[6], mb4x4Index[2]);
+ bS[7].top = InnerBoundaryStrength(mb, mb4x4Index[7], mb4x4Index[3]);
+ bS[8].top = InnerBoundaryStrength(mb, mb4x4Index[8], mb4x4Index[4]);
+ bS[9].top = InnerBoundaryStrength(mb, mb4x4Index[9], mb4x4Index[5]);
+ bS[10].top = InnerBoundaryStrength(mb, mb4x4Index[10], mb4x4Index[6]);
+ bS[11].top = InnerBoundaryStrength(mb, mb4x4Index[11], mb4x4Index[7]);
+ bS[12].top = InnerBoundaryStrength(mb, mb4x4Index[12], mb4x4Index[8]);
+ bS[13].top = InnerBoundaryStrength(mb, mb4x4Index[13], mb4x4Index[9]);
+ bS[14].top = InnerBoundaryStrength(mb, mb4x4Index[14], mb4x4Index[10]);
+ bS[15].top = InnerBoundaryStrength(mb, mb4x4Index[15], mb4x4Index[11]);
+
+ bS[1].left = InnerBoundaryStrength(mb, mb4x4Index[1], mb4x4Index[0]);
+ bS[2].left = InnerBoundaryStrength(mb, mb4x4Index[2], mb4x4Index[1]);
+ bS[3].left = InnerBoundaryStrength(mb, mb4x4Index[3], mb4x4Index[2]);
+ bS[5].left = InnerBoundaryStrength(mb, mb4x4Index[5], mb4x4Index[4]);
+ bS[6].left = InnerBoundaryStrength(mb, mb4x4Index[6], mb4x4Index[5]);
+ bS[7].left = InnerBoundaryStrength(mb, mb4x4Index[7], mb4x4Index[6]);
+ bS[9].left = InnerBoundaryStrength(mb, mb4x4Index[9], mb4x4Index[8]);
+ bS[10].left = InnerBoundaryStrength(mb, mb4x4Index[10], mb4x4Index[9]);
+ bS[11].left = InnerBoundaryStrength(mb, mb4x4Index[11], mb4x4Index[10]);
+ bS[13].left = InnerBoundaryStrength(mb, mb4x4Index[13], mb4x4Index[12]);
+ bS[14].left = InnerBoundaryStrength(mb, mb4x4Index[14], mb4x4Index[13]);
+ bS[15].left = InnerBoundaryStrength(mb, mb4x4Index[15], mb4x4Index[14]);
+ }
+ if (!nonZeroBs &&
+ (bS[4].top || bS[5].top || bS[6].top || bS[7].top ||
+ bS[8].top || bS[9].top || bS[10].top || bS[11].top ||
+ bS[12].top || bS[13].top || bS[14].top || bS[15].top ||
+ bS[1].left || bS[2].left || bS[3].left ||
+ bS[5].left || bS[6].left || bS[7].left ||
+ bS[9].left || bS[10].left || bS[11].left ||
+ bS[13].left || bS[14].left || bS[15].left))
+ nonZeroBs = HANTRO_TRUE;
+ }
+
+ return(nonZeroBs);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: GetLumaEdgeThresholds
+
+ Functional description:
+ Compute alpha, beta and tc0 thresholds for inner, left and top
+ luma edges of a macroblock.
+
+------------------------------------------------------------------------------*/
+void GetLumaEdgeThresholds(
+ edgeThreshold_t *thresholds,
+ mbStorage_t *mb,
+ u32 filteringFlags)
+{
+
+/* Variables */
+
+ u32 indexA, indexB;
+ u32 qpAv, qp, qpTmp;
+
+/* Code */
+
+ ASSERT(thresholds);
+ ASSERT(mb);
+
+ qp = mb->qpY;
+
+ indexA = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetB);
+
+ thresholds[INNER].alpha = alphas[indexA];
+ thresholds[INNER].beta = betas[indexB];
+ thresholds[INNER].tc0 = tc0[indexA];
+
+ if (filteringFlags & FILTER_TOP_EDGE)
+ {
+ qpTmp = mb->mbB->qpY;
+ if (qpTmp != qp)
+ {
+ qpAv = (qp + qpTmp + 1) >> 1;
+
+ indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
+
+ thresholds[TOP].alpha = alphas[indexA];
+ thresholds[TOP].beta = betas[indexB];
+ thresholds[TOP].tc0 = tc0[indexA];
+ }
+ else
+ {
+ thresholds[TOP].alpha = thresholds[INNER].alpha;
+ thresholds[TOP].beta = thresholds[INNER].beta;
+ thresholds[TOP].tc0 = thresholds[INNER].tc0;
+ }
+ }
+ if (filteringFlags & FILTER_LEFT_EDGE)
+ {
+ qpTmp = mb->mbA->qpY;
+ if (qpTmp != qp)
+ {
+ qpAv = (qp + qpTmp + 1) >> 1;
+
+ indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
+
+ thresholds[LEFT].alpha = alphas[indexA];
+ thresholds[LEFT].beta = betas[indexB];
+ thresholds[LEFT].tc0 = tc0[indexA];
+ }
+ else
+ {
+ thresholds[LEFT].alpha = thresholds[INNER].alpha;
+ thresholds[LEFT].beta = thresholds[INNER].beta;
+ thresholds[LEFT].tc0 = thresholds[INNER].tc0;
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: GetChromaEdgeThresholds
+
+ Functional description:
+ Compute alpha, beta and tc0 thresholds for inner, left and top
+ chroma edges of a macroblock.
+
+------------------------------------------------------------------------------*/
+void GetChromaEdgeThresholds(
+ edgeThreshold_t *thresholds,
+ mbStorage_t *mb,
+ u32 filteringFlags,
+ i32 chromaQpIndexOffset)
+{
+
+/* Variables */
+
+ u32 indexA, indexB;
+ u32 qpAv, qp, qpTmp;
+
+/* Code */
+
+ ASSERT(thresholds);
+ ASSERT(mb);
+
+ qp = mb->qpY;
+ qp = h264bsdQpC[CLIP3(0, 51, (i32)qp + chromaQpIndexOffset)];
+
+ indexA = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetB);
+
+ thresholds[INNER].alpha = alphas[indexA];
+ thresholds[INNER].beta = betas[indexB];
+ thresholds[INNER].tc0 = tc0[indexA];
+
+ if (filteringFlags & FILTER_TOP_EDGE)
+ {
+ qpTmp = mb->mbB->qpY;
+ if (qpTmp != mb->qpY)
+ {
+ qpTmp = h264bsdQpC[CLIP3(0, 51, (i32)qpTmp + chromaQpIndexOffset)];
+ qpAv = (qp + qpTmp + 1) >> 1;
+
+ indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
+
+ thresholds[TOP].alpha = alphas[indexA];
+ thresholds[TOP].beta = betas[indexB];
+ thresholds[TOP].tc0 = tc0[indexA];
+ }
+ else
+ {
+ thresholds[TOP].alpha = thresholds[INNER].alpha;
+ thresholds[TOP].beta = thresholds[INNER].beta;
+ thresholds[TOP].tc0 = thresholds[INNER].tc0;
+ }
+ }
+ if (filteringFlags & FILTER_LEFT_EDGE)
+ {
+ qpTmp = mb->mbA->qpY;
+ if (qpTmp != mb->qpY)
+ {
+ qpTmp = h264bsdQpC[CLIP3(0, 51, (i32)qpTmp + chromaQpIndexOffset)];
+ qpAv = (qp + qpTmp + 1) >> 1;
+
+ indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
+
+ thresholds[LEFT].alpha = alphas[indexA];
+ thresholds[LEFT].beta = betas[indexB];
+ thresholds[LEFT].tc0 = tc0[indexA];
+ }
+ else
+ {
+ thresholds[LEFT].alpha = thresholds[INNER].alpha;
+ thresholds[LEFT].beta = thresholds[INNER].beta;
+ thresholds[LEFT].tc0 = thresholds[INNER].tc0;
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: FilterLuma
+
+ Functional description:
+ Function to filter all luma edges of a macroblock
+
+------------------------------------------------------------------------------*/
+void FilterLuma(
+ u8 *data,
+ bS_t *bS,
+ edgeThreshold_t *thresholds,
+ u32 width)
+{
+
+/* Variables */
+
+ u32 vblock;
+ bS_t *tmp;
+ u8 *ptr;
+ u32 offset;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(bS);
+ ASSERT(thresholds);
+
+ ptr = data;
+ tmp = bS;
+
+ offset = TOP;
+
+ /* loop block rows, perform filtering for all vertical edges of the block
+ * row first, then filter each horizontal edge of the row */
+ for (vblock = 4; vblock--;)
+ {
+ /* only perform filtering if bS is non-zero, first of the four
+ * FilterVerLumaEdge handles the left edge of the macroblock, others
+ * filter inner edges */
+ if (tmp[0].left)
+ FilterVerLumaEdge(ptr, tmp[0].left, thresholds + LEFT, width);
+ if (tmp[1].left)
+ FilterVerLumaEdge(ptr+4, tmp[1].left, thresholds + INNER, width);
+ if (tmp[2].left)
+ FilterVerLumaEdge(ptr+8, tmp[2].left, thresholds + INNER, width);
+ if (tmp[3].left)
+ FilterVerLumaEdge(ptr+12, tmp[3].left, thresholds + INNER, width);
+
+ /* if bS is equal for all horizontal edges of the row -> perform
+ * filtering with FilterHorLuma, otherwise use FilterHorLumaEdge for
+ * each edge separately. offset variable indicates top macroblock edge
+ * on the first loop round, inner edge for the other rounds */
+ if (tmp[0].top == tmp[1].top && tmp[1].top == tmp[2].top &&
+ tmp[2].top == tmp[3].top)
+ {
+ if(tmp[0].top)
+ FilterHorLuma(ptr, tmp[0].top, thresholds + offset, (i32)width);
+ }
+ else
+ {
+ if(tmp[0].top)
+ FilterHorLumaEdge(ptr, tmp[0].top, thresholds+offset,
+ (i32)width);
+ if(tmp[1].top)
+ FilterHorLumaEdge(ptr+4, tmp[1].top, thresholds+offset,
+ (i32)width);
+ if(tmp[2].top)
+ FilterHorLumaEdge(ptr+8, tmp[2].top, thresholds+offset,
+ (i32)width);
+ if(tmp[3].top)
+ FilterHorLumaEdge(ptr+12, tmp[3].top, thresholds+offset,
+ (i32)width);
+ }
+
+ /* four pixel rows ahead, i.e. next row of 4x4-blocks */
+ ptr += width*4;
+ tmp += 4;
+ offset = INNER;
+ }
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: FilterChroma
+
+ Functional description:
+ Function to filter all chroma edges of a macroblock
+
+------------------------------------------------------------------------------*/
+void FilterChroma(
+ u8 *dataCb,
+ u8 *dataCr,
+ bS_t *bS,
+ edgeThreshold_t *thresholds,
+ u32 width)
+{
+
+/* Variables */
+
+ u32 vblock;
+ bS_t *tmp;
+ u32 offset;
+
+/* Code */
+
+ ASSERT(dataCb);
+ ASSERT(dataCr);
+ ASSERT(bS);
+ ASSERT(thresholds);
+
+ tmp = bS;
+ offset = TOP;
+
+ /* loop block rows, perform filtering for all vertical edges of the block
+ * row first, then filter each horizontal edge of the row */
+ for (vblock = 0; vblock < 2; vblock++)
+ {
+ /* only perform filtering if bS is non-zero, first two of the four
+ * FilterVerChromaEdge calls handle the left edge of the macroblock,
+ * others filter the inner edge. Note that as chroma uses bS values
+ * determined for luma edges, each bS is used only for 2 pixels of
+ * a 4-pixel edge */
+ if (tmp[0].left)
+ {
+ FilterVerChromaEdge(dataCb, tmp[0].left, thresholds + LEFT, width);
+ FilterVerChromaEdge(dataCr, tmp[0].left, thresholds + LEFT, width);
+ }
+ if (tmp[4].left)
+ {
+ FilterVerChromaEdge(dataCb+2*width, tmp[4].left, thresholds + LEFT,
+ width);
+ FilterVerChromaEdge(dataCr+2*width, tmp[4].left, thresholds + LEFT,
+ width);
+ }
+ if (tmp[2].left)
+ {
+ FilterVerChromaEdge(dataCb+4, tmp[2].left, thresholds + INNER,
+ width);
+ FilterVerChromaEdge(dataCr+4, tmp[2].left, thresholds + INNER,
+ width);
+ }
+ if (tmp[6].left)
+ {
+ FilterVerChromaEdge(dataCb+2*width+4, tmp[6].left,
+ thresholds + INNER, width);
+ FilterVerChromaEdge(dataCr+2*width+4, tmp[6].left,
+ thresholds + INNER, width);
+ }
+
+ /* if bS is equal for all horizontal edges of the row -> perform
+ * filtering with FilterHorChroma, otherwise use FilterHorChromaEdge
+ * for each edge separately. offset variable indicates top macroblock
+ * edge on the first loop round, inner edge for the second */
+ if (tmp[0].top == tmp[1].top && tmp[1].top == tmp[2].top &&
+ tmp[2].top == tmp[3].top)
+ {
+ if(tmp[0].top)
+ {
+ FilterHorChroma(dataCb, tmp[0].top, thresholds+offset,
+ (i32)width);
+ FilterHorChroma(dataCr, tmp[0].top, thresholds+offset,
+ (i32)width);
+ }
+ }
+ else
+ {
+ if (tmp[0].top)
+ {
+ FilterHorChromaEdge(dataCb, tmp[0].top, thresholds+offset,
+ (i32)width);
+ FilterHorChromaEdge(dataCr, tmp[0].top, thresholds+offset,
+ (i32)width);
+ }
+ if (tmp[1].top)
+ {
+ FilterHorChromaEdge(dataCb+2, tmp[1].top, thresholds+offset,
+ (i32)width);
+ FilterHorChromaEdge(dataCr+2, tmp[1].top, thresholds+offset,
+ (i32)width);
+ }
+ if (tmp[2].top)
+ {
+ FilterHorChromaEdge(dataCb+4, tmp[2].top, thresholds+offset,
+ (i32)width);
+ FilterHorChromaEdge(dataCr+4, tmp[2].top, thresholds+offset,
+ (i32)width);
+ }
+ if (tmp[3].top)
+ {
+ FilterHorChromaEdge(dataCb+6, tmp[3].top, thresholds+offset,
+ (i32)width);
+ FilterHorChromaEdge(dataCr+6, tmp[3].top, thresholds+offset,
+ (i32)width);
+ }
+ }
+
+ tmp += 8;
+ dataCb += width*4;
+ dataCr += width*4;
+ offset = INNER;
+ }
+}
+
+#else /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdFilterPicture
+
+ Functional description:
+ Perform deblocking filtering for a picture. Filter does not copy
+ the original picture anywhere but filtering is performed directly
+ on the original image. Parameters controlling the filtering process
+ are computed based on information in macroblock structures of the
+ filtered macroblock, macroblock above and macroblock on the left of
+ the filtered one.
+
+ Inputs:
+ image pointer to image to be filtered
+ mb pointer to macroblock data structure of the top-left
+ macroblock of the picture
+
+ Outputs:
+ image filtered image stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+/*lint --e{550} Symbol not accessed */
+void h264bsdFilterPicture(
+ image_t *image,
+ mbStorage_t *mb)
+{
+
+/* Variables */
+
+ u32 flags;
+ u32 picSizeInMbs, mbRow, mbCol;
+ u32 picWidthInMbs;
+ u8 *data;
+ mbStorage_t *pMb;
+ u8 bS[2][16];
+ u8 thresholdLuma[2][16];
+ u8 thresholdChroma[2][8];
+ u8 alpha[2][2];
+ u8 beta[2][2];
+ OMXResult res;
+
+/* Code */
+
+ ASSERT(image);
+ ASSERT(mb);
+ ASSERT(image->data);
+ ASSERT(image->width);
+ ASSERT(image->height);
+
+ picWidthInMbs = image->width;
+ data = image->data;
+ picSizeInMbs = picWidthInMbs * image->height;
+
+ pMb = mb;
+
+ for (mbRow = 0, mbCol = 0; mbRow < image->height; pMb++)
+ {
+ flags = GetMbFilteringFlags(pMb);
+
+ if (flags)
+ {
+ /* GetBoundaryStrengths function returns non-zero value if any of
+ * the bS values for the macroblock being processed was non-zero */
+ if (GetBoundaryStrengths(pMb, bS, flags))
+ {
+
+ /* Luma */
+ GetLumaEdgeThresholds(pMb,alpha,beta,thresholdLuma,bS,flags);
+ data = image->data + mbRow * picWidthInMbs * 256 + mbCol * 16;
+
+ res = omxVCM4P10_FilterDeblockingLuma_VerEdge_I( data,
+ (OMX_S32)(picWidthInMbs*16),
+ (const OMX_U8*)alpha,
+ (const OMX_U8*)beta,
+ (const OMX_U8*)thresholdLuma,
+ (const OMX_U8*)bS );
+
+ res = omxVCM4P10_FilterDeblockingLuma_HorEdge_I( data,
+ (OMX_S32)(picWidthInMbs*16),
+ (const OMX_U8*)alpha+2,
+ (const OMX_U8*)beta+2,
+ (const OMX_U8*)thresholdLuma+16,
+ (const OMX_U8*)bS+16 );
+ /* Cb */
+ GetChromaEdgeThresholds(pMb, alpha, beta, thresholdChroma,
+ bS, flags, pMb->chromaQpIndexOffset);
+ data = image->data + picSizeInMbs * 256 +
+ mbRow * picWidthInMbs * 64 + mbCol * 8;
+
+ res = omxVCM4P10_FilterDeblockingChroma_VerEdge_I( data,
+ (OMX_S32)(picWidthInMbs*8),
+ (const OMX_U8*)alpha,
+ (const OMX_U8*)beta,
+ (const OMX_U8*)thresholdChroma,
+ (const OMX_U8*)bS );
+ res = omxVCM4P10_FilterDeblockingChroma_HorEdge_I( data,
+ (OMX_S32)(picWidthInMbs*8),
+ (const OMX_U8*)alpha+2,
+ (const OMX_U8*)beta+2,
+ (const OMX_U8*)thresholdChroma+8,
+ (const OMX_U8*)bS+16 );
+ /* Cr */
+ data += (picSizeInMbs * 64);
+ res = omxVCM4P10_FilterDeblockingChroma_VerEdge_I( data,
+ (OMX_S32)(picWidthInMbs*8),
+ (const OMX_U8*)alpha,
+ (const OMX_U8*)beta,
+ (const OMX_U8*)thresholdChroma,
+ (const OMX_U8*)bS );
+ res = omxVCM4P10_FilterDeblockingChroma_HorEdge_I( data,
+ (OMX_S32)(picWidthInMbs*8),
+ (const OMX_U8*)alpha+2,
+ (const OMX_U8*)beta+2,
+ (const OMX_U8*)thresholdChroma+8,
+ (const OMX_U8*)bS+16 );
+ }
+ }
+
+ mbCol++;
+ if (mbCol == picWidthInMbs)
+ {
+ mbCol = 0;
+ mbRow++;
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: GetBoundaryStrengths
+
+ Functional description:
+ Function to calculate boundary strengths for all edges of a
+ macroblock. Function returns HANTRO_TRUE if any of the bS values for
+ the macroblock had non-zero value, HANTRO_FALSE otherwise.
+
+------------------------------------------------------------------------------*/
+u32 GetBoundaryStrengths(mbStorage_t *mb, u8 (*bS)[16], u32 flags)
+{
+
+/* Variables */
+
+ /* this flag is set HANTRO_TRUE as soon as any boundary strength value is
+ * non-zero */
+ u32 nonZeroBs = HANTRO_FALSE;
+ u32 *pTmp;
+ u32 tmp1, tmp2, isIntraMb;
+
+/* Code */
+
+ ASSERT(mb);
+ ASSERT(bS);
+ ASSERT(flags);
+
+ isIntraMb = IS_INTRA_MB(*mb);
+
+ /* top edges */
+ pTmp = (u32*)&bS[1][0];
+ if (flags & FILTER_TOP_EDGE)
+ {
+ if (isIntraMb || IS_INTRA_MB(*mb->mbB))
+ {
+ *pTmp = 0x04040404;
+ nonZeroBs = HANTRO_TRUE;
+ }
+ else
+ {
+ *pTmp = EdgeBoundaryStrengthTop(mb, mb->mbB);
+ if (*pTmp)
+ nonZeroBs = HANTRO_TRUE;
+ }
+ }
+ else
+ {
+ *pTmp = 0;
+ }
+
+ /* left edges */
+ pTmp = (u32*)&bS[0][0];
+ if (flags & FILTER_LEFT_EDGE)
+ {
+ if (isIntraMb || IS_INTRA_MB(*mb->mbA))
+ {
+ /*bS[0][0] = bS[0][1] = bS[0][2] = bS[0][3] = 4;*/
+ *pTmp = 0x04040404;
+ nonZeroBs = HANTRO_TRUE;
+ }
+ else
+ {
+ *pTmp = EdgeBoundaryStrengthLeft(mb, mb->mbA);
+ if (!nonZeroBs && *pTmp)
+ nonZeroBs = HANTRO_TRUE;
+ }
+ }
+ else
+ {
+ *pTmp = 0;
+ }
+
+ /* inner edges */
+ if (isIntraMb)
+ {
+ pTmp++;
+ *pTmp++ = 0x03030303;
+ *pTmp++ = 0x03030303;
+ *pTmp++ = 0x03030303;
+ pTmp++;
+ *pTmp++ = 0x03030303;
+ *pTmp++ = 0x03030303;
+ *pTmp = 0x03030303;
+
+ nonZeroBs = HANTRO_TRUE;
+ }
+ else
+ {
+ pTmp = (u32*)mb->totalCoeff;
+
+ /* 16x16 inter mb -> ref addresses or motion vectors cannot differ,
+ * only check if either of the blocks contain coefficients */
+ if (h264bsdNumMbPart(mb->mbType) == 1)
+ {
+ tmp1 = *pTmp++;
+ tmp2 = *pTmp++;
+ bS[1][4] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [2] || [0] */
+ bS[1][5] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [3] || [1] */
+ bS[0][4] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [1] || [0] */
+ bS[0][5] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [3] || [2] */
+
+ tmp1 = *pTmp++;
+ bS[1][6] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [6] || [4] */
+ bS[1][7] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [7] || [5] */
+ bS[0][12] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [5] || [4] */
+ bS[0][13] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [7] || [6] */
+ tmp2 = *pTmp;
+ bS[1][12] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [10] || [8] */
+ bS[1][13] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [11] || [9] */
+ bS[0][6] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [9] || [8] */
+ bS[0][7] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [11] || [10] */
+
+ bS[1][14] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [14] || [12] */
+ bS[1][15] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [15] || [13] */
+ bS[0][14] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [13] || [12] */
+ bS[0][15] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [15] || [14] */
+
+ {
+ u32 tmp3, tmp4;
+
+ tmp1 = mb->totalCoeff[8];
+ tmp2 = mb->totalCoeff[2];
+ tmp3 = mb->totalCoeff[9];
+ tmp4 = mb->totalCoeff[3];
+
+ bS[1][8] = tmp1 || tmp2 ? 2 : 0;
+ tmp1 = mb->totalCoeff[12];
+ tmp2 = mb->totalCoeff[6];
+ bS[1][9] = tmp3 || tmp4 ? 2 : 0;
+ tmp3 = mb->totalCoeff[13];
+ tmp4 = mb->totalCoeff[7];
+ bS[1][10] = tmp1 || tmp2 ? 2 : 0;
+ tmp1 = mb->totalCoeff[4];
+ tmp2 = mb->totalCoeff[1];
+ bS[1][11] = tmp3 || tmp4 ? 2 : 0;
+ tmp3 = mb->totalCoeff[6];
+ tmp4 = mb->totalCoeff[3];
+ bS[0][8] = tmp1 || tmp2 ? 2 : 0;
+ tmp1 = mb->totalCoeff[12];
+ tmp2 = mb->totalCoeff[9];
+ bS[0][9] = tmp3 || tmp4 ? 2 : 0;
+ tmp3 = mb->totalCoeff[14];
+ tmp4 = mb->totalCoeff[11];
+ bS[0][10] = tmp1 || tmp2 ? 2 : 0;
+ bS[0][11] = tmp3 || tmp4 ? 2 : 0;
+ }
+ }
+
+ /* 16x8 inter mb -> ref addresses and motion vectors can be different
+ * only for the middle horizontal edge, for the other top edges it is
+ * enough to check whether the blocks contain coefficients or not. The
+ * same applies to all internal left edges. */
+ else if (mb->mbType == P_L0_L0_16x8)
+ {
+ tmp1 = *pTmp++;
+ tmp2 = *pTmp++;
+ bS[1][4] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [2] || [0] */
+ bS[1][5] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [3] || [1] */
+ bS[0][4] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [1] || [0] */
+ bS[0][5] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [3] || [2] */
+ tmp1 = *pTmp++;
+ bS[1][6] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [6] || [4] */
+ bS[1][7] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [7] || [5] */
+ bS[0][12] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [5] || [4] */
+ bS[0][13] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [7] || [6] */
+ tmp2 = *pTmp;
+ bS[1][12] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [10] || [8] */
+ bS[1][13] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [11] || [9] */
+ bS[0][6] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [9] || [8] */
+ bS[0][7] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [11] || [10] */
+
+ bS[1][14] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [14] || [12] */
+ bS[1][15] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [15] || [13] */
+ bS[0][14] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [13] || [12] */
+ bS[0][15] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [15] || [14] */
+
+ bS[1][8] = (u8)InnerBoundaryStrength(mb, 8, 2);
+ bS[1][9] = (u8)InnerBoundaryStrength(mb, 9, 3);
+ bS[1][10] = (u8)InnerBoundaryStrength(mb, 12, 6);
+ bS[1][11] = (u8)InnerBoundaryStrength(mb, 13, 7);
+
+ {
+ u32 tmp3, tmp4;
+
+ tmp1 = mb->totalCoeff[4];
+ tmp2 = mb->totalCoeff[1];
+ tmp3 = mb->totalCoeff[6];
+ tmp4 = mb->totalCoeff[3];
+ bS[0][8] = tmp1 || tmp2 ? 2 : 0;
+ tmp1 = mb->totalCoeff[12];
+ tmp2 = mb->totalCoeff[9];
+ bS[0][9] = tmp3 || tmp4 ? 2 : 0;
+ tmp3 = mb->totalCoeff[14];
+ tmp4 = mb->totalCoeff[11];
+ bS[0][10] = tmp1 || tmp2 ? 2 : 0;
+ bS[0][11] = tmp3 || tmp4 ? 2 : 0;
+ }
+ }
+ /* 8x16 inter mb -> ref addresses and motion vectors can be different
+ * only for the middle vertical edge, for the other left edges it is
+ * enough to check whether the blocks contain coefficients or not. The
+ * same applies to all internal top edges. */
+ else if (mb->mbType == P_L0_L0_8x16)
+ {
+ tmp1 = *pTmp++;
+ tmp2 = *pTmp++;
+ bS[1][4] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [2] || [0] */
+ bS[1][5] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [3] || [1] */
+ bS[0][4] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [1] || [0] */
+ bS[0][5] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [3] || [2] */
+ tmp1 = *pTmp++;
+ bS[1][6] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [6] || [4] */
+ bS[1][7] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [7] || [5] */
+ bS[0][12] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [5] || [4] */
+ bS[0][13] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [7] || [6] */
+ tmp2 = *pTmp;
+ bS[1][12] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [10] || [8] */
+ bS[1][13] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [11] || [9] */
+ bS[0][6] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [9] || [8] */
+ bS[0][7] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [11] || [10] */
+
+ bS[1][14] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [14] || [12] */
+ bS[1][15] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [15] || [13] */
+ bS[0][14] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [13] || [12] */
+ bS[0][15] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [15] || [14] */
+
+ bS[0][8] = (u8)InnerBoundaryStrength(mb, 4, 1);
+ bS[0][9] = (u8)InnerBoundaryStrength(mb, 6, 3);
+ bS[0][10] = (u8)InnerBoundaryStrength(mb, 12, 9);
+ bS[0][11] = (u8)InnerBoundaryStrength(mb, 14, 11);
+
+ {
+ u32 tmp3, tmp4;
+
+ tmp1 = mb->totalCoeff[8];
+ tmp2 = mb->totalCoeff[2];
+ tmp3 = mb->totalCoeff[9];
+ tmp4 = mb->totalCoeff[3];
+ bS[1][8] = tmp1 || tmp2 ? 2 : 0;
+ tmp1 = mb->totalCoeff[12];
+ tmp2 = mb->totalCoeff[6];
+ bS[1][9] = tmp3 || tmp4 ? 2 : 0;
+ tmp3 = mb->totalCoeff[13];
+ tmp4 = mb->totalCoeff[7];
+ bS[1][10] = tmp1 || tmp2 ? 2 : 0;
+ bS[1][11] = tmp3 || tmp4 ? 2 : 0;
+ }
+ }
+ else
+ {
+ tmp1 = *pTmp++;
+ bS[1][4] = (tmp1 & 0x00FF00FF) ? 2 : (u8)InnerBoundaryStrength2(mb, 2, 0);
+ bS[1][5] = (tmp1 & 0xFF00FF00) ? 2 : (u8)InnerBoundaryStrength2(mb, 3, 1);
+ bS[0][4] = (tmp1 & 0x0000FFFF) ? 2 : (u8)InnerBoundaryStrength2(mb, 1, 0);
+ bS[0][5] = (tmp1 & 0xFFFF0000) ? 2 : (u8)InnerBoundaryStrength2(mb, 3, 2);
+ tmp1 = *pTmp++;
+ bS[1][6] = (tmp1 & 0x00FF00FF) ? 2 : (u8)InnerBoundaryStrength2(mb, 6, 4);
+ bS[1][7] = (tmp1 & 0xFF00FF00) ? 2 : (u8)InnerBoundaryStrength2(mb, 7, 5);
+ bS[0][12] = (tmp1 & 0x0000FFFF) ? 2 : (u8)InnerBoundaryStrength2(mb, 5, 4);
+ bS[0][13] = (tmp1 & 0xFFFF0000) ? 2 : (u8)InnerBoundaryStrength2(mb, 7, 6);
+ tmp1 = *pTmp++;
+ bS[1][12] = (tmp1 & 0x00FF00FF) ? 2 : (u8)InnerBoundaryStrength2(mb, 10, 8);
+ bS[1][13] = (tmp1 & 0xFF00FF00) ? 2 : (u8)InnerBoundaryStrength2(mb, 11, 9);
+ bS[0][6] = (tmp1 & 0x0000FFFF) ? 2 : (u8)InnerBoundaryStrength2(mb, 9, 8);
+ bS[0][7] = (tmp1 & 0xFFFF0000) ? 2 : (u8)InnerBoundaryStrength2(mb, 11, 10);
+ tmp1 = *pTmp;
+ bS[1][14] = (tmp1 & 0x00FF00FF) ? 2 : (u8)InnerBoundaryStrength2(mb, 14, 12);
+ bS[1][15] = (tmp1 & 0xFF00FF00) ? 2 : (u8)InnerBoundaryStrength2(mb, 15, 13);
+ bS[0][14] = (tmp1 & 0x0000FFFF) ? 2 : (u8)InnerBoundaryStrength2(mb, 13, 12);
+ bS[0][15] = (tmp1 & 0xFFFF0000) ? 2 : (u8)InnerBoundaryStrength2(mb, 15, 14);
+
+ bS[1][8] = (u8)InnerBoundaryStrength(mb, 8, 2);
+ bS[1][9] = (u8)InnerBoundaryStrength(mb, 9, 3);
+ bS[1][10] = (u8)InnerBoundaryStrength(mb, 12, 6);
+ bS[1][11] = (u8)InnerBoundaryStrength(mb, 13, 7);
+
+ bS[0][8] = (u8)InnerBoundaryStrength(mb, 4, 1);
+ bS[0][9] = (u8)InnerBoundaryStrength(mb, 6, 3);
+ bS[0][10] = (u8)InnerBoundaryStrength(mb, 12, 9);
+ bS[0][11] = (u8)InnerBoundaryStrength(mb, 14, 11);
+ }
+ pTmp = (u32*)&bS[0][0];
+ if (!nonZeroBs && (pTmp[1] || pTmp[2] || pTmp[3] ||
+ pTmp[5] || pTmp[6] || pTmp[7]) )
+ {
+ nonZeroBs = HANTRO_TRUE;
+ }
+ }
+
+ return(nonZeroBs);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: GetLumaEdgeThresholds
+
+ Functional description:
+ Compute alpha, beta and tc0 thresholds for inner, left and top
+ luma edges of a macroblock.
+
+------------------------------------------------------------------------------*/
+void GetLumaEdgeThresholds(
+ mbStorage_t *mb,
+ u8 (*alpha)[2],
+ u8 (*beta)[2],
+ u8 (*threshold)[16],
+ u8 (*bs)[16],
+ u32 filteringFlags )
+{
+
+/* Variables */
+
+ u32 indexA, indexB;
+ u32 qpAv, qp, qpTmp;
+ u32 i;
+
+/* Code */
+
+ ASSERT(threshold);
+ ASSERT(bs);
+ ASSERT(beta);
+ ASSERT(alpha);
+ ASSERT(mb);
+
+ qp = mb->qpY;
+
+ indexA = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetB);
+
+ /* Internal edge values */
+ alpha[0][1] = alphas[indexA];
+ alpha[1][1] = alphas[indexA];
+ alpha[1][0] = alphas[indexA];
+ alpha[0][0] = alphas[indexA];
+ beta[0][1] = betas[indexB];
+ beta[1][1] = betas[indexB];
+ beta[1][0] = betas[indexB];
+ beta[0][0] = betas[indexB];
+
+ /* vertical scan order */
+ for (i = 0; i < 2; i++)
+ {
+ u32 t1, t2;
+
+ t1 = bs[i][0];
+ t2 = bs[i][1];
+ threshold[i][0] = (t1) ? tc0[indexA][t1] : 0;
+ t1 = bs[i][2];
+ threshold[i][1] = (t2) ? tc0[indexA][t2] : 0;
+ t2 = bs[i][3];
+ threshold[i][2] = (t1) ? tc0[indexA][t1] : 0;
+ t1 = bs[i][4];
+ threshold[i][3] = (t2) ? tc0[indexA][t2] : 0;
+ t2 = bs[i][5];
+ threshold[i][4] = (t1) ? tc0[indexA][t1] : 0;
+ t1 = bs[i][6];
+ threshold[i][5] = (t2) ? tc0[indexA][t2] : 0;
+ t2 = bs[i][7];
+ threshold[i][6] = (t1) ? tc0[indexA][t1] : 0;
+ t1 = bs[i][8];
+ threshold[i][7] = (t2) ? tc0[indexA][t2] : 0;
+ t2 = bs[i][9];
+ threshold[i][8] = (t1) ? tc0[indexA][t1] : 0;
+ t1 = bs[i][10];
+ threshold[i][9] = (t2) ? tc0[indexA][t2] : 0;
+ t2 = bs[i][11];
+ threshold[i][10] = (t1) ? tc0[indexA][t1] : 0;
+ t1 = bs[i][12];
+ threshold[i][11] = (t2) ? tc0[indexA][t2] : 0;
+ t2 = bs[i][13];
+ threshold[i][12] = (t1) ? tc0[indexA][t1] : 0;
+ t1 = bs[i][14];
+ threshold[i][13] = (t2) ? tc0[indexA][t2] : 0;
+ t2 = bs[i][15];
+ threshold[i][14] = (t1) ? tc0[indexA][t1] : 0;
+ threshold[i][15] = (t2) ? tc0[indexA][t2] : 0;
+ }
+
+ if (filteringFlags & FILTER_TOP_EDGE)
+ {
+ qpTmp = mb->mbB->qpY;
+ if (qpTmp != qp)
+ {
+ u32 t1, t2, t3, t4;
+ qpAv = (qp + qpTmp + 1) >> 1;
+
+ indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
+
+ alpha[1][0] = alphas[indexA];
+ beta[1][0] = betas[indexB];
+ t1 = bs[1][0];
+ t2 = bs[1][1];
+ t3 = bs[1][2];
+ t4 = bs[1][3];
+ threshold[1][0] = (t1 && (t1 < 4)) ? tc0[indexA][t1] : 0;
+ threshold[1][1] = (t2 && (t2 < 4)) ? tc0[indexA][t2] : 0;
+ threshold[1][2] = (t3 && (t3 < 4)) ? tc0[indexA][t3] : 0;
+ threshold[1][3] = (t4 && (t4 < 4)) ? tc0[indexA][t4] : 0;
+ }
+ }
+ if (filteringFlags & FILTER_LEFT_EDGE)
+ {
+ qpTmp = mb->mbA->qpY;
+ if (qpTmp != qp)
+ {
+ qpAv = (qp + qpTmp + 1) >> 1;
+
+ indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
+
+ alpha[0][0] = alphas[indexA];
+ beta[0][0] = betas[indexB];
+ threshold[0][0] = (bs[0][0] && (bs[0][0] < 4)) ? tc0[indexA][bs[0][0]] : 0;
+ threshold[0][1] = (bs[0][1] && (bs[0][1] < 4)) ? tc0[indexA][bs[0][1]] : 0;
+ threshold[0][2] = (bs[0][2] && (bs[0][2] < 4)) ? tc0[indexA][bs[0][2]] : 0;
+ threshold[0][3] = (bs[0][3] && (bs[0][3] < 4)) ? tc0[indexA][bs[0][3]] : 0;
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: GetChromaEdgeThresholds
+
+ Functional description:
+ Compute alpha, beta and tc0 thresholds for inner, left and top
+ chroma edges of a macroblock.
+
+------------------------------------------------------------------------------*/
+void GetChromaEdgeThresholds(
+ mbStorage_t *mb,
+ u8 (*alpha)[2],
+ u8 (*beta)[2],
+ u8 (*threshold)[8],
+ u8 (*bs)[16],
+ u32 filteringFlags,
+ i32 chromaQpIndexOffset)
+{
+
+/* Variables */
+
+ u32 indexA, indexB;
+ u32 qpAv, qp, qpTmp;
+ u32 i;
+
+/* Code */
+
+ ASSERT(threshold);
+ ASSERT(bs);
+ ASSERT(beta);
+ ASSERT(alpha);
+ ASSERT(mb);
+ ASSERT(mb);
+
+ qp = mb->qpY;
+ qp = h264bsdQpC[CLIP3(0, 51, (i32)qp + chromaQpIndexOffset)];
+
+ indexA = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetB);
+
+ alpha[0][1] = alphas[indexA];
+ alpha[1][1] = alphas[indexA];
+ alpha[1][0] = alphas[indexA];
+ alpha[0][0] = alphas[indexA];
+ beta[0][1] = betas[indexB];
+ beta[1][1] = betas[indexB];
+ beta[1][0] = betas[indexB];
+ beta[0][0] = betas[indexB];
+
+ for (i = 0; i < 2; i++)
+ {
+ u32 t1, t2;
+
+ t1 = bs[i][0];
+ t2 = bs[i][1];
+ threshold[i][0] = (t1) ? tc0[indexA][t1] : 0;
+ t1 = bs[i][2];
+ threshold[i][1] = (t2) ? tc0[indexA][t2] : 0;
+ t2 = bs[i][3];
+ threshold[i][2] = (t1) ? tc0[indexA][t1] : 0;
+ t1 = bs[i][8];
+ threshold[i][3] = (t2) ? tc0[indexA][t2] : 0;
+ t2 = bs[i][9];
+ threshold[i][4] = (t1) ? tc0[indexA][t1] : 0;
+ t1 = bs[i][10];
+ threshold[i][5] = (t2) ? tc0[indexA][t2] : 0;
+ t2 = bs[i][11];
+ threshold[i][6] = (t1) ? tc0[indexA][t1] : 0;
+ threshold[i][7] = (t2) ? tc0[indexA][t2] : 0;
+ }
+
+ if (filteringFlags & FILTER_TOP_EDGE)
+ {
+ qpTmp = mb->mbB->qpY;
+ if (qpTmp != mb->qpY)
+ {
+ u32 t1, t2, t3, t4;
+ qpTmp = h264bsdQpC[CLIP3(0, 51, (i32)qpTmp + chromaQpIndexOffset)];
+ qpAv = (qp + qpTmp + 1) >> 1;
+
+ indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
+
+ alpha[1][0] = alphas[indexA];
+ beta[1][0] = betas[indexB];
+
+ t1 = bs[1][0];
+ t2 = bs[1][1];
+ t3 = bs[1][2];
+ t4 = bs[1][3];
+ threshold[1][0] = (t1) ? tc0[indexA][t1] : 0;
+ threshold[1][1] = (t2) ? tc0[indexA][t2] : 0;
+ threshold[1][2] = (t3) ? tc0[indexA][t3] : 0;
+ threshold[1][3] = (t4) ? tc0[indexA][t4] : 0;
+ }
+ }
+ if (filteringFlags & FILTER_LEFT_EDGE)
+ {
+ qpTmp = mb->mbA->qpY;
+ if (qpTmp != mb->qpY)
+ {
+
+ qpTmp = h264bsdQpC[CLIP3(0, 51, (i32)qpTmp + chromaQpIndexOffset)];
+ qpAv = (qp + qpTmp + 1) >> 1;
+
+ indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
+ indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
+
+ alpha[0][0] = alphas[indexA];
+ beta[0][0] = betas[indexB];
+ threshold[0][0] = (bs[0][0]) ? tc0[indexA][bs[0][0]] : 0;
+ threshold[0][1] = (bs[0][1]) ? tc0[indexA][bs[0][1]] : 0;
+ threshold[0][2] = (bs[0][2]) ? tc0[indexA][bs[0][2]] : 0;
+ threshold[0][3] = (bs[0][3]) ? tc0[indexA][bs[0][3]] : 0;
+ }
+ }
+
+}
+
+#endif /* H264DEC_OMXDL */
+
+/*lint +e701 +e702 */
+
--- /dev/null
+++ b/src/h264bsd_deblocking.h
@@ -1,0 +1,57 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_DEBLOCKING_H
+#define H264SWDEC_DEBLOCKING_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_image.h"
+#include "h264bsd_macroblock_layer.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+void h264bsdFilterPicture(
+ image_t *image,
+ mbStorage_t *mb);
+
+#endif /* #ifdef H264SWDEC_DEBLOCKING_H */
+
--- /dev/null
+++ b/src/h264bsd_decoder.c
@@ -1,0 +1,1008 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdInit
+ h264bsdDecode
+ h264bsdShutdown
+ h264bsdCurrentImage
+ h264bsdNextOutputPicture
+ h264bsdPicWidth
+ h264bsdPicHeight
+ h264bsdFlushBuffer
+ h264bsdCheckValidParamSets
+ h264bsdVideoRange
+ h264bsdMatrixCoefficients
+ h264bsdCroppingParams
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_decoder.h"
+#include "h264bsd_nal_unit.h"
+#include "h264bsd_byte_stream.h"
+#include "h264bsd_seq_param_set.h"
+#include "h264bsd_pic_param_set.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_slice_data.h"
+#include "h264bsd_neighbour.h"
+#include "h264bsd_util.h"
+#include "h264bsd_dpb.h"
+#include "h264bsd_deblocking.h"
+#include "h264bsd_conceal.h"
+#include "h264bsd_storage.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdInit
+
+ Functional description:
+ Initialize the decoder.
+
+ Inputs:
+ noOutputReordering flag to indicate the decoder that it does not
+ have to perform reordering of display images.
+
+ Outputs:
+ pStorage pointer to initialized storage structure
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdInit(storage_t *pStorage, u32 noOutputReordering)
+{
+
+/* Variables */
+ u32 size;
+/* Code */
+
+ ASSERT(pStorage);
+
+ h264bsdInitStorage(pStorage);
+
+ /* allocate mbLayer to be next multiple of 64 to enable use of
+ * specific NEON optimized "memset" for clearing the structure */
+ size = (sizeof(macroblockLayer_t) + 63) & ~0x3F;
+
+ pStorage->mbLayer = (macroblockLayer_t*)malloc(size);
+ if (!pStorage->mbLayer)
+ return HANTRO_NOK;
+
+ if (noOutputReordering)
+ pStorage->noReordering = HANTRO_TRUE;
+
+ return HANTRO_OK;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdDecode
+
+ Functional description:
+ Decode a NAL unit. This function calls other modules to perform
+ tasks like
+ * extract and decode NAL unit from the byte stream
+ * decode parameter sets
+ * decode slice header and slice data
+ * conceal errors in the picture
+ * perform deblocking filtering
+
+ This function contains top level control logic of the decoder.
+
+ Inputs:
+ pStorage pointer to storage data structure
+ byteStrm pointer to stream buffer given by application
+ len length of the buffer in bytes
+ picId identifier for a picture, assigned by the
+ application
+
+ Outputs:
+ readBytes number of bytes read from the stream is stored
+ here
+
+ Returns:
+ H264BSD_RDY decoding finished, nothing special
+ H264BSD_PIC_RDY decoding of a picture finished
+ H264BSD_HDRS_RDY param sets activated, information like
+ picture dimensions etc can be read
+ H264BSD_ERROR error in decoding
+ H264BSD_PARAM_SET_ERROR serius error in decoding, failed to
+ activate param sets
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecode(storage_t *pStorage, u8 *byteStrm, u32 len, u32 picId,
+ u32 *readBytes)
+{
+
+/* Variables */
+
+ u32 tmp, ppsId, spsId;
+ i32 picOrderCnt;
+ nalUnit_t nalUnit;
+ seqParamSet_t seqParamSet;
+ picParamSet_t picParamSet;
+ strmData_t strm;
+ u32 accessUnitBoundaryFlag = HANTRO_FALSE;
+ u32 picReady = HANTRO_FALSE;
+
+/* Code */
+
+ ASSERT(pStorage);
+ ASSERT(byteStrm);
+ ASSERT(len);
+ ASSERT(readBytes);
+
+ /* if previous buffer was not finished and same pointer given -> skip NAL
+ * unit extraction */
+ if (pStorage->prevBufNotFinished && byteStrm == pStorage->prevBufPointer)
+ {
+ strm = pStorage->strm[0];
+ strm.pStrmCurrPos = strm.pStrmBuffStart;
+ strm.strmBuffReadBits = strm.bitPosInWord = 0;
+ *readBytes = pStorage->prevBytesConsumed;
+ }
+ else
+ {
+ tmp = h264bsdExtractNalUnit(byteStrm, len, &strm, readBytes);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("BYTE_STREAM");
+ return(H264BSD_ERROR);
+ }
+ /* store stream */
+ pStorage->strm[0] = strm;
+ pStorage->prevBytesConsumed = *readBytes;
+ pStorage->prevBufPointer = byteStrm;
+ }
+ pStorage->prevBufNotFinished = HANTRO_FALSE;
+
+ tmp = h264bsdDecodeNalUnit(&strm, &nalUnit);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("NAL_UNIT");
+ return(H264BSD_ERROR);
+ }
+
+ /* Discard unspecified, reserved, SPS extension and auxiliary picture slices */
+ if(nalUnit.nalUnitType == 0 || nalUnit.nalUnitType >= 13)
+ {
+ DEBUG(("DISCARDED NAL (UNSPECIFIED, REGISTERED, SPS ext or AUX slice)\n"));
+ return(H264BSD_RDY);
+ }
+
+ tmp = h264bsdCheckAccessUnitBoundary(
+ &strm,
+ &nalUnit,
+ pStorage,
+ &accessUnitBoundaryFlag);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("ACCESS UNIT BOUNDARY CHECK");
+ if (tmp == PARAM_SET_ERROR)
+ return(H264BSD_PARAM_SET_ERROR);
+ else
+ return(H264BSD_ERROR);
+ }
+
+ if ( accessUnitBoundaryFlag )
+ {
+ DEBUG(("Access unit boundary\n"));
+ /* conceal if picture started and param sets activated */
+ if (pStorage->picStarted && pStorage->activeSps != NULL)
+ {
+ DEBUG(("CONCEALING..."));
+
+ /* return error if second phase of
+ * initialization is not completed */
+ if (pStorage->pendingActivation)
+ {
+ EPRINT("Pending activation not completed");
+ return (H264BSD_ERROR);
+ }
+
+ if (!pStorage->validSliceInAccessUnit)
+ {
+ pStorage->currImage->data =
+ h264bsdAllocateDpbImage(pStorage->dpb);
+ h264bsdInitRefPicList(pStorage->dpb);
+ tmp = h264bsdConceal(pStorage, pStorage->currImage, P_SLICE);
+ }
+ else
+ tmp = h264bsdConceal(pStorage, pStorage->currImage,
+ pStorage->sliceHeader->sliceType);
+
+ picReady = HANTRO_TRUE;
+
+ /* current NAL unit should be decoded on next activation -> set
+ * readBytes to 0 */
+ *readBytes = 0;
+ pStorage->prevBufNotFinished = HANTRO_TRUE;
+ DEBUG(("...DONE\n"));
+ }
+ else
+ {
+ pStorage->validSliceInAccessUnit = HANTRO_FALSE;
+ }
+ pStorage->skipRedundantSlices = HANTRO_FALSE;
+ }
+
+ if (!picReady)
+ {
+ switch (nalUnit.nalUnitType)
+ {
+ case NAL_SEQ_PARAM_SET:
+ DEBUG(("SEQ PARAM SET\n"));
+ tmp = h264bsdDecodeSeqParamSet(&strm, &seqParamSet);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("SEQ_PARAM_SET");
+ FREE(seqParamSet.offsetForRefFrame);
+ FREE(seqParamSet.vuiParameters);
+ return(H264BSD_ERROR);
+ }
+ tmp = h264bsdStoreSeqParamSet(pStorage, &seqParamSet);
+ break;
+
+ case NAL_PIC_PARAM_SET:
+ DEBUG(("PIC PARAM SET\n"));
+ tmp = h264bsdDecodePicParamSet(&strm, &picParamSet);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("PIC_PARAM_SET");
+ FREE(picParamSet.runLength);
+ FREE(picParamSet.topLeft);
+ FREE(picParamSet.bottomRight);
+ FREE(picParamSet.sliceGroupId);
+ return(H264BSD_ERROR);
+ }
+ tmp = h264bsdStorePicParamSet(pStorage, &picParamSet);
+ break;
+
+ case NAL_CODED_SLICE_IDR:
+ DEBUG(("IDR "));
+ /* fall through */
+ case NAL_CODED_SLICE:
+ DEBUG(("SLICE HEADER\n"));
+
+ /* picture successfully finished and still decoding same old
+ * access unit -> no need to decode redundant slices */
+ if (pStorage->skipRedundantSlices)
+ return(H264BSD_RDY);
+
+ pStorage->picStarted = HANTRO_TRUE;
+
+ if (h264bsdIsStartOfPicture(pStorage))
+ {
+ pStorage->numConcealedMbs = 0;
+ pStorage->currentPicId = picId;
+
+ tmp = h264bsdCheckPpsId(&strm, &ppsId);
+ ASSERT(tmp == HANTRO_OK);
+ /* store old activeSpsId and return headers ready
+ * indication if activeSps changes */
+ spsId = pStorage->activeSpsId;
+ tmp = h264bsdActivateParamSets(pStorage, ppsId,
+ IS_IDR_NAL_UNIT(&nalUnit) ?
+ HANTRO_TRUE : HANTRO_FALSE);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("Param set activation");
+ pStorage->activePpsId = MAX_NUM_PIC_PARAM_SETS;
+ pStorage->activePps = NULL;
+ pStorage->activeSpsId = MAX_NUM_SEQ_PARAM_SETS;
+ pStorage->activeSps = NULL;
+ pStorage->pendingActivation = HANTRO_FALSE;
+
+ if(tmp == MEMORY_ALLOCATION_ERROR)
+ {
+ return H264BSD_MEMALLOC_ERROR;
+ }
+ else
+ return(H264BSD_PARAM_SET_ERROR);
+ }
+
+ if (spsId != pStorage->activeSpsId)
+ {
+ seqParamSet_t *oldSPS = NULL;
+ seqParamSet_t *newSPS = pStorage->activeSps;
+ u32 noOutputOfPriorPicsFlag = 1;
+
+ if(pStorage->oldSpsId < MAX_NUM_SEQ_PARAM_SETS)
+ {
+ oldSPS = pStorage->sps[pStorage->oldSpsId];
+ }
+
+ *readBytes = 0;
+ pStorage->prevBufNotFinished = HANTRO_TRUE;
+
+
+ if(nalUnit.nalUnitType == NAL_CODED_SLICE_IDR)
+ {
+ tmp =
+ h264bsdCheckPriorPicsFlag(&noOutputOfPriorPicsFlag,
+ &strm, newSPS,
+ pStorage->activePps,
+ nalUnit.nalUnitType);
+ }
+ else
+ {
+ tmp = HANTRO_NOK;
+ }
+
+ if((tmp != HANTRO_OK) ||
+ (noOutputOfPriorPicsFlag != 0) ||
+ (pStorage->dpb->noReordering) ||
+ (oldSPS == NULL) ||
+ (oldSPS->picWidthInMbs != newSPS->picWidthInMbs) ||
+ (oldSPS->picHeightInMbs != newSPS->picHeightInMbs) ||
+ (oldSPS->maxDpbSize != newSPS->maxDpbSize))
+ {
+ pStorage->dpb->flushed = 0;
+ }
+ else
+ {
+ h264bsdFlushDpb(pStorage->dpb);
+ }
+
+ pStorage->oldSpsId = pStorage->activeSpsId;
+
+ return(H264BSD_HDRS_RDY);
+ }
+ }
+
+ /* return error if second phase of
+ * initialization is not completed */
+ if (pStorage->pendingActivation)
+ {
+ EPRINT("Pending activation not completed");
+ return (H264BSD_ERROR);
+ }
+ tmp = h264bsdDecodeSliceHeader(&strm, pStorage->sliceHeader + 1,
+ pStorage->activeSps, pStorage->activePps, &nalUnit);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("SLICE_HEADER");
+ return(H264BSD_ERROR);
+ }
+ if (h264bsdIsStartOfPicture(pStorage))
+ {
+ if (!IS_IDR_NAL_UNIT(&nalUnit))
+ {
+ tmp = h264bsdCheckGapsInFrameNum(pStorage->dpb,
+ pStorage->sliceHeader[1].frameNum,
+ nalUnit.nalRefIdc != 0 ?
+ HANTRO_TRUE : HANTRO_FALSE,
+ pStorage->activeSps->
+ gapsInFrameNumValueAllowedFlag);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("Gaps in frame num");
+ return(H264BSD_ERROR);
+ }
+ }
+ pStorage->currImage->data =
+ h264bsdAllocateDpbImage(pStorage->dpb);
+ }
+
+ /* store slice header to storage if successfully decoded */
+ pStorage->sliceHeader[0] = pStorage->sliceHeader[1];
+ pStorage->validSliceInAccessUnit = HANTRO_TRUE;
+ pStorage->prevNalUnit[0] = nalUnit;
+
+ h264bsdComputeSliceGroupMap(pStorage,
+ pStorage->sliceHeader->sliceGroupChangeCycle);
+
+ h264bsdInitRefPicList(pStorage->dpb);
+ tmp = h264bsdReorderRefPicList(pStorage->dpb,
+ &pStorage->sliceHeader->refPicListReordering,
+ pStorage->sliceHeader->frameNum,
+ pStorage->sliceHeader->numRefIdxL0Active);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("Reordering");
+ return(H264BSD_ERROR);
+ }
+
+ DEBUG(("SLICE DATA, FIRST %d\n",
+ pStorage->sliceHeader->firstMbInSlice));
+ tmp = h264bsdDecodeSliceData(&strm, pStorage,
+ pStorage->currImage, pStorage->sliceHeader);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("SLICE_DATA");
+ h264bsdMarkSliceCorrupted(pStorage,
+ pStorage->sliceHeader->firstMbInSlice);
+ return(H264BSD_ERROR);
+ }
+
+ if (h264bsdIsEndOfPicture(pStorage))
+ {
+ picReady = HANTRO_TRUE;
+ pStorage->skipRedundantSlices = HANTRO_TRUE;
+ }
+ break;
+
+ case NAL_SEI:
+ DEBUG(("SEI MESSAGE, NOT DECODED"));
+ break;
+
+ default:
+ DEBUG(("NOT IMPLEMENTED YET %d\n",nalUnit.nalUnitType));
+ }
+ }
+
+ if (picReady)
+ {
+ h264bsdFilterPicture(pStorage->currImage, pStorage->mb);
+
+ h264bsdResetStorage(pStorage);
+
+ picOrderCnt = h264bsdDecodePicOrderCnt(pStorage->poc,
+ pStorage->activeSps, pStorage->sliceHeader, pStorage->prevNalUnit);
+
+ if (pStorage->validSliceInAccessUnit)
+ {
+ if (pStorage->prevNalUnit->nalRefIdc)
+ {
+ tmp = h264bsdMarkDecRefPic(pStorage->dpb,
+ &pStorage->sliceHeader->decRefPicMarking,
+ pStorage->currImage, pStorage->sliceHeader->frameNum,
+ picOrderCnt,
+ IS_IDR_NAL_UNIT(pStorage->prevNalUnit) ?
+ HANTRO_TRUE : HANTRO_FALSE,
+ pStorage->currentPicId, pStorage->numConcealedMbs);
+ }
+ /* non-reference picture, just store for possible display
+ * reordering */
+ else
+ {
+ tmp = h264bsdMarkDecRefPic(pStorage->dpb, NULL,
+ pStorage->currImage, pStorage->sliceHeader->frameNum,
+ picOrderCnt,
+ IS_IDR_NAL_UNIT(pStorage->prevNalUnit) ?
+ HANTRO_TRUE : HANTRO_FALSE,
+ pStorage->currentPicId, pStorage->numConcealedMbs);
+ }
+ }
+
+ pStorage->picStarted = HANTRO_FALSE;
+ pStorage->validSliceInAccessUnit = HANTRO_FALSE;
+
+ return(H264BSD_PIC_RDY);
+ }
+ else
+ return(H264BSD_RDY);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdShutdown
+
+ Functional description:
+ Shutdown a decoder instance. Function frees all the memories
+ allocated for the decoder instance.
+
+ Inputs:
+ pStorage pointer to storage data structure
+
+ Returns:
+ none
+
+
+------------------------------------------------------------------------------*/
+
+void h264bsdShutdown(storage_t *pStorage)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ for (i = 0; i < MAX_NUM_SEQ_PARAM_SETS; i++)
+ {
+ if (pStorage->sps[i])
+ {
+ FREE(pStorage->sps[i]->offsetForRefFrame);
+ FREE(pStorage->sps[i]->vuiParameters);
+ FREE(pStorage->sps[i]);
+ }
+ }
+
+ for (i = 0; i < MAX_NUM_PIC_PARAM_SETS; i++)
+ {
+ if (pStorage->pps[i])
+ {
+ FREE(pStorage->pps[i]->runLength);
+ FREE(pStorage->pps[i]->topLeft);
+ FREE(pStorage->pps[i]->bottomRight);
+ FREE(pStorage->pps[i]->sliceGroupId);
+ FREE(pStorage->pps[i]);
+ }
+ }
+
+ FREE(pStorage->mbLayer);
+ FREE(pStorage->mb);
+ FREE(pStorage->sliceGroupMap);
+
+ h264bsdFreeDpb(pStorage->dpb);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdNextOutputPicture
+
+ Functional description:
+ Get next output picture in display order.
+
+ Inputs:
+ pStorage pointer to storage data structure
+
+ Outputs:
+ picId identifier of the picture will be stored here
+ isIdrPic IDR flag of the picture will be stored here
+ numErrMbs number of concealed macroblocks in the picture
+ will be stored here
+
+ Returns:
+ pointer to the picture data
+ NULL if no pictures available for display
+
+------------------------------------------------------------------------------*/
+
+u8* h264bsdNextOutputPicture(storage_t *pStorage, u32 *picId, u32 *isIdrPic,
+ u32 *numErrMbs)
+{
+
+/* Variables */
+
+ dpbOutPicture_t *pOut;
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ pOut = h264bsdDpbOutputPicture(pStorage->dpb);
+
+ if (pOut != NULL)
+ {
+ *picId = pOut->picId;
+ *isIdrPic = pOut->isIdr;
+ *numErrMbs = pOut->numErrMbs;
+ return (pOut->data);
+ }
+ else
+ return(NULL);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdPicWidth
+
+ Functional description:
+ Get width of the picture in macroblocks
+
+ Inputs:
+ pStorage pointer to storage data structure
+
+ Outputs:
+ none
+
+ Returns:
+ picture width
+ 0 if parameters sets not yet activated
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdPicWidth(storage_t *pStorage)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ if (pStorage->activeSps)
+ return(pStorage->activeSps->picWidthInMbs);
+ else
+ return(0);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdPicHeight
+
+ Functional description:
+ Get height of the picture in macroblocks
+
+ Inputs:
+ pStorage pointer to storage data structure
+
+ Outputs:
+ none
+
+ Returns:
+ picture width
+ 0 if parameters sets not yet activated
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdPicHeight(storage_t *pStorage)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ if (pStorage->activeSps)
+ return(pStorage->activeSps->picHeightInMbs);
+ else
+ return(0);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdFlushBuffer
+
+ Functional description:
+ Flush the decoded picture buffer, see dpb.c for details
+
+ Inputs:
+ pStorage pointer to storage data structure
+
+------------------------------------------------------------------------------*/
+
+void h264bsdFlushBuffer(storage_t *pStorage)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ h264bsdFlushDpb(pStorage->dpb);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckValidParamSets
+
+ Functional description:
+ Check if any valid parameter set combinations (SPS/PPS) exists.
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Returns:
+ 1 at least one valid SPS/PPS combination found
+ 0 no valid param set combinations found
+
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckValidParamSets(storage_t *pStorage)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ return(h264bsdValidParamSets(pStorage) == HANTRO_OK ? 1 : 0);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdVideoRange
+
+ Functional description:
+ Get value of video_full_range_flag received in the VUI data.
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Returns:
+ 1 video_full_range_flag received and value is 1
+ 0 otherwise
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdVideoRange(storage_t *pStorage)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ if (pStorage->activeSps && pStorage->activeSps->vuiParametersPresentFlag &&
+ pStorage->activeSps->vuiParameters &&
+ pStorage->activeSps->vuiParameters->videoSignalTypePresentFlag &&
+ pStorage->activeSps->vuiParameters->videoFullRangeFlag)
+ return(1);
+ else /* default value of video_full_range_flag is 0 */
+ return(0);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdMatrixCoefficients
+
+ Functional description:
+ Get value of matrix_coefficients received in the VUI data
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ value of matrix_coefficients if received
+ 2 otherwise (this is the default value)
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdMatrixCoefficients(storage_t *pStorage)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ if (pStorage->activeSps && pStorage->activeSps->vuiParametersPresentFlag &&
+ pStorage->activeSps->vuiParameters &&
+ pStorage->activeSps->vuiParameters->videoSignalTypePresentFlag &&
+ pStorage->activeSps->vuiParameters->colourDescriptionPresentFlag)
+ return(pStorage->activeSps->vuiParameters->matrixCoefficients);
+ else /* default unspecified */
+ return(2);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: hh264bsdCroppingParams
+
+ Functional description:
+ Get cropping parameters of the active SPS
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ croppingFlag flag indicating if cropping params present is
+ stored here
+ leftOffset cropping left offset in pixels is stored here
+ width width of the image after cropping is stored here
+ topOffset cropping top offset in pixels is stored here
+ height height of the image after cropping is stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdCroppingParams(storage_t *pStorage, u32 *croppingFlag,
+ u32 *leftOffset, u32 *width, u32 *topOffset, u32 *height)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ if (pStorage->activeSps && pStorage->activeSps->frameCroppingFlag)
+ {
+ *croppingFlag = 1;
+ *leftOffset = 2 * pStorage->activeSps->frameCropLeftOffset;
+ *width = 16 * pStorage->activeSps->picWidthInMbs -
+ 2 * (pStorage->activeSps->frameCropLeftOffset +
+ pStorage->activeSps->frameCropRightOffset);
+ *topOffset = 2 * pStorage->activeSps->frameCropTopOffset;
+ *height = 16 * pStorage->activeSps->picHeightInMbs -
+ 2 * (pStorage->activeSps->frameCropTopOffset +
+ pStorage->activeSps->frameCropBottomOffset);
+ }
+ else
+ {
+ *croppingFlag = 0;
+ *leftOffset = 0;
+ *width = 0;
+ *topOffset = 0;
+ *height = 0;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdSampleAspectRatio
+
+ Functional description:
+ Get aspect ratio received in the VUI data
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ sarWidth sample aspect ratio height
+ sarHeight sample aspect ratio width
+
+------------------------------------------------------------------------------*/
+
+void h264bsdSampleAspectRatio(storage_t *pStorage, u32 *sarWidth, u32 *sarHeight)
+{
+
+/* Variables */
+ u32 w = 1;
+ u32 h = 1;
+/* Code */
+
+ ASSERT(pStorage);
+
+
+ if (pStorage->activeSps &&
+ pStorage->activeSps->vuiParametersPresentFlag &&
+ pStorage->activeSps->vuiParameters &&
+ pStorage->activeSps->vuiParameters->aspectRatioPresentFlag )
+ {
+ switch (pStorage->activeSps->vuiParameters->aspectRatioIdc)
+ {
+ case ASPECT_RATIO_UNSPECIFIED: w = 0; h = 0; break;
+ case ASPECT_RATIO_1_1: w = 1; h = 1; break;
+ case ASPECT_RATIO_12_11: w = 12; h = 11; break;
+ case ASPECT_RATIO_10_11: w = 10; h = 11; break;
+ case ASPECT_RATIO_16_11: w = 16; h = 11; break;
+ case ASPECT_RATIO_40_33: w = 40; h = 33; break;
+ case ASPECT_RATIO_24_11: w = 24; h = 11; break;
+ case ASPECT_RATIO_20_11: w = 20; h = 11; break;
+ case ASPECT_RATIO_32_11: w = 32; h = 11; break;
+ case ASPECT_RATIO_80_33: w = 80; h = 33; break;
+ case ASPECT_RATIO_18_11: w = 18; h = 11; break;
+ case ASPECT_RATIO_15_11: w = 15; h = 11; break;
+ case ASPECT_RATIO_64_33: w = 64; h = 33; break;
+ case ASPECT_RATIO_160_99: w = 160; h = 99; break;
+ case ASPECT_RATIO_EXTENDED_SAR:
+ w = pStorage->activeSps->vuiParameters->sarWidth;
+ h = pStorage->activeSps->vuiParameters->sarHeight;
+ if ((w == 0) || (h == 0))
+ w = h = 0;
+ break;
+ default:
+ w = 0;
+ h = 0;
+ break;
+ }
+ }
+
+ /* set aspect ratio*/
+ *sarWidth = w;
+ *sarHeight = h;
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdProfile
+
+ Functional description:
+ Get profile information from active SPS
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ profile current profile
+
+------------------------------------------------------------------------------*/
+u32 h264bsdProfile(storage_t *pStorage)
+{
+ if (pStorage->activeSps)
+ return pStorage->activeSps->profileIdc;
+ else
+ return 0;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdAlloc
+
+ Functional description:
+ Allocate storage for a decoder
+
+ Inputs:
+ none
+
+ Outputs:
+ none
+
+ Returns:
+ pStorage pointer to uninitialized storage structure
+
+------------------------------------------------------------------------------*/
+
+storage_t* h264bsdAlloc()
+{
+ return (storage_t*)malloc(sizeof(storage_t));
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdFree
+
+ Functional description:
+ Free storage for a decoder
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ none
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdFree(storage_t *pStorage)
+{
+ free(pStorage);
+}
--- /dev/null
+++ b/src/h264bsd_decoder.h
@@ -1,0 +1,88 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_DECODER_H
+#define H264SWDEC_DECODER_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/* enumerated return values of the functions */
+enum {
+ H264BSD_RDY,
+ H264BSD_PIC_RDY,
+ H264BSD_HDRS_RDY,
+ H264BSD_ERROR,
+ H264BSD_PARAM_SET_ERROR,
+ H264BSD_MEMALLOC_ERROR
+};
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+typedef struct storage storage_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdInit(storage_t *pStorage, u32 noOutputReordering);
+u32 h264bsdDecode(storage_t *pStorage, u8 *byteStrm, u32 len, u32 picId,
+ u32 *readBytes);
+void h264bsdShutdown(storage_t *pStorage);
+
+u8* h264bsdNextOutputPicture(storage_t *pStorage, u32 *picId, u32 *isIdrPic,
+ u32 *numErrMbs);
+
+u32 h264bsdPicWidth(storage_t *pStorage);
+u32 h264bsdPicHeight(storage_t *pStorage);
+u32 h264bsdVideoRange(storage_t *pStorage);
+u32 h264bsdMatrixCoefficients(storage_t *pStorage);
+void h264bsdCroppingParams(storage_t *pStorage, u32 *croppingFlag,
+ u32 *left, u32 *width, u32 *top, u32 *height);
+void h264bsdSampleAspectRatio(storage_t *pStorage,
+ u32 *sarWidth, u32 *sarHeight);
+u32 h264bsdCheckValidParamSets(storage_t *pStorage);
+
+void h264bsdFlushBuffer(storage_t *pStorage);
+
+u32 h264bsdProfile(storage_t *pStorage);
+
+storage_t* h264bsdAlloc();
+void h264bsdFree(storage_t *pStorage);
+
+#endif /* #ifdef H264SWDEC_DECODER_H */
+
--- /dev/null
+++ b/src/h264bsd_dpb.c
@@ -1,0 +1,1585 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ ComparePictures
+ h264bsdReorderRefPicList
+ Mmcop1
+ Mmcop2
+ Mmcop3
+ Mmcop4
+ Mmcop5
+ Mmcop6
+ h264bsdMarkDecRefPic
+ h264bsdGetRefPicData
+ h264bsdAllocateDpbImage
+ SlidingWindowRefPicMarking
+ h264bsdInitDpb
+ h264bsdResetDpb
+ h264bsdInitRefPicList
+ FindDpbPic
+ SetPicNums
+ h264bsdCheckGapsInFrameNum
+ FindSmallestPicOrderCnt
+ OutputPicture
+ h264bsdDpbOutputPicture
+ h264bsdFlushDpb
+ h264bsdFreeDpb
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_cfg.h"
+#include "h264bsd_dpb.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_image.h"
+#include "h264bsd_util.h"
+#include "basetype.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* macros to determine picture status. Note that IS_SHORT_TERM macro returns
+ * true also for non-existing pictures because non-existing pictures are
+ * regarded short term pictures according to H.264 standard */
+#define IS_REFERENCE(a) ((a).status)
+#define IS_EXISTING(a) ((a).status > NON_EXISTING)
+#define IS_SHORT_TERM(a) \
+ ((a).status == NON_EXISTING || (a).status == SHORT_TERM)
+#define IS_LONG_TERM(a) ((a).status == LONG_TERM)
+
+/* macro to set a picture unused for reference */
+#define SET_UNUSED(a) (a).status = UNUSED;
+
+#define MAX_NUM_REF_IDX_L0_ACTIVE 16
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static i32 ComparePictures(const void *ptr1, const void *ptr2);
+
+static u32 Mmcop1(dpbStorage_t *dpb, u32 currPicNum, u32 differenceOfPicNums);
+
+static u32 Mmcop2(dpbStorage_t *dpb, u32 longTermPicNum);
+
+static u32 Mmcop3(dpbStorage_t *dpb, u32 currPicNum, u32 differenceOfPicNums,
+ u32 longTermFrameIdx);
+
+static u32 Mmcop4(dpbStorage_t *dpb, u32 maxLongTermFrameIdx);
+
+static u32 Mmcop5(dpbStorage_t *dpb);
+
+static u32 Mmcop6(dpbStorage_t *dpb, u32 frameNum, i32 picOrderCnt,
+ u32 longTermFrameIdx);
+
+static u32 SlidingWindowRefPicMarking(dpbStorage_t *dpb);
+
+static i32 FindDpbPic(dpbStorage_t *dpb, i32 picNum, u32 isShortTerm);
+
+static void SetPicNums(dpbStorage_t *dpb, u32 currFrameNum);
+
+static dpbPicture_t* FindSmallestPicOrderCnt(dpbStorage_t *dpb);
+
+static u32 OutputPicture(dpbStorage_t *dpb);
+
+static void ShellSort(dpbPicture_t *pPic, u32 num);
+
+/*------------------------------------------------------------------------------
+
+ Function: ComparePictures
+
+ Functional description:
+ Function to compare dpb pictures, used by the ShellSort() function.
+ Order of the pictures after sorting shall be as follows:
+ 1) short term reference pictures starting with the largest
+ picNum
+ 2) long term reference pictures starting with the smallest
+ longTermPicNum
+ 3) pictures unused for reference but needed for display
+ 4) other pictures
+
+ Returns:
+ -1 pic 1 is greater than pic 2
+ 0 equal from comparison point of view
+ 1 pic 2 is greater then pic 1
+
+------------------------------------------------------------------------------*/
+
+static i32 ComparePictures(const void *ptr1, const void *ptr2)
+{
+
+/* Variables */
+
+ dpbPicture_t *pic1, *pic2;
+
+/* Code */
+
+ ASSERT(ptr1);
+ ASSERT(ptr2);
+
+ pic1 = (dpbPicture_t*)ptr1;
+ pic2 = (dpbPicture_t*)ptr2;
+
+ /* both are non-reference pictures, check if needed for display */
+ if (!IS_REFERENCE(*pic1) && !IS_REFERENCE(*pic2))
+ {
+ if (pic1->toBeDisplayed && !pic2->toBeDisplayed)
+ return(-1);
+ else if (!pic1->toBeDisplayed && pic2->toBeDisplayed)
+ return(1);
+ else
+ return(0);
+ }
+ /* only pic 1 needed for reference -> greater */
+ else if (!IS_REFERENCE(*pic2))
+ return(-1);
+ /* only pic 2 needed for reference -> greater */
+ else if (!IS_REFERENCE(*pic1))
+ return(1);
+ /* both are short term reference pictures -> check picNum */
+ else if (IS_SHORT_TERM(*pic1) && IS_SHORT_TERM(*pic2))
+ {
+ if (pic1->picNum > pic2->picNum)
+ return(-1);
+ else if (pic1->picNum < pic2->picNum)
+ return(1);
+ else
+ return(0);
+ }
+ /* only pic 1 is short term -> greater */
+ else if (IS_SHORT_TERM(*pic1))
+ return(-1);
+ /* only pic 2 is short term -> greater */
+ else if (IS_SHORT_TERM(*pic2))
+ return(1);
+ /* both are long term reference pictures -> check picNum (contains the
+ * longTermPicNum */
+ else
+ {
+ if (pic1->picNum > pic2->picNum)
+ return(1);
+ else if (pic1->picNum < pic2->picNum)
+ return(-1);
+ else
+ return(0);
+ }
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdReorderRefPicList
+
+ Functional description:
+ Function to perform reference picture list reordering based on
+ reordering commands received in the slice header. See details
+ of the process in the H.264 standard.
+
+ Inputs:
+ dpb pointer to dpb storage structure
+ order pointer to reordering commands
+ currFrameNum current frame number
+ numRefIdxActive number of active reference indices for current
+ picture
+
+ Outputs:
+ dpb 'list' field of the structure reordered
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK if non-existing pictures referred to in the
+ reordering commands
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdReorderRefPicList(
+ dpbStorage_t *dpb,
+ refPicListReordering_t *order,
+ u32 currFrameNum,
+ u32 numRefIdxActive)
+{
+
+/* Variables */
+
+ u32 i, j, k, picNumPred, refIdx;
+ i32 picNum, picNumNoWrap, index;
+ u32 isShortTerm;
+
+/* Code */
+
+ ASSERT(order);
+ ASSERT(currFrameNum <= dpb->maxFrameNum);
+ ASSERT(numRefIdxActive <= MAX_NUM_REF_IDX_L0_ACTIVE);
+
+ /* set dpb picture numbers for sorting */
+ SetPicNums(dpb, currFrameNum);
+
+ if (!order->refPicListReorderingFlagL0)
+ return(HANTRO_OK);
+
+ refIdx = 0;
+ picNumPred = currFrameNum;
+
+ i = 0;
+ while (order->command[i].reorderingOfPicNumsIdc < 3)
+ {
+ /* short term */
+ if (order->command[i].reorderingOfPicNumsIdc < 2)
+ {
+ if (order->command[i].reorderingOfPicNumsIdc == 0)
+ {
+ picNumNoWrap =
+ (i32)picNumPred - (i32)order->command[i].absDiffPicNum;
+ if (picNumNoWrap < 0)
+ picNumNoWrap += (i32)dpb->maxFrameNum;
+ }
+ else
+ {
+ picNumNoWrap =
+ (i32)(picNumPred + order->command[i].absDiffPicNum);
+ if (picNumNoWrap >= (i32)dpb->maxFrameNum)
+ picNumNoWrap -= (i32)dpb->maxFrameNum;
+ }
+ picNumPred = (u32)picNumNoWrap;
+ picNum = picNumNoWrap;
+ if ((u32)picNumNoWrap > currFrameNum)
+ picNum -= (i32)dpb->maxFrameNum;
+ isShortTerm = HANTRO_TRUE;
+ }
+ /* long term */
+ else
+ {
+ picNum = (i32)order->command[i].longTermPicNum;
+ isShortTerm = HANTRO_FALSE;
+
+ }
+ /* find corresponding picture from dpb */
+ index = FindDpbPic(dpb, picNum, isShortTerm);
+ if (index < 0 || !IS_EXISTING(dpb->buffer[index]))
+ return(HANTRO_NOK);
+
+ /* shift pictures */
+ for (j = numRefIdxActive; j > refIdx; j--)
+ dpb->list[j] = dpb->list[j-1];
+ /* put picture into the list */
+ dpb->list[refIdx++] = &dpb->buffer[index];
+ /* remove later references to the same picture */
+ for (j = k = refIdx; j <= numRefIdxActive; j++)
+ if(dpb->list[j] != &dpb->buffer[index])
+ dpb->list[k++] = dpb->list[j];
+
+ i++;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Mmcop1
+
+ Functional description:
+ Function to mark a short-term reference picture unused for
+ reference, memory_management_control_operation equal to 1
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, picture does not exist in the buffer
+
+------------------------------------------------------------------------------*/
+
+static u32 Mmcop1(dpbStorage_t *dpb, u32 currPicNum, u32 differenceOfPicNums)
+{
+
+/* Variables */
+
+ i32 index, picNum;
+
+/* Code */
+
+ ASSERT(currPicNum < dpb->maxFrameNum);
+
+ picNum = (i32)currPicNum - (i32)differenceOfPicNums;
+
+ index = FindDpbPic(dpb, picNum, HANTRO_TRUE);
+ if (index < 0)
+ return(HANTRO_NOK);
+
+ SET_UNUSED(dpb->buffer[index]);
+ dpb->numRefFrames--;
+ if (!dpb->buffer[index].toBeDisplayed)
+ dpb->fullness--;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Mmcop2
+
+ Functional description:
+ Function to mark a long-term reference picture unused for
+ reference, memory_management_control_operation equal to 2
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, picture does not exist in the buffer
+
+------------------------------------------------------------------------------*/
+
+static u32 Mmcop2(dpbStorage_t *dpb, u32 longTermPicNum)
+{
+
+/* Variables */
+
+ i32 index;
+
+/* Code */
+
+ index = FindDpbPic(dpb, (i32)longTermPicNum, HANTRO_FALSE);
+ if (index < 0)
+ return(HANTRO_NOK);
+
+ SET_UNUSED(dpb->buffer[index]);
+ dpb->numRefFrames--;
+ if (!dpb->buffer[index].toBeDisplayed)
+ dpb->fullness--;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Mmcop3
+
+ Functional description:
+ Function to assing a longTermFrameIdx to a short-term reference
+ frame (i.e. to change it to a long-term reference picture),
+ memory_management_control_operation equal to 3
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, short-term picture does not exist in the
+ buffer or is a non-existing picture, or invalid
+ longTermFrameIdx given
+
+------------------------------------------------------------------------------*/
+
+static u32 Mmcop3(dpbStorage_t *dpb, u32 currPicNum, u32 differenceOfPicNums,
+ u32 longTermFrameIdx)
+{
+
+/* Variables */
+
+ i32 index, picNum;
+ u32 i;
+
+/* Code */
+
+ ASSERT(dpb);
+ ASSERT(currPicNum < dpb->maxFrameNum);
+
+ if ( (dpb->maxLongTermFrameIdx == NO_LONG_TERM_FRAME_INDICES) ||
+ (longTermFrameIdx > dpb->maxLongTermFrameIdx) )
+ return(HANTRO_NOK);
+
+ /* check if a long term picture with the same longTermFrameIdx already
+ * exist and remove it if necessary */
+ for (i = 0; i < dpb->maxRefFrames; i++)
+ if (IS_LONG_TERM(dpb->buffer[i]) &&
+ (u32)dpb->buffer[i].picNum == longTermFrameIdx)
+ {
+ SET_UNUSED(dpb->buffer[i]);
+ dpb->numRefFrames--;
+ if (!dpb->buffer[i].toBeDisplayed)
+ dpb->fullness--;
+ break;
+ }
+
+ picNum = (i32)currPicNum - (i32)differenceOfPicNums;
+
+ index = FindDpbPic(dpb, picNum, HANTRO_TRUE);
+ if (index < 0)
+ return(HANTRO_NOK);
+ if (!IS_EXISTING(dpb->buffer[index]))
+ return(HANTRO_NOK);
+
+ dpb->buffer[index].status = LONG_TERM;
+ dpb->buffer[index].picNum = (i32)longTermFrameIdx;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Mmcop4
+
+ Functional description:
+ Function to set maxLongTermFrameIdx,
+ memory_management_control_operation equal to 4
+
+ Returns:
+ HANTRO_OK success
+
+------------------------------------------------------------------------------*/
+
+static u32 Mmcop4(dpbStorage_t *dpb, u32 maxLongTermFrameIdx)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ dpb->maxLongTermFrameIdx = maxLongTermFrameIdx;
+
+ for (i = 0; i < dpb->maxRefFrames; i++)
+ if (IS_LONG_TERM(dpb->buffer[i]) &&
+ ( ((u32)dpb->buffer[i].picNum > maxLongTermFrameIdx) ||
+ (dpb->maxLongTermFrameIdx == NO_LONG_TERM_FRAME_INDICES) ) )
+ {
+ SET_UNUSED(dpb->buffer[i]);
+ dpb->numRefFrames--;
+ if (!dpb->buffer[i].toBeDisplayed)
+ dpb->fullness--;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Mmcop5
+
+ Functional description:
+ Function to mark all reference pictures unused for reference and
+ set maxLongTermFrameIdx to NO_LONG_TERM_FRAME_INDICES,
+ memory_management_control_operation equal to 5. Function flushes
+ the buffer and places all pictures that are needed for display into
+ the output buffer.
+
+ Returns:
+ HANTRO_OK success
+
+------------------------------------------------------------------------------*/
+
+static u32 Mmcop5(dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ for (i = 0; i < 16; i++)
+ {
+ if (IS_REFERENCE(dpb->buffer[i]))
+ {
+ SET_UNUSED(dpb->buffer[i]);
+ if (!dpb->buffer[i].toBeDisplayed)
+ dpb->fullness--;
+ }
+ }
+
+ /* output all pictures */
+ while (OutputPicture(dpb) == HANTRO_OK)
+ ;
+ dpb->numRefFrames = 0;
+ dpb->maxLongTermFrameIdx = NO_LONG_TERM_FRAME_INDICES;
+ dpb->prevRefFrameNum = 0;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Mmcop6
+
+ Functional description:
+ Function to assign longTermFrameIdx to the current picture,
+ memory_management_control_operation equal to 6
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid longTermFrameIdx or no room for current
+ picture in the buffer
+
+------------------------------------------------------------------------------*/
+
+static u32 Mmcop6(dpbStorage_t *dpb, u32 frameNum, i32 picOrderCnt,
+ u32 longTermFrameIdx)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(frameNum < dpb->maxFrameNum);
+
+ if ( (dpb->maxLongTermFrameIdx == NO_LONG_TERM_FRAME_INDICES) ||
+ (longTermFrameIdx > dpb->maxLongTermFrameIdx) )
+ return(HANTRO_NOK);
+
+ /* check if a long term picture with the same longTermFrameIdx already
+ * exist and remove it if necessary */
+ for (i = 0; i < dpb->maxRefFrames; i++)
+ if (IS_LONG_TERM(dpb->buffer[i]) &&
+ (u32)dpb->buffer[i].picNum == longTermFrameIdx)
+ {
+ SET_UNUSED(dpb->buffer[i]);
+ dpb->numRefFrames--;
+ if (!dpb->buffer[i].toBeDisplayed)
+ dpb->fullness--;
+ break;
+ }
+
+ if (dpb->numRefFrames < dpb->maxRefFrames)
+ {
+ dpb->currentOut->frameNum = frameNum;
+ dpb->currentOut->picNum = (i32)longTermFrameIdx;
+ dpb->currentOut->picOrderCnt = picOrderCnt;
+ dpb->currentOut->status = LONG_TERM;
+ if (dpb->noReordering)
+ dpb->currentOut->toBeDisplayed = HANTRO_FALSE;
+ else
+ dpb->currentOut->toBeDisplayed = HANTRO_TRUE;
+ dpb->numRefFrames++;
+ dpb->fullness++;
+ return(HANTRO_OK);
+ }
+ /* if there is no room, return an error */
+ else
+ return(HANTRO_NOK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdMarkDecRefPic
+
+ Functional description:
+ Function to perform reference picture marking process. This
+ function should be called both for reference and non-reference
+ pictures. Non-reference pictures shall have mark pointer set to
+ NULL.
+
+ Inputs:
+ dpb pointer to the DPB data structure
+ mark pointer to reference picture marking commands
+ image pointer to current picture to be placed in the buffer
+ frameNum frame number of the current picture
+ picOrderCnt picture order count for the current picture
+ isIdr flag to indicate if the current picture is an
+ IDR picture
+ currentPicId identifier for the current picture, from the
+ application, stored along with the picture
+ numErrMbs number of concealed macroblocks in the current
+ picture, stored along with the picture
+
+ Outputs:
+ dpb 'buffer' modified, possible output frames placed into
+ 'outBuf'
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdMarkDecRefPic(
+ dpbStorage_t *dpb,
+ decRefPicMarking_t *mark,
+ image_t *image,
+ u32 frameNum,
+ i32 picOrderCnt,
+ u32 isIdr,
+ u32 currentPicId,
+ u32 numErrMbs)
+{
+
+/* Variables */
+
+ u32 i, status;
+ u32 markedAsLongTerm;
+ u32 toBeDisplayed;
+
+/* Code */
+
+ ASSERT(dpb);
+ ASSERT(mark || !isIdr);
+ ASSERT(!isIdr || (frameNum == 0 && picOrderCnt == 0));
+ ASSERT(frameNum < dpb->maxFrameNum);
+
+ if (image->data != dpb->currentOut->data)
+ {
+ EPRINT("TRYING TO MARK NON-ALLOCATED IMAGE");
+ return(HANTRO_NOK);
+ }
+
+ dpb->lastContainsMmco5 = HANTRO_FALSE;
+ status = HANTRO_OK;
+
+ toBeDisplayed = dpb->noReordering ? HANTRO_FALSE : HANTRO_TRUE;
+
+ /* non-reference picture, stored for display reordering purposes */
+ if (mark == NULL)
+ {
+ dpb->currentOut->status = UNUSED;
+ dpb->currentOut->frameNum = frameNum;
+ dpb->currentOut->picNum = (i32)frameNum;
+ dpb->currentOut->picOrderCnt = picOrderCnt;
+ dpb->currentOut->toBeDisplayed = toBeDisplayed;
+ if (!dpb->noReordering)
+ dpb->fullness++;
+ }
+ /* IDR picture */
+ else if (isIdr)
+ {
+
+ /* h264bsdCheckGapsInFrameNum not called for IDR pictures -> have to
+ * reset numOut and outIndex here */
+ dpb->numOut = dpb->outIndex = 0;
+
+ /* flush the buffer */
+ Mmcop5(dpb);
+ /* if noOutputOfPriorPicsFlag was set -> the pictures preceding the
+ * IDR picture shall not be output -> set output buffer empty */
+ if (mark->noOutputOfPriorPicsFlag || dpb->noReordering)
+ {
+ dpb->numOut = 0;
+ dpb->outIndex = 0;
+ }
+
+ if (mark->longTermReferenceFlag)
+ {
+ dpb->currentOut->status = LONG_TERM;
+ dpb->maxLongTermFrameIdx = 0;
+ }
+ else
+ {
+ dpb->currentOut->status = SHORT_TERM;
+ dpb->maxLongTermFrameIdx = NO_LONG_TERM_FRAME_INDICES;
+ }
+ dpb->currentOut->frameNum = 0;
+ dpb->currentOut->picNum = 0;
+ dpb->currentOut->picOrderCnt = 0;
+ dpb->currentOut->toBeDisplayed = toBeDisplayed;
+ dpb->fullness = 1;
+ dpb->numRefFrames = 1;
+ }
+ /* reference picture */
+ else
+ {
+ markedAsLongTerm = HANTRO_FALSE;
+ if (mark->adaptiveRefPicMarkingModeFlag)
+ {
+ i = 0;
+ while (mark->operation[i].memoryManagementControlOperation)
+ {
+ switch (mark->operation[i].memoryManagementControlOperation)
+ {
+ case 1:
+ status = Mmcop1(
+ dpb,
+ frameNum,
+ mark->operation[i].differenceOfPicNums);
+ break;
+
+ case 2:
+ status = Mmcop2(dpb, mark->operation[i].longTermPicNum);
+ break;
+
+ case 3:
+ status = Mmcop3(
+ dpb,
+ frameNum,
+ mark->operation[i].differenceOfPicNums,
+ mark->operation[i].longTermFrameIdx);
+ break;
+
+ case 4:
+ status = Mmcop4(
+ dpb,
+ mark->operation[i].maxLongTermFrameIdx);
+ break;
+
+ case 5:
+ status = Mmcop5(dpb);
+ dpb->lastContainsMmco5 = HANTRO_TRUE;
+ frameNum = 0;
+ break;
+
+ case 6:
+ status = Mmcop6(
+ dpb,
+ frameNum,
+ picOrderCnt,
+ mark->operation[i].longTermFrameIdx);
+ if (status == HANTRO_OK)
+ markedAsLongTerm = HANTRO_TRUE;
+ break;
+
+ default: /* invalid memory management control operation */
+ status = HANTRO_NOK;
+ break;
+ }
+ if (status != HANTRO_OK)
+ {
+ break;
+ }
+ i++;
+ }
+ }
+ else
+ {
+ status = SlidingWindowRefPicMarking(dpb);
+ }
+ /* if current picture was not marked as long-term reference by
+ * memory management control operation 6 -> mark current as short
+ * term and insert it into dpb (if there is room) */
+ if (!markedAsLongTerm)
+ {
+ if (dpb->numRefFrames < dpb->maxRefFrames)
+ {
+ dpb->currentOut->frameNum = frameNum;
+ dpb->currentOut->picNum = (i32)frameNum;
+ dpb->currentOut->picOrderCnt = picOrderCnt;
+ dpb->currentOut->status = SHORT_TERM;
+ dpb->currentOut->toBeDisplayed = toBeDisplayed;
+ dpb->fullness++;
+ dpb->numRefFrames++;
+ }
+ /* no room */
+ else
+ {
+ status = HANTRO_NOK;
+ }
+ }
+ }
+
+ dpb->currentOut->isIdr = isIdr;
+ dpb->currentOut->picId = currentPicId;
+ dpb->currentOut->numErrMbs = numErrMbs;
+
+ /* dpb was initialized to not to reorder the pictures -> output current
+ * picture immediately */
+ if (dpb->noReordering)
+ {
+ ASSERT(dpb->numOut == 0);
+ ASSERT(dpb->outIndex == 0);
+ dpb->outBuf[dpb->numOut].data = dpb->currentOut->data;
+ dpb->outBuf[dpb->numOut].isIdr = dpb->currentOut->isIdr;
+ dpb->outBuf[dpb->numOut].picId = dpb->currentOut->picId;
+ dpb->outBuf[dpb->numOut].numErrMbs = dpb->currentOut->numErrMbs;
+ dpb->numOut++;
+ }
+ else
+ {
+ /* output pictures if buffer full */
+ while (dpb->fullness > dpb->dpbSize)
+ {
+ i = OutputPicture(dpb);
+ ASSERT(i == HANTRO_OK);
+ }
+ }
+
+ /* sort dpb */
+ ShellSort(dpb->buffer, dpb->dpbSize+1);
+
+ return(status);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdGetRefPicData
+
+ Functional description:
+ Function to get reference picture data from the reference picture
+ list
+
+ Returns:
+ pointer to desired reference picture data
+ NULL if invalid index or non-existing picture referred
+
+------------------------------------------------------------------------------*/
+
+u8* h264bsdGetRefPicData(dpbStorage_t *dpb, u32 index)
+{
+
+/* Variables */
+
+/* Code */
+
+ if(index > 16 || dpb->list[index] == NULL)
+ return(NULL);
+ else if(!IS_EXISTING(*dpb->list[index]))
+ return(NULL);
+ else
+ return(dpb->list[index]->data);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdAllocateDpbImage
+
+ Functional description:
+ function to allocate memory for a image. This function does not
+ really allocate any memory but reserves one of the buffer
+ positions for decoding of current picture
+
+ Returns:
+ pointer to memory area for the image
+
+
+------------------------------------------------------------------------------*/
+
+u8* h264bsdAllocateDpbImage(dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT( !dpb->buffer[dpb->dpbSize].toBeDisplayed &&
+ !IS_REFERENCE(dpb->buffer[dpb->dpbSize]) );
+ ASSERT(dpb->fullness <= dpb->dpbSize);
+
+ dpb->currentOut = dpb->buffer + dpb->dpbSize;
+
+ return(dpb->currentOut->data);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: SlidingWindowRefPicMarking
+
+ Functional description:
+ Function to perform sliding window refence picture marking process.
+
+ Outputs:
+ HANTRO_OK success
+ HANTRO_NOK failure, no short-term reference frame found that
+ could be marked unused
+
+
+------------------------------------------------------------------------------*/
+
+static u32 SlidingWindowRefPicMarking(dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+ i32 index, picNum;
+ u32 i;
+
+/* Code */
+
+ if (dpb->numRefFrames < dpb->maxRefFrames)
+ {
+ return(HANTRO_OK);
+ }
+ else
+ {
+ index = -1;
+ picNum = 0;
+ /* find the oldest short term picture */
+ for (i = 0; i < dpb->numRefFrames; i++)
+ if (IS_SHORT_TERM(dpb->buffer[i]))
+ if (dpb->buffer[i].picNum < picNum || index == -1)
+ {
+ index = (i32)i;
+ picNum = dpb->buffer[i].picNum;
+ }
+ if (index >= 0)
+ {
+ SET_UNUSED(dpb->buffer[index]);
+ dpb->numRefFrames--;
+ if (!dpb->buffer[index].toBeDisplayed)
+ dpb->fullness--;
+
+ return(HANTRO_OK);
+ }
+ }
+
+ return(HANTRO_NOK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInitDpb
+
+ Functional description:
+ Function to initialize DPB. Reserves memories for the buffer,
+ reference picture list and output buffer. dpbSize indicates
+ the maximum DPB size indicated by the levelIdc in the stream.
+ If noReordering flag is FALSE the DPB stores dpbSize pictures
+ for display reordering purposes. On the other hand, if the
+ flag is TRUE the DPB only stores maxRefFrames reference pictures
+ and outputs all the pictures immediately.
+
+ Inputs:
+ picSizeInMbs picture size in macroblocks
+ dpbSize size of the DPB (number of pictures)
+ maxRefFrames max number of reference frames
+ maxFrameNum max frame number
+ noReordering flag to indicate that DPB does not have to
+ prepare to reorder frames for display
+
+ Outputs:
+ dpb pointer to dpb data storage
+
+ Returns:
+ HANTRO_OK success
+ MEMORY_ALLOCATION_ERROR if memory allocation failed
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdInitDpb(
+ dpbStorage_t *dpb,
+ u32 picSizeInMbs,
+ u32 dpbSize,
+ u32 maxRefFrames,
+ u32 maxFrameNum,
+ u32 noReordering)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(picSizeInMbs);
+ ASSERT(maxRefFrames <= MAX_NUM_REF_PICS);
+ ASSERT(maxRefFrames <= dpbSize);
+ ASSERT(maxFrameNum);
+ ASSERT(dpbSize);
+
+ dpb->maxLongTermFrameIdx = NO_LONG_TERM_FRAME_INDICES;
+ dpb->maxRefFrames = MAX(maxRefFrames, 1);
+ if (noReordering)
+ dpb->dpbSize = dpb->maxRefFrames;
+ else
+ dpb->dpbSize = dpbSize;
+ dpb->maxFrameNum = maxFrameNum;
+ dpb->noReordering = noReordering;
+ dpb->fullness = 0;
+ dpb->numRefFrames = 0;
+ dpb->prevRefFrameNum = 0;
+
+ ALLOCATE(dpb->buffer, MAX_NUM_REF_IDX_L0_ACTIVE + 1, dpbPicture_t);
+ if (dpb->buffer == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+ memset(dpb->buffer, 0,
+ (MAX_NUM_REF_IDX_L0_ACTIVE + 1)*sizeof(dpbPicture_t));
+ for (i = 0; i < dpb->dpbSize + 1; i++)
+ {
+ /* Allocate needed amount of memory, which is:
+ * image size + 32 + 15, where 32 cames from the fact that in ARM OpenMax
+ * DL implementation Functions may read beyond the end of an array,
+ * by a maximum of 32 bytes. And +15 cames for the need to align memory
+ * to 16-byte boundary */
+ ALLOCATE(dpb->buffer[i].pAllocatedData, (picSizeInMbs*384 + 32+15), u8);
+ if (dpb->buffer[i].pAllocatedData == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+
+ dpb->buffer[i].data = ALIGN(dpb->buffer[i].pAllocatedData, 16);
+ }
+
+ ALLOCATE(dpb->list, MAX_NUM_REF_IDX_L0_ACTIVE + 1, dpbPicture_t*);
+ ALLOCATE(dpb->outBuf, dpb->dpbSize+1, dpbOutPicture_t);
+
+ if (dpb->list == NULL || dpb->outBuf == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+
+ memset(dpb->list, 0,
+ ((MAX_NUM_REF_IDX_L0_ACTIVE + 1) * sizeof(dpbPicture_t*)) );
+
+ dpb->numOut = dpb->outIndex = 0;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdResetDpb
+
+ Functional description:
+ Function to reset DPB. This function should be called when an IDR
+ slice (other than the first) activates new sequence parameter set.
+ Function calls h264bsdFreeDpb to free old allocated memories and
+ h264bsdInitDpb to re-initialize the DPB. Same inputs, outputs and
+ returns as for h264bsdInitDpb.
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdResetDpb(
+ dpbStorage_t *dpb,
+ u32 picSizeInMbs,
+ u32 dpbSize,
+ u32 maxRefFrames,
+ u32 maxFrameNum,
+ u32 noReordering)
+{
+
+/* Code */
+
+ ASSERT(picSizeInMbs);
+ ASSERT(maxRefFrames <= MAX_NUM_REF_PICS);
+ ASSERT(maxRefFrames <= dpbSize);
+ ASSERT(maxFrameNum);
+ ASSERT(dpbSize);
+
+ h264bsdFreeDpb(dpb);
+
+ return h264bsdInitDpb(dpb, picSizeInMbs, dpbSize, maxRefFrames,
+ maxFrameNum, noReordering);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInitRefPicList
+
+ Functional description:
+ Function to initialize reference picture list. Function just
+ sets pointers in the list according to pictures in the buffer.
+ The buffer is assumed to contain pictures sorted according to
+ what the H.264 standard says about initial reference picture list.
+
+ Inputs:
+ dpb pointer to dpb data structure
+
+ Outputs:
+ dpb 'list' field initialized
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInitRefPicList(dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ for (i = 0; i < dpb->numRefFrames; i++)
+ dpb->list[i] = &dpb->buffer[i];
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: FindDpbPic
+
+ Functional description:
+ Function to find a reference picture from the buffer. The picture
+ to be found is identified by picNum and isShortTerm flag.
+
+ Returns:
+ index of the picture in the buffer
+ -1 if the specified picture was not found in the buffer
+
+------------------------------------------------------------------------------*/
+
+static i32 FindDpbPic(dpbStorage_t *dpb, i32 picNum, u32 isShortTerm)
+{
+
+/* Variables */
+
+ u32 i = 0;
+ u32 found = HANTRO_FALSE;
+
+/* Code */
+
+ if (isShortTerm)
+ {
+ while (i < dpb->maxRefFrames && !found)
+ {
+ if (IS_SHORT_TERM(dpb->buffer[i]) &&
+ dpb->buffer[i].picNum == picNum)
+ found = HANTRO_TRUE;
+ else
+ i++;
+ }
+ }
+ else
+ {
+ ASSERT(picNum >= 0);
+ while (i < dpb->maxRefFrames && !found)
+ {
+ if (IS_LONG_TERM(dpb->buffer[i]) &&
+ dpb->buffer[i].picNum == picNum)
+ found = HANTRO_TRUE;
+ else
+ i++;
+ }
+ }
+
+ if (found)
+ return((i32)i);
+ else
+ return(-1);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: SetPicNums
+
+ Functional description:
+ Function to set picNum values for short-term pictures in the
+ buffer. Numbering of pictures is based on frame numbers and as
+ frame numbers are modulo maxFrameNum -> frame numbers of older
+ pictures in the buffer may be bigger than the currFrameNum.
+ picNums will be set so that current frame has the largest picNum
+ and all the short-term frames in the buffer will get smaller picNum
+ representing their "distance" from the current frame. This
+ function kind of maps the modulo arithmetic back to normal.
+
+------------------------------------------------------------------------------*/
+
+static void SetPicNums(dpbStorage_t *dpb, u32 currFrameNum)
+{
+
+/* Variables */
+
+ u32 i;
+ i32 frameNumWrap;
+
+/* Code */
+
+ ASSERT(dpb);
+ ASSERT(currFrameNum < dpb->maxFrameNum);
+
+ for (i = 0; i < dpb->numRefFrames; i++)
+ if (IS_SHORT_TERM(dpb->buffer[i]))
+ {
+ if (dpb->buffer[i].frameNum > currFrameNum)
+ frameNumWrap =
+ (i32)dpb->buffer[i].frameNum - (i32)dpb->maxFrameNum;
+ else
+ frameNumWrap = (i32)dpb->buffer[i].frameNum;
+ dpb->buffer[i].picNum = frameNumWrap;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckGapsInFrameNum
+
+ Functional description:
+ Function to check gaps in frame_num and generate non-existing
+ (short term) reference pictures if necessary. This function should
+ be called only for non-IDR pictures.
+
+ Inputs:
+ dpb pointer to dpb data structure
+ frameNum frame number of the current picture
+ isRefPic flag to indicate if current picture is a reference or
+ non-reference picture
+ gapsAllowed Flag which indicates active SPS stance on whether
+ to allow gaps
+
+ Outputs:
+ dpb 'buffer' possibly modified by inserting non-existing
+ pictures with sliding window marking process
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK error in sliding window reference picture marking or
+ frameNum equal to previous reference frame used for
+ a reference picture
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckGapsInFrameNum(dpbStorage_t *dpb, u32 frameNum, u32 isRefPic,
+ u32 gapsAllowed)
+{
+
+/* Variables */
+
+ u32 unUsedShortTermFrameNum;
+ u8 *tmp;
+
+/* Code */
+
+ ASSERT(dpb);
+ ASSERT(dpb->fullness <= dpb->dpbSize);
+ ASSERT(frameNum < dpb->maxFrameNum);
+
+ dpb->numOut = 0;
+ dpb->outIndex = 0;
+
+ if(!gapsAllowed)
+ return(HANTRO_OK);
+
+ if ( (frameNum != dpb->prevRefFrameNum) &&
+ (frameNum != ((dpb->prevRefFrameNum + 1) % dpb->maxFrameNum)))
+ {
+
+ unUsedShortTermFrameNum = (dpb->prevRefFrameNum + 1) % dpb->maxFrameNum;
+
+ /* store data pointer of last buffer position to be used as next
+ * "allocated" data pointer if last buffer position after this process
+ * contains data pointer located in outBuf (buffer placed in the output
+ * shall not be overwritten by the current picture) */
+ tmp = dpb->buffer[dpb->dpbSize].data;
+ do
+ {
+ SetPicNums(dpb, unUsedShortTermFrameNum);
+
+ if (SlidingWindowRefPicMarking(dpb) != HANTRO_OK)
+ {
+ return(HANTRO_NOK);
+ }
+
+ /* output pictures if buffer full */
+ while (dpb->fullness >= dpb->dpbSize)
+ {
+#ifdef _ASSERT_USED
+ ASSERT(!dpb->noReordering);
+ ASSERT(OutputPicture(dpb) == HANTRO_OK);
+#else
+ OutputPicture(dpb);
+#endif
+ }
+
+ /* add to end of list */
+ ASSERT( !dpb->buffer[dpb->dpbSize].toBeDisplayed &&
+ !IS_REFERENCE(dpb->buffer[dpb->dpbSize]) );
+ dpb->buffer[dpb->dpbSize].status = NON_EXISTING;
+ dpb->buffer[dpb->dpbSize].frameNum = unUsedShortTermFrameNum;
+ dpb->buffer[dpb->dpbSize].picNum = (i32)unUsedShortTermFrameNum;
+ dpb->buffer[dpb->dpbSize].picOrderCnt = 0;
+ dpb->buffer[dpb->dpbSize].toBeDisplayed = HANTRO_FALSE;
+ dpb->fullness++;
+ dpb->numRefFrames++;
+
+ /* sort the buffer */
+ ShellSort(dpb->buffer, dpb->dpbSize+1);
+
+ unUsedShortTermFrameNum = (unUsedShortTermFrameNum + 1) %
+ dpb->maxFrameNum;
+
+ } while (unUsedShortTermFrameNum != frameNum);
+
+ /* pictures placed in output buffer -> check that 'data' in
+ * buffer position dpbSize is not in the output buffer (this will be
+ * "allocated" by h264bsdAllocateDpbImage). If it is -> exchange data
+ * pointer with the one stored in the beginning */
+ if (dpb->numOut)
+ {
+ u32 i;
+
+ for (i = 0; i < dpb->numOut; i++)
+ {
+ if (dpb->outBuf[i].data == dpb->buffer[dpb->dpbSize].data)
+ {
+ /* find buffer position containing data pointer stored in
+ * tmp */
+ for (i = 0; i < dpb->dpbSize; i++)
+ {
+ if (dpb->buffer[i].data == tmp)
+ {
+ dpb->buffer[i].data =
+ dpb->buffer[dpb->dpbSize].data;
+ dpb->buffer[dpb->dpbSize].data = tmp;
+ break;
+ }
+ }
+ ASSERT(i < dpb->dpbSize);
+ break;
+ }
+ }
+ }
+ }
+ /* frameNum for reference pictures shall not be the same as for previous
+ * reference picture, otherwise accesses to pictures in the buffer cannot
+ * be solved unambiguously */
+ else if (isRefPic && frameNum == dpb->prevRefFrameNum)
+ {
+ return(HANTRO_NOK);
+ }
+
+ /* save current frame_num in prevRefFrameNum. For non-reference frame
+ * prevFrameNum is set to frame number of last non-existing frame above */
+ if (isRefPic)
+ dpb->prevRefFrameNum = frameNum;
+ else if (frameNum != dpb->prevRefFrameNum)
+ {
+ dpb->prevRefFrameNum =
+ (frameNum + dpb->maxFrameNum - 1) % dpb->maxFrameNum;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: FindSmallestPicOrderCnt
+
+ Functional description:
+ Function to find picture with smallest picture order count. This
+ will be the next picture in display order.
+
+ Returns:
+ pointer to the picture, NULL if no pictures to be displayed
+
+------------------------------------------------------------------------------*/
+
+dpbPicture_t* FindSmallestPicOrderCnt(dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+ u32 i;
+ i32 picOrderCnt;
+ dpbPicture_t *tmp;
+
+/* Code */
+
+ ASSERT(dpb);
+
+ picOrderCnt = 0x7FFFFFFF;
+ tmp = NULL;
+
+ for (i = 0; i <= dpb->dpbSize; i++)
+ {
+ if (dpb->buffer[i].toBeDisplayed &&
+ (dpb->buffer[i].picOrderCnt < picOrderCnt))
+ {
+ tmp = dpb->buffer + i;
+ picOrderCnt = dpb->buffer[i].picOrderCnt;
+ }
+ }
+
+ return(tmp);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: OutputPicture
+
+ Functional description:
+ Function to put next display order picture into the output buffer.
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK no pictures to display
+
+------------------------------------------------------------------------------*/
+
+u32 OutputPicture(dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+ dpbPicture_t *tmp;
+
+/* Code */
+
+ ASSERT(dpb);
+
+ if (dpb->noReordering)
+ return(HANTRO_NOK);
+
+ tmp = FindSmallestPicOrderCnt(dpb);
+
+ /* no pictures to be displayed */
+ if (tmp == NULL)
+ return(HANTRO_NOK);
+
+ dpb->outBuf[dpb->numOut].data = tmp->data;
+ dpb->outBuf[dpb->numOut].isIdr = tmp->isIdr;
+ dpb->outBuf[dpb->numOut].picId = tmp->picId;
+ dpb->outBuf[dpb->numOut].numErrMbs = tmp->numErrMbs;
+ dpb->numOut++;
+
+ tmp->toBeDisplayed = HANTRO_FALSE;
+ if (!IS_REFERENCE(*tmp))
+ {
+ dpb->fullness--;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdDpbOutputPicture
+
+ Functional description:
+ Function to get next display order picture from the output buffer.
+
+ Return:
+ pointer to output picture structure, NULL if no pictures to
+ display
+
+------------------------------------------------------------------------------*/
+
+dpbOutPicture_t* h264bsdDpbOutputPicture(dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(dpb);
+
+ if (dpb->outIndex < dpb->numOut)
+ return(dpb->outBuf + dpb->outIndex++);
+ else
+ return(NULL);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdFlushDpb
+
+ Functional description:
+ Function to flush the DPB. Function puts all pictures needed for
+ display into the output buffer. This function shall be called in
+ the end of the stream to obtain pictures buffered for display
+ re-ordering purposes.
+
+------------------------------------------------------------------------------*/
+
+void h264bsdFlushDpb(dpbStorage_t *dpb)
+{
+
+ /* don't do anything if buffer not reserved */
+ if (dpb->buffer)
+ {
+ dpb->flushed = 1;
+ /* output all pictures */
+ while (OutputPicture(dpb) == HANTRO_OK)
+ ;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdFreeDpb
+
+ Functional description:
+ Function to free memories reserved for the DPB.
+
+------------------------------------------------------------------------------*/
+
+void h264bsdFreeDpb(dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(dpb);
+
+ if (dpb->buffer)
+ {
+ for (i = 0; i < dpb->dpbSize+1; i++)
+ {
+ FREE(dpb->buffer[i].pAllocatedData);
+ }
+ }
+ FREE(dpb->buffer);
+ FREE(dpb->list);
+ FREE(dpb->outBuf);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: ShellSort
+
+ Functional description:
+ Sort pictures in the buffer. Function implements Shell's method,
+ i.e. diminishing increment sort. See e.g. "Numerical Recipes in C"
+ for more information.
+
+------------------------------------------------------------------------------*/
+
+static void ShellSort(dpbPicture_t *pPic, u32 num)
+{
+
+ u32 i, j;
+ u32 step;
+ dpbPicture_t tmpPic;
+
+ step = 7;
+
+ while (step)
+ {
+ for (i = step; i < num; i++)
+ {
+ tmpPic = pPic[i];
+ j = i;
+ while (j >= step && ComparePictures(pPic + j - step, &tmpPic) > 0)
+ {
+ pPic[j] = pPic[j-step];
+ j -= step;
+ }
+ pPic[j] = tmpPic;
+ }
+ step >>= 1;
+ }
+
+}
+
--- /dev/null
+++ b/src/h264bsd_dpb.h
@@ -1,0 +1,150 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_DPB_H
+#define H264SWDEC_DPB_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_image.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/* enumeration to represent status of buffered image */
+typedef enum {
+ UNUSED = 0,
+ NON_EXISTING,
+ SHORT_TERM,
+ LONG_TERM
+} dpbPictureStatus_e;
+
+/* structure to represent a buffered picture */
+typedef struct {
+ u8 *data; /* 16-byte aligned pointer of pAllocatedData */
+ u8 *pAllocatedData; /* allocated picture pointer; (size + 15) bytes */
+ i32 picNum;
+ u32 frameNum;
+ i32 picOrderCnt;
+ dpbPictureStatus_e status;
+ u32 toBeDisplayed;
+ u32 picId;
+ u32 numErrMbs;
+ u32 isIdr;
+} dpbPicture_t;
+
+/* structure to represent display image output from the buffer */
+typedef struct {
+ u8 *data;
+ u32 picId;
+ u32 numErrMbs;
+ u32 isIdr;
+} dpbOutPicture_t;
+
+/* structure to represent DPB */
+typedef struct {
+ dpbPicture_t *buffer;
+ dpbPicture_t **list;
+ dpbPicture_t *currentOut;
+ dpbOutPicture_t *outBuf;
+ u32 numOut;
+ u32 outIndex;
+ u32 maxRefFrames;
+ u32 dpbSize;
+ u32 maxFrameNum;
+ u32 maxLongTermFrameIdx;
+ u32 numRefFrames;
+ u32 fullness;
+ u32 prevRefFrameNum;
+ u32 lastContainsMmco5;
+ u32 noReordering;
+ u32 flushed;
+} dpbStorage_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdInitDpb(
+ dpbStorage_t *dpb,
+ u32 picSizeInMbs,
+ u32 dpbSize,
+ u32 numRefFrames,
+ u32 maxFrameNum,
+ u32 noReordering);
+
+u32 h264bsdResetDpb(
+ dpbStorage_t *dpb,
+ u32 picSizeInMbs,
+ u32 dpbSize,
+ u32 numRefFrames,
+ u32 maxFrameNum,
+ u32 noReordering);
+
+void h264bsdInitRefPicList(dpbStorage_t *dpb);
+
+u8* h264bsdAllocateDpbImage(dpbStorage_t *dpb);
+
+u8* h264bsdGetRefPicData(dpbStorage_t *dpb, u32 index);
+
+u32 h264bsdReorderRefPicList(
+ dpbStorage_t *dpb,
+ refPicListReordering_t *order,
+ u32 currFrameNum,
+ u32 numRefIdxActive);
+
+u32 h264bsdMarkDecRefPic(
+ dpbStorage_t *dpb,
+ decRefPicMarking_t *mark,
+ image_t *image,
+ u32 frameNum,
+ i32 picOrderCnt,
+ u32 isIdr,
+ u32 picId,
+ u32 numErrMbs);
+
+u32 h264bsdCheckGapsInFrameNum(dpbStorage_t *dpb, u32 frameNum, u32 isRefPic,
+ u32 gapsAllowed);
+
+dpbOutPicture_t* h264bsdDpbOutputPicture(dpbStorage_t *dpb);
+
+void h264bsdFlushDpb(dpbStorage_t *dpb);
+
+void h264bsdFreeDpb(dpbStorage_t *dpb);
+
+#endif /* #ifdef H264SWDEC_DPB_H */
+
--- /dev/null
+++ b/src/h264bsd_image.c
@@ -1,0 +1,346 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdWriteMacroblock
+ h264bsdWriteOutputBlocks
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_image.h"
+#include "h264bsd_util.h"
+#include "h264bsd_neighbour.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* x- and y-coordinates for each block, defined in h264bsd_intra_prediction.c */
+extern const u32 h264bsdBlockX[];
+extern const u32 h264bsdBlockY[];
+
+/* clipping table, defined in h264bsd_intra_prediction.c */
+extern const u8 h264bsdClip[];
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdWriteMacroblock
+
+ Functional description:
+ Write one macroblock into the image. Both luma and chroma
+ components will be written at the same time.
+
+ Inputs:
+ data pointer to macroblock data to be written, 256 values for
+ luma followed by 64 values for both chroma components
+
+ Outputs:
+ image pointer to the image where the macroblock will be written
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_NEON
+void h264bsdWriteMacroblock(image_t *image, u8 *data)
+{
+
+/* Variables */
+
+ u32 i;
+ u32 width;
+ u32 *lum, *cb, *cr;
+ u32 *ptr;
+ u32 tmp1, tmp2;
+
+/* Code */
+
+ ASSERT(image);
+ ASSERT(data);
+ ASSERT(!((u32)data&0x3));
+
+ width = image->width;
+
+ /*lint -save -e826 lum, cb and cr used to copy 4 bytes at the time, disable
+ * "area too small" info message */
+ lum = (u32*)image->luma;
+ cb = (u32*)image->cb;
+ cr = (u32*)image->cr;
+ ASSERT(!((u32)lum&0x3));
+ ASSERT(!((u32)cb&0x3));
+ ASSERT(!((u32)cr&0x3));
+
+ ptr = (u32*)data;
+
+ width *= 4;
+ for (i = 16; i ; i--)
+ {
+ tmp1 = *ptr++;
+ tmp2 = *ptr++;
+ *lum++ = tmp1;
+ *lum++ = tmp2;
+ tmp1 = *ptr++;
+ tmp2 = *ptr++;
+ *lum++ = tmp1;
+ *lum++ = tmp2;
+ lum += width-4;
+ }
+
+ width >>= 1;
+ for (i = 8; i ; i--)
+ {
+ tmp1 = *ptr++;
+ tmp2 = *ptr++;
+ *cb++ = tmp1;
+ *cb++ = tmp2;
+ cb += width-2;
+ }
+
+ for (i = 8; i ; i--)
+ {
+ tmp1 = *ptr++;
+ tmp2 = *ptr++;
+ *cr++ = tmp1;
+ *cr++ = tmp2;
+ cr += width-2;
+ }
+
+}
+#endif
+#ifndef H264DEC_OMXDL
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdWriteOutputBlocks
+
+ Functional description:
+ Write one macroblock into the image. Prediction for the macroblock
+ and the residual are given separately and will be combined while
+ writing the data to the image
+
+ Inputs:
+ data pointer to macroblock prediction data, 256 values for
+ luma followed by 64 values for both chroma components
+ mbNum number of the macroblock
+ residual pointer to residual data, 16 16-element arrays for luma
+ followed by 4 16-element arrays for both chroma
+ components
+
+ Outputs:
+ image pointer to the image where the data will be written
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdWriteOutputBlocks(image_t *image, u32 mbNum, u8 *data,
+ i32 residual[][16])
+{
+
+/* Variables */
+
+ u32 i;
+ u32 picWidth, picSize;
+ u8 *lum, *cb, *cr;
+ u8 *imageBlock;
+ u8 *tmp;
+ u32 row, col;
+ u32 block;
+ u32 x, y;
+ i32 *pRes;
+ i32 tmp1, tmp2, tmp3, tmp4;
+ const u8 *clp = h264bsdClip + 512;
+
+/* Code */
+
+ ASSERT(image);
+ ASSERT(data);
+ ASSERT(mbNum < image->width * image->height);
+ ASSERT(!((u32)data&0x3));
+
+ /* Image size in macroblocks */
+ picWidth = image->width;
+ picSize = picWidth * image->height;
+ row = mbNum / picWidth;
+ col = mbNum % picWidth;
+
+ /* Output macroblock position in output picture */
+ lum = (image->data + row * picWidth * 256 + col * 16);
+ cb = (image->data + picSize * 256 + row * picWidth * 64 + col * 8);
+ cr = (cb + picSize * 64);
+
+ picWidth *= 16;
+
+ for (block = 0; block < 16; block++)
+ {
+ x = h264bsdBlockX[block];
+ y = h264bsdBlockY[block];
+
+ pRes = residual[block];
+
+ ASSERT(pRes);
+
+ tmp = data + y*16 + x;
+ imageBlock = lum + y*picWidth + x;
+
+ ASSERT(!((u32)tmp&0x3));
+ ASSERT(!((u32)imageBlock&0x3));
+
+ if (IS_RESIDUAL_EMPTY(pRes))
+ {
+ /*lint -e826 */
+ i32 *in32 = (i32*)tmp;
+ i32 *out32 = (i32*)imageBlock;
+
+ /* Residual is zero => copy prediction block to output */
+ tmp1 = *in32; in32 += 4;
+ tmp2 = *in32; in32 += 4;
+ *out32 = tmp1; out32 += picWidth/4;
+ *out32 = tmp2; out32 += picWidth/4;
+ tmp1 = *in32; in32 += 4;
+ tmp2 = *in32;
+ *out32 = tmp1; out32 += picWidth/4;
+ *out32 = tmp2;
+ }
+ else
+ {
+
+ RANGE_CHECK_ARRAY(pRes, -512, 511, 16);
+
+ /* Calculate image = prediction + residual
+ * Process four pixels in a loop */
+ for (i = 4; i; i--)
+ {
+ tmp1 = tmp[0];
+ tmp2 = *pRes++;
+ tmp3 = tmp[1];
+ tmp1 = clp[tmp1 + tmp2];
+ tmp4 = *pRes++;
+ imageBlock[0] = (u8)tmp1;
+ tmp3 = clp[tmp3 + tmp4];
+ tmp1 = tmp[2];
+ tmp2 = *pRes++;
+ imageBlock[1] = (u8)tmp3;
+ tmp1 = clp[tmp1 + tmp2];
+ tmp3 = tmp[3];
+ tmp4 = *pRes++;
+ imageBlock[2] = (u8)tmp1;
+ tmp3 = clp[tmp3 + tmp4];
+ tmp += 16;
+ imageBlock[3] = (u8)tmp3;
+ imageBlock += picWidth;
+ }
+ }
+
+ }
+
+ picWidth /= 2;
+
+ for (block = 16; block <= 23; block++)
+ {
+ x = h264bsdBlockX[block & 0x3];
+ y = h264bsdBlockY[block & 0x3];
+
+ pRes = residual[block];
+
+ ASSERT(pRes);
+
+ tmp = data + 256;
+ imageBlock = cb;
+
+ if (block >= 20)
+ {
+ imageBlock = cr;
+ tmp += 64;
+ }
+
+ tmp += y*8 + x;
+ imageBlock += y*picWidth + x;
+
+ ASSERT(!((u32)tmp&0x3));
+ ASSERT(!((u32)imageBlock&0x3));
+
+ if (IS_RESIDUAL_EMPTY(pRes))
+ {
+ /*lint -e826 */
+ i32 *in32 = (i32*)tmp;
+ i32 *out32 = (i32*)imageBlock;
+
+ /* Residual is zero => copy prediction block to output */
+ tmp1 = *in32; in32 += 2;
+ tmp2 = *in32; in32 += 2;
+ *out32 = tmp1; out32 += picWidth/4;
+ *out32 = tmp2; out32 += picWidth/4;
+ tmp1 = *in32; in32 += 2;
+ tmp2 = *in32;
+ *out32 = tmp1; out32 += picWidth/4;
+ *out32 = tmp2;
+ }
+ else
+ {
+
+ RANGE_CHECK_ARRAY(pRes, -512, 511, 16);
+
+ for (i = 4; i; i--)
+ {
+ tmp1 = tmp[0];
+ tmp2 = *pRes++;
+ tmp3 = tmp[1];
+ tmp1 = clp[tmp1 + tmp2];
+ tmp4 = *pRes++;
+ imageBlock[0] = (u8)tmp1;
+ tmp3 = clp[tmp3 + tmp4];
+ tmp1 = tmp[2];
+ tmp2 = *pRes++;
+ imageBlock[1] = (u8)tmp3;
+ tmp1 = clp[tmp1 + tmp2];
+ tmp3 = tmp[3];
+ tmp4 = *pRes++;
+ imageBlock[2] = (u8)tmp1;
+ tmp3 = clp[tmp3 + tmp4];
+ tmp += 8;
+ imageBlock[3] = (u8)tmp3;
+ imageBlock += picWidth;
+ }
+ }
+ }
+
+}
+#endif /* H264DEC_OMXDL */
+
--- /dev/null
+++ b/src/h264bsd_image.h
@@ -1,0 +1,69 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_IMAGE_H
+#define H264SWDEC_IMAGE_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+typedef struct
+{
+ u8 *data;
+ u32 width;
+ u32 height;
+ /* current MB's components */
+ u8 *luma;
+ u8 *cb;
+ u8 *cr;
+} image_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+void h264bsdWriteMacroblock(image_t *image, u8 *data);
+
+#ifndef H264DEC_OMXDL
+void h264bsdWriteOutputBlocks(image_t *image, u32 mbNum, u8 *data,
+ i32 residual[][16]);
+#endif
+
+#endif /* #ifdef H264SWDEC_IMAGE_H */
+
--- /dev/null
+++ b/src/h264bsd_inter_prediction.c
@@ -1,0 +1,1028 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdInterPrediction
+ MvPrediction16x16
+ MvPrediction16x8
+ MvPrediction8x16
+ MvPrediction8x8
+ MvPrediction
+ MedianFilter
+ GetInterNeighbour
+ GetPredictionMv
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_inter_prediction.h"
+#include "h264bsd_neighbour.h"
+#include "h264bsd_util.h"
+#include "h264bsd_reconstruct.h"
+#include "h264bsd_dpb.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+typedef struct
+{
+ u32 available;
+ u32 refIndex;
+ mv_t mv;
+} interNeighbour_t;
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 MvPrediction16x16(mbStorage_t *pMb, mbPred_t *mbPred,
+ dpbStorage_t *dpb);
+static u32 MvPrediction16x8(mbStorage_t *pMb, mbPred_t *mbPred,
+ dpbStorage_t *dpb);
+static u32 MvPrediction8x16(mbStorage_t *pMb, mbPred_t *mbPred,
+ dpbStorage_t *dpb);
+static u32 MvPrediction8x8(mbStorage_t *pMb, subMbPred_t *subMbPred,
+ dpbStorage_t *dpb);
+static u32 MvPrediction(mbStorage_t *pMb, subMbPred_t *subMbPred,
+ u32 mbPartIdx, u32 subMbPartIdx);
+static i32 MedianFilter(i32 a, i32 b, i32 c);
+
+static void GetInterNeighbour(u32 sliceId, mbStorage_t *nMb,
+ interNeighbour_t *n, u32 index);
+static void GetPredictionMv(mv_t *mv, interNeighbour_t *a, u32 refIndex);
+
+static const neighbour_t N_A_SUB_PART[4][4][4] = {
+ { { {MB_A,5}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_A,5}, {MB_A,7}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_A,5}, {MB_CURR,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_A,5}, {MB_CURR,0}, {MB_A,7}, {MB_CURR,2} } },
+
+ { { {MB_CURR,1}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,1}, {MB_CURR,3}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,1}, {MB_CURR,4}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,1}, {MB_CURR,4}, {MB_CURR,3}, {MB_CURR,6} } },
+
+ { { {MB_A,13}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_A,13}, {MB_A,15}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_A,13}, {MB_CURR,8}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_A,13}, {MB_CURR,8}, {MB_A,15}, {MB_CURR,10} } },
+
+ { { {MB_CURR,9}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,9}, {MB_CURR,11}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,9}, {MB_CURR,12}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,9}, {MB_CURR,12}, {MB_CURR,11}, {MB_CURR,14} } } };
+
+static const neighbour_t N_B_SUB_PART[4][4][4] = {
+ { { {MB_B,10}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,10}, {MB_CURR,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,10}, {MB_B,11}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,10}, {MB_B,11}, {MB_CURR,0}, {MB_CURR,1} } },
+
+ { { {MB_B,14}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,14}, {MB_CURR,4}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,14}, {MB_B,15}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,14}, {MB_B,15}, {MB_CURR,4}, {MB_CURR,5} } },
+
+ { { {MB_CURR,2}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,2}, {MB_CURR,8}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,2}, {MB_CURR,3}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,2}, {MB_CURR,3}, {MB_CURR,8}, {MB_CURR,9} } },
+
+ { { {MB_CURR,6}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,6}, {MB_CURR,12}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,6}, {MB_CURR,7}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,6}, {MB_CURR,7}, {MB_CURR,12}, {MB_CURR,13} } } };
+
+static const neighbour_t N_C_SUB_PART[4][4][4] = {
+ { { {MB_B,14}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,14}, {MB_NA,4}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,11}, {MB_B,14}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,11}, {MB_B,14}, {MB_CURR,1}, {MB_NA,4} } },
+
+ { { {MB_C,10}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_C,10}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,15}, {MB_C,10}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,15}, {MB_C,10}, {MB_CURR,5}, {MB_NA,0} } },
+
+ { { {MB_CURR,6}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,6}, {MB_NA,12}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,3}, {MB_CURR,6}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,3}, {MB_CURR,6}, {MB_CURR,9}, {MB_NA,12} } },
+
+ { { {MB_NA,2}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_NA,2}, {MB_NA,8}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,7}, {MB_NA,2}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,7}, {MB_NA,2}, {MB_CURR,13}, {MB_NA,8} } } };
+
+static const neighbour_t N_D_SUB_PART[4][4][4] = {
+ { { {MB_D,15}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_D,15}, {MB_A,5}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_D,15}, {MB_B,10}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_D,15}, {MB_B,10}, {MB_A,5}, {MB_CURR,0} } },
+
+ { { {MB_B,11}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,11}, {MB_CURR,1}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,11}, {MB_B,14}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_B,11}, {MB_B,14}, {MB_CURR,1}, {MB_CURR,4} } },
+
+ { { {MB_A,7}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_A,7}, {MB_A,13}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_A,7}, {MB_CURR,2}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_A,7}, {MB_CURR,2}, {MB_A,13}, {MB_CURR,8} } },
+
+ { { {MB_CURR,3}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,3}, {MB_CURR,9}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,3}, {MB_CURR,6}, {MB_NA,0}, {MB_NA,0} },
+ { {MB_CURR,3}, {MB_CURR,6}, {MB_CURR,9}, {MB_CURR,12} } } };
+
+
+#ifdef H264DEC_OMXDL
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterPrediction
+
+ Functional description:
+ Processes one inter macroblock. Performs motion vector prediction
+ and reconstructs prediction macroblock. Writes the final macroblock
+ (prediction + residual) into the output image (currImage)
+
+ Inputs:
+ pMb pointer to macroblock specific information
+ pMbLayer pointer to current macroblock data from stream
+ dpb pointer to decoded picture buffer
+ mbNum current macroblock number
+ currImage pointer to output image
+ data pointer where predicted macroblock will be stored
+
+ Outputs:
+ pMb structure is updated with current macroblock
+ currImage current macroblock is written into image
+ data prediction is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK error in motion vector prediction
+
+------------------------------------------------------------------------------*/
+u32 h264bsdInterPrediction(mbStorage_t *pMb, macroblockLayer_t *pMbLayer,
+ dpbStorage_t *dpb, u32 mbNum, image_t *currImage, u8 *data)
+{
+
+/* Variables */
+
+ u32 i;
+ u32 x, y;
+ u32 colAndRow;
+ subMbPartMode_e subPartMode;
+ image_t refImage;
+ u8 fillBuff[32*21 + 15 + 32];
+ u8 *pFill;
+ u32 tmp;
+/* Code */
+
+ ASSERT(pMb);
+ ASSERT(h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTER);
+ ASSERT(pMbLayer);
+
+ /* 16-byte alignment */
+ pFill = ALIGN(fillBuff, 16);
+
+ /* set row bits 15:0 */
+ colAndRow = mbNum / currImage->width;
+ /*set col to bits 31:16 */
+ colAndRow += (mbNum - colAndRow * currImage->width) << 16;
+ colAndRow <<= 4;
+
+ refImage.width = currImage->width;
+ refImage.height = currImage->height;
+
+ switch (pMb->mbType)
+ {
+ case P_Skip:
+ case P_L0_16x16:
+ if (MvPrediction16x16(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK)
+ return(HANTRO_NOK);
+ refImage.data = pMb->refAddr[0];
+ tmp = (0<<24) + (0<<16) + (16<<8) + 16;
+ h264bsdPredictSamples(data, pMb->mv, &refImage,
+ colAndRow, tmp, pFill);
+ break;
+
+ case P_L0_L0_16x8:
+ if ( MvPrediction16x8(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK)
+ return(HANTRO_NOK);
+ refImage.data = pMb->refAddr[0];
+ tmp = (0<<24) + (0<<16) + (16<<8) + 8;
+ h264bsdPredictSamples(data, pMb->mv, &refImage,
+ colAndRow, tmp, pFill);
+
+ refImage.data = pMb->refAddr[2];
+ tmp = (0<<24) + (8<<16) + (16<<8) + 8;
+ h264bsdPredictSamples(data, pMb->mv+8, &refImage,
+ colAndRow, tmp, pFill);
+ break;
+
+ case P_L0_L0_8x16:
+ if ( MvPrediction8x16(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK)
+ return(HANTRO_NOK);
+ refImage.data = pMb->refAddr[0];
+ tmp = (0<<24) + (0<<16) + (8<<8) + 16;
+ h264bsdPredictSamples(data, pMb->mv, &refImage,
+ colAndRow, tmp, pFill);
+ refImage.data = pMb->refAddr[1];
+ tmp = (8<<24) + (0<<16) + (8<<8) + 16;
+ h264bsdPredictSamples(data, pMb->mv+4, &refImage,
+ colAndRow, tmp, pFill);
+ break;
+
+ default: /* P_8x8 and P_8x8ref0 */
+ if ( MvPrediction8x8(pMb, &pMbLayer->subMbPred, dpb) != HANTRO_OK)
+ return(HANTRO_NOK);
+ for (i = 0; i < 4; i++)
+ {
+ refImage.data = pMb->refAddr[i];
+ subPartMode =
+ h264bsdSubMbPartMode(pMbLayer->subMbPred.subMbType[i]);
+ x = i & 0x1 ? 8 : 0;
+ y = i < 2 ? 0 : 8;
+ switch (subPartMode)
+ {
+ case MB_SP_8x8:
+ tmp = (x<<24) + (y<<16) + (8<<8) + 8;
+ h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
+ colAndRow, tmp, pFill);
+ break;
+
+ case MB_SP_8x4:
+ tmp = (x<<24) + (y<<16) + (8<<8) + 4;
+ h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
+ colAndRow, tmp, pFill);
+ tmp = (x<<24) + ((y+4)<<16) + (8<<8) + 4;
+ h264bsdPredictSamples(data, pMb->mv+4*i+2, &refImage,
+ colAndRow, tmp, pFill);
+ break;
+
+ case MB_SP_4x8:
+ tmp = (x<<24) + (y<<16) + (4<<8) + 8;
+ h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
+ colAndRow, tmp, pFill);
+ tmp = ((x+4)<<24) + (y<<16) + (4<<8) + 8;
+ h264bsdPredictSamples(data, pMb->mv+4*i+1, &refImage,
+ colAndRow, tmp, pFill);
+ break;
+
+ default:
+ tmp = (x<<24) + (y<<16) + (4<<8) + 4;
+ h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
+ colAndRow, tmp, pFill);
+ tmp = ((x+4)<<24) + (y<<16) + (4<<8) + 4;
+ h264bsdPredictSamples(data, pMb->mv+4*i+1, &refImage,
+ colAndRow, tmp, pFill);
+ tmp = (x<<24) + ((y+4)<<16) + (4<<8) + 4;
+ h264bsdPredictSamples(data, pMb->mv+4*i+2, &refImage,
+ colAndRow, tmp, pFill);
+ tmp = ((x+4)<<24) + ((y+4)<<16) + (4<<8) + 4;
+ h264bsdPredictSamples(data, pMb->mv+4*i+3, &refImage,
+ colAndRow, tmp, pFill);
+ break;
+ }
+ }
+ break;
+ }
+
+ /* if decoded flag > 1 -> mb has already been successfully decoded and
+ * written to output -> do not write again */
+ if (pMb->decoded > 1)
+ return HANTRO_OK;
+
+ return(HANTRO_OK);
+}
+
+#else /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterPrediction
+
+ Functional description:
+ Processes one inter macroblock. Performs motion vector prediction
+ and reconstructs prediction macroblock. Writes the final macroblock
+ (prediction + residual) into the output image (currImage)
+
+ Inputs:
+ pMb pointer to macroblock specific information
+ pMbLayer pointer to current macroblock data from stream
+ dpb pointer to decoded picture buffer
+ mbNum current macroblock number
+ currImage pointer to output image
+ data pointer where predicted macroblock will be stored
+
+ Outputs:
+ pMb structure is updated with current macroblock
+ currImage current macroblock is written into image
+ data prediction is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK error in motion vector prediction
+
+------------------------------------------------------------------------------*/
+u32 h264bsdInterPrediction(mbStorage_t *pMb, macroblockLayer_t *pMbLayer,
+ dpbStorage_t *dpb, u32 mbNum, image_t *currImage, u8 *data)
+{
+
+/* Variables */
+
+ u32 i;
+ u32 x, y;
+ u32 row, col;
+ subMbPartMode_e subPartMode;
+ image_t refImage;
+
+/* Code */
+
+ ASSERT(pMb);
+ ASSERT(h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTER);
+ ASSERT(pMbLayer);
+
+ row = mbNum / currImage->width;
+ col = mbNum - row * currImage->width;
+ row *= 16;
+ col *= 16;
+
+ refImage.width = currImage->width;
+ refImage.height = currImage->height;
+
+ switch (pMb->mbType)
+ {
+ case P_Skip:
+ case P_L0_16x16:
+ if (MvPrediction16x16(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK)
+ return(HANTRO_NOK);
+ refImage.data = pMb->refAddr[0];
+ h264bsdPredictSamples(data, pMb->mv, &refImage, col, row, 0, 0,
+ 16, 16);
+ break;
+
+ case P_L0_L0_16x8:
+ if ( MvPrediction16x8(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK)
+ return(HANTRO_NOK);
+ refImage.data = pMb->refAddr[0];
+ h264bsdPredictSamples(data, pMb->mv, &refImage, col, row, 0, 0,
+ 16, 8);
+ refImage.data = pMb->refAddr[2];
+ h264bsdPredictSamples(data, pMb->mv+8, &refImage, col, row, 0, 8,
+ 16, 8);
+ break;
+
+ case P_L0_L0_8x16:
+ if ( MvPrediction8x16(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK)
+ return(HANTRO_NOK);
+ refImage.data = pMb->refAddr[0];
+ h264bsdPredictSamples(data, pMb->mv, &refImage, col, row, 0, 0,
+ 8, 16);
+ refImage.data = pMb->refAddr[1];
+ h264bsdPredictSamples(data, pMb->mv+4, &refImage, col, row, 8, 0,
+ 8, 16);
+ break;
+
+ default: /* P_8x8 and P_8x8ref0 */
+ if ( MvPrediction8x8(pMb, &pMbLayer->subMbPred, dpb) != HANTRO_OK)
+ return(HANTRO_NOK);
+ for (i = 0; i < 4; i++)
+ {
+ refImage.data = pMb->refAddr[i];
+ subPartMode =
+ h264bsdSubMbPartMode(pMbLayer->subMbPred.subMbType[i]);
+ x = i & 0x1 ? 8 : 0;
+ y = i < 2 ? 0 : 8;
+ switch (subPartMode)
+ {
+ case MB_SP_8x8:
+ h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
+ col, row, x, y, 8, 8);
+ break;
+
+ case MB_SP_8x4:
+ h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
+ col, row, x, y, 8, 4);
+ h264bsdPredictSamples(data, pMb->mv+4*i+2, &refImage,
+ col, row, x, y+4, 8, 4);
+ break;
+
+ case MB_SP_4x8:
+ h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
+ col, row, x, y, 4, 8);
+ h264bsdPredictSamples(data, pMb->mv+4*i+1, &refImage,
+ col, row, x+4, y, 4, 8);
+ break;
+
+ default:
+ h264bsdPredictSamples(data, pMb->mv+4*i, &refImage,
+ col, row, x, y, 4, 4);
+ h264bsdPredictSamples(data, pMb->mv+4*i+1, &refImage,
+ col, row, x+4, y, 4, 4);
+ h264bsdPredictSamples(data, pMb->mv+4*i+2, &refImage,
+ col, row, x, y+4, 4, 4);
+ h264bsdPredictSamples(data, pMb->mv+4*i+3, &refImage,
+ col, row, x+4, y+4, 4, 4);
+ break;
+ }
+ }
+ break;
+ }
+
+ /* if decoded flag > 1 -> mb has already been successfully decoded and
+ * written to output -> do not write again */
+ if (pMb->decoded > 1)
+ return HANTRO_OK;
+
+ if (pMb->mbType != P_Skip)
+ {
+ h264bsdWriteOutputBlocks(currImage, mbNum, data,
+ pMbLayer->residual.level);
+ }
+ else
+ {
+ h264bsdWriteMacroblock(currImage, data);
+ }
+
+ return(HANTRO_OK);
+}
+#endif /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+
+ Function: MvPrediction16x16
+
+ Functional description:
+ Motion vector prediction for 16x16 partition mode
+
+------------------------------------------------------------------------------*/
+
+u32 MvPrediction16x16(mbStorage_t *pMb, mbPred_t *mbPred, dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+ mv_t mv;
+ mv_t mvPred;
+ interNeighbour_t a[3]; /* A, B, C */
+ u32 refIndex;
+ u8 *tmp;
+ u32 *tmpMv1, *tmpMv2;
+
+/* Code */
+
+ refIndex = mbPred->refIdxL0[0];
+
+ GetInterNeighbour(pMb->sliceId, pMb->mbA, a, 5);
+ GetInterNeighbour(pMb->sliceId, pMb->mbB, a+1, 10);
+ /*lint --e(740) Unusual pointer cast (incompatible indirect types) */
+ tmpMv1 = (u32*)(&a[0].mv); /* we test just that both MVs are zero */
+ /*lint --e(740) */
+ tmpMv2 = (u32*)(&a[1].mv); /* i.e. a[0].mv.hor == 0 && a[0].mv.ver == 0 */
+ if (pMb->mbType == P_Skip &&
+ (!a[0].available || !a[1].available ||
+ ( a[0].refIndex == 0 && ((u32)(*tmpMv1) == 0) ) ||
+ ( a[1].refIndex == 0 && ((u32)(*tmpMv2) == 0) )))
+ {
+ mv.hor = mv.ver = 0;
+ }
+ else
+ {
+ mv = mbPred->mvdL0[0];
+ GetInterNeighbour(pMb->sliceId, pMb->mbC, a+2, 10);
+ if (!a[2].available)
+ {
+ GetInterNeighbour(pMb->sliceId, pMb->mbD, a+2, 15);
+ }
+
+ GetPredictionMv(&mvPred, a, refIndex);
+
+ mv.hor += mvPred.hor;
+ mv.ver += mvPred.ver;
+
+ /* horizontal motion vector range [-2048, 2047.75] */
+ if ((u32)(i32)(mv.hor+8192) >= (16384))
+ return(HANTRO_NOK);
+
+ /* vertical motion vector range [-512, 511.75]
+ * (smaller for low levels) */
+ if ((u32)(i32)(mv.ver+2048) >= (4096))
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdGetRefPicData(dpb, refIndex);
+ if (tmp == NULL)
+ return(HANTRO_NOK);
+
+ pMb->mv[0] = pMb->mv[1] = pMb->mv[2] = pMb->mv[3] =
+ pMb->mv[4] = pMb->mv[5] = pMb->mv[6] = pMb->mv[7] =
+ pMb->mv[8] = pMb->mv[9] = pMb->mv[10] = pMb->mv[11] =
+ pMb->mv[12] = pMb->mv[13] = pMb->mv[14] = pMb->mv[15] = mv;
+
+ pMb->refPic[0] = refIndex;
+ pMb->refPic[1] = refIndex;
+ pMb->refPic[2] = refIndex;
+ pMb->refPic[3] = refIndex;
+ pMb->refAddr[0] = tmp;
+ pMb->refAddr[1] = tmp;
+ pMb->refAddr[2] = tmp;
+ pMb->refAddr[3] = tmp;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: MvPrediction16x8
+
+ Functional description:
+ Motion vector prediction for 16x8 partition mode
+
+------------------------------------------------------------------------------*/
+
+u32 MvPrediction16x8(mbStorage_t *pMb, mbPred_t *mbPred, dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+ mv_t mv;
+ mv_t mvPred;
+ interNeighbour_t a[3]; /* A, B, C */
+ u32 refIndex;
+ u8 *tmp;
+
+/* Code */
+
+ mv = mbPred->mvdL0[0];
+ refIndex = mbPred->refIdxL0[0];
+
+ GetInterNeighbour(pMb->sliceId, pMb->mbB, a+1, 10);
+
+ if (a[1].refIndex == refIndex)
+ mvPred = a[1].mv;
+ else
+ {
+ GetInterNeighbour(pMb->sliceId, pMb->mbA, a, 5);
+ GetInterNeighbour(pMb->sliceId, pMb->mbC, a+2, 10);
+ if (!a[2].available)
+ {
+ GetInterNeighbour(pMb->sliceId, pMb->mbD, a+2, 15);
+ }
+
+ GetPredictionMv(&mvPred, a, refIndex);
+
+ }
+ mv.hor += mvPred.hor;
+ mv.ver += mvPred.ver;
+
+ /* horizontal motion vector range [-2048, 2047.75] */
+ if ((u32)(i32)(mv.hor+8192) >= (16384))
+ return(HANTRO_NOK);
+
+ /* vertical motion vector range [-512, 511.75] (smaller for low levels) */
+ if ((u32)(i32)(mv.ver+2048) >= (4096))
+ return(HANTRO_NOK);
+
+ tmp = h264bsdGetRefPicData(dpb, refIndex);
+ if (tmp == NULL)
+ return(HANTRO_NOK);
+
+ pMb->mv[0] = pMb->mv[1] = pMb->mv[2] = pMb->mv[3] =
+ pMb->mv[4] = pMb->mv[5] = pMb->mv[6] = pMb->mv[7] = mv;
+ pMb->refPic[0] = refIndex;
+ pMb->refPic[1] = refIndex;
+ pMb->refAddr[0] = tmp;
+ pMb->refAddr[1] = tmp;
+
+ mv = mbPred->mvdL0[1];
+ refIndex = mbPred->refIdxL0[1];
+
+ GetInterNeighbour(pMb->sliceId, pMb->mbA, a, 13);
+ if (a[0].refIndex == refIndex)
+ mvPred = a[0].mv;
+ else
+ {
+ a[1].available = HANTRO_TRUE;
+ a[1].refIndex = pMb->refPic[0];
+ a[1].mv = pMb->mv[0];
+
+ /* c is not available */
+ GetInterNeighbour(pMb->sliceId, pMb->mbA, a+2, 7);
+
+ GetPredictionMv(&mvPred, a, refIndex);
+
+ }
+ mv.hor += mvPred.hor;
+ mv.ver += mvPred.ver;
+
+ /* horizontal motion vector range [-2048, 2047.75] */
+ if ((u32)(i32)(mv.hor+8192) >= (16384))
+ return(HANTRO_NOK);
+
+ /* vertical motion vector range [-512, 511.75] (smaller for low levels) */
+ if ((u32)(i32)(mv.ver+2048) >= (4096))
+ return(HANTRO_NOK);
+
+ tmp = h264bsdGetRefPicData(dpb, refIndex);
+ if (tmp == NULL)
+ return(HANTRO_NOK);
+
+ pMb->mv[8] = pMb->mv[9] = pMb->mv[10] = pMb->mv[11] =
+ pMb->mv[12] = pMb->mv[13] = pMb->mv[14] = pMb->mv[15] = mv;
+ pMb->refPic[2] = refIndex;
+ pMb->refPic[3] = refIndex;
+ pMb->refAddr[2] = tmp;
+ pMb->refAddr[3] = tmp;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: MvPrediction8x16
+
+ Functional description:
+ Motion vector prediction for 8x16 partition mode
+
+------------------------------------------------------------------------------*/
+
+u32 MvPrediction8x16(mbStorage_t *pMb, mbPred_t *mbPred, dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+ mv_t mv;
+ mv_t mvPred;
+ interNeighbour_t a[3]; /* A, B, C */
+ u32 refIndex;
+ u8 *tmp;
+
+/* Code */
+
+ mv = mbPred->mvdL0[0];
+ refIndex = mbPred->refIdxL0[0];
+
+ GetInterNeighbour(pMb->sliceId, pMb->mbA, a, 5);
+
+ if (a[0].refIndex == refIndex)
+ mvPred = a[0].mv;
+ else
+ {
+ GetInterNeighbour(pMb->sliceId, pMb->mbB, a+1, 10);
+ GetInterNeighbour(pMb->sliceId, pMb->mbB, a+2, 14);
+ if (!a[2].available)
+ {
+ GetInterNeighbour(pMb->sliceId, pMb->mbD, a+2, 15);
+ }
+
+ GetPredictionMv(&mvPred, a, refIndex);
+
+ }
+ mv.hor += mvPred.hor;
+ mv.ver += mvPred.ver;
+
+ /* horizontal motion vector range [-2048, 2047.75] */
+ if ((u32)(i32)(mv.hor+8192) >= (16384))
+ return(HANTRO_NOK);
+
+ /* vertical motion vector range [-512, 511.75] (smaller for low levels) */
+ if ((u32)(i32)(mv.ver+2048) >= (4096))
+ return(HANTRO_NOK);
+
+ tmp = h264bsdGetRefPicData(dpb, refIndex);
+ if (tmp == NULL)
+ return(HANTRO_NOK);
+
+ pMb->mv[0] = pMb->mv[1] = pMb->mv[2] = pMb->mv[3] =
+ pMb->mv[8] = pMb->mv[9] = pMb->mv[10] = pMb->mv[11] = mv;
+ pMb->refPic[0] = refIndex;
+ pMb->refPic[2] = refIndex;
+ pMb->refAddr[0] = tmp;
+ pMb->refAddr[2] = tmp;
+
+ mv = mbPred->mvdL0[1];
+ refIndex = mbPred->refIdxL0[1];
+
+ GetInterNeighbour(pMb->sliceId, pMb->mbC, a+2, 10);
+ if (!a[2].available)
+ {
+ GetInterNeighbour(pMb->sliceId, pMb->mbB, a+2, 11);
+ }
+ if (a[2].refIndex == refIndex)
+ mvPred = a[2].mv;
+ else
+ {
+ a[0].available = HANTRO_TRUE;
+ a[0].refIndex = pMb->refPic[0];
+ a[0].mv = pMb->mv[0];
+
+ GetInterNeighbour(pMb->sliceId, pMb->mbB, a+1, 14);
+
+ GetPredictionMv(&mvPred, a, refIndex);
+
+ }
+ mv.hor += mvPred.hor;
+ mv.ver += mvPred.ver;
+
+ /* horizontal motion vector range [-2048, 2047.75] */
+ if ((u32)(i32)(mv.hor+8192) >= (16384))
+ return(HANTRO_NOK);
+
+ /* vertical motion vector range [-512, 511.75] (smaller for low levels) */
+ if ((u32)(i32)(mv.ver+2048) >= (4096))
+ return(HANTRO_NOK);
+
+ tmp = h264bsdGetRefPicData(dpb, refIndex);
+ if (tmp == NULL)
+ return(HANTRO_NOK);
+
+ pMb->mv[4] = pMb->mv[5] = pMb->mv[6] = pMb->mv[7] =
+ pMb->mv[12] = pMb->mv[13] = pMb->mv[14] = pMb->mv[15] = mv;
+ pMb->refPic[1] = refIndex;
+ pMb->refPic[3] = refIndex;
+ pMb->refAddr[1] = tmp;
+ pMb->refAddr[3] = tmp;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: MvPrediction8x8
+
+ Functional description:
+ Motion vector prediction for 8x8 partition mode
+
+------------------------------------------------------------------------------*/
+
+u32 MvPrediction8x8(mbStorage_t *pMb, subMbPred_t *subMbPred, dpbStorage_t *dpb)
+{
+
+/* Variables */
+
+ u32 i, j;
+ u32 numSubMbPart;
+
+/* Code */
+
+ for (i = 0; i < 4; i++)
+ {
+ numSubMbPart = h264bsdNumSubMbPart(subMbPred->subMbType[i]);
+ pMb->refPic[i] = subMbPred->refIdxL0[i];
+ pMb->refAddr[i] = h264bsdGetRefPicData(dpb, subMbPred->refIdxL0[i]);
+ if (pMb->refAddr[i] == NULL)
+ return(HANTRO_NOK);
+ for (j = 0; j < numSubMbPart; j++)
+ {
+ if (MvPrediction(pMb, subMbPred, i, j) != HANTRO_OK)
+ return(HANTRO_NOK);
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: MvPrediction
+
+ Functional description:
+ Perform motion vector prediction for sub-partition
+
+------------------------------------------------------------------------------*/
+
+u32 MvPrediction(mbStorage_t *pMb, subMbPred_t *subMbPred, u32 mbPartIdx,
+ u32 subMbPartIdx)
+{
+
+/* Variables */
+
+ mv_t mv, mvPred;
+ u32 refIndex;
+ subMbPartMode_e subMbPartMode;
+ const neighbour_t *n;
+ mbStorage_t *nMb;
+ interNeighbour_t a[3]; /* A, B, C */
+
+/* Code */
+
+ mv = subMbPred->mvdL0[mbPartIdx][subMbPartIdx];
+ subMbPartMode = h264bsdSubMbPartMode(subMbPred->subMbType[mbPartIdx]);
+ refIndex = subMbPred->refIdxL0[mbPartIdx];
+
+ n = N_A_SUB_PART[mbPartIdx][subMbPartMode]+subMbPartIdx;
+ nMb = h264bsdGetNeighbourMb(pMb, n->mb);
+ GetInterNeighbour(pMb->sliceId, nMb, a, n->index);
+
+ n = N_B_SUB_PART[mbPartIdx][subMbPartMode]+subMbPartIdx;
+ nMb = h264bsdGetNeighbourMb(pMb, n->mb);
+ GetInterNeighbour(pMb->sliceId, nMb, a+1, n->index);
+
+ n = N_C_SUB_PART[mbPartIdx][subMbPartMode]+subMbPartIdx;
+ nMb = h264bsdGetNeighbourMb(pMb, n->mb);
+ GetInterNeighbour(pMb->sliceId, nMb, a+2, n->index);
+
+ if (!a[2].available)
+ {
+ n = N_D_SUB_PART[mbPartIdx][subMbPartMode]+subMbPartIdx;
+ nMb = h264bsdGetNeighbourMb(pMb, n->mb);
+ GetInterNeighbour(pMb->sliceId, nMb, a+2, n->index);
+ }
+
+ GetPredictionMv(&mvPred, a, refIndex);
+
+ mv.hor += mvPred.hor;
+ mv.ver += mvPred.ver;
+
+ /* horizontal motion vector range [-2048, 2047.75] */
+ if (((u32)(i32)(mv.hor+8192) >= (16384)))
+ return(HANTRO_NOK);
+
+ /* vertical motion vector range [-512, 511.75] (smaller for low levels) */
+ if (((u32)(i32)(mv.ver+2048) >= (4096)))
+ return(HANTRO_NOK);
+
+ switch (subMbPartMode)
+ {
+ case MB_SP_8x8:
+ pMb->mv[4*mbPartIdx] = mv;
+ pMb->mv[4*mbPartIdx + 1] = mv;
+ pMb->mv[4*mbPartIdx + 2] = mv;
+ pMb->mv[4*mbPartIdx + 3] = mv;
+ break;
+
+ case MB_SP_8x4:
+ pMb->mv[4*mbPartIdx + 2*subMbPartIdx] = mv;
+ pMb->mv[4*mbPartIdx + 2*subMbPartIdx + 1] = mv;
+ break;
+
+ case MB_SP_4x8:
+ pMb->mv[4*mbPartIdx + subMbPartIdx] = mv;
+ pMb->mv[4*mbPartIdx + subMbPartIdx + 2] = mv;
+ break;
+
+ case MB_SP_4x4:
+ pMb->mv[4*mbPartIdx + subMbPartIdx] = mv;
+ break;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: MedianFilter
+
+ Functional description:
+ Median filtering for motion vector prediction
+
+------------------------------------------------------------------------------*/
+
+i32 MedianFilter(i32 a, i32 b, i32 c)
+{
+
+/* Variables */
+
+ i32 max,min,med;
+
+/* Code */
+
+ max = min = med = a;
+ if (b > max)
+ {
+ max = b;
+ }
+ else if (b < min)
+ {
+ min = b;
+ }
+ if (c > max)
+ {
+ med = max;
+ }
+ else if (c < min)
+ {
+ med = min;
+ }
+ else
+ {
+ med = c;
+ }
+
+ return(med);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: GetInterNeighbour
+
+ Functional description:
+ Get availability, reference index and motion vector of a neighbour
+
+------------------------------------------------------------------------------*/
+
+void GetInterNeighbour(u32 sliceId, mbStorage_t *nMb,
+ interNeighbour_t *n, u32 index)
+{
+
+ n->available = HANTRO_FALSE;
+ n->refIndex = 0xFFFFFFFF;
+ n->mv.hor = n->mv.ver = 0;
+
+ if (nMb && (sliceId == nMb->sliceId))
+ {
+ u32 tmp;
+ mv_t tmpMv;
+
+ tmp = nMb->mbType;
+ n->available = HANTRO_TRUE;
+ /* MbPartPredMode "inlined" */
+ if (tmp <= P_8x8ref0)
+ {
+ tmpMv = nMb->mv[index];
+ tmp = nMb->refPic[index>>2];
+ n->refIndex = tmp;
+ n->mv = tmpMv;
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: GetPredictionMv
+
+ Functional description:
+ Compute motion vector predictor based on neighbours A, B and C
+
+------------------------------------------------------------------------------*/
+
+void GetPredictionMv(mv_t *mv, interNeighbour_t *a, u32 refIndex)
+{
+
+ if ( a[1].available || a[2].available || !a[0].available)
+ {
+ u32 isA, isB, isC;
+ isA = (a[0].refIndex == refIndex) ? HANTRO_TRUE : HANTRO_FALSE;
+ isB = (a[1].refIndex == refIndex) ? HANTRO_TRUE : HANTRO_FALSE;
+ isC = (a[2].refIndex == refIndex) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ if (((u32)isA+(u32)isB+(u32)isC) != 1)
+ {
+ mv->hor = (i16)MedianFilter(a[0].mv.hor, a[1].mv.hor, a[2].mv.hor);
+ mv->ver = (i16)MedianFilter(a[0].mv.ver, a[1].mv.ver, a[2].mv.ver);
+ }
+ else if (isA)
+ *mv = a[0].mv;
+ else if (isB)
+ *mv = a[1].mv;
+ else
+ *mv = a[2].mv;
+ }
+ else
+ {
+ *mv = a[0].mv;
+ }
+
+}
+
+
--- /dev/null
+++ b/src/h264bsd_inter_prediction.h
@@ -1,0 +1,57 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_INTER_PREDICTION_H
+#define H264SWDEC_INTER_PREDICTION_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_image.h"
+#include "h264bsd_macroblock_layer.h"
+#include "h264bsd_dpb.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdInterPrediction(mbStorage_t *pMb, macroblockLayer_t *pMbLayer,
+ dpbStorage_t *dpb, u32 mbNum, image_t *image, u8 *data);
+
+#endif /* #ifdef H264SWDEC_INTER_PREDICTION_H */
+
--- /dev/null
+++ b/src/h264bsd_intra_prediction.c
@@ -1,0 +1,1942 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdIntraPrediction
+ h264bsdGetNeighbourPels
+ h264bsdIntra16x16Prediction
+ h264bsdIntra4x4Prediction
+ h264bsdIntraChromaPrediction
+ h264bsdAddResidual
+ Intra16x16VerticalPrediction
+ Intra16x16HorizontalPrediction
+ Intra16x16DcPrediction
+ Intra16x16PlanePrediction
+ IntraChromaDcPrediction
+ IntraChromaHorizontalPrediction
+ IntraChromaVerticalPrediction
+ IntraChromaPlanePrediction
+ Get4x4NeighbourPels
+ Write4x4To16x16
+ Intra4x4VerticalPrediction
+ Intra4x4HorizontalPrediction
+ Intra4x4DcPrediction
+ Intra4x4DiagonalDownLeftPrediction
+ Intra4x4DiagonalDownRightPrediction
+ Intra4x4VerticalRightPrediction
+ Intra4x4HorizontalDownPrediction
+ Intra4x4VerticalLeftPrediction
+ Intra4x4HorizontalUpPrediction
+ DetermineIntra4x4PredMode
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_intra_prediction.h"
+#include "h264bsd_util.h"
+#include "h264bsd_macroblock_layer.h"
+#include "h264bsd_neighbour.h"
+#include "h264bsd_image.h"
+
+#ifdef H264DEC_OMXDL
+#include "omxtypes.h"
+#include "omxVC.h"
+#endif /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* Switch off the following Lint messages for this file:
+ * Info 702: Shift right of signed quantity (int)
+ */
+/*lint -e702 */
+
+
+/* x- and y-coordinates for each block */
+const u32 h264bsdBlockX[16] =
+ { 0, 4, 0, 4, 8, 12, 8, 12, 0, 4, 0, 4, 8, 12, 8, 12 };
+const u32 h264bsdBlockY[16] =
+ { 0, 0, 4, 4, 0, 0, 4, 4, 8, 8, 12, 12, 8, 8, 12, 12 };
+
+const u8 h264bsdClip[1280] =
+{
+ 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,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,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,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,
+ 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,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,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,63,
+ 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
+ 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
+ 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
+ 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
+ 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
+ 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
+ 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
+ 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
+ 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
+};
+
+u8 *get_h264bsdClip() {
+ return (u8*)h264bsdClip;
+}
+
+#ifndef H264DEC_OMXDL
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+static void Get4x4NeighbourPels(u8 *a, u8 *l, u8 *data, u8 *above, u8 *left,
+ u32 blockNum);
+static void Intra16x16VerticalPrediction(u8 *data, u8 *above);
+static void Intra16x16HorizontalPrediction(u8 *data, u8 *left);
+static void Intra16x16DcPrediction(u8 *data, u8 *above, u8 *left,
+ u32 A, u32 B);
+static void Intra16x16PlanePrediction(u8 *data, u8 *above, u8 *left);
+static void IntraChromaDcPrediction(u8 *data, u8 *above, u8 *left,
+ u32 A, u32 B);
+static void IntraChromaHorizontalPrediction(u8 *data, u8 *left);
+static void IntraChromaVerticalPrediction(u8 *data, u8 *above);
+static void IntraChromaPlanePrediction(u8 *data, u8 *above, u8 *left);
+
+static void Intra4x4VerticalPrediction(u8 *data, u8 *above);
+static void Intra4x4HorizontalPrediction(u8 *data, u8 *left);
+static void Intra4x4DcPrediction(u8 *data, u8 *above, u8 *left, u32 A, u32 B);
+static void Intra4x4DiagonalDownLeftPrediction(u8 *data, u8 *above);
+static void Intra4x4DiagonalDownRightPrediction(u8 *data, u8 *above, u8 *left);
+static void Intra4x4VerticalRightPrediction(u8 *data, u8 *above, u8 *left);
+static void Intra4x4HorizontalDownPrediction(u8 *data, u8 *above, u8 *left);
+static void Intra4x4VerticalLeftPrediction(u8 *data, u8 *above);
+static void Intra4x4HorizontalUpPrediction(u8 *data, u8 *left);
+void h264bsdAddResidual(u8 *data, i32 *residual, u32 blockNum);
+
+static void Write4x4To16x16(u8 *data, u8 *data4x4, u32 blockNum);
+#endif /* H264DEC_OMXDL */
+
+static u32 DetermineIntra4x4PredMode(macroblockLayer_t *pMbLayer,
+ u32 available, neighbour_t *nA, neighbour_t *nB, u32 index,
+ mbStorage_t *nMbA, mbStorage_t *nMbB);
+
+
+#ifdef H264DEC_OMXDL
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdIntra16x16Prediction
+
+ Functional description:
+ Perform intra 16x16 prediction mode for luma pixels and add
+ residual into prediction. The resulting luma pixels are
+ stored in macroblock array 'data'.
+
+------------------------------------------------------------------------------*/
+u32 h264bsdIntra16x16Prediction(mbStorage_t *pMb, u8 *data, u8 *ptr,
+ u32 width, u32 constrainedIntraPred)
+{
+
+/* Variables */
+
+ u32 availableA, availableB, availableD;
+ OMXResult omxRes;
+
+/* Code */
+ ASSERT(pMb);
+ ASSERT(data);
+ ASSERT(ptr);
+ ASSERT(h264bsdPredModeIntra16x16(pMb->mbType) < 4);
+
+ availableA = h264bsdIsNeighbourAvailable(pMb, pMb->mbA);
+ if (availableA && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbA->mbType) == PRED_MODE_INTER))
+ availableA = HANTRO_FALSE;
+ availableB = h264bsdIsNeighbourAvailable(pMb, pMb->mbB);
+ if (availableB && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbB->mbType) == PRED_MODE_INTER))
+ availableB = HANTRO_FALSE;
+ availableD = h264bsdIsNeighbourAvailable(pMb, pMb->mbD);
+ if (availableD && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbD->mbType) == PRED_MODE_INTER))
+ availableD = HANTRO_FALSE;
+
+ omxRes = omxVCM4P10_PredictIntra_16x16( (ptr-1),
+ (ptr - width),
+ (ptr - width-1),
+ data,
+ (i32)width,
+ 16,
+ (OMXVCM4P10Intra16x16PredMode)
+ h264bsdPredModeIntra16x16(pMb->mbType),
+ (i32)(availableB + (availableA<<1) +
+ (availableD<<5)) );
+ if (omxRes != OMX_Sts_NoErr)
+ return HANTRO_NOK;
+ else
+ return(HANTRO_OK);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdIntra4x4Prediction
+
+ Functional description:
+ Perform intra 4x4 prediction for luma pixels and add residual
+ into prediction. The resulting luma pixels are stored in
+ macroblock array 'data'. The intra 4x4 prediction mode for each
+ block is stored in 'pMb' structure.
+
+------------------------------------------------------------------------------*/
+u32 h264bsdIntra4x4Prediction(mbStorage_t *pMb, u8 *data,
+ macroblockLayer_t *mbLayer,
+ u8 *ptr, u32 width,
+ u32 constrainedIntraPred, u32 block)
+{
+
+/* Variables */
+ u32 mode;
+ neighbour_t neighbour, neighbourB;
+ mbStorage_t *nMb, *nMb2;
+ u32 availableA, availableB, availableC, availableD;
+
+ OMXResult omxRes;
+ u32 x, y;
+ u8 *l, *a, *al;
+/* Code */
+ ASSERT(pMb);
+ ASSERT(data);
+ ASSERT(mbLayer);
+ ASSERT(ptr);
+ ASSERT(pMb->intra4x4PredMode[block] < 9);
+
+ neighbour = *h264bsdNeighbour4x4BlockA(block);
+ nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
+ availableA = h264bsdIsNeighbourAvailable(pMb, nMb);
+ if (availableA && constrainedIntraPred &&
+ ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
+ {
+ availableA = HANTRO_FALSE;
+ }
+
+ neighbourB = *h264bsdNeighbour4x4BlockB(block);
+ nMb2 = h264bsdGetNeighbourMb(pMb, neighbourB.mb);
+ availableB = h264bsdIsNeighbourAvailable(pMb, nMb2);
+ if (availableB && constrainedIntraPred &&
+ ( h264bsdMbPartPredMode(nMb2->mbType) == PRED_MODE_INTER) )
+ {
+ availableB = HANTRO_FALSE;
+ }
+
+ mode = DetermineIntra4x4PredMode(mbLayer,
+ (u32)(availableA && availableB),
+ &neighbour, &neighbourB, block, nMb, nMb2);
+ pMb->intra4x4PredMode[block] = (u8)mode;
+
+ neighbour = *h264bsdNeighbour4x4BlockC(block);
+ nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
+ availableC = h264bsdIsNeighbourAvailable(pMb, nMb);
+ if (availableC && constrainedIntraPred &&
+ ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
+ {
+ availableC = HANTRO_FALSE;
+ }
+
+ neighbour = *h264bsdNeighbour4x4BlockD(block);
+ nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
+ availableD = h264bsdIsNeighbourAvailable(pMb, nMb);
+ if (availableD && constrainedIntraPred &&
+ ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
+ {
+ availableD = HANTRO_FALSE;
+ }
+
+ x = h264bsdBlockX[block];
+ y = h264bsdBlockY[block];
+
+ if (y == 0)
+ a = ptr - width + x;
+ else
+ a = data-16;
+
+ if (x == 0)
+ l = ptr + y * width -1;
+ else
+ {
+ l = data-1;
+ width = 16;
+ }
+
+ if (x == 0)
+ al = l-width;
+ else
+ al = a-1;
+
+ omxRes = omxVCM4P10_PredictIntra_4x4( l,
+ a,
+ al,
+ data,
+ (i32)width,
+ 16,
+ (OMXVCM4P10Intra4x4PredMode)mode,
+ (i32)(availableB +
+ (availableA<<1) +
+ (availableD<<5) +
+ (availableC<<6)) );
+ if (omxRes != OMX_Sts_NoErr)
+ return HANTRO_NOK;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdIntraChromaPrediction
+
+ Functional description:
+ Perform intra prediction for chroma pixels and add residual
+ into prediction. The resulting chroma pixels are stored in 'data'.
+
+------------------------------------------------------------------------------*/
+u32 h264bsdIntraChromaPrediction(mbStorage_t *pMb, u8 *data, image_t *image,
+ u32 predMode, u32 constrainedIntraPred)
+{
+
+/* Variables */
+
+ u32 availableA, availableB, availableD;
+ OMXResult omxRes;
+ u8 *ptr;
+ u32 width;
+
+/* Code */
+ ASSERT(pMb);
+ ASSERT(data);
+ ASSERT(image);
+ ASSERT(predMode < 4);
+
+ availableA = h264bsdIsNeighbourAvailable(pMb, pMb->mbA);
+ if (availableA && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbA->mbType) == PRED_MODE_INTER))
+ availableA = HANTRO_FALSE;
+ availableB = h264bsdIsNeighbourAvailable(pMb, pMb->mbB);
+ if (availableB && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbB->mbType) == PRED_MODE_INTER))
+ availableB = HANTRO_FALSE;
+ availableD = h264bsdIsNeighbourAvailable(pMb, pMb->mbD);
+ if (availableD && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbD->mbType) == PRED_MODE_INTER))
+ availableD = HANTRO_FALSE;
+
+ ptr = image->cb;
+ width = image->width*8;
+
+ omxRes = omxVCM4P10_PredictIntraChroma_8x8( (ptr-1),
+ (ptr - width),
+ (ptr - width -1),
+ data,
+ (i32)width,
+ 8,
+ (OMXVCM4P10IntraChromaPredMode)
+ predMode,
+ (i32)(availableB +
+ (availableA<<1) +
+ (availableD<<5)) );
+ if (omxRes != OMX_Sts_NoErr)
+ return HANTRO_NOK;
+
+ /* advance pointers */
+ data += 64;
+ ptr = image->cr;
+
+ omxRes = omxVCM4P10_PredictIntraChroma_8x8( (ptr-1),
+ (ptr - width),
+ (ptr - width -1),
+ data,
+ (i32)width,
+ 8,
+ (OMXVCM4P10IntraChromaPredMode)
+ predMode,
+ (i32)(availableB +
+ (availableA<<1) +
+ (availableD<<5)) );
+ if (omxRes != OMX_Sts_NoErr)
+ return HANTRO_NOK;
+
+ return(HANTRO_OK);
+
+}
+
+
+#else /* H264DEC_OMXDL */
+
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdIntraPrediction
+
+ Functional description:
+ Processes one intra macroblock. Performs intra prediction using
+ specified prediction mode. Writes the final macroblock
+ (prediction + residual) into the output image (image)
+
+ Inputs:
+ pMb pointer to macroblock specific information
+ mbLayer pointer to current macroblock data from stream
+ image pointer to output image
+ mbNum current macroblock number
+ constrainedIntraPred flag specifying if neighbouring inter
+ macroblocks are used in intra prediction
+ data pointer where output macroblock will be stored
+
+ Outputs:
+ pMb structure is updated with current macroblock
+ image current macroblock is written into image
+ data current macroblock is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK error in intra prediction
+
+------------------------------------------------------------------------------*/
+u32 h264bsdIntraPrediction(mbStorage_t *pMb, macroblockLayer_t *mbLayer,
+ image_t *image, u32 mbNum, u32 constrainedIntraPred, u8 *data)
+{
+
+/* Variables */
+
+ /* pelAbove and pelLeft contain samples above and left to the current
+ * macroblock. Above array contains also sample above-left to the current
+ * mb as well as 4 samples above-right to the current mb (latter only for
+ * luma) */
+ /* lumD + lumB + lumC + cbD + cbB + crD + crB */
+ u8 pelAbove[1 + 16 + 4 + 1 + 8 + 1 + 8];
+ /* lumA + cbA + crA */
+ u8 pelLeft[16 + 8 + 8];
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pMb);
+ ASSERT(image);
+ ASSERT(mbNum < image->width * image->height);
+ ASSERT(h264bsdMbPartPredMode(pMb->mbType) != PRED_MODE_INTER);
+
+ h264bsdGetNeighbourPels(image, pelAbove, pelLeft, mbNum);
+
+ if (h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTRA16x16)
+ {
+ tmp = h264bsdIntra16x16Prediction(pMb, data, mbLayer->residual.level,
+ pelAbove, pelLeft, constrainedIntraPred);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ else
+ {
+ tmp = h264bsdIntra4x4Prediction(pMb, data, mbLayer,
+ pelAbove, pelLeft, constrainedIntraPred);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ tmp = h264bsdIntraChromaPrediction(pMb, data + 256,
+ mbLayer->residual.level+16, pelAbove + 21, pelLeft + 16,
+ mbLayer->mbPred.intraChromaPredMode, constrainedIntraPred);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* if decoded flag > 1 -> mb has already been successfully decoded and
+ * written to output -> do not write again */
+ if (pMb->decoded > 1)
+ return HANTRO_OK;
+
+ h264bsdWriteMacroblock(image, data);
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdGetNeighbourPels
+
+ Functional description:
+ Get pixel values from neighbouring macroblocks into 'above'
+ and 'left' arrays.
+
+------------------------------------------------------------------------------*/
+
+void h264bsdGetNeighbourPels(image_t *image, u8 *above, u8 *left, u32 mbNum)
+{
+
+/* Variables */
+
+ u32 i;
+ u32 width, picSize;
+ u8 *ptr, *tmp;
+ u32 row, col;
+
+/* Code */
+
+ ASSERT(image);
+ ASSERT(above);
+ ASSERT(left);
+ ASSERT(mbNum < image->width * image->height);
+
+ if (!mbNum)
+ return;
+
+ width = image->width;
+ picSize = width * image->height;
+ row = mbNum / width;
+ col = mbNum - row * width;
+
+ width *= 16;
+ ptr = image->data + row * 16 * width + col * 16;
+
+ /* note that luma samples above-right to current macroblock do not make
+ * sense when current mb is the right-most mb in a row. Same applies to
+ * sample above-left if col is zero. However, usage of pels in prediction
+ * is controlled by neighbour availability information in actual prediction
+ * process */
+ if (row)
+ {
+ tmp = ptr - (width + 1);
+ for (i = 21; i--;)
+ *above++ = *tmp++;
+ }
+
+ if (col)
+ {
+ ptr--;
+ for (i = 16; i--; ptr+=width)
+ *left++ = *ptr;
+ }
+
+ width >>= 1;
+ ptr = image->data + picSize * 256 + row * 8 * width + col * 8;
+
+ if (row)
+ {
+ tmp = ptr - (width + 1);
+ for (i = 9; i--;)
+ *above++ = *tmp++;
+ tmp += (picSize * 64) - 9;
+ for (i = 9; i--;)
+ *above++ = *tmp++;
+ }
+
+ if (col)
+ {
+ ptr--;
+ for (i = 8; i--; ptr+=width)
+ *left++ = *ptr;
+ ptr += (picSize * 64) - 8 * width;
+ for (i = 8; i--; ptr+=width)
+ *left++ = *ptr;
+ }
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra16x16Prediction
+
+ Functional description:
+ Perform intra 16x16 prediction mode for luma pixels and add
+ residual into prediction. The resulting luma pixels are
+ stored in macroblock array 'data'.
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdIntra16x16Prediction(mbStorage_t *pMb, u8 *data, i32 residual[][16],
+ u8 *above, u8 *left, u32 constrainedIntraPred)
+{
+
+/* Variables */
+
+ u32 i;
+ u32 availableA, availableB, availableD;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(residual);
+ ASSERT(above);
+ ASSERT(left);
+ ASSERT(h264bsdPredModeIntra16x16(pMb->mbType) < 4);
+
+ availableA = h264bsdIsNeighbourAvailable(pMb, pMb->mbA);
+ if (availableA && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbA->mbType) == PRED_MODE_INTER))
+ availableA = HANTRO_FALSE;
+ availableB = h264bsdIsNeighbourAvailable(pMb, pMb->mbB);
+ if (availableB && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbB->mbType) == PRED_MODE_INTER))
+ availableB = HANTRO_FALSE;
+ availableD = h264bsdIsNeighbourAvailable(pMb, pMb->mbD);
+ if (availableD && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbD->mbType) == PRED_MODE_INTER))
+ availableD = HANTRO_FALSE;
+
+ switch(h264bsdPredModeIntra16x16(pMb->mbType))
+ {
+ case 0: /* Intra_16x16_Vertical */
+ if (!availableB)
+ return(HANTRO_NOK);
+ Intra16x16VerticalPrediction(data, above+1);
+ break;
+
+ case 1: /* Intra_16x16_Horizontal */
+ if (!availableA)
+ return(HANTRO_NOK);
+ Intra16x16HorizontalPrediction(data, left);
+ break;
+
+ case 2: /* Intra_16x16_DC */
+ Intra16x16DcPrediction(data, above+1, left, availableA, availableB);
+ break;
+
+ default: /* case 3: Intra_16x16_Plane */
+ if (!availableA || !availableB || !availableD)
+ return(HANTRO_NOK);
+ Intra16x16PlanePrediction(data, above+1, left);
+ break;
+ }
+ /* add residual */
+ for (i = 0; i < 16; i++)
+ h264bsdAddResidual(data, residual[i], i);
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra4x4Prediction
+
+ Functional description:
+ Perform intra 4x4 prediction for luma pixels and add residual
+ into prediction. The resulting luma pixels are stored in
+ macroblock array 'data'. The intra 4x4 prediction mode for each
+ block is stored in 'pMb' structure.
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdIntra4x4Prediction(mbStorage_t *pMb, u8 *data,
+ macroblockLayer_t *mbLayer, u8 *above,
+ u8 *left, u32 constrainedIntraPred)
+{
+
+/* Variables */
+
+ u32 block;
+ u32 mode;
+ neighbour_t neighbour, neighbourB;
+ mbStorage_t *nMb, *nMb2;
+ u8 a[1 + 4 + 4], l[1 + 4];
+ u32 data4x4[4];
+ u32 availableA, availableB, availableC, availableD;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(mbLayer);
+ ASSERT(above);
+ ASSERT(left);
+
+ for (block = 0; block < 16; block++)
+ {
+
+ ASSERT(pMb->intra4x4PredMode[block] < 9);
+
+ neighbour = *h264bsdNeighbour4x4BlockA(block);
+ nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
+ availableA = h264bsdIsNeighbourAvailable(pMb, nMb);
+ if (availableA && constrainedIntraPred &&
+ ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
+ {
+ availableA = HANTRO_FALSE;
+ }
+
+ neighbourB = *h264bsdNeighbour4x4BlockB(block);
+ nMb2 = h264bsdGetNeighbourMb(pMb, neighbourB.mb);
+ availableB = h264bsdIsNeighbourAvailable(pMb, nMb2);
+ if (availableB && constrainedIntraPred &&
+ ( h264bsdMbPartPredMode(nMb2->mbType) == PRED_MODE_INTER) )
+ {
+ availableB = HANTRO_FALSE;
+ }
+
+ mode = DetermineIntra4x4PredMode(mbLayer,
+ (u32)(availableA && availableB),
+ &neighbour, &neighbourB, block, nMb, nMb2);
+ pMb->intra4x4PredMode[block] = (u8)mode;
+
+ neighbour = *h264bsdNeighbour4x4BlockC(block);
+ nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
+ availableC = h264bsdIsNeighbourAvailable(pMb, nMb);
+ if (availableC && constrainedIntraPred &&
+ ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
+ {
+ availableC = HANTRO_FALSE;
+ }
+
+ neighbour = *h264bsdNeighbour4x4BlockD(block);
+ nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
+ availableD = h264bsdIsNeighbourAvailable(pMb, nMb);
+ if (availableD && constrainedIntraPred &&
+ ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
+ {
+ availableD = HANTRO_FALSE;
+ }
+
+ Get4x4NeighbourPels(a, l, data, above, left, block);
+
+ switch(mode)
+ {
+ case 0: /* Intra_4x4_Vertical */
+ if (!availableB)
+ return(HANTRO_NOK);
+ Intra4x4VerticalPrediction((u8*)data4x4, a + 1);
+ break;
+ case 1: /* Intra_4x4_Horizontal */
+ if (!availableA)
+ return(HANTRO_NOK);
+ Intra4x4HorizontalPrediction((u8*)data4x4, l + 1);
+ break;
+ case 2: /* Intra_4x4_DC */
+ Intra4x4DcPrediction((u8*)data4x4, a + 1, l + 1,
+ availableA, availableB);
+ break;
+ case 3: /* Intra_4x4_Diagonal_Down_Left */
+ if (!availableB)
+ return(HANTRO_NOK);
+ if (!availableC)
+ {
+ a[5] = a[6] = a[7] = a[8] = a[4];
+ }
+ Intra4x4DiagonalDownLeftPrediction((u8*)data4x4, a + 1);
+ break;
+ case 4: /* Intra_4x4_Diagonal_Down_Right */
+ if (!availableA || !availableB || !availableD)
+ return(HANTRO_NOK);
+ Intra4x4DiagonalDownRightPrediction((u8*)data4x4, a + 1, l + 1);
+ break;
+ case 5: /* Intra_4x4_Vertical_Right */
+ if (!availableA || !availableB || !availableD)
+ return(HANTRO_NOK);
+ Intra4x4VerticalRightPrediction((u8*)data4x4, a + 1, l + 1);
+ break;
+ case 6: /* Intra_4x4_Horizontal_Down */
+ if (!availableA || !availableB || !availableD)
+ return(HANTRO_NOK);
+ Intra4x4HorizontalDownPrediction((u8*)data4x4, a + 1, l + 1);
+ break;
+ case 7: /* Intra_4x4_Vertical_Left */
+ if (!availableB)
+ return(HANTRO_NOK);
+ if (!availableC)
+ {
+ a[5] = a[6] = a[7] = a[8] = a[4];
+ }
+ Intra4x4VerticalLeftPrediction((u8*)data4x4, a + 1);
+ break;
+ default: /* case 8 Intra_4x4_Horizontal_Up */
+ if (!availableA)
+ return(HANTRO_NOK);
+ Intra4x4HorizontalUpPrediction((u8*)data4x4, l + 1);
+ break;
+ }
+
+ Write4x4To16x16(data, (u8*)data4x4, block);
+ h264bsdAddResidual(data, mbLayer->residual.level[block], block);
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: IntraChromaPrediction
+
+ Functional description:
+ Perform intra prediction for chroma pixels and add residual
+ into prediction. The resulting chroma pixels are stored in 'data'.
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdIntraChromaPrediction(mbStorage_t *pMb, u8 *data, i32 residual[][16],
+ u8 *above, u8 *left, u32 predMode, u32 constrainedIntraPred)
+{
+
+/* Variables */
+
+ u32 i, comp, block;
+ u32 availableA, availableB, availableD;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(residual);
+ ASSERT(above);
+ ASSERT(left);
+ ASSERT(predMode < 4);
+
+ availableA = h264bsdIsNeighbourAvailable(pMb, pMb->mbA);
+ if (availableA && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbA->mbType) == PRED_MODE_INTER))
+ availableA = HANTRO_FALSE;
+ availableB = h264bsdIsNeighbourAvailable(pMb, pMb->mbB);
+ if (availableB && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbB->mbType) == PRED_MODE_INTER))
+ availableB = HANTRO_FALSE;
+ availableD = h264bsdIsNeighbourAvailable(pMb, pMb->mbD);
+ if (availableD && constrainedIntraPred &&
+ (h264bsdMbPartPredMode(pMb->mbD->mbType) == PRED_MODE_INTER))
+ availableD = HANTRO_FALSE;
+
+ for (comp = 0, block = 16; comp < 2; comp++)
+ {
+ switch(predMode)
+ {
+ case 0: /* Intra_Chroma_DC */
+ IntraChromaDcPrediction(data, above+1, left, availableA,
+ availableB);
+ break;
+
+ case 1: /* Intra_Chroma_Horizontal */
+ if (!availableA)
+ return(HANTRO_NOK);
+ IntraChromaHorizontalPrediction(data, left);
+ break;
+
+ case 2: /* Intra_Chroma_Vertical */
+ if (!availableB)
+ return(HANTRO_NOK);
+ IntraChromaVerticalPrediction(data, above+1);
+
+ break;
+
+ default: /* case 3: Intra_Chroma_Plane */
+ if (!availableA || !availableB || !availableD)
+ return(HANTRO_NOK);
+ IntraChromaPlanePrediction(data, above+1, left);
+ break;
+ }
+ for (i = 0; i < 4; i++, block++)
+ h264bsdAddResidual(data, residual[i], block);
+
+ /* advance pointers */
+ data += 64;
+ above += 9;
+ left += 8;
+ residual += 4;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdAddResidual
+
+ Functional description:
+ Add residual of a block into prediction in macroblock array 'data'.
+ The result (residual + prediction) is stored in 'data'.
+
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_OMXDL
+void h264bsdAddResidual(u8 *data, i32 *residual, u32 blockNum)
+{
+
+/* Variables */
+
+ u32 i;
+ u32 x, y;
+ u32 width;
+ i32 tmp1, tmp2, tmp3, tmp4;
+ u8 *tmp;
+ const u8 *clp = h264bsdClip + 512;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(residual);
+ ASSERT(blockNum < 16 + 4 + 4);
+
+ if (IS_RESIDUAL_EMPTY(residual))
+ return;
+
+ RANGE_CHECK_ARRAY(residual, -512, 511, 16);
+
+ if (blockNum < 16)
+ {
+ width = 16;
+ x = h264bsdBlockX[blockNum];
+ y = h264bsdBlockY[blockNum];
+ }
+ else
+ {
+ width = 8;
+ x = h264bsdBlockX[blockNum & 0x3];
+ y = h264bsdBlockY[blockNum & 0x3];
+ }
+
+ tmp = data + y*width + x;
+ for (i = 4; i; i--)
+ {
+ tmp1 = *residual++;
+ tmp2 = tmp[0];
+ tmp3 = *residual++;
+ tmp4 = tmp[1];
+
+ tmp[0] = clp[tmp1 + tmp2];
+
+ tmp1 = *residual++;
+ tmp2 = tmp[2];
+
+ tmp[1] = clp[tmp3 + tmp4];
+
+ tmp3 = *residual++;
+ tmp4 = tmp[3];
+
+ tmp1 = clp[tmp1 + tmp2];
+ tmp3 = clp[tmp3 + tmp4];
+ tmp[2] = (u8)tmp1;
+ tmp[3] = (u8)tmp3;
+
+ tmp += width;
+ }
+
+}
+#endif
+/*------------------------------------------------------------------------------
+
+ Function: Intra16x16VerticalPrediction
+
+ Functional description:
+ Perform intra 16x16 vertical prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra16x16VerticalPrediction(u8 *data, u8 *above)
+{
+
+/* Variables */
+
+ u32 i, j;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+
+ for (i = 0; i < 16; i++)
+ {
+ for (j = 0; j < 16; j++)
+ {
+ *data++ = above[j];
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra16x16HorizontalPrediction
+
+ Functional description:
+ Perform intra 16x16 horizontal prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra16x16HorizontalPrediction(u8 *data, u8 *left)
+{
+
+/* Variables */
+
+ u32 i, j;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(left);
+
+ for (i = 0; i < 16; i++)
+ {
+ for (j = 0; j < 16; j++)
+ {
+ *data++ = left[i];
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra16x16DcPrediction
+
+ Functional description:
+ Perform intra 16x16 DC prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra16x16DcPrediction(u8 *data, u8 *above, u8 *left, u32 availableA,
+ u32 availableB)
+{
+
+/* Variables */
+
+ u32 i, tmp;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+ ASSERT(left);
+
+ if (availableA && availableB)
+ {
+ for (i = 0, tmp = 0; i < 16; i++)
+ tmp += above[i] + left[i];
+ tmp = (tmp + 16) >> 5;
+ }
+ else if (availableA)
+ {
+ for (i = 0, tmp = 0; i < 16; i++)
+ tmp += left[i];
+ tmp = (tmp + 8) >> 4;
+ }
+ else if (availableB)
+ {
+ for (i = 0, tmp = 0; i < 16; i++)
+ tmp += above[i];
+ tmp = (tmp + 8) >> 4;
+ }
+ /* neither A nor B available */
+ else
+ {
+ tmp = 128;
+ }
+ for (i = 0; i < 256; i++)
+ data[i] = (u8)tmp;
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra16x16PlanePrediction
+
+ Functional description:
+ Perform intra 16x16 plane prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra16x16PlanePrediction(u8 *data, u8 *above, u8 *left)
+{
+
+/* Variables */
+
+ u32 i, j;
+ i32 a, b, c;
+ i32 tmp;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+ ASSERT(left);
+
+ a = 16 * (above[15] + left[15]);
+
+ for (i = 0, b = 0; i < 8; i++)
+ b += ((i32)i + 1) * (above[8+i] - above[6-i]);
+ b = (5 * b + 32) >> 6;
+
+ for (i = 0, c = 0; i < 7; i++)
+ c += ((i32)i + 1) * (left[8+i] - left[6-i]);
+ /* p[-1,-1] has to be accessed through above pointer */
+ c += ((i32)i + 1) * (left[8+i] - above[-1]);
+ c = (5 * c + 32) >> 6;
+
+ for (i = 0; i < 16; i++)
+ {
+ for (j = 0; j < 16; j++)
+ {
+ tmp = (a + b * ((i32)j - 7) + c * ((i32)i - 7) + 16) >> 5;
+ data[i*16+j] = (u8)CLIP1(tmp);
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: IntraChromaDcPrediction
+
+ Functional description:
+ Perform intra chroma DC prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void IntraChromaDcPrediction(u8 *data, u8 *above, u8 *left, u32 availableA,
+ u32 availableB)
+{
+
+/* Variables */
+
+ u32 i;
+ u32 tmp1, tmp2;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+ ASSERT(left);
+
+ /* y = 0..3 */
+ if (availableA && availableB)
+ {
+ tmp1 = above[0] + above[1] + above[2] + above[3] +
+ left[0] + left[1] + left[2] + left[3];
+ tmp1 = (tmp1 + 4) >> 3;
+ tmp2 = (above[4] + above[5] + above[6] + above[7] + 2) >> 2;
+ }
+ else if (availableB)
+ {
+ tmp1 = (above[0] + above[1] + above[2] + above[3] + 2) >> 2;
+ tmp2 = (above[4] + above[5] + above[6] + above[7] + 2) >> 2;
+ }
+ else if (availableA)
+ {
+ tmp1 = (left[0] + left[1] + left[2] + left[3] + 2) >> 2;
+ tmp2 = tmp1;
+ }
+ /* neither A nor B available */
+ else
+ {
+ tmp1 = tmp2 = 128;
+ }
+
+ ASSERT(tmp1 < 256 && tmp2 < 256);
+ for (i = 4; i--;)
+ {
+ *data++ = (u8)tmp1;
+ *data++ = (u8)tmp1;
+ *data++ = (u8)tmp1;
+ *data++ = (u8)tmp1;
+ *data++ = (u8)tmp2;
+ *data++ = (u8)tmp2;
+ *data++ = (u8)tmp2;
+ *data++ = (u8)tmp2;
+ }
+
+ /* y = 4...7 */
+ if (availableA)
+ {
+ tmp1 = (left[4] + left[5] + left[6] + left[7] + 2) >> 2;
+ if (availableB)
+ {
+ tmp2 = above[4] + above[5] + above[6] + above[7] +
+ left[4] + left[5] + left[6] + left[7];
+ tmp2 = (tmp2 + 4) >> 3;
+ }
+ else
+ tmp2 = tmp1;
+ }
+ else if (availableB)
+ {
+ tmp1 = (above[0] + above[1] + above[2] + above[3] + 2) >> 2;
+ tmp2 = (above[4] + above[5] + above[6] + above[7] + 2) >> 2;
+ }
+ else
+ {
+ tmp1 = tmp2 = 128;
+ }
+
+ ASSERT(tmp1 < 256 && tmp2 < 256);
+ for (i = 4; i--;)
+ {
+ *data++ = (u8)tmp1;
+ *data++ = (u8)tmp1;
+ *data++ = (u8)tmp1;
+ *data++ = (u8)tmp1;
+ *data++ = (u8)tmp2;
+ *data++ = (u8)tmp2;
+ *data++ = (u8)tmp2;
+ *data++ = (u8)tmp2;
+ }
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: IntraChromaHorizontalPrediction
+
+ Functional description:
+ Perform intra chroma horizontal prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void IntraChromaHorizontalPrediction(u8 *data, u8 *left)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(left);
+
+ for (i = 8; i--;)
+ {
+ *data++ = *left;
+ *data++ = *left;
+ *data++ = *left;
+ *data++ = *left;
+ *data++ = *left;
+ *data++ = *left;
+ *data++ = *left;
+ *data++ = *left++;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: IntraChromaVerticalPrediction
+
+ Functional description:
+ Perform intra chroma vertical prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void IntraChromaVerticalPrediction(u8 *data, u8 *above)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+
+ for (i = 8; i--;data++/*above-=8*/)
+ {
+ data[0] = *above;
+ data[8] = *above;
+ data[16] = *above;
+ data[24] = *above;
+ data[32] = *above;
+ data[40] = *above;
+ data[48] = *above;
+ data[56] = *above++;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: IntraChromaPlanePrediction
+
+ Functional description:
+ Perform intra chroma plane prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void IntraChromaPlanePrediction(u8 *data, u8 *above, u8 *left)
+{
+
+/* Variables */
+
+ u32 i;
+ i32 a, b, c;
+ i32 tmp;
+ const u8 *clp = h264bsdClip + 512;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+ ASSERT(left);
+
+ a = 16 * (above[7] + left[7]);
+
+ b = (above[4] - above[2]) + 2 * (above[5] - above[1])
+ + 3 * (above[6] - above[0]) + 4 * (above[7] - above[-1]);
+ b = (17 * b + 16) >> 5;
+
+ /* p[-1,-1] has to be accessed through above pointer */
+ c = (left[4] - left[2]) + 2 * (left[5] - left[1])
+ + 3 * (left[6] - left[0]) + 4 * (left[7] - above[-1]);
+ c = (17 * c + 16) >> 5;
+
+ /*a += 16;*/
+ a = a - 3 * c + 16;
+ for (i = 8; i--; a += c)
+ {
+ tmp = (a - 3 * b);
+ *data++ = clp[tmp>>5];
+ tmp += b;
+ *data++ = clp[tmp>>5];
+ tmp += b;
+ *data++ = clp[tmp>>5];
+ tmp += b;
+ *data++ = clp[tmp>>5];
+ tmp += b;
+ *data++ = clp[tmp>>5];
+ tmp += b;
+ *data++ = clp[tmp>>5];
+ tmp += b;
+ *data++ = clp[tmp>>5];
+ tmp += b;
+ *data++ = clp[tmp>>5];
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Get4x4NeighbourPels
+
+ Functional description:
+ Get neighbouring pixels of a 4x4 block into 'a' and 'l'.
+
+------------------------------------------------------------------------------*/
+
+void Get4x4NeighbourPels(u8 *a, u8 *l, u8 *data, u8 *above, u8 *left,
+ u32 blockNum)
+{
+
+/* Variables */
+
+ u32 x, y;
+ u8 t1, t2;
+
+/* Code */
+
+ ASSERT(a);
+ ASSERT(l);
+ ASSERT(data);
+ ASSERT(above);
+ ASSERT(left);
+ ASSERT(blockNum < 16);
+
+ x = h264bsdBlockX[blockNum];
+ y = h264bsdBlockY[blockNum];
+
+ /* A and D */
+ if (x == 0)
+ {
+ t1 = left[y ];
+ t2 = left[y + 1];
+ l[1] = t1;
+ l[2] = t2;
+ t1 = left[y + 2];
+ t2 = left[y + 3];
+ l[3] = t1;
+ l[4] = t2;
+ }
+ else
+ {
+ t1 = data[y * 16 + x - 1 ];
+ t2 = data[y * 16 + x - 1 + 16];
+ l[1] = t1;
+ l[2] = t2;
+ t1 = data[y * 16 + x - 1 + 32];
+ t2 = data[y * 16 + x - 1 + 48];
+ l[3] = t1;
+ l[4] = t2;
+ }
+
+ /* B, C and D */
+ if (y == 0)
+ {
+ t1 = above[x ];
+ t2 = above[x ];
+ l[0] = t1;
+ a[0] = t2;
+ t1 = above[x + 1];
+ t2 = above[x + 2];
+ a[1] = t1;
+ a[2] = t2;
+ t1 = above[x + 3];
+ t2 = above[x + 4];
+ a[3] = t1;
+ a[4] = t2;
+ t1 = above[x + 5];
+ t2 = above[x + 6];
+ a[5] = t1;
+ a[6] = t2;
+ t1 = above[x + 7];
+ t2 = above[x + 8];
+ a[7] = t1;
+ a[8] = t2;
+ }
+ else
+ {
+ t1 = data[(y - 1) * 16 + x ];
+ t2 = data[(y - 1) * 16 + x + 1];
+ a[1] = t1;
+ a[2] = t2;
+ t1 = data[(y - 1) * 16 + x + 2];
+ t2 = data[(y - 1) * 16 + x + 3];
+ a[3] = t1;
+ a[4] = t2;
+ t1 = data[(y - 1) * 16 + x + 4];
+ t2 = data[(y - 1) * 16 + x + 5];
+ a[5] = t1;
+ a[6] = t2;
+ t1 = data[(y - 1) * 16 + x + 6];
+ t2 = data[(y - 1) * 16 + x + 7];
+ a[7] = t1;
+ a[8] = t2;
+
+ if (x == 0)
+ l[0] = a[0] = left[y-1];
+ else
+ l[0] = a[0] = data[(y - 1) * 16 + x - 1];
+ }
+}
+
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra4x4VerticalPrediction
+
+ Functional description:
+ Perform intra 4x4 vertical prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra4x4VerticalPrediction(u8 *data, u8 *above)
+{
+
+/* Variables */
+
+ u8 t1, t2;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+
+ t1 = above[0];
+ t2 = above[1];
+ data[0] = data[4] = data[8] = data[12] = t1;
+ data[1] = data[5] = data[9] = data[13] = t2;
+ t1 = above[2];
+ t2 = above[3];
+ data[2] = data[6] = data[10] = data[14] = t1;
+ data[3] = data[7] = data[11] = data[15] = t2;
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra4x4HorizontalPrediction
+
+ Functional description:
+ Perform intra 4x4 horizontal prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra4x4HorizontalPrediction(u8 *data, u8 *left)
+{
+
+/* Variables */
+
+ u8 t1, t2;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(left);
+
+ t1 = left[0];
+ t2 = left[1];
+ data[0] = data[1] = data[2] = data[3] = t1;
+ data[4] = data[5] = data[6] = data[7] = t2;
+ t1 = left[2];
+ t2 = left[3];
+ data[8] = data[9] = data[10] = data[11] = t1;
+ data[12] = data[13] = data[14] = data[15] = t2;
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra4x4DcPrediction
+
+ Functional description:
+ Perform intra 4x4 DC prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra4x4DcPrediction(u8 *data, u8 *above, u8 *left, u32 availableA,
+ u32 availableB)
+{
+
+/* Variables */
+
+ u32 tmp;
+ u8 t1, t2, t3, t4;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+ ASSERT(left);
+
+ if (availableA && availableB)
+ {
+ t1 = above[0]; t2 = above[1]; t3 = above[2]; t4 = above[3];
+ tmp = t1 + t2 + t3 + t4;
+ t1 = left[0]; t2 = left[1]; t3 = left[2]; t4 = left[3];
+ tmp += t1 + t2 + t3 + t4;
+ tmp = (tmp + 4) >> 3;
+ }
+ else if (availableA)
+ {
+ t1 = left[0]; t2 = left[1]; t3 = left[2]; t4 = left[3];
+ tmp = (t1 + t2 + t3 + t4 + 2) >> 2;
+ }
+ else if (availableB)
+ {
+ t1 = above[0]; t2 = above[1]; t3 = above[2]; t4 = above[3];
+ tmp = (t1 + t2 + t3 + t4 + 2) >> 2;
+ }
+ else
+ {
+ tmp = 128;
+ }
+
+ ASSERT(tmp < 256);
+ data[0] = data[1] = data[2] = data[3] =
+ data[4] = data[5] = data[6] = data[7] =
+ data[8] = data[9] = data[10] = data[11] =
+ data[12] = data[13] = data[14] = data[15] = (u8)tmp;
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra4x4DiagonalDownLeftPrediction
+
+ Functional description:
+ Perform intra 4x4 diagonal down-left prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra4x4DiagonalDownLeftPrediction(u8 *data, u8 *above)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+
+ data[ 0] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
+ data[ 1] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
+ data[ 4] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
+ data[ 2] = (above[2] + 2 * above[3] + above[4] + 2) >> 2;
+ data[ 5] = (above[2] + 2 * above[3] + above[4] + 2) >> 2;
+ data[ 8] = (above[2] + 2 * above[3] + above[4] + 2) >> 2;
+ data[ 3] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
+ data[ 6] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
+ data[ 9] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
+ data[12] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
+ data[ 7] = (above[4] + 2 * above[5] + above[6] + 2) >> 2;
+ data[10] = (above[4] + 2 * above[5] + above[6] + 2) >> 2;
+ data[13] = (above[4] + 2 * above[5] + above[6] + 2) >> 2;
+ data[11] = (above[5] + 2 * above[6] + above[7] + 2) >> 2;
+ data[14] = (above[5] + 2 * above[6] + above[7] + 2) >> 2;
+ data[15] = (above[6] + 3 * above[7] + 2) >> 2;
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra4x4DiagonalDownRightPrediction
+
+ Functional description:
+ Perform intra 4x4 diagonal down-right prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra4x4DiagonalDownRightPrediction(u8 *data, u8 *above, u8 *left)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+ ASSERT(left);
+
+ data[ 0] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
+ data[ 5] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
+ data[10] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
+ data[15] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
+ data[ 1] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
+ data[ 6] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
+ data[11] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
+ data[ 2] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
+ data[ 7] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
+ data[ 3] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
+ data[ 4] = (left[-1] + 2 * left[0] + left[1] + 2) >> 2;
+ data[ 9] = (left[-1] + 2 * left[0] + left[1] + 2) >> 2;
+ data[14] = (left[-1] + 2 * left[0] + left[1] + 2) >> 2;
+ data[ 8] = (left[0] + 2 * left[1] + left[2] + 2) >> 2;
+ data[13] = (left[0] + 2 * left[1] + left[2] + 2) >> 2;
+ data[12] = (left[1] + 2 * left[2] + left[3] + 2) >> 2;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra4x4VerticalRightPrediction
+
+ Functional description:
+ Perform intra 4x4 vertical right prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra4x4VerticalRightPrediction(u8 *data, u8 *above, u8 *left)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+ ASSERT(left);
+
+ data[ 0] = (above[-1] + above[0] + 1) >> 1;
+ data[ 9] = (above[-1] + above[0] + 1) >> 1;
+ data[ 5] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
+ data[14] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
+ data[ 4] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
+ data[13] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
+ data[ 1] = (above[0] + above[1] + 1) >> 1;
+ data[10] = (above[0] + above[1] + 1) >> 1;
+ data[ 6] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
+ data[15] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
+ data[ 2] = (above[1] + above[2] + 1) >> 1;
+ data[11] = (above[1] + above[2] + 1) >> 1;
+ data[ 7] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
+ data[ 3] = (above[2] + above[3] + 1) >> 1;
+ data[ 8] = (left[1] + 2 * left[0] + left[-1] + 2) >> 2;
+ data[12] = (left[2] + 2 * left[1] + left[0] + 2) >> 2;
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra4x4HorizontalDownPrediction
+
+ Functional description:
+ Perform intra 4x4 horizontal down prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra4x4HorizontalDownPrediction(u8 *data, u8 *above, u8 *left)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+ ASSERT(left);
+
+ data[ 0] = (left[-1] + left[0] + 1) >> 1;
+ data[ 6] = (left[-1] + left[0] + 1) >> 1;
+ data[ 5] = (left[-1] + 2 * left[0] + left[1] + 2) >> 2;
+ data[11] = (left[-1] + 2 * left[0] + left[1] + 2) >> 2;
+ data[ 4] = (left[0] + left[1] + 1) >> 1;
+ data[10] = (left[0] + left[1] + 1) >> 1;
+ data[ 9] = (left[0] + 2 * left[1] + left[2] + 2) >> 2;
+ data[15] = (left[0] + 2 * left[1] + left[2] + 2) >> 2;
+ data[ 8] = (left[1] + left[2] + 1) >> 1;
+ data[14] = (left[1] + left[2] + 1) >> 1;
+ data[13] = (left[1] + 2 * left[2] + left[3] + 2) >> 2;
+ data[12] = (left[2] + left[3] + 1) >> 1;
+ data[ 1] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
+ data[ 7] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
+ data[ 2] = (above[1] + 2 * above[0] + above[-1] + 2) >> 2;
+ data[ 3] = (above[2] + 2 * above[1] + above[0] + 2) >> 2;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra4x4VerticalLeftPrediction
+
+ Functional description:
+ Perform intra 4x4 vertical left prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra4x4VerticalLeftPrediction(u8 *data, u8 *above)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(above);
+
+ data[ 0] = (above[0] + above[1] + 1) >> 1;
+ data[ 1] = (above[1] + above[2] + 1) >> 1;
+ data[ 2] = (above[2] + above[3] + 1) >> 1;
+ data[ 3] = (above[3] + above[4] + 1) >> 1;
+ data[ 4] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
+ data[ 5] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
+ data[ 6] = (above[2] + 2 * above[3] + above[4] + 2) >> 2;
+ data[ 7] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
+ data[ 8] = (above[1] + above[2] + 1) >> 1;
+ data[ 9] = (above[2] + above[3] + 1) >> 1;
+ data[10] = (above[3] + above[4] + 1) >> 1;
+ data[11] = (above[4] + above[5] + 1) >> 1;
+ data[12] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
+ data[13] = (above[2] + 2 * above[3] + above[4] + 2) >> 2;
+ data[14] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
+ data[15] = (above[4] + 2 * above[5] + above[6] + 2) >> 2;
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: Intra4x4HorizontalUpPrediction
+
+ Functional description:
+ Perform intra 4x4 horizontal up prediction mode.
+
+------------------------------------------------------------------------------*/
+
+void Intra4x4HorizontalUpPrediction(u8 *data, u8 *left)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(left);
+
+ data[ 0] = (left[0] + left[1] + 1) >> 1;
+ data[ 1] = (left[0] + 2 * left[1] + left[2] + 2) >> 2;
+ data[ 2] = (left[1] + left[2] + 1) >> 1;
+ data[ 3] = (left[1] + 2 * left[2] + left[3] + 2) >> 2;
+ data[ 4] = (left[1] + left[2] + 1) >> 1;
+ data[ 5] = (left[1] + 2 * left[2] + left[3] + 2) >> 2;
+ data[ 6] = (left[2] + left[3] + 1) >> 1;
+ data[ 7] = (left[2] + 3 * left[3] + 2) >> 2;
+ data[ 8] = (left[2] + left[3] + 1) >> 1;
+ data[ 9] = (left[2] + 3 * left[3] + 2) >> 2;
+ data[10] = left[3];
+ data[11] = left[3];
+ data[12] = left[3];
+ data[13] = left[3];
+ data[14] = left[3];
+ data[15] = left[3];
+
+}
+
+#endif /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+
+ Function: Write4x4To16x16
+
+ Functional description:
+ Write a 4x4 block (data4x4) into correct position
+ in 16x16 macroblock (data).
+
+------------------------------------------------------------------------------*/
+
+void Write4x4To16x16(u8 *data, u8 *data4x4, u32 blockNum)
+{
+
+/* Variables */
+
+ u32 x, y;
+ u32 *in32, *out32;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(data4x4);
+ ASSERT(blockNum < 16);
+
+ x = h264bsdBlockX[blockNum];
+ y = h264bsdBlockY[blockNum];
+
+ data += y*16+x;
+
+ ASSERT(((u32)data&0x3) == 0);
+
+ /*lint --e(826) */
+ out32 = (u32 *)data;
+ /*lint --e(826) */
+ in32 = (u32 *)data4x4;
+
+ out32[0] = *in32++;
+ out32[4] = *in32++;
+ out32[8] = *in32++;
+ out32[12] = *in32++;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DetermineIntra4x4PredMode
+
+ Functional description:
+ Returns the intra 4x4 prediction mode of a block based on the
+ neighbouring macroblocks and information parsed from stream.
+
+------------------------------------------------------------------------------*/
+
+u32 DetermineIntra4x4PredMode(macroblockLayer_t *pMbLayer,
+ u32 available, neighbour_t *nA, neighbour_t *nB, u32 index,
+ mbStorage_t *nMbA, mbStorage_t *nMbB)
+{
+
+/* Variables */
+
+ u32 mode1, mode2;
+ mbStorage_t *pMb;
+
+/* Code */
+
+ ASSERT(pMbLayer);
+
+ /* dc only prediction? */
+ if (!available)
+ mode1 = 2;
+ else
+ {
+ pMb = nMbA;
+ if (h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTRA4x4)
+ {
+ mode1 = pMb->intra4x4PredMode[nA->index];
+ }
+ else
+ mode1 = 2;
+
+ pMb = nMbB;
+ if (h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTRA4x4)
+ {
+ mode2 = pMb->intra4x4PredMode[nB->index];
+ }
+ else
+ mode2 = 2;
+
+ mode1 = MIN(mode1, mode2);
+ }
+
+ if (!pMbLayer->mbPred.prevIntra4x4PredModeFlag[index])
+ {
+ if (pMbLayer->mbPred.remIntra4x4PredMode[index] < mode1)
+ {
+ mode1 = pMbLayer->mbPred.remIntra4x4PredMode[index];
+ }
+ else
+ {
+ mode1 = pMbLayer->mbPred.remIntra4x4PredMode[index] + 1;
+ }
+ }
+
+ return(mode1);
+}
+
+
+/*lint +e702 */
+
+
--- /dev/null
+++ b/src/h264bsd_intra_prediction.h
@@ -1,0 +1,82 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_INTRA_PREDICTION_H
+#define H264SWDEC_INTRA_PREDICTION_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_image.h"
+#include "h264bsd_macroblock_layer.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_OMXDL
+u32 h264bsdIntraPrediction(mbStorage_t *pMb, macroblockLayer_t *mbLayer,
+ image_t *image, u32 mbNum, u32 constrainedIntraPred, u8 *data);
+
+u32 h264bsdIntra4x4Prediction(mbStorage_t *pMb, u8 *data,
+ macroblockLayer_t *mbLayer,
+ u8 *above, u8 *left, u32 constrainedIntraPred);
+u32 h264bsdIntra16x16Prediction(mbStorage_t *pMb, u8 *data, i32 residual[][16],
+ u8 *above, u8 *left, u32 constrainedIntraPred);
+
+u32 h264bsdIntraChromaPrediction(mbStorage_t *pMb, u8 *data, i32 residual[][16],
+ u8 *above, u8 *left, u32 predMode, u32 constrainedIntraPred);
+
+void h264bsdGetNeighbourPels(image_t *image, u8 *above, u8 *left, u32 mbNum);
+
+#else
+
+u32 h264bsdIntra4x4Prediction(mbStorage_t *pMb, u8 *data,
+ macroblockLayer_t *mbLayer,
+ u8 *pImage, u32 width,
+ u32 constrainedIntraPred, u32 block);
+
+u32 h264bsdIntra16x16Prediction(mbStorage_t *pMb, u8 *data, u8 *pImage,
+ u32 width, u32 constrainedIntraPred);
+
+u32 h264bsdIntraChromaPrediction(mbStorage_t *pMb, u8 *data, image_t *image,
+ u32 predMode, u32 constrainedIntraPred);
+
+#endif
+
+#endif /* #ifdef H264SWDEC_INTRA_PREDICTION_H */
+
--- /dev/null
+++ b/src/h264bsd_macroblock_layer.c
@@ -1,0 +1,1447 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodeMacroblockLayer
+ h264bsdMbPartPredMode
+ h264bsdNumMbPart
+ h264bsdNumSubMbPart
+ DecodeMbPred
+ DecodeSubMbPred
+ DecodeResidual
+ DetermineNc
+ CbpIntra16x16
+ h264bsdPredModeIntra16x16
+ h264bsdDecodeMacroblock
+ ProcessResidual
+ h264bsdSubMbPartMode
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_macroblock_layer.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_util.h"
+#include "h264bsd_vlc.h"
+#include "h264bsd_cavlc.h"
+#include "h264bsd_nal_unit.h"
+#include "h264bsd_neighbour.h"
+#include "h264bsd_transform.h"
+#include "h264bsd_intra_prediction.h"
+#include "h264bsd_inter_prediction.h"
+
+#ifdef H264DEC_OMXDL
+#include "omxtypes.h"
+#include "omxVC.h"
+#include "armVC.h"
+#endif /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+#ifdef H264DEC_OMXDL
+static const u32 chromaIndex[8] = { 256, 260, 288, 292, 320, 324, 352, 356 };
+static const u32 lumaIndex[16] = { 0, 4, 64, 68,
+ 8, 12, 72, 76,
+ 128, 132, 192, 196,
+ 136, 140, 200, 204 };
+#endif
+/* mapping of dc coefficients array to luma blocks */
+static const u32 dcCoeffIndex[16] =
+ {0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15};
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 DecodeMbPred(strmData_t *pStrmData, mbPred_t *pMbPred,
+ mbType_e mbType, u32 numRefIdxActive);
+static u32 DecodeSubMbPred(strmData_t *pStrmData, subMbPred_t *pSubMbPred,
+ mbType_e mbType, u32 numRefIdxActive);
+static u32 DecodeResidual(strmData_t *pStrmData, residual_t *pResidual,
+ mbStorage_t *pMb, mbType_e mbType, u32 codedBlockPattern);
+
+#ifdef H264DEC_OMXDL
+static u32 DetermineNc(mbStorage_t *pMb, u32 blockIndex, u8 *pTotalCoeff);
+#else
+static u32 DetermineNc(mbStorage_t *pMb, u32 blockIndex, i16 *pTotalCoeff);
+#endif
+
+static u32 CbpIntra16x16(mbType_e mbType);
+#ifdef H264DEC_OMXDL
+static u32 ProcessIntra4x4Residual(mbStorage_t *pMb, u8 *data, u32 constrainedIntraPred,
+ macroblockLayer_t *mbLayer, const u8 **pSrc, image_t *image);
+static u32 ProcessChromaResidual(mbStorage_t *pMb, u8 *data, const u8 **pSrc );
+static u32 ProcessIntra16x16Residual(mbStorage_t *pMb, u8 *data, u32 constrainedIntraPred,
+ u32 intraChromaPredMode, const u8 **pSrc, image_t *image);
+
+
+#else
+static u32 ProcessResidual(mbStorage_t *pMb, i32 residualLevel[][16], u32 *);
+#endif
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdDecodeMacroblockLayer
+
+ Functional description:
+ Parse macroblock specific information from bit stream.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ pMb pointer to macroblock storage structure
+ sliceType type of the current slice
+ numRefIdxActive maximum reference index
+
+ Outputs:
+ pMbLayer stores the macroblock data parsed from stream
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK end of stream or error in stream
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeMacroblockLayer(strmData_t *pStrmData,
+ macroblockLayer_t *pMbLayer, mbStorage_t *pMb, u32 sliceType,
+ u32 numRefIdxActive)
+{
+
+/* Variables */
+
+ u32 tmp, i, value;
+ i32 itmp;
+ mbPartPredMode_e partMode;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pMbLayer);
+
+#ifdef H264DEC_NEON
+ h264bsdClearMbLayer(pMbLayer, ((sizeof(macroblockLayer_t) + 63) & ~0x3F));
+#else
+ memset(pMbLayer, 0, sizeof(macroblockLayer_t));
+#endif
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+
+ if (IS_I_SLICE(sliceType))
+ {
+ if ((value + 6) > 31 || tmp != HANTRO_OK)
+ return(HANTRO_NOK);
+ pMbLayer->mbType = (mbType_e)(value + 6);
+ }
+ else
+ {
+ if ((value + 1) > 31 || tmp != HANTRO_OK)
+ return(HANTRO_NOK);
+ pMbLayer->mbType = (mbType_e)(value + 1);
+ }
+
+ if (pMbLayer->mbType == I_PCM)
+ {
+ i32 *level;
+ while( !h264bsdIsByteAligned(pStrmData) )
+ {
+ /* pcm_alignment_zero_bit */
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp)
+ return(HANTRO_NOK);
+ }
+
+ level = pMbLayer->residual.level[0];
+ for (i = 0; i < 384; i++)
+ {
+ value = h264bsdGetBits(pStrmData, 8);
+ if (value == END_OF_STREAM)
+ return(HANTRO_NOK);
+ *level++ = (i32)value;
+ }
+ }
+ else
+ {
+ partMode = h264bsdMbPartPredMode(pMbLayer->mbType);
+ if ( (partMode == PRED_MODE_INTER) &&
+ (h264bsdNumMbPart(pMbLayer->mbType) == 4) )
+ {
+ tmp = DecodeSubMbPred(pStrmData, &pMbLayer->subMbPred,
+ pMbLayer->mbType, numRefIdxActive);
+ }
+ else
+ {
+ tmp = DecodeMbPred(pStrmData, &pMbLayer->mbPred,
+ pMbLayer->mbType, numRefIdxActive);
+ }
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ if (partMode != PRED_MODE_INTRA16x16)
+ {
+ tmp = h264bsdDecodeExpGolombMapped(pStrmData, &value,
+ (u32)(partMode == PRED_MODE_INTRA4x4));
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pMbLayer->codedBlockPattern = value;
+ }
+ else
+ {
+ pMbLayer->codedBlockPattern = CbpIntra16x16(pMbLayer->mbType);
+ }
+
+ if ( pMbLayer->codedBlockPattern ||
+ (partMode == PRED_MODE_INTRA16x16) )
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK || (itmp < -26) || (itmp > 25) )
+ return(HANTRO_NOK);
+ pMbLayer->mbQpDelta = itmp;
+
+ tmp = DecodeResidual(pStrmData, &pMbLayer->residual, pMb,
+ pMbLayer->mbType, pMbLayer->codedBlockPattern);
+
+ pStrmData->strmBuffReadBits =
+ (u32)(pStrmData->pStrmCurrPos - pStrmData->pStrmBuffStart) * 8 +
+ pStrmData->bitPosInWord;
+
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdMbPartPredMode
+
+ Functional description:
+ Returns the prediction mode of a macroblock type
+
+------------------------------------------------------------------------------*/
+
+mbPartPredMode_e h264bsdMbPartPredMode(mbType_e mbType)
+{
+
+/* Variables */
+
+
+/* Code */
+
+ ASSERT(mbType <= 31);
+
+ if ((mbType <= P_8x8ref0))
+ return(PRED_MODE_INTER);
+ else if (mbType == I_4x4)
+ return(PRED_MODE_INTRA4x4);
+ else
+ return(PRED_MODE_INTRA16x16);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdNumMbPart
+
+ Functional description:
+ Returns the amount of macroblock partitions in a macroblock type
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdNumMbPart(mbType_e mbType)
+{
+
+/* Variables */
+
+
+/* Code */
+
+ ASSERT(h264bsdMbPartPredMode(mbType) == PRED_MODE_INTER);
+
+ switch (mbType)
+ {
+ case P_L0_16x16:
+ case P_Skip:
+ return(1);
+
+ case P_L0_L0_16x8:
+ case P_L0_L0_8x16:
+ return(2);
+
+ /* P_8x8 or P_8x8ref0 */
+ default:
+ return(4);
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdNumSubMbPart
+
+ Functional description:
+ Returns the amount of sub-partitions in a sub-macroblock type
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdNumSubMbPart(subMbType_e subMbType)
+{
+
+/* Variables */
+
+
+/* Code */
+
+ ASSERT(subMbType <= P_L0_4x4);
+
+ switch (subMbType)
+ {
+ case P_L0_8x8:
+ return(1);
+
+ case P_L0_8x4:
+ case P_L0_4x8:
+ return(2);
+
+ /* P_L0_4x4 */
+ default:
+ return(4);
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeMbPred
+
+ Functional description:
+ Parse macroblock prediction information from bit stream and store
+ in 'pMbPred'.
+
+------------------------------------------------------------------------------*/
+
+u32 DecodeMbPred(strmData_t *pStrmData, mbPred_t *pMbPred, mbType_e mbType,
+ u32 numRefIdxActive)
+{
+
+/* Variables */
+
+ u32 tmp, i, j, value;
+ i32 itmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pMbPred);
+
+ switch (h264bsdMbPartPredMode(mbType))
+ {
+ case PRED_MODE_INTER: /* PRED_MODE_INTER */
+ if (numRefIdxActive > 1)
+ {
+ for (i = h264bsdNumMbPart(mbType), j = 0; i--; j++)
+ {
+ tmp = h264bsdDecodeExpGolombTruncated(pStrmData, &value,
+ (u32)(numRefIdxActive > 2));
+ if (tmp != HANTRO_OK || value >= numRefIdxActive)
+ return(HANTRO_NOK);
+
+ pMbPred->refIdxL0[j] = value;
+ }
+ }
+
+ for (i = h264bsdNumMbPart(mbType), j = 0; i--; j++)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pMbPred->mvdL0[j].hor = (i16)itmp;
+
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pMbPred->mvdL0[j].ver = (i16)itmp;
+ }
+ break;
+
+ case PRED_MODE_INTRA4x4:
+ for (itmp = 0, i = 0; itmp < 2; itmp++)
+ {
+ value = h264bsdShowBits32(pStrmData);
+ tmp = 0;
+ for (j = 8; j--; i++)
+ {
+ pMbPred->prevIntra4x4PredModeFlag[i] =
+ value & 0x80000000 ? HANTRO_TRUE : HANTRO_FALSE;
+ value <<= 1;
+ if (!pMbPred->prevIntra4x4PredModeFlag[i])
+ {
+ pMbPred->remIntra4x4PredMode[i] = value>>29;
+ value <<= 3;
+ tmp++;
+ }
+ }
+ if (h264bsdFlushBits(pStrmData, 8 + 3*tmp) == END_OF_STREAM)
+ return(HANTRO_NOK);
+ }
+ /* fall-through */
+
+ case PRED_MODE_INTRA16x16:
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK || value > 3)
+ return(HANTRO_NOK);
+ pMbPred->intraChromaPredMode = value;
+ break;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeSubMbPred
+
+ Functional description:
+ Parse sub-macroblock prediction information from bit stream and
+ store in 'pMbPred'.
+
+------------------------------------------------------------------------------*/
+
+u32 DecodeSubMbPred(strmData_t *pStrmData, subMbPred_t *pSubMbPred,
+ mbType_e mbType, u32 numRefIdxActive)
+{
+
+/* Variables */
+
+ u32 tmp, i, j, value;
+ i32 itmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSubMbPred);
+ ASSERT(h264bsdMbPartPredMode(mbType) == PRED_MODE_INTER);
+
+ for (i = 0; i < 4; i++)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK || value > 3)
+ return(HANTRO_NOK);
+ pSubMbPred->subMbType[i] = (subMbType_e)value;
+ }
+
+ if ( (numRefIdxActive > 1) && (mbType != P_8x8ref0) )
+ {
+ for (i = 0; i < 4; i++)
+ {
+ tmp = h264bsdDecodeExpGolombTruncated(pStrmData, &value,
+ (u32)(numRefIdxActive > 2));
+ if (tmp != HANTRO_OK || value >= numRefIdxActive)
+ return(HANTRO_NOK);
+ pSubMbPred->refIdxL0[i] = value;
+ }
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ j = 0;
+ for (value = h264bsdNumSubMbPart(pSubMbPred->subMbType[i]);
+ value--; j++)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSubMbPred->mvdL0[i][j].hor = (i16)itmp;
+
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSubMbPred->mvdL0[i][j].ver = (i16)itmp;
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+#ifdef H264DEC_OMXDL
+/*------------------------------------------------------------------------------
+
+ Function: DecodeResidual
+
+ Functional description:
+ Parse residual information from bit stream and store in 'pResidual'.
+
+------------------------------------------------------------------------------*/
+
+u32 DecodeResidual(strmData_t *pStrmData, residual_t *pResidual,
+ mbStorage_t *pMb, mbType_e mbType, u32 codedBlockPattern)
+{
+
+/* Variables */
+
+ u32 i, j;
+ u32 blockCoded;
+ u32 blockIndex;
+ u32 is16x16;
+ OMX_INT nc;
+ OMXResult omxRes;
+ OMX_U8 *pPosCoefBuf;
+
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pResidual);
+
+ pPosCoefBuf = pResidual->posCoefBuf;
+
+ /* luma DC is at index 24 */
+ if (h264bsdMbPartPredMode(mbType) == PRED_MODE_INTRA16x16)
+ {
+ nc = (OMX_INT)DetermineNc(pMb, 0, pResidual->totalCoeff);
+#ifndef H264DEC_NEON
+ omxRes = omxVCM4P10_DecodeCoeffsToPairCAVLC(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[24],
+ &pPosCoefBuf,
+ nc,
+ 16);
+#else
+ omxRes = armVCM4P10_DecodeCoeffsToPair(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[24],
+ &pPosCoefBuf,
+ nc,
+ 16);
+#endif
+ if (omxRes != OMX_Sts_NoErr)
+ return(HANTRO_NOK);
+ is16x16 = HANTRO_TRUE;
+ }
+ else
+ is16x16 = HANTRO_FALSE;
+
+ for (i = 4, blockIndex = 0; i--;)
+ {
+ /* luma cbp in bits 0-3 */
+ blockCoded = codedBlockPattern & 0x1;
+ codedBlockPattern >>= 1;
+ if (blockCoded)
+ {
+ for (j = 4; j--; blockIndex++)
+ {
+ nc = (OMX_INT)DetermineNc(pMb,blockIndex,pResidual->totalCoeff);
+ if (is16x16)
+ {
+#ifndef H264DEC_NEON
+ omxRes = omxVCM4P10_DecodeCoeffsToPairCAVLC(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[blockIndex],
+ &pPosCoefBuf,
+ nc,
+ 15);
+#else
+ omxRes = armVCM4P10_DecodeCoeffsToPair(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[blockIndex],
+ &pPosCoefBuf,
+ nc,
+ 15);
+#endif
+ }
+ else
+ {
+#ifndef H264DEC_NEON
+ omxRes = omxVCM4P10_DecodeCoeffsToPairCAVLC(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[blockIndex],
+ &pPosCoefBuf,
+ nc,
+ 16);
+#else
+ omxRes = armVCM4P10_DecodeCoeffsToPair(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[blockIndex],
+ &pPosCoefBuf,
+ nc,
+ 16);
+#endif
+ }
+ if (omxRes != OMX_Sts_NoErr)
+ return(HANTRO_NOK);
+ }
+ }
+ else
+ blockIndex += 4;
+ }
+
+ /* chroma DC block are at indices 25 and 26 */
+ blockCoded = codedBlockPattern & 0x3;
+ if (blockCoded)
+ {
+#ifndef H264DEC_NEON
+ omxRes = omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC(
+ (const OMX_U8**) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[25],
+ &pPosCoefBuf);
+#else
+ omxRes = armVCM4P10_DecodeCoeffsToPair(
+ (const OMX_U8**) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[25],
+ &pPosCoefBuf,
+ 17,
+ 4);
+#endif
+ if (omxRes != OMX_Sts_NoErr)
+ return(HANTRO_NOK);
+#ifndef H264DEC_NEON
+ omxRes = omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC(
+ (const OMX_U8**) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[26],
+ &pPosCoefBuf);
+#else
+ omxRes = armVCM4P10_DecodeCoeffsToPair(
+ (const OMX_U8**) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[26],
+ &pPosCoefBuf,
+ 17,
+ 4);
+#endif
+ if (omxRes != OMX_Sts_NoErr)
+ return(HANTRO_NOK);
+ }
+
+ /* chroma AC */
+ blockCoded = codedBlockPattern & 0x2;
+ if (blockCoded)
+ {
+ for (i = 8; i--;blockIndex++)
+ {
+ nc = (OMX_INT)DetermineNc(pMb, blockIndex, pResidual->totalCoeff);
+#ifndef H264DEC_NEON
+ omxRes = omxVCM4P10_DecodeCoeffsToPairCAVLC(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[blockIndex],
+ &pPosCoefBuf,
+ nc,
+ 15);
+#else
+ omxRes = armVCM4P10_DecodeCoeffsToPair(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[blockIndex],
+ &pPosCoefBuf,
+ nc,
+ 15);
+#endif
+ if (omxRes != OMX_Sts_NoErr)
+ return(HANTRO_NOK);
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+#else
+/*------------------------------------------------------------------------------
+
+ Function: DecodeResidual
+
+ Functional description:
+ Parse residual information from bit stream and store in 'pResidual'.
+
+------------------------------------------------------------------------------*/
+
+u32 DecodeResidual(strmData_t *pStrmData, residual_t *pResidual,
+ mbStorage_t *pMb, mbType_e mbType, u32 codedBlockPattern)
+{
+
+/* Variables */
+
+ u32 i, j, tmp;
+ i32 nc;
+ u32 blockCoded;
+ u32 blockIndex;
+ u32 is16x16;
+ i32 (*level)[16];
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pResidual);
+
+ level = pResidual->level;
+
+ /* luma DC is at index 24 */
+ if (h264bsdMbPartPredMode(mbType) == PRED_MODE_INTRA16x16)
+ {
+ nc = (i32)DetermineNc(pMb, 0, pResidual->totalCoeff);
+ tmp = h264bsdDecodeResidualBlockCavlc(pStrmData, level[24], nc, 16);
+ if ((tmp & 0xF) != HANTRO_OK)
+ return(tmp);
+ pResidual->totalCoeff[24] = (tmp >> 4) & 0xFF;
+ is16x16 = HANTRO_TRUE;
+ }
+ else
+ is16x16 = HANTRO_FALSE;
+
+ for (i = 4, blockIndex = 0; i--;)
+ {
+ /* luma cbp in bits 0-3 */
+ blockCoded = codedBlockPattern & 0x1;
+ codedBlockPattern >>= 1;
+ if (blockCoded)
+ {
+ for (j = 4; j--; blockIndex++)
+ {
+ nc = (i32)DetermineNc(pMb, blockIndex, pResidual->totalCoeff);
+ if (is16x16)
+ {
+ tmp = h264bsdDecodeResidualBlockCavlc(pStrmData,
+ level[blockIndex] + 1, nc, 15);
+ pResidual->coeffMap[blockIndex] = tmp >> 15;
+ }
+ else
+ {
+ tmp = h264bsdDecodeResidualBlockCavlc(pStrmData,
+ level[blockIndex], nc, 16);
+ pResidual->coeffMap[blockIndex] = tmp >> 16;
+ }
+ if ((tmp & 0xF) != HANTRO_OK)
+ return(tmp);
+ pResidual->totalCoeff[blockIndex] = (tmp >> 4) & 0xFF;
+ }
+ }
+ else
+ blockIndex += 4;
+ }
+
+ /* chroma DC block are at indices 25 and 26 */
+ blockCoded = codedBlockPattern & 0x3;
+ if (blockCoded)
+ {
+ tmp = h264bsdDecodeResidualBlockCavlc(pStrmData, level[25], -1, 4);
+ if ((tmp & 0xF) != HANTRO_OK)
+ return(tmp);
+ pResidual->totalCoeff[25] = (tmp >> 4) & 0xFF;
+ tmp = h264bsdDecodeResidualBlockCavlc(pStrmData, level[25]+4, -1, 4);
+ if ((tmp & 0xF) != HANTRO_OK)
+ return(tmp);
+ pResidual->totalCoeff[26] = (tmp >> 4) & 0xFF;
+ }
+
+ /* chroma AC */
+ blockCoded = codedBlockPattern & 0x2;
+ if (blockCoded)
+ {
+ for (i = 8; i--;blockIndex++)
+ {
+ nc = (i32)DetermineNc(pMb, blockIndex, pResidual->totalCoeff);
+ tmp = h264bsdDecodeResidualBlockCavlc(pStrmData,
+ level[blockIndex] + 1, nc, 15);
+ if ((tmp & 0xF) != HANTRO_OK)
+ return(tmp);
+ pResidual->totalCoeff[blockIndex] = (tmp >> 4) & 0xFF;
+ pResidual->coeffMap[blockIndex] = (tmp >> 15);
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+#endif
+
+/*------------------------------------------------------------------------------
+
+ Function: DetermineNc
+
+ Functional description:
+ Returns the nC of a block.
+
+------------------------------------------------------------------------------*/
+#ifdef H264DEC_OMXDL
+u32 DetermineNc(mbStorage_t *pMb, u32 blockIndex, u8 *pTotalCoeff)
+#else
+u32 DetermineNc(mbStorage_t *pMb, u32 blockIndex, i16 *pTotalCoeff)
+#endif
+{
+/*lint -e702 */
+/* Variables */
+
+ u32 tmp;
+ i32 n;
+ const neighbour_t *neighbourA, *neighbourB;
+ u8 neighbourAindex, neighbourBindex;
+
+/* Code */
+
+ ASSERT(blockIndex < 24);
+
+ /* if neighbour block belongs to current macroblock totalCoeff array
+ * mbStorage has not been set/updated yet -> use pTotalCoeff */
+ neighbourA = h264bsdNeighbour4x4BlockA(blockIndex);
+ neighbourB = h264bsdNeighbour4x4BlockB(blockIndex);
+ neighbourAindex = neighbourA->index;
+ neighbourBindex = neighbourB->index;
+ if (neighbourA->mb == MB_CURR && neighbourB->mb == MB_CURR)
+ {
+ n = (pTotalCoeff[neighbourAindex] +
+ pTotalCoeff[neighbourBindex] + 1)>>1;
+ }
+ else if (neighbourA->mb == MB_CURR)
+ {
+ n = pTotalCoeff[neighbourAindex];
+ if (h264bsdIsNeighbourAvailable(pMb, pMb->mbB))
+ {
+ n = (n + pMb->mbB->totalCoeff[neighbourBindex] + 1) >> 1;
+ }
+ }
+ else if (neighbourB->mb == MB_CURR)
+ {
+ n = pTotalCoeff[neighbourBindex];
+ if (h264bsdIsNeighbourAvailable(pMb, pMb->mbA))
+ {
+ n = (n + pMb->mbA->totalCoeff[neighbourAindex] + 1) >> 1;
+ }
+ }
+ else
+ {
+ n = tmp = 0;
+ if (h264bsdIsNeighbourAvailable(pMb, pMb->mbA))
+ {
+ n = pMb->mbA->totalCoeff[neighbourAindex];
+ tmp = 1;
+ }
+ if (h264bsdIsNeighbourAvailable(pMb, pMb->mbB))
+ {
+ if (tmp)
+ n = (n + pMb->mbB->totalCoeff[neighbourBindex] + 1) >> 1;
+ else
+ n = pMb->mbB->totalCoeff[neighbourBindex];
+ }
+ }
+ return((u32)n);
+/*lint +e702 */
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: CbpIntra16x16
+
+ Functional description:
+ Returns the coded block pattern for intra 16x16 macroblock.
+
+------------------------------------------------------------------------------*/
+
+u32 CbpIntra16x16(mbType_e mbType)
+{
+
+/* Variables */
+
+ u32 cbp;
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(mbType >= I_16x16_0_0_0 && mbType <= I_16x16_3_2_1);
+
+ if (mbType >= I_16x16_0_0_1)
+ cbp = 15;
+ else
+ cbp = 0;
+
+ /* tmp is 0 for I_16x16_0_0_0 mb type */
+ /* ignore lint warning on arithmetic on enum's */
+ tmp = /*lint -e(656)*/(mbType - I_16x16_0_0_0) >> 2;
+ if (tmp > 2)
+ tmp -= 3;
+
+ cbp += tmp << 4;
+
+ return(cbp);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdPredModeIntra16x16
+
+ Functional description:
+ Returns the prediction mode for intra 16x16 macroblock.
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdPredModeIntra16x16(mbType_e mbType)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(mbType >= I_16x16_0_0_0 && mbType <= I_16x16_3_2_1);
+
+ /* tmp is 0 for I_16x16_0_0_0 mb type */
+ /* ignore lint warning on arithmetic on enum's */
+ tmp = /*lint -e(656)*/(mbType - I_16x16_0_0_0);
+
+ return(tmp & 0x3);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdDecodeMacroblock
+
+ Functional description:
+ Decode one macroblock and write into output image.
+
+ Inputs:
+ pMb pointer to macroblock specific information
+ mbLayer pointer to current macroblock data from stream
+ currImage pointer to output image
+ dpb pointer to decoded picture buffer
+ qpY pointer to slice QP
+ mbNum current macroblock number
+ constrainedIntraPred flag specifying if neighbouring inter
+ macroblocks are used in intra prediction
+
+ Outputs:
+ pMb structure is updated with current macroblock
+ currImage decoded macroblock is written into output image
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK error in macroblock decoding
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeMacroblock(mbStorage_t *pMb, macroblockLayer_t *pMbLayer,
+ image_t *currImage, dpbStorage_t *dpb, i32 *qpY, u32 mbNum,
+ u32 constrainedIntraPredFlag, u8* data)
+{
+
+/* Variables */
+
+ u32 i, tmp;
+ mbType_e mbType;
+#ifdef H264DEC_OMXDL
+ const u8 *pSrc;
+#endif
+/* Code */
+
+ ASSERT(pMb);
+ ASSERT(pMbLayer);
+ ASSERT(currImage);
+ ASSERT(qpY && *qpY < 52);
+ ASSERT(mbNum < currImage->width*currImage->height);
+
+ mbType = pMbLayer->mbType;
+ pMb->mbType = mbType;
+
+ pMb->decoded++;
+
+ h264bsdSetCurrImageMbPointers(currImage, mbNum);
+
+ if (mbType == I_PCM)
+ {
+ u8 *pData = (u8*)data;
+#ifdef H264DEC_OMXDL
+ u8 *tot = pMb->totalCoeff;
+#else
+ i16 *tot = pMb->totalCoeff;
+#endif
+ i32 *lev = pMbLayer->residual.level[0];
+
+ pMb->qpY = 0;
+
+ /* if decoded flag > 1 -> mb has already been successfully decoded and
+ * written to output -> do not write again */
+ if (pMb->decoded > 1)
+ {
+ for (i = 24; i--;)
+ *tot++ = 16;
+ return HANTRO_OK;
+ }
+
+ for (i = 24; i--;)
+ {
+ *tot++ = 16;
+ for (tmp = 16; tmp--;)
+ *pData++ = (u8)(*lev++);
+ }
+ h264bsdWriteMacroblock(currImage, (u8*)data);
+
+ return(HANTRO_OK);
+ }
+ else
+ {
+#ifdef H264DEC_OMXDL
+ if (h264bsdMbPartPredMode(mbType) == PRED_MODE_INTER)
+ {
+ tmp = h264bsdInterPrediction(pMb, pMbLayer, dpb, mbNum,
+ currImage, (u8*)data);
+ if (tmp != HANTRO_OK) return (tmp);
+ }
+#endif
+ if (mbType != P_Skip)
+ {
+ memcpy(pMb->totalCoeff,
+ pMbLayer->residual.totalCoeff,
+ 27*sizeof(*pMb->totalCoeff));
+
+ /* update qpY */
+ if (pMbLayer->mbQpDelta)
+ {
+ *qpY = *qpY + pMbLayer->mbQpDelta;
+ if (*qpY < 0) *qpY += 52;
+ else if (*qpY >= 52) *qpY -= 52;
+ }
+ pMb->qpY = (u32)*qpY;
+
+#ifdef H264DEC_OMXDL
+ pSrc = pMbLayer->residual.posCoefBuf;
+
+ if (h264bsdMbPartPredMode(mbType) == PRED_MODE_INTER)
+ {
+ OMXResult res;
+ u8 *p;
+ u8 *totalCoeff = pMb->totalCoeff;
+
+ for (i = 0; i < 16; i++, totalCoeff++)
+ {
+ p = data + lumaIndex[i];
+ if (*totalCoeff)
+ {
+ res = omxVCM4P10_DequantTransformResidualFromPairAndAdd(
+ &pSrc, p, 0, p, 16, 16, *qpY, *totalCoeff);
+ if (res != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+ }
+
+ }
+ else if (h264bsdMbPartPredMode(mbType) == PRED_MODE_INTRA4x4)
+ {
+ tmp = ProcessIntra4x4Residual(pMb,
+ data,
+ constrainedIntraPredFlag,
+ pMbLayer,
+ &pSrc,
+ currImage);
+ if (tmp != HANTRO_OK)
+ return (tmp);
+ }
+ else if (h264bsdMbPartPredMode(mbType) == PRED_MODE_INTRA16x16)
+ {
+ tmp = ProcessIntra16x16Residual(pMb,
+ data,
+ constrainedIntraPredFlag,
+ pMbLayer->mbPred.intraChromaPredMode,
+ &pSrc,
+ currImage);
+ if (tmp != HANTRO_OK)
+ return (tmp);
+ }
+
+ tmp = ProcessChromaResidual(pMb, data, &pSrc);
+
+#else
+ tmp = ProcessResidual(pMb, pMbLayer->residual.level,
+ pMbLayer->residual.coeffMap);
+#endif
+ if (tmp != HANTRO_OK)
+ return (tmp);
+ }
+ else
+ {
+ memset(pMb->totalCoeff, 0, 27*sizeof(*pMb->totalCoeff));
+ pMb->qpY = (u32)*qpY;
+ }
+#ifdef H264DEC_OMXDL
+ /* if decoded flag > 1 -> mb has already been successfully decoded and
+ * written to output -> do not write again */
+ if (pMb->decoded > 1)
+ return HANTRO_OK;
+
+ h264bsdWriteMacroblock(currImage, data);
+#else
+ if (h264bsdMbPartPredMode(mbType) != PRED_MODE_INTER)
+ {
+ tmp = h264bsdIntraPrediction(pMb, pMbLayer, currImage, mbNum,
+ constrainedIntraPredFlag, (u8*)data);
+ if (tmp != HANTRO_OK) return (tmp);
+ }
+ else
+ {
+ tmp = h264bsdInterPrediction(pMb, pMbLayer, dpb, mbNum,
+ currImage, (u8*)data);
+ if (tmp != HANTRO_OK) return (tmp);
+ }
+#endif
+ }
+
+ return HANTRO_OK;
+}
+
+
+#ifdef H264DEC_OMXDL
+
+/*------------------------------------------------------------------------------
+
+ Function: ProcessChromaResidual
+
+ Functional description:
+ Process the residual data of chroma with
+ inverse quantization and inverse transform.
+
+------------------------------------------------------------------------------*/
+u32 ProcessChromaResidual(mbStorage_t *pMb, u8 *data, const u8 **pSrc )
+{
+ u32 i;
+ u32 chromaQp;
+ i16 *pDc;
+ i16 dc[4 + 4] = {0,0,0,0,0,0,0,0};
+ u8 *totalCoeff;
+ OMXResult result;
+ u8 *p;
+
+ /* chroma DC processing. First chroma dc block is block with index 25 */
+ chromaQp =
+ h264bsdQpC[CLIP3(0, 51, (i32)pMb->qpY + pMb->chromaQpIndexOffset)];
+
+ if (pMb->totalCoeff[25])
+ {
+ pDc = dc;
+ result = omxVCM4P10_TransformDequantChromaDCFromPair(
+ pSrc,
+ pDc,
+ (i32)chromaQp);
+ if (result != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+ if (pMb->totalCoeff[26])
+ {
+ pDc = dc+4;
+ result = omxVCM4P10_TransformDequantChromaDCFromPair(
+ pSrc,
+ pDc,
+ (i32)chromaQp);
+ if (result != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+
+ pDc = dc;
+ totalCoeff = pMb->totalCoeff + 16;
+ for (i = 0; i < 8; i++, pDc++, totalCoeff++)
+ {
+ /* chroma prediction */
+ if (*totalCoeff || *pDc)
+ {
+ p = data + chromaIndex[i];
+ result = omxVCM4P10_DequantTransformResidualFromPairAndAdd(
+ pSrc,
+ p,
+ pDc,
+ p,
+ 8,
+ 8,
+ (i32)chromaQp,
+ *totalCoeff);
+ if (result != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+ }
+
+ return(HANTRO_OK);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: ProcessIntra16x16Residual
+
+ Functional description:
+ Process the residual data of luma with
+ inverse quantization and inverse transform.
+
+------------------------------------------------------------------------------*/
+u32 ProcessIntra16x16Residual(mbStorage_t *pMb,
+ u8 *data,
+ u32 constrainedIntraPred,
+ u32 intraChromaPredMode,
+ const u8** pSrc,
+ image_t *image)
+{
+ u32 i;
+ i16 *pDc;
+ i16 dc[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ u8 *totalCoeff;
+ OMXResult result;
+ u8 *p;
+
+ totalCoeff = pMb->totalCoeff;
+
+ if (totalCoeff[24])
+ {
+ pDc = dc;
+ result = omxVCM4P10_TransformDequantLumaDCFromPair(
+ pSrc,
+ pDc,
+ (i32)pMb->qpY);
+ if (result != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+ /* Intra 16x16 pred */
+ if (h264bsdIntra16x16Prediction(pMb, data, image->luma,
+ image->width*16, constrainedIntraPred) != HANTRO_OK)
+ return(HANTRO_NOK);
+ for (i = 0; i < 16; i++, totalCoeff++)
+ {
+ p = data + lumaIndex[i];
+ pDc = &dc[dcCoeffIndex[i]];
+ if (*totalCoeff || *pDc)
+ {
+ result = omxVCM4P10_DequantTransformResidualFromPairAndAdd(
+ pSrc,
+ p,
+ pDc,
+ p,
+ 16,
+ 16,
+ (i32)pMb->qpY,
+ *totalCoeff);
+ if (result != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+ }
+
+ if (h264bsdIntraChromaPrediction(pMb, data + 256,
+ image,
+ intraChromaPredMode,
+ constrainedIntraPred) != HANTRO_OK)
+ return(HANTRO_NOK);
+
+ return HANTRO_OK;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: ProcessIntra4x4Residual
+
+ Functional description:
+ Process the residual data of luma with
+ inverse quantization and inverse transform.
+
+------------------------------------------------------------------------------*/
+u32 ProcessIntra4x4Residual(mbStorage_t *pMb,
+ u8 *data,
+ u32 constrainedIntraPred,
+ macroblockLayer_t *mbLayer,
+ const u8 **pSrc,
+ image_t *image)
+{
+ u32 i;
+ u8 *totalCoeff;
+ OMXResult result;
+ u8 *p;
+
+ totalCoeff = pMb->totalCoeff;
+
+ for (i = 0; i < 16; i++, totalCoeff++)
+ {
+ p = data + lumaIndex[i];
+ if (h264bsdIntra4x4Prediction(pMb, p, mbLayer, image->luma,
+ image->width*16, constrainedIntraPred, i) != HANTRO_OK)
+ return(HANTRO_NOK);
+
+ if (*totalCoeff)
+ {
+ result = omxVCM4P10_DequantTransformResidualFromPairAndAdd(
+ pSrc,
+ p,
+ NULL,
+ p,
+ 16,
+ 16,
+ (i32)pMb->qpY,
+ *totalCoeff);
+ if (result != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+ }
+
+ if (h264bsdIntraChromaPrediction(pMb, data + 256,
+ image,
+ mbLayer->mbPred.intraChromaPredMode,
+ constrainedIntraPred) != HANTRO_OK)
+ return(HANTRO_NOK);
+
+ return HANTRO_OK;
+}
+
+#else /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+
+ Function: ProcessResidual
+
+ Functional description:
+ Process the residual data of one macroblock with
+ inverse quantization and inverse transform.
+
+------------------------------------------------------------------------------*/
+
+u32 ProcessResidual(mbStorage_t *pMb, i32 residualLevel[][16], u32 *coeffMap)
+{
+
+/* Variables */
+
+ u32 i;
+ u32 chromaQp;
+ i32 (*blockData)[16];
+ i32 (*blockDc)[16];
+ i16 *totalCoeff;
+ i32 *chromaDc;
+ const u32 *dcCoeffIdx;
+
+/* Code */
+
+ ASSERT(pMb);
+ ASSERT(residualLevel);
+
+ /* set pointers to DC coefficient blocks */
+ blockDc = residualLevel + 24;
+
+ blockData = residualLevel;
+ totalCoeff = pMb->totalCoeff;
+ if (h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTRA16x16)
+ {
+ if (totalCoeff[24])
+ {
+ h264bsdProcessLumaDc(*blockDc, pMb->qpY);
+ }
+ dcCoeffIdx = dcCoeffIndex;
+
+ for (i = 16; i--; blockData++, totalCoeff++, coeffMap++)
+ {
+ /* set dc coefficient of luma block */
+ (*blockData)[0] = (*blockDc)[*dcCoeffIdx++];
+ if ((*blockData)[0] || *totalCoeff)
+ {
+ if (h264bsdProcessBlock(*blockData, pMb->qpY, 1, *coeffMap) !=
+ HANTRO_OK)
+ return(HANTRO_NOK);
+ }
+ else
+ MARK_RESIDUAL_EMPTY(*blockData);
+ }
+ }
+ else
+ {
+ for (i = 16; i--; blockData++, totalCoeff++, coeffMap++)
+ {
+ if (*totalCoeff)
+ {
+ if (h264bsdProcessBlock(*blockData, pMb->qpY, 0, *coeffMap) !=
+ HANTRO_OK)
+ return(HANTRO_NOK);
+ }
+ else
+ MARK_RESIDUAL_EMPTY(*blockData);
+ }
+ }
+
+ /* chroma DC processing. First chroma dc block is block with index 25 */
+ chromaQp =
+ h264bsdQpC[CLIP3(0, 51, (i32)pMb->qpY + pMb->chromaQpIndexOffset)];
+ if (pMb->totalCoeff[25] || pMb->totalCoeff[26])
+ h264bsdProcessChromaDc(residualLevel[25], chromaQp);
+ chromaDc = residualLevel[25];
+ for (i = 8; i--; blockData++, totalCoeff++, coeffMap++)
+ {
+ /* set dc coefficient of chroma block */
+ (*blockData)[0] = *chromaDc++;
+ if ((*blockData)[0] || *totalCoeff)
+ {
+ if (h264bsdProcessBlock(*blockData, chromaQp, 1,*coeffMap) !=
+ HANTRO_OK)
+ return(HANTRO_NOK);
+ }
+ else
+ MARK_RESIDUAL_EMPTY(*blockData);
+ }
+
+ return(HANTRO_OK);
+}
+#endif /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdSubMbPartMode
+
+ Functional description:
+ Returns the macroblock's sub-partition mode.
+
+------------------------------------------------------------------------------*/
+
+subMbPartMode_e h264bsdSubMbPartMode(subMbType_e subMbType)
+{
+
+/* Variables */
+
+
+/* Code */
+
+ ASSERT(subMbType < 4);
+
+ return((subMbPartMode_e)subMbType);
+
+}
+
+
--- /dev/null
+++ b/src/h264bsd_macroblock_layer.h
@@ -1,0 +1,213 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_MACROBLOCK_LAYER_H
+#define H264SWDEC_MACROBLOCK_LAYER_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+#include "h264bsd_image.h"
+#include "h264bsd_dpb.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/* Macro to determine if a mb is an intra mb */
+#define IS_INTRA_MB(a) ((a).mbType > 5)
+
+/* Macro to determine if a mb is an I_PCM mb */
+#define IS_I_PCM_MB(a) ((a).mbType == 31)
+
+typedef enum {
+ P_Skip = 0,
+ P_L0_16x16 = 1,
+ P_L0_L0_16x8 = 2,
+ P_L0_L0_8x16 = 3,
+ P_8x8 = 4,
+ P_8x8ref0 = 5,
+ I_4x4 = 6,
+ I_16x16_0_0_0 = 7,
+ I_16x16_1_0_0 = 8,
+ I_16x16_2_0_0 = 9,
+ I_16x16_3_0_0 = 10,
+ I_16x16_0_1_0 = 11,
+ I_16x16_1_1_0 = 12,
+ I_16x16_2_1_0 = 13,
+ I_16x16_3_1_0 = 14,
+ I_16x16_0_2_0 = 15,
+ I_16x16_1_2_0 = 16,
+ I_16x16_2_2_0 = 17,
+ I_16x16_3_2_0 = 18,
+ I_16x16_0_0_1 = 19,
+ I_16x16_1_0_1 = 20,
+ I_16x16_2_0_1 = 21,
+ I_16x16_3_0_1 = 22,
+ I_16x16_0_1_1 = 23,
+ I_16x16_1_1_1 = 24,
+ I_16x16_2_1_1 = 25,
+ I_16x16_3_1_1 = 26,
+ I_16x16_0_2_1 = 27,
+ I_16x16_1_2_1 = 28,
+ I_16x16_2_2_1 = 29,
+ I_16x16_3_2_1 = 30,
+ I_PCM = 31
+} mbType_e;
+
+typedef enum {
+ P_L0_8x8 = 0,
+ P_L0_8x4 = 1,
+ P_L0_4x8 = 2,
+ P_L0_4x4 = 3
+} subMbType_e;
+
+typedef enum {
+ MB_P_16x16 = 0,
+ MB_P_16x8,
+ MB_P_8x16,
+ MB_P_8x8
+} mbPartMode_e;
+
+typedef enum {
+ MB_SP_8x8 = 0,
+ MB_SP_8x4,
+ MB_SP_4x8,
+ MB_SP_4x4
+} subMbPartMode_e;
+
+typedef enum {
+ PRED_MODE_INTRA4x4 = 0,
+ PRED_MODE_INTRA16x16 ,
+ PRED_MODE_INTER
+} mbPartPredMode_e;
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+typedef struct
+{
+ /* MvPrediction16x16 assumes that MVs are 16bits */
+ i16 hor;
+ i16 ver;
+} mv_t;
+
+typedef struct
+{
+ u32 prevIntra4x4PredModeFlag[16];
+ u32 remIntra4x4PredMode[16];
+ u32 intraChromaPredMode;
+ u32 refIdxL0[4];
+ mv_t mvdL0[4];
+} mbPred_t;
+
+typedef struct
+{
+ subMbType_e subMbType[4];
+ u32 refIdxL0[4];
+ mv_t mvdL0[4][4];
+} subMbPred_t;
+
+typedef struct
+{
+#ifdef H264DEC_OMXDL
+ u8 posCoefBuf[27*16*3];
+ u8 totalCoeff[27];
+#else
+ i16 totalCoeff[27];
+#endif
+ i32 level[26][16];
+ u32 coeffMap[24];
+} residual_t;
+
+typedef struct
+{
+ mbType_e mbType;
+ u32 codedBlockPattern;
+ i32 mbQpDelta;
+ mbPred_t mbPred;
+ subMbPred_t subMbPred;
+ residual_t residual;
+} macroblockLayer_t;
+
+typedef struct mbStorage
+{
+ mbType_e mbType;
+ u32 sliceId;
+ u32 disableDeblockingFilterIdc;
+ i32 filterOffsetA;
+ i32 filterOffsetB;
+ u32 qpY;
+ i32 chromaQpIndexOffset;
+#ifdef H264DEC_OMXDL
+ u8 totalCoeff[27];
+#else
+ i16 totalCoeff[27];
+#endif
+ u8 intra4x4PredMode[16];
+ u32 refPic[4];
+ u8* refAddr[4];
+ mv_t mv[16];
+ u32 decoded;
+ struct mbStorage *mbA;
+ struct mbStorage *mbB;
+ struct mbStorage *mbC;
+ struct mbStorage *mbD;
+} mbStorage_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeMacroblockLayer(strmData_t *pStrmData,
+ macroblockLayer_t *pMbLayer, mbStorage_t *pMb, u32 sliceType,
+ u32 numRefIdxActive);
+
+u32 h264bsdNumMbPart(mbType_e mbType);
+u32 h264bsdNumSubMbPart(subMbType_e subMbType);
+
+subMbPartMode_e h264bsdSubMbPartMode(subMbType_e subMbType);
+
+u32 h264bsdDecodeMacroblock(mbStorage_t *pMb, macroblockLayer_t *pMbLayer,
+ image_t *currImage, dpbStorage_t *dpb, i32 *qpY, u32 mbNum,
+ u32 constrainedIntraPredFlag, u8* data);
+
+u32 h264bsdPredModeIntra16x16(mbType_e mbType);
+
+mbPartPredMode_e h264bsdMbPartPredMode(mbType_e mbType);
+#ifdef H264DEC_NEON
+u32 h264bsdClearMbLayer(macroblockLayer_t *pMbLayer, u32 size);
+#endif
+
+#endif /* #ifdef H264SWDEC_MACROBLOCK_LAYER_H */
+
+
--- /dev/null
+++ b/src/h264bsd_nal_unit.c
@@ -1,0 +1,118 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodeNalUnit
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_nal_unit.h"
+#include "h264bsd_util.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdDecodeNalUnit
+
+ Functional description:
+ Decode NAL unit header information
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ pNalUnit NAL unit header information is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid NAL unit header information
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeNalUnit(strmData_t *pStrmData, nalUnit_t *pNalUnit)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pNalUnit);
+ ASSERT(pStrmData->bitPosInWord == 0);
+
+ /* forbidden_zero_bit (not checked to be zero, errors ignored) */
+ tmp = h264bsdGetBits(pStrmData, 1);
+ /* Assuming that NAL unit starts from byte boundary �> don't have to check
+ * following 7 bits for END_OF_STREAM */
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdGetBits(pStrmData, 2);
+ pNalUnit->nalRefIdc = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 5);
+ pNalUnit->nalUnitType = (nalUnitType_e)tmp;
+
+ /* data partitioning NAL units not supported */
+ if ( (tmp == 2) || (tmp == 3) || (tmp == 4) )
+ {
+ return(HANTRO_NOK);
+ }
+
+ /* nal_ref_idc shall not be zero for these nal_unit_types */
+ if ( ( (tmp == NAL_SEQ_PARAM_SET) || (tmp == NAL_PIC_PARAM_SET) ||
+ (tmp == NAL_CODED_SLICE_IDR) ) && (pNalUnit->nalRefIdc == 0) )
+ {
+ return(HANTRO_NOK);
+ }
+ /* nal_ref_idc shall be zero for these nal_unit_types */
+ else if ( ( (tmp == NAL_SEI) || (tmp == NAL_ACCESS_UNIT_DELIMITER) ||
+ (tmp == NAL_END_OF_SEQUENCE) || (tmp == NAL_END_OF_STREAM) ||
+ (tmp == NAL_FILLER_DATA) ) && (pNalUnit->nalRefIdc != 0) )
+ {
+ return(HANTRO_NOK);
+ }
+
+ return(HANTRO_OK);
+
+}
+
--- /dev/null
+++ b/src/h264bsd_nal_unit.h
@@ -1,0 +1,77 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_NAL_UNIT_H
+#define H264SWDEC_NAL_UNIT_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/* macro to determine if NAL unit pointed by pNalUnit contains an IDR slice */
+#define IS_IDR_NAL_UNIT(pNalUnit) \
+ ((pNalUnit)->nalUnitType == NAL_CODED_SLICE_IDR)
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+typedef enum {
+ NAL_CODED_SLICE = 1,
+ NAL_CODED_SLICE_IDR = 5,
+ NAL_SEI = 6,
+ NAL_SEQ_PARAM_SET = 7,
+ NAL_PIC_PARAM_SET = 8,
+ NAL_ACCESS_UNIT_DELIMITER = 9,
+ NAL_END_OF_SEQUENCE = 10,
+ NAL_END_OF_STREAM = 11,
+ NAL_FILLER_DATA = 12,
+ NAL_MAX_TYPE_VALUE = 31
+} nalUnitType_e;
+
+typedef struct
+{
+ nalUnitType_e nalUnitType;
+ u32 nalRefIdc;
+} nalUnit_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeNalUnit(strmData_t *pStrmData, nalUnit_t *pNalUnit);
+
+#endif /* #ifdef H264SWDEC_NAL_UNIT_H */
+
--- /dev/null
+++ b/src/h264bsd_neighbour.c
@@ -1,0 +1,383 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdInitMbNeighbours
+ h264bsdGetNeighbourMb
+ h264bsdNeighbour4x4BlockA
+ h264bsdNeighbour4x4BlockB
+ h264bsdNeighbour4x4BlockC
+ h264bsdNeighbour4x4BlockD
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_neighbour.h"
+#include "h264bsd_util.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* Following four tables indicate neighbours of each block of a macroblock.
+ * First 16 values are for luma blocks, next 4 values for Cb and last 4
+ * values for Cr. Elements of the table indicate to which macroblock the
+ * neighbour block belongs and the index of the neighbour block in question.
+ * Indexing of the blocks goes as follows
+ *
+ * Y Cb Cr
+ * 0 1 4 5 16 17 20 21
+ * 2 3 6 7 18 19 22 23
+ * 8 9 12 13
+ * 10 11 14 15
+ */
+
+/* left neighbour for each block */
+static const neighbour_t N_A_4x4B[24] = {
+ {MB_A,5}, {MB_CURR,0}, {MB_A,7}, {MB_CURR,2},
+ {MB_CURR,1}, {MB_CURR,4}, {MB_CURR,3}, {MB_CURR,6},
+ {MB_A,13}, {MB_CURR,8}, {MB_A,15}, {MB_CURR,10},
+ {MB_CURR,9}, {MB_CURR,12},{MB_CURR,11},{MB_CURR,14},
+ {MB_A,17}, {MB_CURR,16},{MB_A,19}, {MB_CURR,18},
+ {MB_A,21}, {MB_CURR,20},{MB_A,23}, {MB_CURR,22} };
+
+/* above neighbour for each block */
+static const neighbour_t N_B_4x4B[24] = {
+ {MB_B,10}, {MB_B,11}, {MB_CURR,0}, {MB_CURR,1},
+ {MB_B,14}, {MB_B,15}, {MB_CURR,4}, {MB_CURR,5},
+ {MB_CURR,2}, {MB_CURR,3}, {MB_CURR,8}, {MB_CURR,9},
+ {MB_CURR,6}, {MB_CURR,7}, {MB_CURR,12},{MB_CURR,13},
+ {MB_B,18}, {MB_B,19}, {MB_CURR,16},{MB_CURR,17},
+ {MB_B,22}, {MB_B,23}, {MB_CURR,20},{MB_CURR,21} };
+
+/* above-right neighbour for each block */
+static const neighbour_t N_C_4x4B[24] = {
+ {MB_B,11}, {MB_B,14}, {MB_CURR,1}, {MB_NA,4},
+ {MB_B,15}, {MB_C,10}, {MB_CURR,5}, {MB_NA,0},
+ {MB_CURR,3}, {MB_CURR,6}, {MB_CURR,9}, {MB_NA,12},
+ {MB_CURR,7}, {MB_NA,2}, {MB_CURR,13},{MB_NA,8},
+ {MB_B,19}, {MB_C,18}, {MB_CURR,17},{MB_NA,16},
+ {MB_B,23}, {MB_C,22}, {MB_CURR,21},{MB_NA,20} };
+
+/* above-left neighbour for each block */
+static const neighbour_t N_D_4x4B[24] = {
+ {MB_D,15}, {MB_B,10}, {MB_A,5}, {MB_CURR,0},
+ {MB_B,11}, {MB_B,14}, {MB_CURR,1}, {MB_CURR,4},
+ {MB_A,7}, {MB_CURR,2}, {MB_A,13}, {MB_CURR,8},
+ {MB_CURR,3}, {MB_CURR,6}, {MB_CURR,9}, {MB_CURR,12},
+ {MB_D,19}, {MB_B,18}, {MB_A,17}, {MB_CURR,16},
+ {MB_D,23}, {MB_B,22}, {MB_A,21}, {MB_CURR,20} };
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInitMbNeighbours
+
+ Functional description:
+ Initialize macroblock neighbours. Function sets neighbour
+ macroblock pointers in macroblock structures to point to
+ macroblocks on the left, above, above-right and above-left.
+ Pointers are set NULL if the neighbour does not fit into the
+ picture.
+
+ Inputs:
+ picWidth width of the picture in macroblocks
+ picSizeInMbs no need to clarify
+
+ Outputs:
+ pMbStorage neighbour pointers of each mbStorage structure
+ stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInitMbNeighbours(mbStorage_t *pMbStorage, u32 picWidth,
+ u32 picSizeInMbs)
+{
+
+/* Variables */
+
+ u32 i, row, col;
+
+/* Code */
+
+ ASSERT(pMbStorage);
+ ASSERT(picWidth);
+ ASSERT(picWidth <= picSizeInMbs);
+ ASSERT(((picSizeInMbs / picWidth) * picWidth) == picSizeInMbs);
+
+ row = col = 0;
+
+ for (i = 0; i < picSizeInMbs; i++)
+ {
+
+ if (col)
+ pMbStorage[i].mbA = pMbStorage + i - 1;
+ else
+ pMbStorage[i].mbA = NULL;
+
+ if (row)
+ pMbStorage[i].mbB = pMbStorage + i - picWidth;
+ else
+ pMbStorage[i].mbB = NULL;
+
+ if (row && (col < picWidth - 1))
+ pMbStorage[i].mbC = pMbStorage + i - (picWidth - 1);
+ else
+ pMbStorage[i].mbC = NULL;
+
+ if (row && col)
+ pMbStorage[i].mbD = pMbStorage + i - (picWidth + 1);
+ else
+ pMbStorage[i].mbD = NULL;
+
+ col++;
+ if (col == picWidth)
+ {
+ col = 0;
+ row++;
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdGetNeighbourMb
+
+ Functional description:
+ Get pointer to neighbour macroblock.
+
+ Inputs:
+ pMb pointer to macroblock structure of the macroblock
+ whose neighbour is wanted
+ neighbour indicates which neighbour is wanted
+
+ Outputs:
+ none
+
+ Returns:
+ pointer to neighbour macroblock
+ NULL if not available
+
+------------------------------------------------------------------------------*/
+
+mbStorage_t* h264bsdGetNeighbourMb(mbStorage_t *pMb, neighbourMb_e neighbour)
+{
+
+/* Variables */
+
+
+/* Code */
+
+ ASSERT((neighbour <= MB_CURR) || (neighbour == MB_NA));
+
+ if (neighbour == MB_A)
+ return(pMb->mbA);
+ else if (neighbour == MB_B)
+ return(pMb->mbB);
+ else if (neighbour == MB_C)
+ return(pMb->mbC);
+ else if (neighbour == MB_D)
+ return(pMb->mbD);
+ else if (neighbour == MB_CURR)
+ return(pMb);
+ else
+ return(NULL);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdNeighbour4x4BlockA
+
+ Functional description:
+ Get left neighbour of the block. Function returns pointer to
+ the table defined in the beginning of the file.
+
+ Inputs:
+ blockIndex indicates the block whose neighbours are wanted
+
+ Outputs:
+
+ Returns:
+ pointer to neighbour structure
+
+------------------------------------------------------------------------------*/
+
+const neighbour_t* h264bsdNeighbour4x4BlockA(u32 blockIndex)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(blockIndex < 24);
+
+ return(N_A_4x4B+blockIndex);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdNeighbour4x4BlockB
+
+ Functional description:
+ Get above neighbour of the block. Function returns pointer to
+ the table defined in the beginning of the file.
+
+ Inputs:
+ blockIndex indicates the block whose neighbours are wanted
+
+ Outputs:
+
+ Returns:
+ pointer to neighbour structure
+
+------------------------------------------------------------------------------*/
+
+const neighbour_t* h264bsdNeighbour4x4BlockB(u32 blockIndex)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(blockIndex < 24);
+
+ return(N_B_4x4B+blockIndex);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdNeighbour4x4BlockC
+
+ Functional description:
+ Get above-right neighbour of the block. Function returns pointer
+ to the table defined in the beginning of the file.
+
+ Inputs:
+ blockIndex indicates the block whose neighbours are wanted
+
+ Outputs:
+
+ Returns:
+ pointer to neighbour structure
+
+------------------------------------------------------------------------------*/
+
+const neighbour_t* h264bsdNeighbour4x4BlockC(u32 blockIndex)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(blockIndex < 24);
+
+ return(N_C_4x4B+blockIndex);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdNeighbour4x4BlockD
+
+ Functional description:
+ Get above-left neighbour of the block. Function returns pointer to
+ the table defined in the beginning of the file.
+
+ Inputs:
+ blockIndex indicates the block whose neighbours are wanted
+
+ Outputs:
+
+ Returns:
+ pointer to neighbour structure
+
+------------------------------------------------------------------------------*/
+
+const neighbour_t* h264bsdNeighbour4x4BlockD(u32 blockIndex)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(blockIndex < 24);
+
+ return(N_D_4x4B+blockIndex);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdIsNeighbourAvailable
+
+ Functional description:
+ Check if neighbour macroblock is available. Neighbour macroblock
+ is considered available if it is within the picture and belongs
+ to the same slice as the current macroblock.
+
+ Inputs:
+ pMb pointer to the current macroblock
+ pNeighbour pointer to the neighbour macroblock
+
+ Outputs:
+ none
+
+ Returns:
+ TRUE neighbour is available
+ FALSE neighbour is not available
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdIsNeighbourAvailable(mbStorage_t *pMb, mbStorage_t *pNeighbour)
+{
+
+/* Variables */
+
+/* Code */
+
+ if ( (pNeighbour == NULL) || (pMb->sliceId != pNeighbour->sliceId) )
+ return(HANTRO_FALSE);
+ else
+ return(HANTRO_TRUE);
+
+}
+
--- /dev/null
+++ b/src/h264bsd_neighbour.h
@@ -1,0 +1,79 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_NEIGHBOUR_H
+#define H264SWDEC_NEIGHBOUR_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_macroblock_layer.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+typedef enum {
+ MB_A = 0,
+ MB_B,
+ MB_C,
+ MB_D,
+ MB_CURR,
+ MB_NA = 0xFF
+} neighbourMb_e;
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+typedef struct
+{
+ neighbourMb_e mb;
+ u8 index;
+} neighbour_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+void h264bsdInitMbNeighbours(mbStorage_t *pMbStorage, u32 picWidth,
+ u32 picSizeInMbs);
+
+mbStorage_t* h264bsdGetNeighbourMb(mbStorage_t *pMb, neighbourMb_e neighbour);
+
+u32 h264bsdIsNeighbourAvailable(mbStorage_t *pMb, mbStorage_t *pNeighbour);
+
+const neighbour_t* h264bsdNeighbour4x4BlockA(u32 blockIndex);
+const neighbour_t* h264bsdNeighbour4x4BlockB(u32 blockIndex);
+const neighbour_t* h264bsdNeighbour4x4BlockC(u32 blockIndex);
+const neighbour_t* h264bsdNeighbour4x4BlockD(u32 blockIndex);
+
+#endif /* #ifdef H264SWDEC_NEIGHBOUR_H */
+
--- /dev/null
+++ b/src/h264bsd_pic_order_cnt.c
@@ -1,0 +1,348 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodePicOrderCnt
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_util.h"
+#include "h264bsd_pic_order_cnt.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdDecodePicOrderCnt
+
+ Functional description:
+ Compute picture order count for a picture. Function implements
+ computation of all POC types (0, 1 and 2), type is obtained from
+ sps. See standard for description of the POC types and how POC is
+ computed for each type.
+
+ Function returns the minimum of top field and bottom field pic
+ order counts.
+
+ Inputs:
+ poc pointer to previous results
+ sps pointer to sequence parameter set
+ slicHeader pointer to current slice header, frame number and
+ other params needed for POC computation
+ pNalUnit pointer to current NAL unit structrue, function needs
+ to know if this is an IDR picture and also if this is
+ a reference picture
+
+ Outputs:
+ poc results stored here for computation of next POC
+
+ Returns:
+ picture order count
+
+------------------------------------------------------------------------------*/
+
+i32 h264bsdDecodePicOrderCnt(pocStorage_t *poc, seqParamSet_t *sps,
+ sliceHeader_t *pSliceHeader, nalUnit_t *pNalUnit)
+{
+
+/* Variables */
+
+ u32 i;
+ i32 picOrderCnt;
+ u32 frameNumOffset, absFrameNum, picOrderCntCycleCnt;
+ u32 frameNumInPicOrderCntCycle;
+ i32 expectedDeltaPicOrderCntCycle;
+ u32 containsMmco5;
+
+/* Code */
+
+ ASSERT(poc);
+ ASSERT(sps);
+ ASSERT(pSliceHeader);
+ ASSERT(pNalUnit);
+ ASSERT(sps->picOrderCntType <= 2);
+
+#if 0
+ /* JanSa: I don't think this is necessary, don't see any reason to
+ * increment prevFrameNum one by one instead of one big increment.
+ * However, standard specifies that this should be done -> if someone
+ * figures out any case when the outcome would be different for step by
+ * step increment, this part of the code should be enabled */
+
+ /* if there was a gap in frame numbering and picOrderCntType is 1 or 2 ->
+ * "compute" pic order counts for non-existing frames. These are not
+ * actually computed, but process needs to be done to update the
+ * prevFrameNum and prevFrameNumOffset */
+ if ( sps->picOrderCntType > 0 &&
+ pSliceHeader->frameNum != poc->prevFrameNum &&
+ pSliceHeader->frameNum != ((poc->prevFrameNum + 1) % sps->maxFrameNum))
+ {
+
+ /* use variable i for unUsedShortTermFrameNum */
+ i = (poc->prevFrameNum + 1) % sps->maxFrameNum;
+
+ do
+ {
+ if (poc->prevFrameNum > i)
+ frameNumOffset = poc->prevFrameNumOffset + sps->maxFrameNum;
+ else
+ frameNumOffset = poc->prevFrameNumOffset;
+
+ poc->prevFrameNumOffset = frameNumOffset;
+ poc->prevFrameNum = i;
+
+ i = (i + 1) % sps->maxFrameNum;
+
+ } while (i != pSliceHeader->frameNum);
+ }
+#endif
+
+ /* check if current slice includes mmco equal to 5 */
+ containsMmco5 = HANTRO_FALSE;
+ if (pSliceHeader->decRefPicMarking.adaptiveRefPicMarkingModeFlag)
+ {
+ i = 0;
+ while (pSliceHeader->decRefPicMarking.operation[i].
+ memoryManagementControlOperation)
+ {
+ if (pSliceHeader->decRefPicMarking.operation[i].
+ memoryManagementControlOperation == 5)
+ {
+ containsMmco5 = HANTRO_TRUE;
+ break;
+ }
+ i++;
+ }
+ }
+ switch (sps->picOrderCntType)
+ {
+
+ case 0:
+ /* set prevPicOrderCnt values for IDR frame */
+ if (IS_IDR_NAL_UNIT(pNalUnit))
+ {
+ poc->prevPicOrderCntMsb = 0;
+ poc->prevPicOrderCntLsb = 0;
+ }
+
+ /* compute picOrderCntMsb (stored in picOrderCnt variable) */
+ if ( (pSliceHeader->picOrderCntLsb < poc->prevPicOrderCntLsb) &&
+ ((poc->prevPicOrderCntLsb - pSliceHeader->picOrderCntLsb) >=
+ sps->maxPicOrderCntLsb/2) )
+ {
+ picOrderCnt = poc->prevPicOrderCntMsb +
+ (i32)sps->maxPicOrderCntLsb;
+ }
+ else if ((pSliceHeader->picOrderCntLsb > poc->prevPicOrderCntLsb) &&
+ ((pSliceHeader->picOrderCntLsb - poc->prevPicOrderCntLsb) >
+ sps->maxPicOrderCntLsb/2) )
+ {
+ picOrderCnt = poc->prevPicOrderCntMsb -
+ (i32)sps->maxPicOrderCntLsb;
+ }
+ else
+ picOrderCnt = poc->prevPicOrderCntMsb;
+
+ /* standard specifies that prevPicOrderCntMsb is from previous
+ * rererence frame -> replace old value only if current frame is
+ * rererence frame */
+ if (pNalUnit->nalRefIdc)
+ poc->prevPicOrderCntMsb = picOrderCnt;
+
+ /* compute top field order cnt (stored in picOrderCnt) */
+ picOrderCnt += (i32)pSliceHeader->picOrderCntLsb;
+
+ /* if delta for bottom field is negative -> bottom will be the
+ * minimum pic order count */
+ if (pSliceHeader->deltaPicOrderCntBottom < 0)
+ picOrderCnt += pSliceHeader->deltaPicOrderCntBottom;
+
+ /* standard specifies that prevPicOrderCntLsb is from previous
+ * rererence frame -> replace old value only if current frame is
+ * rererence frame */
+ if (pNalUnit->nalRefIdc)
+ {
+ /* if current frame contains mmco5 -> modify values to be
+ * stored */
+ if (containsMmco5)
+ {
+ poc->prevPicOrderCntMsb = 0;
+ /* prevPicOrderCntLsb should be the top field picOrderCnt
+ * if previous frame included mmco5. Top field picOrderCnt
+ * for frames containing mmco5 is obtained by subtracting
+ * the picOrderCnt from original top field order count ->
+ * value is zero if top field was the minimum, i.e. delta
+ * for bottom was positive, otherwise value is
+ * -deltaPicOrderCntBottom */
+ if (pSliceHeader->deltaPicOrderCntBottom < 0)
+ poc->prevPicOrderCntLsb =
+ (u32)(-pSliceHeader->deltaPicOrderCntBottom);
+ else
+ poc->prevPicOrderCntLsb = 0;
+ picOrderCnt = 0;
+ }
+ else
+ {
+ poc->prevPicOrderCntLsb = pSliceHeader->picOrderCntLsb;
+ }
+ }
+
+ break;
+
+ case 1:
+
+ /* step 1 (in the description in the standard) */
+ if (IS_IDR_NAL_UNIT(pNalUnit))
+ frameNumOffset = 0;
+ else if (poc->prevFrameNum > pSliceHeader->frameNum)
+ frameNumOffset = poc->prevFrameNumOffset + sps->maxFrameNum;
+ else
+ frameNumOffset = poc->prevFrameNumOffset;
+
+ /* step 2 */
+ if (sps->numRefFramesInPicOrderCntCycle)
+ absFrameNum = frameNumOffset + pSliceHeader->frameNum;
+ else
+ absFrameNum = 0;
+
+ if (pNalUnit->nalRefIdc == 0 && absFrameNum > 0)
+ absFrameNum -= 1;
+
+ /* step 3 */
+ if (absFrameNum > 0)
+ {
+ picOrderCntCycleCnt =
+ (absFrameNum - 1)/sps->numRefFramesInPicOrderCntCycle;
+ frameNumInPicOrderCntCycle =
+ (absFrameNum - 1)%sps->numRefFramesInPicOrderCntCycle;
+ }
+
+ /* step 4 */
+ expectedDeltaPicOrderCntCycle = 0;
+ for (i = 0; i < sps->numRefFramesInPicOrderCntCycle; i++)
+ expectedDeltaPicOrderCntCycle += sps->offsetForRefFrame[i];
+
+ /* step 5 (picOrderCnt used to store expectedPicOrderCnt) */
+ /*lint -esym(644,picOrderCntCycleCnt) always initialized */
+ /*lint -esym(644,frameNumInPicOrderCntCycle) always initialized */
+ if (absFrameNum > 0)
+ {
+ picOrderCnt =
+ (i32)picOrderCntCycleCnt * expectedDeltaPicOrderCntCycle;
+ for (i = 0; i <= frameNumInPicOrderCntCycle; i++)
+ picOrderCnt += sps->offsetForRefFrame[i];
+ }
+ else
+ picOrderCnt = 0;
+
+ if (pNalUnit->nalRefIdc == 0)
+ picOrderCnt += sps->offsetForNonRefPic;
+
+ /* step 6 (picOrderCnt is top field order cnt if delta for bottom
+ * is positive, otherwise it is bottom field order cnt) */
+ picOrderCnt += pSliceHeader->deltaPicOrderCnt[0];
+
+ if ( (sps->offsetForTopToBottomField +
+ pSliceHeader->deltaPicOrderCnt[1]) < 0 )
+ {
+ picOrderCnt += sps->offsetForTopToBottomField +
+ pSliceHeader->deltaPicOrderCnt[1];
+ }
+
+ /* if current picture contains mmco5 -> set prevFrameNumOffset and
+ * prevFrameNum to 0 for computation of picOrderCnt of next
+ * frame, otherwise store frameNum and frameNumOffset to poc
+ * structure */
+ if (!containsMmco5)
+ {
+ poc->prevFrameNumOffset = frameNumOffset;
+ poc->prevFrameNum = pSliceHeader->frameNum;
+ }
+ else
+ {
+ poc->prevFrameNumOffset = 0;
+ poc->prevFrameNum = 0;
+ picOrderCnt = 0;
+ }
+ break;
+
+ default: /* case 2 */
+ /* derive frameNumOffset */
+ if (IS_IDR_NAL_UNIT(pNalUnit))
+ frameNumOffset = 0;
+ else if (poc->prevFrameNum > pSliceHeader->frameNum)
+ frameNumOffset = poc->prevFrameNumOffset + sps->maxFrameNum;
+ else
+ frameNumOffset = poc->prevFrameNumOffset;
+
+ /* derive picOrderCnt (type 2 has same value for top and bottom
+ * field order cnts) */
+ if (IS_IDR_NAL_UNIT(pNalUnit))
+ picOrderCnt = 0;
+ else if (pNalUnit->nalRefIdc == 0)
+ picOrderCnt =
+ 2 * (i32)(frameNumOffset + pSliceHeader->frameNum) - 1;
+ else
+ picOrderCnt =
+ 2 * (i32)(frameNumOffset + pSliceHeader->frameNum);
+
+ /* if current picture contains mmco5 -> set prevFrameNumOffset and
+ * prevFrameNum to 0 for computation of picOrderCnt of next
+ * frame, otherwise store frameNum and frameNumOffset to poc
+ * structure */
+ if (!containsMmco5)
+ {
+ poc->prevFrameNumOffset = frameNumOffset;
+ poc->prevFrameNum = pSliceHeader->frameNum;
+ }
+ else
+ {
+ poc->prevFrameNumOffset = 0;
+ poc->prevFrameNum = 0;
+ picOrderCnt = 0;
+ }
+ break;
+
+ }
+
+ /*lint -esym(644,picOrderCnt) always initialized */
+ return(picOrderCnt);
+
+}
+
--- /dev/null
+++ b/src/h264bsd_pic_order_cnt.h
@@ -1,0 +1,69 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_PIC_ORDER_CNT_H
+#define H264SWDEC_PIC_ORDER_CNT_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_seq_param_set.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_nal_unit.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/* structure to store information computed for previous picture, needed for
+ * POC computation of a picture. Two first fields for POC type 0, last two
+ * for types 1 and 2 */
+typedef struct
+{
+ u32 prevPicOrderCntLsb;
+ i32 prevPicOrderCntMsb;
+ u32 prevFrameNum;
+ u32 prevFrameNumOffset;
+} pocStorage_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+i32 h264bsdDecodePicOrderCnt(pocStorage_t *poc, seqParamSet_t *sps,
+ sliceHeader_t *sliceHeader, nalUnit_t *pNalUnit);
+
+#endif /* #ifdef H264SWDEC_PIC_ORDER_CNT_H */
+
--- /dev/null
+++ b/src/h264bsd_pic_param_set.c
@@ -1,0 +1,336 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodePicParamSet
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_pic_param_set.h"
+#include "h264bsd_util.h"
+#include "h264bsd_vlc.h"
+#include "h264bsd_cfg.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* lookup table for ceil(log2(numSliceGroups)), i.e. number of bits needed to
+ * represent range [0, numSliceGroups)
+ *
+ * NOTE: if MAX_NUM_SLICE_GROUPS is higher than 8 this table has to be resized
+ * accordingly */
+static const u32 CeilLog2NumSliceGroups[8] = {1, 1, 2, 2, 3, 3, 3, 3};
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdDecodePicParamSet
+
+ Functional description:
+ Decode picture parameter set information from the stream.
+
+ Function allocates memory for
+ - run lengths if slice group map type is 0
+ - top-left and bottom-right arrays if map type is 2
+ - for slice group ids if map type is 6
+
+ Validity of some of the slice group mapping information depends
+ on the image dimensions which are not known here. Therefore the
+ validity has to be checked afterwards, currently in the parameter
+ set activation phase.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ pPicParamSet decoded information is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, invalid information or end of stream
+ MEMORY_ALLOCATION_ERROR for memory allocation failure
+
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodePicParamSet(strmData_t *pStrmData, picParamSet_t *pPicParamSet)
+{
+
+/* Variables */
+
+ u32 tmp, i, value;
+ i32 itmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pPicParamSet);
+
+
+ memset(pPicParamSet, 0, sizeof(picParamSet_t));
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pPicParamSet->picParameterSetId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pPicParamSet->picParameterSetId >= MAX_NUM_PIC_PARAM_SETS)
+ {
+ EPRINT("pic_parameter_set_id");
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pPicParamSet->seqParameterSetId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pPicParamSet->seqParameterSetId >= MAX_NUM_SEQ_PARAM_SETS)
+ {
+ EPRINT("seq_param_set_id");
+ return(HANTRO_NOK);
+ }
+
+ /* entropy_coding_mode_flag, shall be 0 for baseline profile */
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp)
+ {
+ EPRINT("entropy_coding_mode_flag");
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicParamSet->picOrderPresentFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ /* num_slice_groups_minus1 */
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pPicParamSet->numSliceGroups = value + 1;
+ if (pPicParamSet->numSliceGroups > MAX_NUM_SLICE_GROUPS)
+ {
+ EPRINT("num_slice_groups_minus1");
+ return(HANTRO_NOK);
+ }
+
+ /* decode slice group mapping information if more than one slice groups */
+ if (pPicParamSet->numSliceGroups > 1)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pPicParamSet->sliceGroupMapType);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pPicParamSet->sliceGroupMapType > 6)
+ {
+ EPRINT("slice_group_map_type");
+ return(HANTRO_NOK);
+ }
+
+ if (pPicParamSet->sliceGroupMapType == 0)
+ {
+ ALLOCATE(pPicParamSet->runLength,
+ pPicParamSet->numSliceGroups, u32);
+ if (pPicParamSet->runLength == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+ for (i = 0; i < pPicParamSet->numSliceGroups; i++)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pPicParamSet->runLength[i] = value+1;
+ /* param values checked in CheckPps() */
+ }
+ }
+ else if (pPicParamSet->sliceGroupMapType == 2)
+ {
+ ALLOCATE(pPicParamSet->topLeft,
+ pPicParamSet->numSliceGroups - 1, u32);
+ ALLOCATE(pPicParamSet->bottomRight,
+ pPicParamSet->numSliceGroups - 1, u32);
+ if (pPicParamSet->topLeft == NULL ||
+ pPicParamSet->bottomRight == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+ for (i = 0; i < pPicParamSet->numSliceGroups - 1; i++)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pPicParamSet->topLeft[i] = value;
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pPicParamSet->bottomRight[i] = value;
+ /* param values checked in CheckPps() */
+ }
+ }
+ else if ( (pPicParamSet->sliceGroupMapType == 3) ||
+ (pPicParamSet->sliceGroupMapType == 4) ||
+ (pPicParamSet->sliceGroupMapType == 5) )
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicParamSet->sliceGroupChangeDirectionFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pPicParamSet->sliceGroupChangeRate = value + 1;
+ /* param value checked in CheckPps() */
+ }
+ else if (pPicParamSet->sliceGroupMapType == 6)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pPicParamSet->picSizeInMapUnits = value + 1;
+
+ ALLOCATE(pPicParamSet->sliceGroupId,
+ pPicParamSet->picSizeInMapUnits, u32);
+ if (pPicParamSet->sliceGroupId == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+
+ /* determine number of bits needed to represent range
+ * [0, numSliceGroups) */
+ tmp = CeilLog2NumSliceGroups[pPicParamSet->numSliceGroups-1];
+
+ for (i = 0; i < pPicParamSet->picSizeInMapUnits; i++)
+ {
+ pPicParamSet->sliceGroupId[i] = h264bsdGetBits(pStrmData, tmp);
+ if ( pPicParamSet->sliceGroupId[i] >=
+ pPicParamSet->numSliceGroups )
+ {
+ EPRINT("slice_group_id");
+ return(HANTRO_NOK);
+ }
+ }
+ }
+ }
+
+ /* num_ref_idx_l0_active_minus1 */
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (value > 31)
+ {
+ EPRINT("num_ref_idx_l0_active_minus1");
+ return(HANTRO_NOK);
+ }
+ pPicParamSet->numRefIdxL0Active = value + 1;
+
+ /* num_ref_idx_l1_active_minus1 */
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (value > 31)
+ {
+ EPRINT("num_ref_idx_l1_active_minus1");
+ return(HANTRO_NOK);
+ }
+
+ /* weighted_pred_flag, this shall be 0 for baseline profile */
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp)
+ {
+ EPRINT("weighted_pred_flag");
+ return(HANTRO_NOK);
+ }
+
+ /* weighted_bipred_idc */
+ tmp = h264bsdGetBits(pStrmData, 2);
+ if (tmp > 2)
+ {
+ EPRINT("weighted_bipred_idc");
+ return(HANTRO_NOK);
+ }
+
+ /* pic_init_qp_minus26 */
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if ((itmp < -26) || (itmp > 25))
+ {
+ EPRINT("pic_init_qp_minus26");
+ return(HANTRO_NOK);
+ }
+ pPicParamSet->picInitQp = (u32)(itmp + 26);
+
+ /* pic_init_qs_minus26 */
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if ((itmp < -26) || (itmp > 25))
+ {
+ EPRINT("pic_init_qs_minus26");
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if ((itmp < -12) || (itmp > 12))
+ {
+ EPRINT("chroma_qp_index_offset");
+ return(HANTRO_NOK);
+ }
+ pPicParamSet->chromaQpIndexOffset = itmp;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicParamSet->deblockingFilterControlPresentFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicParamSet->constrainedIntraPredFlag = (tmp == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicParamSet->redundantPicCntPresentFlag = (tmp == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdRbspTrailingBits(pStrmData);
+
+ /* ignore possible errors in trailing bits of parameters sets */
+ return(HANTRO_OK);
+
+}
+
--- /dev/null
+++ b/src/h264bsd_pic_param_set.h
@@ -1,0 +1,78 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_PIC_PARAM_SET_H
+#define H264SWDEC_PIC_PARAM_SET_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/* data structure to store PPS information decoded from the stream */
+typedef struct
+{
+ u32 picParameterSetId;
+ u32 seqParameterSetId;
+ u32 picOrderPresentFlag;
+ u32 numSliceGroups;
+ u32 sliceGroupMapType;
+ u32 *runLength;
+ u32 *topLeft;
+ u32 *bottomRight;
+ u32 sliceGroupChangeDirectionFlag;
+ u32 sliceGroupChangeRate;
+ u32 picSizeInMapUnits;
+ u32 *sliceGroupId;
+ u32 numRefIdxL0Active;
+ u32 picInitQp;
+ i32 chromaQpIndexOffset;
+ u32 deblockingFilterControlPresentFlag;
+ u32 constrainedIntraPredFlag;
+ u32 redundantPicCntPresentFlag;
+} picParamSet_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodePicParamSet(strmData_t *pStrmData,
+ picParamSet_t *pPicParamSet);
+
+#endif /* #ifdef H264SWDEC_PIC_PARAM_SET_H */
+
--- /dev/null
+++ b/src/h264bsd_reconstruct.c
@@ -1,0 +1,2316 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_reconstruct.h"
+#include "h264bsd_macroblock_layer.h"
+#include "h264bsd_image.h"
+#include "h264bsd_util.h"
+
+#ifdef H264DEC_OMXDL
+#include "omxtypes.h"
+#include "omxVC.h"
+#include "armVC.h"
+#endif /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* Switch off the following Lint messages for this file:
+ * Info 701: Shift left of signed quantity (int)
+ * Info 702: Shift right of signed quantity (int)
+ */
+/*lint -e701 -e702 */
+
+/* Luma fractional-sample positions
+ *
+ * G a b c H
+ * d e f g
+ * h i j k m
+ * n p q r
+ * M s N
+ *
+ * G, H, M and N are integer sample positions
+ * a-s are fractional samples that need to be interpolated.
+ */
+#ifndef H264DEC_OMXDL
+static const u32 lumaFracPos[4][4] = {
+ /* G d h n a e i p b f j q c g k r */
+ {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}, {12, 13, 14, 15}};
+#endif /* H264DEC_OMXDL */
+
+/* clipping table, defined in h264bsd_intra_prediction.c */
+extern const u8 h264bsdClip[];
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+#ifndef H264DEC_OMXDL
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateChromaHor
+
+ Functional description:
+ This function performs chroma interpolation in horizontal direction.
+ Overfilling is done only if needed. Reference image (pRef) is
+ read at correct position and the predicted part is written to
+ macroblock's chrominance (predPartChroma)
+ Inputs:
+ pRef pointer to reference frame Cb top-left corner
+ x0 integer x-coordinate for prediction
+ y0 integer y-coordinate for prediction
+ width width of the reference frame chrominance in pixels
+ height height of the reference frame chrominance in pixels
+ xFrac horizontal fraction for prediction in 1/8 pixels
+ chromaPartWidth width of the predicted part in pixels
+ chromaPartHeight height of the predicted part in pixels
+ Outputs:
+ predPartChroma pointer where predicted part is written
+
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_ARM11
+void h264bsdInterpolateChromaHor(
+ u8 *pRef,
+ u8 *predPartChroma,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 xFrac,
+ u32 chromaPartWidth,
+ u32 chromaPartHeight)
+{
+
+/* Variables */
+
+ u32 x, y, tmp1, tmp2, tmp3, tmp4, c, val;
+ u8 *ptrA, *cbr;
+ u32 comp;
+ u8 block[9*8*2];
+
+/* Code */
+
+ ASSERT(predPartChroma);
+ ASSERT(chromaPartWidth);
+ ASSERT(chromaPartHeight);
+ ASSERT(xFrac < 8);
+ ASSERT(pRef);
+
+ if ((x0 < 0) || ((u32)x0+chromaPartWidth+1 > width) ||
+ (y0 < 0) || ((u32)y0+chromaPartHeight > height))
+ {
+ h264bsdFillBlock(pRef, block, x0, y0, width, height,
+ chromaPartWidth + 1, chromaPartHeight, chromaPartWidth + 1);
+ pRef += width * height;
+ h264bsdFillBlock(pRef, block + (chromaPartWidth+1)*chromaPartHeight,
+ x0, y0, width, height, chromaPartWidth + 1,
+ chromaPartHeight, chromaPartWidth + 1);
+
+ pRef = block;
+ x0 = 0;
+ y0 = 0;
+ width = chromaPartWidth+1;
+ height = chromaPartHeight;
+ }
+
+ val = 8 - xFrac;
+
+ for (comp = 0; comp <= 1; comp++)
+ {
+
+ ptrA = pRef + (comp * height + (u32)y0) * width + x0;
+ cbr = predPartChroma + comp * 8 * 8;
+
+ /* 2x2 pels per iteration
+ * bilinear horizontal interpolation */
+ for (y = (chromaPartHeight >> 1); y; y--)
+ {
+ for (x = (chromaPartWidth >> 1); x; x--)
+ {
+ tmp1 = ptrA[width];
+ tmp2 = *ptrA++;
+ tmp3 = ptrA[width];
+ tmp4 = *ptrA++;
+ c = ((val * tmp1 + xFrac * tmp3) << 3) + 32;
+ c >>= 6;
+ cbr[8] = (u8)c;
+ c = ((val * tmp2 + xFrac * tmp4) << 3) + 32;
+ c >>= 6;
+ *cbr++ = (u8)c;
+ tmp1 = ptrA[width];
+ tmp2 = *ptrA;
+ c = ((val * tmp3 + xFrac * tmp1) << 3) + 32;
+ c >>= 6;
+ cbr[8] = (u8)c;
+ c = ((val * tmp4 + xFrac * tmp2) << 3) + 32;
+ c >>= 6;
+ *cbr++ = (u8)c;
+ }
+ cbr += 2*8 - chromaPartWidth;
+ ptrA += 2*width - chromaPartWidth;
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateChromaVer
+
+ Functional description:
+ This function performs chroma interpolation in vertical direction.
+ Overfilling is done only if needed. Reference image (pRef) is
+ read at correct position and the predicted part is written to
+ macroblock's chrominance (predPartChroma)
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInterpolateChromaVer(
+ u8 *pRef,
+ u8 *predPartChroma,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 yFrac,
+ u32 chromaPartWidth,
+ u32 chromaPartHeight)
+{
+
+/* Variables */
+
+ u32 x, y, tmp1, tmp2, tmp3, c, val;
+ u8 *ptrA, *cbr;
+ u32 comp;
+ u8 block[9*8*2];
+
+/* Code */
+
+ ASSERT(predPartChroma);
+ ASSERT(chromaPartWidth);
+ ASSERT(chromaPartHeight);
+ ASSERT(yFrac < 8);
+ ASSERT(pRef);
+
+ if ((x0 < 0) || ((u32)x0+chromaPartWidth > width) ||
+ (y0 < 0) || ((u32)y0+chromaPartHeight+1 > height))
+ {
+ h264bsdFillBlock(pRef, block, x0, y0, width, height, chromaPartWidth,
+ chromaPartHeight + 1, chromaPartWidth);
+ pRef += width * height;
+ h264bsdFillBlock(pRef, block + chromaPartWidth*(chromaPartHeight+1),
+ x0, y0, width, height, chromaPartWidth,
+ chromaPartHeight + 1, chromaPartWidth);
+
+ pRef = block;
+ x0 = 0;
+ y0 = 0;
+ width = chromaPartWidth;
+ height = chromaPartHeight+1;
+ }
+
+ val = 8 - yFrac;
+
+ for (comp = 0; comp <= 1; comp++)
+ {
+
+ ptrA = pRef + (comp * height + (u32)y0) * width + x0;
+ cbr = predPartChroma + comp * 8 * 8;
+
+ /* 2x2 pels per iteration
+ * bilinear vertical interpolation */
+ for (y = (chromaPartHeight >> 1); y; y--)
+ {
+ for (x = (chromaPartWidth >> 1); x; x--)
+ {
+ tmp3 = ptrA[width*2];
+ tmp2 = ptrA[width];
+ tmp1 = *ptrA++;
+ c = ((val * tmp2 + yFrac * tmp3) << 3) + 32;
+ c >>= 6;
+ cbr[8] = (u8)c;
+ c = ((val * tmp1 + yFrac * tmp2) << 3) + 32;
+ c >>= 6;
+ *cbr++ = (u8)c;
+ tmp3 = ptrA[width*2];
+ tmp2 = ptrA[width];
+ tmp1 = *ptrA++;
+ c = ((val * tmp2 + yFrac * tmp3) << 3) + 32;
+ c >>= 6;
+ cbr[8] = (u8)c;
+ c = ((val * tmp1 + yFrac * tmp2) << 3) + 32;
+ c >>= 6;
+ *cbr++ = (u8)c;
+ }
+ cbr += 2*8 - chromaPartWidth;
+ ptrA += 2*width - chromaPartWidth;
+ }
+ }
+
+}
+#endif
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateChromaHorVer
+
+ Functional description:
+ This function performs chroma interpolation in horizontal and
+ vertical direction. Overfilling is done only if needed. Reference
+ image (ref) is read at correct position and the predicted part
+ is written to macroblock's chrominance (predPartChroma)
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInterpolateChromaHorVer(
+ u8 *ref,
+ u8 *predPartChroma,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 xFrac,
+ u32 yFrac,
+ u32 chromaPartWidth,
+ u32 chromaPartHeight)
+{
+ u8 block[9*9*2];
+ u32 x, y, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, valX, valY, plus32 = 32;
+ u32 comp;
+ u8 *ptrA, *cbr;
+
+/* Code */
+
+ ASSERT(predPartChroma);
+ ASSERT(chromaPartWidth);
+ ASSERT(chromaPartHeight);
+ ASSERT(xFrac < 8);
+ ASSERT(yFrac < 8);
+ ASSERT(ref);
+
+ if ((x0 < 0) || ((u32)x0+chromaPartWidth+1 > width) ||
+ (y0 < 0) || ((u32)y0+chromaPartHeight+1 > height))
+ {
+ h264bsdFillBlock(ref, block, x0, y0, width, height,
+ chromaPartWidth + 1, chromaPartHeight + 1, chromaPartWidth + 1);
+ ref += width * height;
+ h264bsdFillBlock(ref, block + (chromaPartWidth+1)*(chromaPartHeight+1),
+ x0, y0, width, height, chromaPartWidth + 1,
+ chromaPartHeight + 1, chromaPartWidth + 1);
+
+ ref = block;
+ x0 = 0;
+ y0 = 0;
+ width = chromaPartWidth+1;
+ height = chromaPartHeight+1;
+ }
+
+ valX = 8 - xFrac;
+ valY = 8 - yFrac;
+
+ for (comp = 0; comp <= 1; comp++)
+ {
+
+ ptrA = ref + (comp * height + (u32)y0) * width + x0;
+ cbr = predPartChroma + comp * 8 * 8;
+
+ /* 2x2 pels per iteration
+ * bilinear vertical and horizontal interpolation */
+ for (y = (chromaPartHeight >> 1); y; y--)
+ {
+ tmp1 = *ptrA;
+ tmp3 = ptrA[width];
+ tmp5 = ptrA[width*2];
+ tmp1 *= valY;
+ tmp1 += tmp3 * yFrac;
+ tmp3 *= valY;
+ tmp3 += tmp5 * yFrac;
+ for (x = (chromaPartWidth >> 1); x; x--)
+ {
+ tmp2 = *++ptrA;
+ tmp4 = ptrA[width];
+ tmp6 = ptrA[width*2];
+ tmp2 *= valY;
+ tmp2 += tmp4 * yFrac;
+ tmp4 *= valY;
+ tmp4 += tmp6 * yFrac;
+ tmp1 = tmp1 * valX + plus32;
+ tmp3 = tmp3 * valX + plus32;
+ tmp1 += tmp2 * xFrac;
+ tmp1 >>= 6;
+ tmp3 += tmp4 * xFrac;
+ tmp3 >>= 6;
+ cbr[8] = (u8)tmp3;
+ *cbr++ = (u8)tmp1;
+
+ tmp1 = *++ptrA;
+ tmp3 = ptrA[width];
+ tmp5 = ptrA[width*2];
+ tmp1 *= valY;
+ tmp1 += tmp3 * yFrac;
+ tmp3 *= valY;
+ tmp3 += tmp5 * yFrac;
+ tmp2 = tmp2 * valX + plus32;
+ tmp4 = tmp4 * valX + plus32;
+ tmp2 += tmp1 * xFrac;
+ tmp2 >>= 6;
+ tmp4 += tmp3 * xFrac;
+ tmp4 >>= 6;
+ cbr[8] = (u8)tmp4;
+ *cbr++ = (u8)tmp2;
+ }
+ cbr += 2*8 - chromaPartWidth;
+ ptrA += 2*width - chromaPartWidth;
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: PredictChroma
+
+ Functional description:
+ Top level chroma prediction function that calls the appropriate
+ interpolation function. The output is written to macroblock array.
+
+------------------------------------------------------------------------------*/
+
+static void PredictChroma(
+ u8 *mbPartChroma,
+ u32 xAL,
+ u32 yAL,
+ u32 partWidth,
+ u32 partHeight,
+ mv_t *mv,
+ image_t *refPic)
+{
+
+/* Variables */
+
+ u32 xFrac, yFrac, width, height, chromaPartWidth, chromaPartHeight;
+ i32 xInt, yInt;
+ u8 *ref;
+
+/* Code */
+
+ ASSERT(mv);
+ ASSERT(refPic);
+ ASSERT(refPic->data);
+ ASSERT(refPic->width);
+ ASSERT(refPic->height);
+
+ width = 8 * refPic->width;
+ height = 8 * refPic->height;
+
+ xInt = (xAL >> 1) + (mv->hor >> 3);
+ yInt = (yAL >> 1) + (mv->ver >> 3);
+ xFrac = mv->hor & 0x7;
+ yFrac = mv->ver & 0x7;
+
+ chromaPartWidth = partWidth >> 1;
+ chromaPartHeight = partHeight >> 1;
+ ref = refPic->data + 256 * refPic->width * refPic->height;
+
+ if (xFrac && yFrac)
+ {
+ h264bsdInterpolateChromaHorVer(ref, mbPartChroma, xInt, yInt, width,
+ height, xFrac, yFrac, chromaPartWidth, chromaPartHeight);
+ }
+ else if (xFrac)
+ {
+ h264bsdInterpolateChromaHor(ref, mbPartChroma, xInt, yInt, width,
+ height, xFrac, chromaPartWidth, chromaPartHeight);
+ }
+ else if (yFrac)
+ {
+ h264bsdInterpolateChromaVer(ref, mbPartChroma, xInt, yInt, width,
+ height, yFrac, chromaPartWidth, chromaPartHeight);
+ }
+ else
+ {
+ h264bsdFillBlock(ref, mbPartChroma, xInt, yInt, width, height,
+ chromaPartWidth, chromaPartHeight, 8);
+ ref += width * height;
+ h264bsdFillBlock(ref, mbPartChroma + 8*8, xInt, yInt, width, height,
+ chromaPartWidth, chromaPartHeight, 8);
+ }
+
+}
+
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateVerHalf
+
+ Functional description:
+ Function to perform vertical interpolation of pixel position 'h'
+ for a block. Overfilling is done only if needed. Reference
+ image (ref) is read at correct position and the predicted part
+ is written to macroblock array (mb)
+
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_ARM11
+void h264bsdInterpolateVerHalf(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight)
+{
+ u32 p1[21*21/4+1];
+ u32 i, j;
+ i32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ u8 *ptrC, *ptrV;
+ const u8 *clp = h264bsdClip + 512;
+
+ /* Code */
+
+ ASSERT(ref);
+ ASSERT(mb);
+
+ if ((x0 < 0) || ((u32)x0+partWidth > width) ||
+ (y0 < 0) || ((u32)y0+partHeight+5 > height))
+ {
+ h264bsdFillBlock(ref, (u8*)p1, x0, y0, width, height,
+ partWidth, partHeight+5, partWidth);
+
+ x0 = 0;
+ y0 = 0;
+ ref = (u8*)p1;
+ width = partWidth;
+ }
+
+ ref += (u32)y0 * width + (u32)x0;
+
+ ptrC = ref + width;
+ ptrV = ptrC + 5*width;
+
+ /* 4 pixels per iteration, interpolate using 5 vertical samples */
+ for (i = (partHeight >> 2); i; i--)
+ {
+ /* h1 = (16 + A + 16(G+M) + 4(G+M) - 4(C+R) - (C+R) + T) >> 5 */
+ for (j = partWidth; j; j--)
+ {
+ tmp4 = ptrV[-(i32)width*2];
+ tmp5 = ptrV[-(i32)width];
+ tmp1 = ptrV[width];
+ tmp2 = ptrV[width*2];
+ tmp6 = *ptrV++;
+
+ tmp7 = tmp4 + tmp1;
+ tmp2 -= (tmp7 << 2);
+ tmp2 -= tmp7;
+ tmp2 += 16;
+ tmp7 = tmp5 + tmp6;
+ tmp3 = ptrC[width*2];
+ tmp2 += (tmp7 << 4);
+ tmp2 += (tmp7 << 2);
+ tmp2 += tmp3;
+ tmp2 = clp[tmp2>>5];
+ tmp1 += 16;
+ mb[48] = (u8)tmp2;
+
+ tmp7 = tmp3 + tmp6;
+ tmp1 -= (tmp7 << 2);
+ tmp1 -= tmp7;
+ tmp7 = tmp4 + tmp5;
+ tmp2 = ptrC[width];
+ tmp1 += (tmp7 << 4);
+ tmp1 += (tmp7 << 2);
+ tmp1 += tmp2;
+ tmp1 = clp[tmp1>>5];
+ tmp6 += 16;
+ mb[32] = (u8)tmp1;
+
+ tmp7 = tmp2 + tmp5;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp7 = tmp4 + tmp3;
+ tmp1 = *ptrC;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp6 += tmp1;
+ tmp6 = clp[tmp6>>5];
+ tmp5 += 16;
+ mb[16] = (u8)tmp6;
+
+ tmp1 += tmp4;
+ tmp5 -= (tmp1 << 2);
+ tmp5 -= tmp1;
+ tmp3 += tmp2;
+ tmp6 = ptrC[-(i32)width];
+ tmp5 += (tmp3 << 4);
+ tmp5 += (tmp3 << 2);
+ tmp5 += tmp6;
+ tmp5 = clp[tmp5>>5];
+ *mb++ = (u8)tmp5;
+ ptrC++;
+ }
+ ptrC += 4*width - partWidth;
+ ptrV += 4*width - partWidth;
+ mb += 4*16 - partWidth;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateVerQuarter
+
+ Functional description:
+ Function to perform vertical interpolation of pixel position 'd'
+ or 'n' for a block. Overfilling is done only if needed. Reference
+ image (ref) is read at correct position and the predicted part
+ is written to macroblock array (mb)
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInterpolateVerQuarter(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight,
+ u32 verOffset) /* 0 for pixel d, 1 for pixel n */
+{
+ u32 p1[21*21/4+1];
+ u32 i, j;
+ i32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ u8 *ptrC, *ptrV, *ptrInt;
+ const u8 *clp = h264bsdClip + 512;
+
+ /* Code */
+
+ ASSERT(ref);
+ ASSERT(mb);
+
+ if ((x0 < 0) || ((u32)x0+partWidth > width) ||
+ (y0 < 0) || ((u32)y0+partHeight+5 > height))
+ {
+ h264bsdFillBlock(ref, (u8*)p1, x0, y0, width, height,
+ partWidth, partHeight+5, partWidth);
+
+ x0 = 0;
+ y0 = 0;
+ ref = (u8*)p1;
+ width = partWidth;
+ }
+
+ ref += (u32)y0 * width + (u32)x0;
+
+ ptrC = ref + width;
+ ptrV = ptrC + 5*width;
+
+ /* Pointer to integer sample position, either M or R */
+ ptrInt = ptrC + (2+verOffset)*width;
+
+ /* 4 pixels per iteration
+ * interpolate using 5 vertical samples and average between
+ * interpolated value and integer sample value */
+ for (i = (partHeight >> 2); i; i--)
+ {
+ /* h1 = (16 + A + 16(G+M) + 4(G+M) - 4(C+R) - (C+R) + T) >> 5 */
+ for (j = partWidth; j; j--)
+ {
+ tmp4 = ptrV[-(i32)width*2];
+ tmp5 = ptrV[-(i32)width];
+ tmp1 = ptrV[width];
+ tmp2 = ptrV[width*2];
+ tmp6 = *ptrV++;
+
+ tmp7 = tmp4 + tmp1;
+ tmp2 -= (tmp7 << 2);
+ tmp2 -= tmp7;
+ tmp2 += 16;
+ tmp7 = tmp5 + tmp6;
+ tmp3 = ptrC[width*2];
+ tmp2 += (tmp7 << 4);
+ tmp2 += (tmp7 << 2);
+ tmp2 += tmp3;
+ tmp2 = clp[tmp2>>5];
+ tmp7 = ptrInt[width*2];
+ tmp1 += 16;
+ tmp2++;
+ mb[48] = (u8)((tmp2 + tmp7) >> 1);
+
+ tmp7 = tmp3 + tmp6;
+ tmp1 -= (tmp7 << 2);
+ tmp1 -= tmp7;
+ tmp7 = tmp4 + tmp5;
+ tmp2 = ptrC[width];
+ tmp1 += (tmp7 << 4);
+ tmp1 += (tmp7 << 2);
+ tmp1 += tmp2;
+ tmp1 = clp[tmp1>>5];
+ tmp7 = ptrInt[width];
+ tmp6 += 16;
+ tmp1++;
+ mb[32] = (u8)((tmp1 + tmp7) >> 1);
+
+ tmp7 = tmp2 + tmp5;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp7 = tmp4 + tmp3;
+ tmp1 = *ptrC;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp6 += tmp1;
+ tmp6 = clp[tmp6>>5];
+ tmp7 = *ptrInt;
+ tmp5 += 16;
+ tmp6++;
+ mb[16] = (u8)((tmp6 + tmp7) >> 1);
+
+ tmp1 += tmp4;
+ tmp5 -= (tmp1 << 2);
+ tmp5 -= tmp1;
+ tmp3 += tmp2;
+ tmp6 = ptrC[-(i32)width];
+ tmp5 += (tmp3 << 4);
+ tmp5 += (tmp3 << 2);
+ tmp5 += tmp6;
+ tmp5 = clp[tmp5>>5];
+ tmp7 = ptrInt[-(i32)width];
+ tmp5++;
+ *mb++ = (u8)((tmp5 + tmp7) >> 1);
+ ptrC++;
+ ptrInt++;
+ }
+ ptrC += 4*width - partWidth;
+ ptrV += 4*width - partWidth;
+ ptrInt += 4*width - partWidth;
+ mb += 4*16 - partWidth;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateHorHalf
+
+ Functional description:
+ Function to perform horizontal interpolation of pixel position 'b'
+ for a block. Overfilling is done only if needed. Reference
+ image (ref) is read at correct position and the predicted part
+ is written to macroblock array (mb)
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInterpolateHorHalf(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight)
+{
+ u32 p1[21*21/4+1];
+ u8 *ptrJ;
+ u32 x, y;
+ i32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ const u8 *clp = h264bsdClip + 512;
+
+ /* Code */
+
+ ASSERT(ref);
+ ASSERT(mb);
+ ASSERT((partWidth&0x3) == 0);
+ ASSERT((partHeight&0x3) == 0);
+
+ if ((x0 < 0) || ((u32)x0+partWidth+5 > width) ||
+ (y0 < 0) || ((u32)y0+partHeight > height))
+ {
+ h264bsdFillBlock(ref, (u8*)p1, x0, y0, width, height,
+ partWidth+5, partHeight, partWidth+5);
+
+ x0 = 0;
+ y0 = 0;
+ ref = (u8*)p1;
+ width = partWidth + 5;
+ }
+
+ ref += (u32)y0 * width + (u32)x0;
+
+ ptrJ = ref + 5;
+
+ for (y = partHeight; y; y--)
+ {
+ tmp6 = *(ptrJ - 5);
+ tmp5 = *(ptrJ - 4);
+ tmp4 = *(ptrJ - 3);
+ tmp3 = *(ptrJ - 2);
+ tmp2 = *(ptrJ - 1);
+
+ /* calculate 4 pels per iteration */
+ for (x = (partWidth >> 2); x; x--)
+ {
+ /* First pixel */
+ tmp6 += 16;
+ tmp7 = tmp3 + tmp4;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp7 = tmp2 + tmp5;
+ tmp1 = *ptrJ++;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp6 += tmp1;
+ tmp6 = clp[tmp6>>5];
+ /* Second pixel */
+ tmp5 += 16;
+ tmp7 = tmp2 + tmp3;
+ *mb++ = (u8)tmp6;
+ tmp5 += (tmp7 << 4);
+ tmp5 += (tmp7 << 2);
+ tmp7 = tmp1 + tmp4;
+ tmp6 = *ptrJ++;
+ tmp5 -= (tmp7 << 2);
+ tmp5 -= tmp7;
+ tmp5 += tmp6;
+ tmp5 = clp[tmp5>>5];
+ /* Third pixel */
+ tmp4 += 16;
+ tmp7 = tmp1 + tmp2;
+ *mb++ = (u8)tmp5;
+ tmp4 += (tmp7 << 4);
+ tmp4 += (tmp7 << 2);
+ tmp7 = tmp6 + tmp3;
+ tmp5 = *ptrJ++;
+ tmp4 -= (tmp7 << 2);
+ tmp4 -= tmp7;
+ tmp4 += tmp5;
+ tmp4 = clp[tmp4>>5];
+ /* Fourth pixel */
+ tmp3 += 16;
+ tmp7 = tmp6 + tmp1;
+ *mb++ = (u8)tmp4;
+ tmp3 += (tmp7 << 4);
+ tmp3 += (tmp7 << 2);
+ tmp7 = tmp5 + tmp2;
+ tmp4 = *ptrJ++;
+ tmp3 -= (tmp7 << 2);
+ tmp3 -= tmp7;
+ tmp3 += tmp4;
+ tmp3 = clp[tmp3>>5];
+ tmp7 = tmp4;
+ tmp4 = tmp6;
+ tmp6 = tmp2;
+ tmp2 = tmp7;
+ *mb++ = (u8)tmp3;
+ tmp3 = tmp5;
+ tmp5 = tmp1;
+ }
+ ptrJ += width - partWidth;
+ mb += 16 - partWidth;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateHorQuarter
+
+ Functional description:
+ Function to perform horizontal interpolation of pixel position 'a'
+ or 'c' for a block. Overfilling is done only if needed. Reference
+ image (ref) is read at correct position and the predicted part
+ is written to macroblock array (mb)
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInterpolateHorQuarter(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight,
+ u32 horOffset) /* 0 for pixel a, 1 for pixel c */
+{
+ u32 p1[21*21/4+1];
+ u8 *ptrJ;
+ u32 x, y;
+ i32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ const u8 *clp = h264bsdClip + 512;
+
+ /* Code */
+
+ ASSERT(ref);
+ ASSERT(mb);
+
+ if ((x0 < 0) || ((u32)x0+partWidth+5 > width) ||
+ (y0 < 0) || ((u32)y0+partHeight > height))
+ {
+ h264bsdFillBlock(ref, (u8*)p1, x0, y0, width, height,
+ partWidth+5, partHeight, partWidth+5);
+
+ x0 = 0;
+ y0 = 0;
+ ref = (u8*)p1;
+ width = partWidth + 5;
+ }
+
+ ref += (u32)y0 * width + (u32)x0;
+
+ ptrJ = ref + 5;
+
+ for (y = partHeight; y; y--)
+ {
+ tmp6 = *(ptrJ - 5);
+ tmp5 = *(ptrJ - 4);
+ tmp4 = *(ptrJ - 3);
+ tmp3 = *(ptrJ - 2);
+ tmp2 = *(ptrJ - 1);
+
+ /* calculate 4 pels per iteration */
+ for (x = (partWidth >> 2); x; x--)
+ {
+ /* First pixel */
+ tmp6 += 16;
+ tmp7 = tmp3 + tmp4;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp7 = tmp2 + tmp5;
+ tmp1 = *ptrJ++;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp6 += tmp1;
+ tmp6 = clp[tmp6>>5];
+ tmp5 += 16;
+ if (!horOffset)
+ tmp6 += tmp4;
+ else
+ tmp6 += tmp3;
+ *mb++ = (u8)((tmp6 + 1) >> 1);
+ /* Second pixel */
+ tmp7 = tmp2 + tmp3;
+ tmp5 += (tmp7 << 4);
+ tmp5 += (tmp7 << 2);
+ tmp7 = tmp1 + tmp4;
+ tmp6 = *ptrJ++;
+ tmp5 -= (tmp7 << 2);
+ tmp5 -= tmp7;
+ tmp5 += tmp6;
+ tmp5 = clp[tmp5>>5];
+ tmp4 += 16;
+ if (!horOffset)
+ tmp5 += tmp3;
+ else
+ tmp5 += tmp2;
+ *mb++ = (u8)((tmp5 + 1) >> 1);
+ /* Third pixel */
+ tmp7 = tmp1 + tmp2;
+ tmp4 += (tmp7 << 4);
+ tmp4 += (tmp7 << 2);
+ tmp7 = tmp6 + tmp3;
+ tmp5 = *ptrJ++;
+ tmp4 -= (tmp7 << 2);
+ tmp4 -= tmp7;
+ tmp4 += tmp5;
+ tmp4 = clp[tmp4>>5];
+ tmp3 += 16;
+ if (!horOffset)
+ tmp4 += tmp2;
+ else
+ tmp4 += tmp1;
+ *mb++ = (u8)((tmp4 + 1) >> 1);
+ /* Fourth pixel */
+ tmp7 = tmp6 + tmp1;
+ tmp3 += (tmp7 << 4);
+ tmp3 += (tmp7 << 2);
+ tmp7 = tmp5 + tmp2;
+ tmp4 = *ptrJ++;
+ tmp3 -= (tmp7 << 2);
+ tmp3 -= tmp7;
+ tmp3 += tmp4;
+ tmp3 = clp[tmp3>>5];
+ if (!horOffset)
+ tmp3 += tmp1;
+ else
+ tmp3 += tmp6;
+ *mb++ = (u8)((tmp3 + 1) >> 1);
+ tmp3 = tmp5;
+ tmp5 = tmp1;
+ tmp7 = tmp4;
+ tmp4 = tmp6;
+ tmp6 = tmp2;
+ tmp2 = tmp7;
+ }
+ ptrJ += width - partWidth;
+ mb += 16 - partWidth;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateHorVerQuarter
+
+ Functional description:
+ Function to perform horizontal and vertical interpolation of pixel
+ position 'e', 'g', 'p' or 'r' for a block. Overfilling is done only
+ if needed. Reference image (ref) is read at correct position and
+ the predicted part is written to macroblock array (mb)
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInterpolateHorVerQuarter(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight,
+ u32 horVerOffset) /* 0 for pixel e, 1 for pixel g,
+ 2 for pixel p, 3 for pixel r */
+{
+ u32 p1[21*21/4+1];
+ u8 *ptrC, *ptrJ, *ptrV;
+ u32 x, y;
+ i32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ const u8 *clp = h264bsdClip + 512;
+
+ /* Code */
+
+ ASSERT(ref);
+ ASSERT(mb);
+
+ if ((x0 < 0) || ((u32)x0+partWidth+5 > width) ||
+ (y0 < 0) || ((u32)y0+partHeight+5 > height))
+ {
+ h264bsdFillBlock(ref, (u8*)p1, x0, y0, width, height,
+ partWidth+5, partHeight+5, partWidth+5);
+
+ x0 = 0;
+ y0 = 0;
+ ref = (u8*)p1;
+ width = partWidth+5;
+ }
+
+ /* Ref points to G + (-2, -2) */
+ ref += (u32)y0 * width + (u32)x0;
+
+ /* ptrJ points to either J or Q, depending on vertical offset */
+ ptrJ = ref + (((horVerOffset & 0x2) >> 1) + 2) * width + 5;
+
+ /* ptrC points to either C or D, depending on horizontal offset */
+ ptrC = ref + width + 2 + (horVerOffset & 0x1);
+
+ for (y = partHeight; y; y--)
+ {
+ tmp6 = *(ptrJ - 5);
+ tmp5 = *(ptrJ - 4);
+ tmp4 = *(ptrJ - 3);
+ tmp3 = *(ptrJ - 2);
+ tmp2 = *(ptrJ - 1);
+
+ /* Horizontal interpolation, calculate 4 pels per iteration */
+ for (x = (partWidth >> 2); x; x--)
+ {
+ /* First pixel */
+ tmp6 += 16;
+ tmp7 = tmp3 + tmp4;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp7 = tmp2 + tmp5;
+ tmp1 = *ptrJ++;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp6 += tmp1;
+ tmp6 = clp[tmp6>>5];
+ /* Second pixel */
+ tmp5 += 16;
+ tmp7 = tmp2 + tmp3;
+ *mb++ = (u8)tmp6;
+ tmp5 += (tmp7 << 4);
+ tmp5 += (tmp7 << 2);
+ tmp7 = tmp1 + tmp4;
+ tmp6 = *ptrJ++;
+ tmp5 -= (tmp7 << 2);
+ tmp5 -= tmp7;
+ tmp5 += tmp6;
+ tmp5 = clp[tmp5>>5];
+ /* Third pixel */
+ tmp4 += 16;
+ tmp7 = tmp1 + tmp2;
+ *mb++ = (u8)tmp5;
+ tmp4 += (tmp7 << 4);
+ tmp4 += (tmp7 << 2);
+ tmp7 = tmp6 + tmp3;
+ tmp5 = *ptrJ++;
+ tmp4 -= (tmp7 << 2);
+ tmp4 -= tmp7;
+ tmp4 += tmp5;
+ tmp4 = clp[tmp4>>5];
+ /* Fourth pixel */
+ tmp3 += 16;
+ tmp7 = tmp6 + tmp1;
+ *mb++ = (u8)tmp4;
+ tmp3 += (tmp7 << 4);
+ tmp3 += (tmp7 << 2);
+ tmp7 = tmp5 + tmp2;
+ tmp4 = *ptrJ++;
+ tmp3 -= (tmp7 << 2);
+ tmp3 -= tmp7;
+ tmp3 += tmp4;
+ tmp3 = clp[tmp3>>5];
+ tmp7 = tmp4;
+ tmp4 = tmp6;
+ tmp6 = tmp2;
+ tmp2 = tmp7;
+ *mb++ = (u8)tmp3;
+ tmp3 = tmp5;
+ tmp5 = tmp1;
+ }
+ ptrJ += width - partWidth;
+ mb += 16 - partWidth;
+ }
+
+ mb -= 16*partHeight;
+ ptrV = ptrC + 5*width;
+
+ for (y = (partHeight >> 2); y; y--)
+ {
+ /* Vertical interpolation and averaging, 4 pels per iteration */
+ for (x = partWidth; x; x--)
+ {
+ tmp4 = ptrV[-(i32)width*2];
+ tmp5 = ptrV[-(i32)width];
+ tmp1 = ptrV[width];
+ tmp2 = ptrV[width*2];
+ tmp6 = *ptrV++;
+
+ tmp7 = tmp4 + tmp1;
+ tmp2 -= (tmp7 << 2);
+ tmp2 -= tmp7;
+ tmp2 += 16;
+ tmp7 = tmp5 + tmp6;
+ tmp3 = ptrC[width*2];
+ tmp2 += (tmp7 << 4);
+ tmp2 += (tmp7 << 2);
+ tmp2 += tmp3;
+ tmp7 = clp[tmp2>>5];
+ tmp2 = mb[48];
+ tmp1 += 16;
+ tmp7++;
+ mb[48] = (u8)((tmp2 + tmp7) >> 1);
+
+ tmp7 = tmp3 + tmp6;
+ tmp1 -= (tmp7 << 2);
+ tmp1 -= tmp7;
+ tmp7 = tmp4 + tmp5;
+ tmp2 = ptrC[width];
+ tmp1 += (tmp7 << 4);
+ tmp1 += (tmp7 << 2);
+ tmp1 += tmp2;
+ tmp7 = clp[tmp1>>5];
+ tmp1 = mb[32];
+ tmp6 += 16;
+ tmp7++;
+ mb[32] = (u8)((tmp1 + tmp7) >> 1);
+
+ tmp1 = *ptrC;
+ tmp7 = tmp2 + tmp5;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp7 = tmp4 + tmp3;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp6 += tmp1;
+ tmp7 = clp[tmp6>>5];
+ tmp6 = mb[16];
+ tmp5 += 16;
+ tmp7++;
+ mb[16] = (u8)((tmp6 + tmp7) >> 1);
+
+ tmp6 = ptrC[-(i32)width];
+ tmp1 += tmp4;
+ tmp5 -= (tmp1 << 2);
+ tmp5 -= tmp1;
+ tmp3 += tmp2;
+ tmp5 += (tmp3 << 4);
+ tmp5 += (tmp3 << 2);
+ tmp5 += tmp6;
+ tmp7 = clp[tmp5>>5];
+ tmp5 = *mb;
+ tmp7++;
+ *mb++ = (u8)((tmp5 + tmp7) >> 1);
+ ptrC++;
+
+ }
+ ptrC += 4*width - partWidth;
+ ptrV += 4*width - partWidth;
+ mb += 4*16 - partWidth;
+ }
+
+}
+#endif
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateMidHalf
+
+ Functional description:
+ Function to perform horizontal and vertical interpolation of pixel
+ position 'j' for a block. Overfilling is done only if needed.
+ Reference image (ref) is read at correct position and the predicted
+ part is written to macroblock array (mb)
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInterpolateMidHalf(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight)
+{
+ u32 p1[21*21/4+1];
+ u32 x, y;
+ i32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ i32 *ptrC, *ptrV, *b1;
+ u8 *ptrJ;
+ i32 table[21*16];
+ const u8 *clp = h264bsdClip + 512;
+
+ /* Code */
+
+ ASSERT(ref);
+ ASSERT(mb);
+
+ if ((x0 < 0) || ((u32)x0+partWidth+5 > width) ||
+ (y0 < 0) || ((u32)y0+partHeight+5 > height))
+ {
+ h264bsdFillBlock(ref, (u8*)p1, x0, y0, width, height,
+ partWidth+5, partHeight+5, partWidth+5);
+
+ x0 = 0;
+ y0 = 0;
+ ref = (u8*)p1;
+ width = partWidth+5;
+ }
+
+ ref += (u32)y0 * width + (u32)x0;
+
+ b1 = table;
+ ptrJ = ref + 5;
+
+ /* First step: calculate intermediate values for
+ * horizontal interpolation */
+ for (y = partHeight + 5; y; y--)
+ {
+ tmp6 = *(ptrJ - 5);
+ tmp5 = *(ptrJ - 4);
+ tmp4 = *(ptrJ - 3);
+ tmp3 = *(ptrJ - 2);
+ tmp2 = *(ptrJ - 1);
+
+ /* 4 pels per iteration */
+ for (x = (partWidth >> 2); x; x--)
+ {
+ /* First pixel */
+ tmp7 = tmp3 + tmp4;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp7 = tmp2 + tmp5;
+ tmp1 = *ptrJ++;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp6 += tmp1;
+ *b1++ = tmp6;
+ /* Second pixel */
+ tmp7 = tmp2 + tmp3;
+ tmp5 += (tmp7 << 4);
+ tmp5 += (tmp7 << 2);
+ tmp7 = tmp1 + tmp4;
+ tmp6 = *ptrJ++;
+ tmp5 -= (tmp7 << 2);
+ tmp5 -= tmp7;
+ tmp5 += tmp6;
+ *b1++ = tmp5;
+ /* Third pixel */
+ tmp7 = tmp1 + tmp2;
+ tmp4 += (tmp7 << 4);
+ tmp4 += (tmp7 << 2);
+ tmp7 = tmp6 + tmp3;
+ tmp5 = *ptrJ++;
+ tmp4 -= (tmp7 << 2);
+ tmp4 -= tmp7;
+ tmp4 += tmp5;
+ *b1++ = tmp4;
+ /* Fourth pixel */
+ tmp7 = tmp6 + tmp1;
+ tmp3 += (tmp7 << 4);
+ tmp3 += (tmp7 << 2);
+ tmp7 = tmp5 + tmp2;
+ tmp4 = *ptrJ++;
+ tmp3 -= (tmp7 << 2);
+ tmp3 -= tmp7;
+ tmp3 += tmp4;
+ *b1++ = tmp3;
+ tmp7 = tmp4;
+ tmp4 = tmp6;
+ tmp6 = tmp2;
+ tmp2 = tmp7;
+ tmp3 = tmp5;
+ tmp5 = tmp1;
+ }
+ ptrJ += width - partWidth;
+ }
+
+ /* Second step: calculate vertical interpolation */
+ ptrC = table + partWidth;
+ ptrV = ptrC + 5*partWidth;
+ for (y = (partHeight >> 2); y; y--)
+ {
+ /* 4 pels per iteration */
+ for (x = partWidth; x; x--)
+ {
+ tmp4 = ptrV[-(i32)partWidth*2];
+ tmp5 = ptrV[-(i32)partWidth];
+ tmp1 = ptrV[partWidth];
+ tmp2 = ptrV[partWidth*2];
+ tmp6 = *ptrV++;
+
+ tmp7 = tmp4 + tmp1;
+ tmp2 -= (tmp7 << 2);
+ tmp2 -= tmp7;
+ tmp2 += 512;
+ tmp7 = tmp5 + tmp6;
+ tmp3 = ptrC[partWidth*2];
+ tmp2 += (tmp7 << 4);
+ tmp2 += (tmp7 << 2);
+ tmp2 += tmp3;
+ tmp7 = clp[tmp2>>10];
+ tmp1 += 512;
+ mb[48] = (u8)tmp7;
+
+ tmp7 = tmp3 + tmp6;
+ tmp1 -= (tmp7 << 2);
+ tmp1 -= tmp7;
+ tmp7 = tmp4 + tmp5;
+ tmp2 = ptrC[partWidth];
+ tmp1 += (tmp7 << 4);
+ tmp1 += (tmp7 << 2);
+ tmp1 += tmp2;
+ tmp7 = clp[tmp1>>10];
+ tmp6 += 512;
+ mb[32] = (u8)tmp7;
+
+ tmp1 = *ptrC;
+ tmp7 = tmp2 + tmp5;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp7 = tmp4 + tmp3;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp6 += tmp1;
+ tmp7 = clp[tmp6>>10];
+ tmp5 += 512;
+ mb[16] = (u8)tmp7;
+
+ tmp6 = ptrC[-(i32)partWidth];
+ tmp1 += tmp4;
+ tmp5 -= (tmp1 << 2);
+ tmp5 -= tmp1;
+ tmp3 += tmp2;
+ tmp5 += (tmp3 << 4);
+ tmp5 += (tmp3 << 2);
+ tmp5 += tmp6;
+ tmp7 = clp[tmp5>>10];
+ *mb++ = (u8)tmp7;
+ ptrC++;
+ }
+ mb += 4*16 - partWidth;
+ ptrC += 3*partWidth;
+ ptrV += 3*partWidth;
+ }
+
+}
+
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateMidVerQuarter
+
+ Functional description:
+ Function to perform horizontal and vertical interpolation of pixel
+ position 'f' or 'q' for a block. Overfilling is done only if needed.
+ Reference image (ref) is read at correct position and the predicted
+ part is written to macroblock array (mb)
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInterpolateMidVerQuarter(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight,
+ u32 verOffset) /* 0 for pixel f, 1 for pixel q */
+{
+ u32 p1[21*21/4+1];
+ u32 x, y;
+ i32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ i32 *ptrC, *ptrV, *ptrInt, *b1;
+ u8 *ptrJ;
+ i32 table[21*16];
+ const u8 *clp = h264bsdClip + 512;
+
+ /* Code */
+
+ ASSERT(ref);
+ ASSERT(mb);
+
+ if ((x0 < 0) || ((u32)x0+partWidth+5 > width) ||
+ (y0 < 0) || ((u32)y0+partHeight+5 > height))
+ {
+ h264bsdFillBlock(ref, (u8*)p1, x0, y0, width, height,
+ partWidth+5, partHeight+5, partWidth+5);
+
+ x0 = 0;
+ y0 = 0;
+ ref = (u8*)p1;
+ width = partWidth+5;
+ }
+
+ ref += (u32)y0 * width + (u32)x0;
+
+ b1 = table;
+ ptrJ = ref + 5;
+
+ /* First step: calculate intermediate values for
+ * horizontal interpolation */
+ for (y = partHeight + 5; y; y--)
+ {
+ tmp6 = *(ptrJ - 5);
+ tmp5 = *(ptrJ - 4);
+ tmp4 = *(ptrJ - 3);
+ tmp3 = *(ptrJ - 2);
+ tmp2 = *(ptrJ - 1);
+ for (x = (partWidth >> 2); x; x--)
+ {
+ /* First pixel */
+ tmp7 = tmp3 + tmp4;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp7 = tmp2 + tmp5;
+ tmp1 = *ptrJ++;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp6 += tmp1;
+ *b1++ = tmp6;
+ /* Second pixel */
+ tmp7 = tmp2 + tmp3;
+ tmp5 += (tmp7 << 4);
+ tmp5 += (tmp7 << 2);
+ tmp7 = tmp1 + tmp4;
+ tmp6 = *ptrJ++;
+ tmp5 -= (tmp7 << 2);
+ tmp5 -= tmp7;
+ tmp5 += tmp6;
+ *b1++ = tmp5;
+ /* Third pixel */
+ tmp7 = tmp1 + tmp2;
+ tmp4 += (tmp7 << 4);
+ tmp4 += (tmp7 << 2);
+ tmp7 = tmp6 + tmp3;
+ tmp5 = *ptrJ++;
+ tmp4 -= (tmp7 << 2);
+ tmp4 -= tmp7;
+ tmp4 += tmp5;
+ *b1++ = tmp4;
+ /* Fourth pixel */
+ tmp7 = tmp6 + tmp1;
+ tmp3 += (tmp7 << 4);
+ tmp3 += (tmp7 << 2);
+ tmp7 = tmp5 + tmp2;
+ tmp4 = *ptrJ++;
+ tmp3 -= (tmp7 << 2);
+ tmp3 -= tmp7;
+ tmp3 += tmp4;
+ *b1++ = tmp3;
+ tmp7 = tmp4;
+ tmp4 = tmp6;
+ tmp6 = tmp2;
+ tmp2 = tmp7;
+ tmp3 = tmp5;
+ tmp5 = tmp1;
+ }
+ ptrJ += width - partWidth;
+ }
+
+ /* Second step: calculate vertical interpolation and average */
+ ptrC = table + partWidth;
+ ptrV = ptrC + 5*partWidth;
+ /* Pointer to integer sample position, either M or R */
+ ptrInt = ptrC + (2+verOffset)*partWidth;
+ for (y = (partHeight >> 2); y; y--)
+ {
+ for (x = partWidth; x; x--)
+ {
+ tmp4 = ptrV[-(i32)partWidth*2];
+ tmp5 = ptrV[-(i32)partWidth];
+ tmp1 = ptrV[partWidth];
+ tmp2 = ptrV[partWidth*2];
+ tmp6 = *ptrV++;
+
+ tmp7 = tmp4 + tmp1;
+ tmp2 -= (tmp7 << 2);
+ tmp2 -= tmp7;
+ tmp2 += 512;
+ tmp7 = tmp5 + tmp6;
+ tmp3 = ptrC[partWidth*2];
+ tmp2 += (tmp7 << 4);
+ tmp2 += (tmp7 << 2);
+ tmp7 = ptrInt[partWidth*2];
+ tmp2 += tmp3;
+ tmp2 = clp[tmp2>>10];
+ tmp7 += 16;
+ tmp7 = clp[tmp7>>5];
+ tmp1 += 512;
+ tmp2++;
+ mb[48] = (u8)((tmp7 + tmp2) >> 1);
+
+ tmp7 = tmp3 + tmp6;
+ tmp1 -= (tmp7 << 2);
+ tmp1 -= tmp7;
+ tmp7 = tmp4 + tmp5;
+ tmp2 = ptrC[partWidth];
+ tmp1 += (tmp7 << 4);
+ tmp1 += (tmp7 << 2);
+ tmp7 = ptrInt[partWidth];
+ tmp1 += tmp2;
+ tmp1 = clp[tmp1>>10];
+ tmp7 += 16;
+ tmp7 = clp[tmp7>>5];
+ tmp6 += 512;
+ tmp1++;
+ mb[32] = (u8)((tmp7 + tmp1) >> 1);
+
+ tmp1 = *ptrC;
+ tmp7 = tmp2 + tmp5;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp7 = tmp4 + tmp3;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp7 = *ptrInt;
+ tmp6 += tmp1;
+ tmp6 = clp[tmp6>>10];
+ tmp7 += 16;
+ tmp7 = clp[tmp7>>5];
+ tmp5 += 512;
+ tmp6++;
+ mb[16] = (u8)((tmp7 + tmp6) >> 1);
+
+ tmp6 = ptrC[-(i32)partWidth];
+ tmp1 += tmp4;
+ tmp5 -= (tmp1 << 2);
+ tmp5 -= tmp1;
+ tmp3 += tmp2;
+ tmp5 += (tmp3 << 4);
+ tmp5 += (tmp3 << 2);
+ tmp7 = ptrInt[-(i32)partWidth];
+ tmp5 += tmp6;
+ tmp5 = clp[tmp5>>10];
+ tmp7 += 16;
+ tmp7 = clp[tmp7>>5];
+ tmp5++;
+ *mb++ = (u8)((tmp7 + tmp5) >> 1);
+ ptrC++;
+ ptrInt++;
+ }
+ mb += 4*16 - partWidth;
+ ptrC += 3*partWidth;
+ ptrV += 3*partWidth;
+ ptrInt += 3*partWidth;
+ }
+
+}
+
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdInterpolateMidHorQuarter
+
+ Functional description:
+ Function to perform horizontal and vertical interpolation of pixel
+ position 'i' or 'k' for a block. Overfilling is done only if needed.
+ Reference image (ref) is read at correct position and the predicted
+ part is written to macroblock array (mb)
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInterpolateMidHorQuarter(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight,
+ u32 horOffset) /* 0 for pixel i, 1 for pixel k */
+{
+ u32 p1[21*21/4+1];
+ u32 x, y;
+ i32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ i32 *ptrJ, *ptrInt, *h1;
+ u8 *ptrC, *ptrV;
+ i32 table[21*16];
+ i32 tableWidth = (i32)partWidth+5;
+ const u8 *clp = h264bsdClip + 512;
+
+ /* Code */
+
+ ASSERT(ref);
+ ASSERT(mb);
+
+ if ((x0 < 0) || ((u32)x0+partWidth+5 > width) ||
+ (y0 < 0) || ((u32)y0+partHeight+5 > height))
+ {
+ h264bsdFillBlock(ref, (u8*)p1, x0, y0, width, height,
+ partWidth+5, partHeight+5, partWidth+5);
+
+ x0 = 0;
+ y0 = 0;
+ ref = (u8*)p1;
+ width = partWidth+5;
+ }
+
+ ref += (u32)y0 * width + (u32)x0;
+
+ h1 = table + tableWidth;
+ ptrC = ref + width;
+ ptrV = ptrC + 5*width;
+
+ /* First step: calculate intermediate values for
+ * vertical interpolation */
+ for (y = (partHeight >> 2); y; y--)
+ {
+ for (x = (u32)tableWidth; x; x--)
+ {
+ tmp4 = ptrV[-(i32)width*2];
+ tmp5 = ptrV[-(i32)width];
+ tmp1 = ptrV[width];
+ tmp2 = ptrV[width*2];
+ tmp6 = *ptrV++;
+
+ tmp7 = tmp4 + tmp1;
+ tmp2 -= (tmp7 << 2);
+ tmp2 -= tmp7;
+ tmp7 = tmp5 + tmp6;
+ tmp3 = ptrC[width*2];
+ tmp2 += (tmp7 << 4);
+ tmp2 += (tmp7 << 2);
+ tmp2 += tmp3;
+ h1[tableWidth*2] = tmp2;
+
+ tmp7 = tmp3 + tmp6;
+ tmp1 -= (tmp7 << 2);
+ tmp1 -= tmp7;
+ tmp7 = tmp4 + tmp5;
+ tmp2 = ptrC[width];
+ tmp1 += (tmp7 << 4);
+ tmp1 += (tmp7 << 2);
+ tmp1 += tmp2;
+ h1[tableWidth] = tmp1;
+
+ tmp1 = *ptrC;
+ tmp7 = tmp2 + tmp5;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp7 = tmp4 + tmp3;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp6 += tmp1;
+ *h1 = tmp6;
+
+ tmp6 = ptrC[-(i32)width];
+ tmp1 += tmp4;
+ tmp5 -= (tmp1 << 2);
+ tmp5 -= tmp1;
+ tmp3 += tmp2;
+ tmp5 += (tmp3 << 4);
+ tmp5 += (tmp3 << 2);
+ tmp5 += tmp6;
+ h1[-tableWidth] = tmp5;
+ h1++;
+ ptrC++;
+ }
+ ptrC += 4*width - partWidth - 5;
+ ptrV += 4*width - partWidth - 5;
+ h1 += 3*tableWidth;
+ }
+
+ /* Second step: calculate horizontal interpolation and average */
+ ptrJ = table + 5;
+ /* Pointer to integer sample position, either G or H */
+ ptrInt = table + 2 + horOffset;
+ for (y = partHeight; y; y--)
+ {
+ tmp6 = *(ptrJ - 5);
+ tmp5 = *(ptrJ - 4);
+ tmp4 = *(ptrJ - 3);
+ tmp3 = *(ptrJ - 2);
+ tmp2 = *(ptrJ - 1);
+ for (x = (partWidth>>2); x; x--)
+ {
+ /* First pixel */
+ tmp6 += 512;
+ tmp7 = tmp3 + tmp4;
+ tmp6 += (tmp7 << 4);
+ tmp6 += (tmp7 << 2);
+ tmp7 = tmp2 + tmp5;
+ tmp1 = *ptrJ++;
+ tmp6 -= (tmp7 << 2);
+ tmp6 -= tmp7;
+ tmp7 = *ptrInt++;
+ tmp6 += tmp1;
+ tmp6 = clp[tmp6 >> 10];
+ tmp7 += 16;
+ tmp7 = clp[tmp7 >> 5];
+ tmp5 += 512;
+ tmp6++;
+ *mb++ = (u8)((tmp6 + tmp7) >> 1);
+ /* Second pixel */
+ tmp7 = tmp2 + tmp3;
+ tmp5 += (tmp7 << 4);
+ tmp5 += (tmp7 << 2);
+ tmp7 = tmp1 + tmp4;
+ tmp6 = *ptrJ++;
+ tmp5 -= (tmp7 << 2);
+ tmp5 -= tmp7;
+ tmp7 = *ptrInt++;
+ tmp5 += tmp6;
+ tmp5 = clp[tmp5 >> 10];
+ tmp7 += 16;
+ tmp7 = clp[tmp7 >> 5];
+ tmp4 += 512;
+ tmp5++;
+ *mb++ = (u8)((tmp5 + tmp7) >> 1);
+ /* Third pixel */
+ tmp7 = tmp1 + tmp2;
+ tmp4 += (tmp7 << 4);
+ tmp4 += (tmp7 << 2);
+ tmp7 = tmp6 + tmp3;
+ tmp5 = *ptrJ++;
+ tmp4 -= (tmp7 << 2);
+ tmp4 -= tmp7;
+ tmp7 = *ptrInt++;
+ tmp4 += tmp5;
+ tmp4 = clp[tmp4 >> 10];
+ tmp7 += 16;
+ tmp7 = clp[tmp7 >> 5];
+ tmp3 += 512;
+ tmp4++;
+ *mb++ = (u8)((tmp4 + tmp7) >> 1);
+ /* Fourth pixel */
+ tmp7 = tmp6 + tmp1;
+ tmp3 += (tmp7 << 4);
+ tmp3 += (tmp7 << 2);
+ tmp7 = tmp5 + tmp2;
+ tmp4 = *ptrJ++;
+ tmp3 -= (tmp7 << 2);
+ tmp3 -= tmp7;
+ tmp7 = *ptrInt++;
+ tmp3 += tmp4;
+ tmp3 = clp[tmp3 >> 10];
+ tmp7 += 16;
+ tmp7 = clp[tmp7 >> 5];
+ tmp3++;
+ *mb++ = (u8)((tmp3 + tmp7) >> 1);
+ tmp3 = tmp5;
+ tmp5 = tmp1;
+ tmp7 = tmp4;
+ tmp4 = tmp6;
+ tmp6 = tmp2;
+ tmp2 = tmp7;
+ }
+ ptrJ += 5;
+ ptrInt += 5;
+ mb += 16 - partWidth;
+ }
+
+}
+
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdPredictSamples
+
+ Functional description:
+ This function reconstructs a prediction for a macroblock partition.
+ The prediction is either copied or interpolated using the reference
+ frame and the motion vector. Both luminance and chrominance parts are
+ predicted. The prediction is stored in given macroblock array (data).
+ Inputs:
+ data pointer to macroblock array (384 bytes) for output
+ mv pointer to motion vector used for prediction
+ refPic pointer to reference picture structure
+ xA x-coordinate for current macroblock
+ yA y-coordinate for current macroblock
+ partX x-offset for partition in macroblock
+ partY y-offset for partition in macroblock
+ partWidth width of partition
+ partHeight height of partition
+ Outputs:
+ data macroblock array (16x16+8x8+8x8) where predicted
+ partition is stored at correct position
+
+------------------------------------------------------------------------------*/
+
+void h264bsdPredictSamples(
+ u8 *data,
+ mv_t *mv,
+ image_t *refPic,
+ u32 xA,
+ u32 yA,
+ u32 partX,
+ u32 partY,
+ u32 partWidth,
+ u32 partHeight)
+
+{
+
+/* Variables */
+
+ u32 xFrac, yFrac, width, height;
+ i32 xInt, yInt;
+ u8 *lumaPartData;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(mv);
+ ASSERT(partWidth);
+ ASSERT(partHeight);
+ ASSERT(refPic);
+ ASSERT(refPic->data);
+ ASSERT(refPic->width);
+ ASSERT(refPic->height);
+
+ /* luma */
+ lumaPartData = data + 16*partY + partX;
+
+ xFrac = mv->hor & 0x3;
+ yFrac = mv->ver & 0x3;
+
+ width = 16 * refPic->width;
+ height = 16 * refPic->height;
+
+ xInt = (i32)xA + (i32)partX + (mv->hor >> 2);
+ yInt = (i32)yA + (i32)partY + (mv->ver >> 2);
+
+ ASSERT(lumaFracPos[xFrac][yFrac] < 16);
+
+ switch (lumaFracPos[xFrac][yFrac])
+ {
+ case 0: /* G */
+ h264bsdFillBlock(refPic->data, lumaPartData,
+ xInt,yInt,width,height,partWidth,partHeight,16);
+ break;
+ case 1: /* d */
+ h264bsdInterpolateVerQuarter(refPic->data, lumaPartData,
+ xInt, yInt-2, width, height, partWidth, partHeight, 0);
+ break;
+ case 2: /* h */
+ h264bsdInterpolateVerHalf(refPic->data, lumaPartData,
+ xInt, yInt-2, width, height, partWidth, partHeight);
+ break;
+ case 3: /* n */
+ h264bsdInterpolateVerQuarter(refPic->data, lumaPartData,
+ xInt, yInt-2, width, height, partWidth, partHeight, 1);
+ break;
+ case 4: /* a */
+ h264bsdInterpolateHorQuarter(refPic->data, lumaPartData,
+ xInt-2, yInt, width, height, partWidth, partHeight, 0);
+ break;
+ case 5: /* e */
+ h264bsdInterpolateHorVerQuarter(refPic->data, lumaPartData,
+ xInt-2, yInt-2, width, height, partWidth, partHeight, 0);
+ break;
+ case 6: /* i */
+ h264bsdInterpolateMidHorQuarter(refPic->data, lumaPartData,
+ xInt-2, yInt-2, width, height, partWidth, partHeight, 0);
+ break;
+ case 7: /* p */
+ h264bsdInterpolateHorVerQuarter(refPic->data, lumaPartData,
+ xInt-2, yInt-2, width, height, partWidth, partHeight, 2);
+ break;
+ case 8: /* b */
+ h264bsdInterpolateHorHalf(refPic->data, lumaPartData,
+ xInt-2, yInt, width, height, partWidth, partHeight);
+ break;
+ case 9: /* f */
+ h264bsdInterpolateMidVerQuarter(refPic->data, lumaPartData,
+ xInt-2, yInt-2, width, height, partWidth, partHeight, 0);
+ break;
+ case 10: /* j */
+ h264bsdInterpolateMidHalf(refPic->data, lumaPartData,
+ xInt-2, yInt-2, width, height, partWidth, partHeight);
+ break;
+ case 11: /* q */
+ h264bsdInterpolateMidVerQuarter(refPic->data, lumaPartData,
+ xInt-2, yInt-2, width, height, partWidth, partHeight, 1);
+ break;
+ case 12: /* c */
+ h264bsdInterpolateHorQuarter(refPic->data, lumaPartData,
+ xInt-2, yInt, width, height, partWidth, partHeight, 1);
+ break;
+ case 13: /* g */
+ h264bsdInterpolateHorVerQuarter(refPic->data, lumaPartData,
+ xInt-2, yInt-2, width, height, partWidth, partHeight, 1);
+ break;
+ case 14: /* k */
+ h264bsdInterpolateMidHorQuarter(refPic->data, lumaPartData,
+ xInt-2, yInt-2, width, height, partWidth, partHeight, 1);
+ break;
+ default: /* case 15, r */
+ h264bsdInterpolateHorVerQuarter(refPic->data, lumaPartData,
+ xInt-2, yInt-2, width, height, partWidth, partHeight, 3);
+ break;
+ }
+
+ /* chroma */
+ PredictChroma(
+ data + 16*16 + (partY>>1)*8 + (partX>>1),
+ xA + partX,
+ yA + partY,
+ partWidth,
+ partHeight,
+ mv,
+ refPic);
+
+}
+
+#else /* H264DEC_OMXDL */
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdPredictSamples
+
+ Functional description:
+ This function reconstructs a prediction for a macroblock partition.
+ The prediction is either copied or interpolated using the reference
+ frame and the motion vector. Both luminance and chrominance parts are
+ predicted. The prediction is stored in given macroblock array (data).
+ Inputs:
+ data pointer to macroblock array (384 bytes) for output
+ mv pointer to motion vector used for prediction
+ refPic pointer to reference picture structure
+ xA x-coordinate for current macroblock
+ yA y-coordinate for current macroblock
+ partX x-offset for partition in macroblock
+ partY y-offset for partition in macroblock
+ partWidth width of partition
+ partHeight height of partition
+ Outputs:
+ data macroblock array (16x16+8x8+8x8) where predicted
+ partition is stored at correct position
+
+------------------------------------------------------------------------------*/
+
+/*lint -e{550} Symbol 'res' not accessed */
+void h264bsdPredictSamples(
+ u8 *data,
+ mv_t *mv,
+ image_t *refPic,
+ u32 colAndRow,
+ u32 part,
+ u8 *pFill)
+
+{
+
+/* Variables */
+
+ u32 xFrac, yFrac;
+ u32 width, height;
+ i32 xInt, yInt, x0, y0;
+ u8 *partData, *ref;
+ OMXSize roi;
+ u32 fillWidth;
+ u32 fillHeight;
+ OMXResult res;
+ u32 xA, yA;
+ u32 partX, partY;
+ u32 partWidth, partHeight;
+
+/* Code */
+
+ ASSERT(data);
+ ASSERT(mv);
+ ASSERT(refPic);
+ ASSERT(refPic->data);
+ ASSERT(refPic->width);
+ ASSERT(refPic->height);
+
+ xA = (colAndRow & 0xFFFF0000) >> 16;
+ yA = (colAndRow & 0x0000FFFF);
+
+ partX = (part & 0xFF000000) >> 24;
+ partY = (part & 0x00FF0000) >> 16;
+ partWidth = (part & 0x0000FF00) >> 8;
+ partHeight = (part & 0x000000FF);
+
+ ASSERT(partWidth);
+ ASSERT(partHeight);
+
+ /* luma */
+ partData = data + 16*partY + partX;
+
+ xFrac = mv->hor & 0x3;
+ yFrac = mv->ver & 0x3;
+
+ width = 16 * refPic->width;
+ height = 16 * refPic->height;
+
+ xInt = (i32)xA + (i32)partX + (mv->hor >> 2);
+ yInt = (i32)yA + (i32)partY + (mv->ver >> 2);
+
+ x0 = (xFrac) ? xInt-2 : xInt;
+ y0 = (yFrac) ? yInt-2 : yInt;
+
+ if (xFrac)
+ {
+ if (partWidth == 16)
+ fillWidth = 32;
+ else
+ fillWidth = 16;
+ }
+ else
+ fillWidth = (partWidth*2);
+ if (yFrac)
+ fillHeight = partHeight+5;
+ else
+ fillHeight = partHeight;
+
+
+ if ((x0 < 0) || ((u32)x0+fillWidth > width) ||
+ (y0 < 0) || ((u32)y0+fillHeight > height))
+ {
+ h264bsdFillBlock(refPic->data, (u8*)pFill, x0, y0, width, height,
+ fillWidth, fillHeight, fillWidth);
+
+ x0 = 0;
+ y0 = 0;
+ ref = pFill;
+ width = fillWidth;
+ if (yFrac)
+ ref += 2*width;
+ if (xFrac)
+ ref += 2;
+ }
+ else
+ {
+ /*lint --e(737) Loss of sign */
+ ref = refPic->data + yInt*width + xInt;
+ }
+ /* Luma interpolation */
+ roi.width = (i32)partWidth;
+ roi.height = (i32)partHeight;
+
+ res = omxVCM4P10_InterpolateLuma(ref, (i32)width, partData, 16,
+ (i32)xFrac, (i32)yFrac, roi);
+ ASSERT(res == 0);
+
+ /* Chroma */
+ width = 8 * refPic->width;
+ height = 8 * refPic->height;
+
+ x0 = ((xA + partX) >> 1) + (mv->hor >> 3);
+ y0 = ((yA + partY) >> 1) + (mv->ver >> 3);
+ xFrac = mv->hor & 0x7;
+ yFrac = mv->ver & 0x7;
+
+ ref = refPic->data + 256 * refPic->width * refPic->height;
+
+ roi.width = (i32)(partWidth >> 1);
+ fillWidth = ((partWidth >> 1) + 8) & ~0x7;
+ roi.height = (i32)(partHeight >> 1);
+ fillHeight = (partHeight >> 1) + 1;
+
+ if ((x0 < 0) || ((u32)x0+fillWidth > width) ||
+ (y0 < 0) || ((u32)y0+fillHeight > height))
+ {
+ h264bsdFillBlock(ref, pFill, x0, y0, width, height,
+ fillWidth, fillHeight, fillWidth);
+ ref += width * height;
+ h264bsdFillBlock(ref, pFill + fillWidth*fillHeight,
+ x0, y0, width, height, fillWidth,
+ fillHeight, fillWidth);
+
+ ref = pFill;
+ x0 = 0;
+ y0 = 0;
+ width = fillWidth;
+ height = fillHeight;
+ }
+
+ partData = data + 16*16 + (partY>>1)*8 + (partX>>1);
+
+ /* Chroma interpolation */
+ /*lint --e(737) Loss of sign */
+ ref += y0 * width + x0;
+ res = armVCM4P10_Interpolate_Chroma(ref, width, partData, 8,
+ (u32)roi.width, (u32)roi.height, xFrac, yFrac);
+ ASSERT(res == 0);
+ partData += 8 * 8;
+ ref += height * width;
+ res = armVCM4P10_Interpolate_Chroma(ref, width, partData, 8,
+ (u32)roi.width, (u32)roi.height, xFrac, yFrac);
+ ASSERT(res == 0);
+
+}
+
+#endif /* H264DEC_OMXDL */
+
+
+/*------------------------------------------------------------------------------
+
+ Function: FillRow1
+
+ Functional description:
+ This function gets a row of reference pels in a 'normal' case when no
+ overfilling is necessary.
+
+------------------------------------------------------------------------------*/
+
+static void FillRow1(
+ u8 *ref,
+ u8 *fill,
+ i32 left,
+ i32 center,
+ i32 right)
+{
+
+ ASSERT(ref);
+ ASSERT(fill);
+
+ memcpy(fill, ref, (u32)center);
+
+ /*lint -e(715) */
+}
+
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdFillRow7
+
+ Functional description:
+ This function gets a row of reference pels when horizontal coordinate
+ is partly negative or partly greater than reference picture width
+ (overfilling some pels on left and/or right edge).
+ Inputs:
+ ref pointer to reference samples
+ left amount of pixels to overfill on left-edge
+ center amount of pixels to copy
+ right amount of pixels to overfill on right-edge
+ Outputs:
+ fill pointer where samples are stored
+
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_NEON
+void h264bsdFillRow7(
+ u8 *ref,
+ u8 *fill,
+ i32 left,
+ i32 center,
+ i32 right)
+{
+ u8 tmp;
+
+ ASSERT(ref);
+ ASSERT(fill);
+
+ if (left)
+ tmp = *ref;
+
+ for ( ; left; left--)
+ /*lint -esym(644,tmp) tmp is initialized if used */
+ *fill++ = tmp;
+
+ for ( ; center; center--)
+ *fill++ = *ref++;
+
+ if (right)
+ tmp = ref[-1];
+
+ for ( ; right; right--)
+ /*lint -esym(644,tmp) tmp is initialized if used */
+ *fill++ = tmp;
+}
+#endif
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdFillBlock
+
+ Functional description:
+ This function gets a block of reference pels. It determines whether
+ overfilling is needed or not and repeatedly calls an appropriate
+ function (by using a function pointer) that fills one row the block.
+ Inputs:
+ ref pointer to reference frame
+ x0 x-coordinate for block
+ y0 y-coordinate for block
+ width width of reference frame
+ height height of reference frame
+ blockWidth width of block
+ blockHeight height of block
+ fillScanLength length of a line in output array (pixels)
+ Outputs:
+ fill pointer to array where output block is written
+
+------------------------------------------------------------------------------*/
+
+void h264bsdFillBlock(
+ u8 *ref,
+ u8 *fill,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 blockWidth,
+ u32 blockHeight,
+ u32 fillScanLength)
+
+{
+
+/* Variables */
+
+ i32 xstop, ystop;
+ void (*fp)(u8*, u8*, i32, i32, i32);
+ i32 left, x, right;
+ i32 top, y, bottom;
+
+/* Code */
+
+ ASSERT(ref);
+ ASSERT(fill);
+ ASSERT(width);
+ ASSERT(height);
+ ASSERT(fill);
+ ASSERT(blockWidth);
+ ASSERT(blockHeight);
+
+ xstop = x0 + (i32)blockWidth;
+ ystop = y0 + (i32)blockHeight;
+
+ /* Choose correct function whether overfilling on left-edge or right-edge
+ * is needed or not */
+ if (x0 >= 0 && xstop <= (i32)width)
+ fp = FillRow1;
+ else
+ fp = h264bsdFillRow7;
+
+ if (ystop < 0)
+ y0 = -(i32)blockHeight;
+
+ if (xstop < 0)
+ x0 = -(i32)blockWidth;
+
+ if (y0 > (i32)height)
+ y0 = (i32)height;
+
+ if (x0 > (i32)width)
+ x0 = (i32)width;
+
+ xstop = x0 + (i32)blockWidth;
+ ystop = y0 + (i32)blockHeight;
+
+ if (x0 > 0)
+ ref += x0;
+
+ if (y0 > 0)
+ ref += y0 * (i32)width;
+
+ left = x0 < 0 ? -x0 : 0;
+ right = xstop > (i32)width ? xstop - (i32)width : 0;
+ x = (i32)blockWidth - left - right;
+
+ top = y0 < 0 ? -y0 : 0;
+ bottom = ystop > (i32)height ? ystop - (i32)height : 0;
+ y = (i32)blockHeight - top - bottom;
+
+ /* Top-overfilling */
+ for ( ; top; top-- )
+ {
+ (*fp)(ref, fill, left, x, right);
+ fill += fillScanLength;
+ }
+
+ /* Lines inside reference image */
+ for ( ; y; y-- )
+ {
+ (*fp)(ref, fill, left, x, right);
+ ref += width;
+ fill += fillScanLength;
+ }
+
+ ref -= width;
+
+ /* Bottom-overfilling */
+ for ( ; bottom; bottom-- )
+ {
+ (*fp)(ref, fill, left, x, right);
+ fill += fillScanLength;
+ }
+}
+
+/*lint +e701 +e702 */
+
+
--- /dev/null
+++ b/src/h264bsd_reconstruct.h
@@ -1,0 +1,211 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_RECONSTRUCT_H
+#define H264SWDEC_RECONSTRUCT_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_macroblock_layer.h"
+#include "h264bsd_image.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_OMXDL
+void h264bsdPredictSamples(
+ u8 *data,
+ mv_t *mv,
+ image_t *refPic,
+ u32 xA,
+ u32 yA,
+ u32 partX,
+ u32 partY,
+ u32 partWidth,
+ u32 partHeight);
+#else
+void h264bsdPredictSamples(
+ u8 *data,
+ mv_t *mv,
+ image_t *refPic,
+ u32 colAndRow,/* packaged data | column | row |*/
+ u32 part, /* packaged data |partX|partY|partWidth|partHeight|*/
+ u8 *pFill);
+#endif
+
+void h264bsdFillBlock(
+ u8 * ref,
+ u8 * fill,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 blockWidth,
+ u32 blockHeight,
+ u32 fillScanLength);
+
+void h264bsdInterpolateChromaHor(
+ u8 *pRef,
+ u8 *predPartChroma,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 xFrac,
+ u32 chromaPartWidth,
+ u32 chromaPartHeight);
+
+void h264bsdInterpolateChromaVer(
+ u8 *pRef,
+ u8 *predPartChroma,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 yFrac,
+ u32 chromaPartWidth,
+ u32 chromaPartHeight);
+
+void h264bsdInterpolateChromaHorVer(
+ u8 *ref,
+ u8 *predPartChroma,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 xFrac,
+ u32 yFrac,
+ u32 chromaPartWidth,
+ u32 chromaPartHeight);
+
+void h264bsdInterpolateVerHalf(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight);
+
+void h264bsdInterpolateVerQuarter(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight,
+ u32 verOffset);
+
+void h264bsdInterpolateHorHalf(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight);
+
+void h264bsdInterpolateHorQuarter(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight,
+ u32 horOffset);
+
+void h264bsdInterpolateHorVerQuarter(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight,
+ u32 horVerOffset);
+
+void h264bsdInterpolateMidHalf(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight);
+
+void h264bsdInterpolateMidVerQuarter(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight,
+ u32 verOffset);
+
+void h264bsdInterpolateMidHorQuarter(
+ u8 *ref,
+ u8 *mb,
+ i32 x0,
+ i32 y0,
+ u32 width,
+ u32 height,
+ u32 partWidth,
+ u32 partHeight,
+ u32 horOffset);
+
+
+void h264bsdFillRow7(
+ u8 *ref,
+ u8 *fill,
+ i32 left,
+ i32 center,
+ i32 right);
+
+#endif /* #ifdef H264SWDEC_RECONSTRUCT_H */
+
--- /dev/null
+++ b/src/h264bsd_sei.c
@@ -1,0 +1,1694 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodeSeiMessage
+ DecodeBufferingPeriod
+ DecodePictureTiming
+ DecodePanScanRectangle
+ DecodeFillerPayload
+ DecodeUserDataRegisteredITuTT35
+ DecodeUserDataUnregistered
+ DecodeRecoveryPoint
+ DecodeDecRefPicMarkingRepetition
+ DecodeSparePic
+ DecodeSceneInfo
+ DecodeSubSeqInfo
+ DecodeSubSeqLayerCharacteristics
+ DecodeSubSeqCharacteristics
+ DecodeFullFrameFreeze
+ DecodeFullFrameSnapshot
+ DecodeProgressiveRefinementSegmentStart
+ DecodeProgressiveRefinementSegmentEnd
+ DecodeMotionConstrainedSliceGroupSet
+ DecodeReservedSeiMessage
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_sei.h"
+#include "basetype.h"
+#include "h264bsd_util.h"
+#include "h264bsd_stream.h"
+#include "h264bsd_vlc.h"
+#include "h264bsd_seq_param_set.h"
+#include "h264bsd_slice_header.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+static const u32 numClockTS[9] = {1,1,1,2,2,3,3,2,3};
+static const u32 ceilLog2NumSliceGroups[9] = {0,1,1,2,2,3,3,3,3};
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 DecodeBufferingPeriod(
+ strmData_t *pStrmData,
+ seiBufferingPeriod_t *pBufferingPeriod,
+ u32 cpbCnt,
+ u32 initialCpbRemovalDelayLength,
+ u32 nalHrdBpPresentFlag,
+ u32 vclHrdBpPresentFlag);
+
+static u32 DecodePictureTiming(
+ strmData_t *pStrmData,
+ seiPicTiming_t *pPicTiming,
+ u32 cpbRemovalDelayLength,
+ u32 dpbOutputDelayLength,
+ u32 timeOffsetLength,
+ u32 cpbDpbDelaysPresentFlag,
+ u32 picStructPresentFlag);
+
+static u32 DecodePanScanRectangle(
+ strmData_t *pStrmData,
+ seiPanScanRect_t *pPanScanRectangle);
+
+static u32 DecodeFillerPayload(strmData_t *pStrmData, u32 payloadSize);
+
+static u32 DecodeUserDataRegisteredITuTT35(
+ strmData_t *pStrmData,
+ seiUserDataRegisteredItuTT35_t *pUserDataRegisteredItuTT35,
+ u32 payloadSize);
+
+static u32 DecodeUserDataUnregistered(
+ strmData_t *pStrmData,
+ seiUserDataUnregistered_t *pUserDataUnregistered,
+ u32 payloadSize);
+
+static u32 DecodeRecoveryPoint(
+ strmData_t *pStrmData,
+ seiRecoveryPoint_t *pRecoveryPoint);
+
+static u32 DecodeDecRefPicMarkingRepetition(
+ strmData_t *pStrmData,
+ seiDecRefPicMarkingRepetition_t *pDecRefPicMarkingRepetition,
+ u32 numRefFrames);
+
+static u32 DecodeSparePic(
+ strmData_t *pStrmData,
+ seiSparePic_t *pSparePic,
+ u32 picSizeInMapUnits);
+
+static u32 DecodeSceneInfo(
+ strmData_t *pStrmData,
+ seiSceneInfo_t *pSceneInfo);
+
+static u32 DecodeSubSeqInfo(
+ strmData_t *pStrmData,
+ seiSubSeqInfo_t *pSubSeqInfo);
+
+static u32 DecodeSubSeqLayerCharacteristics(
+ strmData_t *pStrmData,
+ seiSubSeqLayerCharacteristics_t *pSubSeqLayerCharacteristics);
+
+static u32 DecodeSubSeqCharacteristics(
+ strmData_t *pStrmData,
+ seiSubSeqCharacteristics_t *pSubSeqCharacteristics);
+
+static u32 DecodeFullFrameFreeze(
+ strmData_t *pStrmData,
+ seiFullFrameFreeze_t *pFullFrameFreeze);
+
+static u32 DecodeFullFrameSnapshot(
+ strmData_t *pStrmData,
+ seiFullFrameSnapshot_t *pFullFrameSnapshot);
+
+static u32 DecodeProgressiveRefinementSegmentStart(
+ strmData_t *pStrmData,
+ seiProgressiveRefinementSegmentStart_t *pProgressiveRefinementSegmentStart);
+
+static u32 DecodeProgressiveRefinementSegmentEnd(
+ strmData_t *pStrmData,
+ seiProgressiveRefinementSegmentEnd_t *pProgressiveRefinementSegmentEnd);
+
+static u32 DecodeMotionConstrainedSliceGroupSet(
+ strmData_t *pStrmData,
+ seiMotionConstrainedSliceGroupSet_t *pMotionConstrainedSliceGroupSet,
+ u32 numSliceGroups);
+
+static u32 DecodeReservedSeiMessage(
+ strmData_t *pStrmData,
+ seiReservedSeiMessage_t *pReservedSeiMessage,
+ u32 payloadSize);
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdDecodeSeiMessage
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeSeiMessage(
+ strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet,
+ seiMessage_t *pSeiMessage,
+ u32 numSliceGroups)
+{
+
+/* Variables */
+
+ u32 tmp, payloadType, payloadSize, status;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSeiMessage);
+
+
+ memset(pSeiMessage, 0, sizeof(seiMessage_t));
+
+ do
+ {
+ payloadType = 0;
+ while((tmp = h264bsdGetBits(pStrmData, 8)) == 0xFF)
+ {
+ payloadType += 255;
+ }
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ payloadType += tmp;
+
+ payloadSize = 0;
+ while((tmp = h264bsdGetBits(pStrmData, 8)) == 0xFF)
+ {
+ payloadSize += 255;
+ }
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ payloadSize += tmp;
+
+ pSeiMessage->payloadType = payloadType;
+
+ switch (payloadType)
+ {
+ case 0:
+ ASSERT(pSeqParamSet);
+ status = DecodeBufferingPeriod(
+ pStrmData,
+ &pSeiMessage->bufferingPeriod,
+ pSeqParamSet->vuiParameters->vclHrdParameters.cpbCnt,
+ pSeqParamSet->vuiParameters->vclHrdParameters.
+ initialCpbRemovalDelayLength,
+ pSeqParamSet->vuiParameters->nalHrdParametersPresentFlag,
+ pSeqParamSet->vuiParameters->vclHrdParametersPresentFlag);
+ break;
+
+ case 1:
+ ASSERT(pSeqParamSet->vuiParametersPresentFlag);
+ status = DecodePictureTiming(
+ pStrmData,
+ &pSeiMessage->picTiming,
+ pSeqParamSet->vuiParameters->vclHrdParameters.
+ cpbRemovalDelayLength,
+ pSeqParamSet->vuiParameters->vclHrdParameters.
+ dpbOutputDelayLength,
+ pSeqParamSet->vuiParameters->vclHrdParameters.
+ timeOffsetLength,
+ pSeqParamSet->vuiParameters->nalHrdParametersPresentFlag ||
+ pSeqParamSet->vuiParameters->vclHrdParametersPresentFlag ?
+ HANTRO_TRUE : HANTRO_FALSE,
+ pSeqParamSet->vuiParameters->picStructPresentFlag);
+ break;
+
+ case 2:
+ status = DecodePanScanRectangle(
+ pStrmData,
+ &pSeiMessage->panScanRect);
+ break;
+
+ case 3:
+ status = DecodeFillerPayload(pStrmData, payloadSize);
+ break;
+
+ case 4:
+ status = DecodeUserDataRegisteredITuTT35(
+ pStrmData,
+ &pSeiMessage->userDataRegisteredItuTT35,
+ payloadSize);
+ break;
+
+ case 5:
+ status = DecodeUserDataUnregistered(
+ pStrmData,
+ &pSeiMessage->userDataUnregistered,
+ payloadSize);
+ break;
+
+ case 6:
+ status = DecodeRecoveryPoint(
+ pStrmData,
+ &pSeiMessage->recoveryPoint);
+ break;
+
+ case 7:
+ status = DecodeDecRefPicMarkingRepetition(
+ pStrmData,
+ &pSeiMessage->decRefPicMarkingRepetition,
+ pSeqParamSet->numRefFrames);
+ break;
+
+ case 8:
+ ASSERT(pSeqParamSet);
+ status = DecodeSparePic(
+ pStrmData,
+ &pSeiMessage->sparePic,
+ pSeqParamSet->picWidthInMbs * pSeqParamSet->picHeightInMbs);
+ break;
+
+ case 9:
+ status = DecodeSceneInfo(
+ pStrmData,
+ &pSeiMessage->sceneInfo);
+ break;
+
+ case 10:
+ status = DecodeSubSeqInfo(
+ pStrmData,
+ &pSeiMessage->subSeqInfo);
+ break;
+
+ case 11:
+ status = DecodeSubSeqLayerCharacteristics(
+ pStrmData,
+ &pSeiMessage->subSeqLayerCharacteristics);
+ break;
+
+ case 12:
+ status = DecodeSubSeqCharacteristics(
+ pStrmData,
+ &pSeiMessage->subSeqCharacteristics);
+ break;
+
+ case 13:
+ status = DecodeFullFrameFreeze(
+ pStrmData,
+ &pSeiMessage->fullFrameFreeze);
+ break;
+
+ case 14: /* This SEI does not contain data, what to do ??? */
+ status = HANTRO_OK;
+ break;
+
+ case 15:
+ status = DecodeFullFrameSnapshot(
+ pStrmData,
+ &pSeiMessage->fullFrameSnapshot);
+ break;
+
+ case 16:
+ status = DecodeProgressiveRefinementSegmentStart(
+ pStrmData,
+ &pSeiMessage->progressiveRefinementSegmentStart);
+ break;
+
+ case 17:
+ status = DecodeProgressiveRefinementSegmentEnd(
+ pStrmData,
+ &pSeiMessage->progressiveRefinementSegmentEnd);
+ break;
+
+ case 18:
+ ASSERT(numSliceGroups);
+ status = DecodeMotionConstrainedSliceGroupSet(
+ pStrmData,
+ &pSeiMessage->motionConstrainedSliceGroupSet,
+ numSliceGroups);
+ break;
+
+ default:
+ status = DecodeReservedSeiMessage(
+ pStrmData,
+ &pSeiMessage->reservedSeiMessage,
+ payloadSize);
+ break;
+ }
+
+ if (status != HANTRO_OK)
+ return(status);
+
+ while (!h264bsdIsByteAligned(pStrmData))
+ {
+ if (h264bsdGetBits(pStrmData, 1) != 1)
+ return(HANTRO_NOK);
+ while (!h264bsdIsByteAligned(pStrmData))
+ {
+ if (h264bsdGetBits(pStrmData, 1) != 0)
+ return(HANTRO_NOK);
+ }
+ }
+ } while (h264bsdMoreRbspData(pStrmData));
+
+ return(h264bsdRbspTrailingBits(pStrmData));
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeBufferingPeriod
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeBufferingPeriod(
+ strmData_t *pStrmData,
+ seiBufferingPeriod_t *pBufferingPeriod,
+ u32 cpbCnt,
+ u32 initialCpbRemovalDelayLength,
+ u32 nalHrdBpPresentFlag,
+ u32 vclHrdBpPresentFlag)
+{
+
+/* Variables */
+
+ u32 tmp, i;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pBufferingPeriod);
+ ASSERT(cpbCnt);
+ ASSERT(initialCpbRemovalDelayLength);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pBufferingPeriod->seqParameterSetId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pBufferingPeriod->seqParameterSetId > 31)
+ return(HANTRO_NOK);
+
+ if (nalHrdBpPresentFlag)
+ {
+ for (i = 0; i < cpbCnt; i++)
+ {
+ tmp = h264bsdGetBits(pStrmData, initialCpbRemovalDelayLength);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp == 0)
+ return(HANTRO_NOK);
+ pBufferingPeriod->initialCpbRemovalDelay[i] = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, initialCpbRemovalDelayLength);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pBufferingPeriod->initialCpbRemovalDelayOffset[i] = tmp;
+ }
+ }
+
+ if (vclHrdBpPresentFlag)
+ {
+ for (i = 0; i < cpbCnt; i++)
+ {
+ tmp = h264bsdGetBits(pStrmData, initialCpbRemovalDelayLength);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pBufferingPeriod->initialCpbRemovalDelay[i] = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, initialCpbRemovalDelayLength);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pBufferingPeriod->initialCpbRemovalDelayOffset[i] = tmp;
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodePictureTiming
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodePictureTiming(
+ strmData_t *pStrmData,
+ seiPicTiming_t *pPicTiming,
+ u32 cpbRemovalDelayLength,
+ u32 dpbOutputDelayLength,
+ u32 timeOffsetLength,
+ u32 cpbDpbDelaysPresentFlag,
+ u32 picStructPresentFlag)
+{
+
+/* Variables */
+
+ u32 tmp, i;
+ i32 itmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pPicTiming);
+
+
+ if (cpbDpbDelaysPresentFlag)
+ {
+ tmp = h264bsdGetBits(pStrmData, cpbRemovalDelayLength);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->cpbRemovalDelay = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, dpbOutputDelayLength);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->dpbOutputDelay = tmp;
+ }
+
+ if (picStructPresentFlag)
+ {
+ tmp = h264bsdGetBits(pStrmData, 4);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp > 8)
+ return(HANTRO_NOK);
+ pPicTiming->picStruct = tmp;
+
+ for (i = 0; i < numClockTS[pPicTiming->picStruct]; i++)
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->clockTimeStampFlag[i] = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pPicTiming->clockTimeStampFlag[i])
+ {
+ tmp = h264bsdGetBits(pStrmData, 2);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->ctType[i] = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->nuitFieldBasedFlag[i] = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 5);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp > 6)
+ return(HANTRO_NOK);
+ pPicTiming->countingType[i] = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->fullTimeStampFlag[i] = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->discontinuityFlag[i] = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->cntDroppedFlag[i] = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->nFrames[i] = tmp;
+
+ if (pPicTiming->fullTimeStampFlag[i])
+ {
+ tmp = h264bsdGetBits(pStrmData, 6);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp > 59)
+ return(HANTRO_NOK);
+ pPicTiming->secondsValue[i] = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 6);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp > 59)
+ return(HANTRO_NOK);
+ pPicTiming->minutesValue[i] = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 5);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp > 23)
+ return(HANTRO_NOK);
+ pPicTiming->hoursValue[i] = tmp;
+ }
+ else
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->secondsFlag[i] = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pPicTiming->secondsFlag[i])
+ {
+ tmp = h264bsdGetBits(pStrmData, 6);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp > 59)
+ return(HANTRO_NOK);
+ pPicTiming->secondsValue[i] = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->minutesFlag[i] = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pPicTiming->minutesFlag[i])
+ {
+ tmp = h264bsdGetBits(pStrmData, 6);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp > 59)
+ return(HANTRO_NOK);
+ pPicTiming->minutesValue[i] = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPicTiming->hoursFlag[i] = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pPicTiming->hoursFlag[i])
+ {
+ tmp = h264bsdGetBits(pStrmData, 5);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp > 23)
+ return(HANTRO_NOK);
+ pPicTiming->hoursValue[i] = tmp;
+ }
+ }
+ }
+ }
+ if (timeOffsetLength)
+ {
+ tmp = h264bsdGetBits(pStrmData, timeOffsetLength);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ itmp = (i32)tmp;
+ /* following "converts" timeOffsetLength-bit signed
+ * integer into i32 */
+ /*lint -save -e701 -e702 */
+ itmp <<= (32 - timeOffsetLength);
+ itmp >>= (32 - timeOffsetLength);
+ /*lint -restore */
+ pPicTiming->timeOffset[i] = itmp;
+ }
+ else
+ pPicTiming->timeOffset[i] = 0;
+ }
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodePanScanRectangle
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodePanScanRectangle(
+ strmData_t *pStrmData,
+ seiPanScanRect_t *pPanScanRectangle)
+{
+
+/* Variables */
+
+ u32 tmp, i;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pPanScanRectangle);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pPanScanRectangle->panScanRectId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pPanScanRectangle->panScanRectCancelFlag = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (!pPanScanRectangle->panScanRectCancelFlag)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pPanScanRectangle->panScanCnt);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pPanScanRectangle->panScanCnt > 2)
+ return(HANTRO_NOK);
+ pPanScanRectangle->panScanCnt++;
+
+ for (i = 0; i < pPanScanRectangle->panScanCnt; i++)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData,
+ &pPanScanRectangle->panScanRectLeftOffset[i]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData,
+ &pPanScanRectangle->panScanRectRightOffset[i]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData,
+ &pPanScanRectangle->panScanRectTopOffset[i]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData,
+ &pPanScanRectangle->panScanRectBottomOffset[i]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pPanScanRectangle->panScanRectRepetitionPeriod);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pPanScanRectangle->panScanRectRepetitionPeriod > 16384)
+ return(HANTRO_NOK);
+ if (pPanScanRectangle->panScanCnt > 1 &&
+ pPanScanRectangle->panScanRectRepetitionPeriod > 1)
+ return(HANTRO_NOK);
+ }
+
+ return(HANTRO_OK);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeFillerPayload
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeFillerPayload(strmData_t *pStrmData, u32 payloadSize)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStrmData);
+
+
+ if (payloadSize)
+ if (h264bsdFlushBits(pStrmData, 8 * payloadSize) == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeUserDataRegisteredITuTT35
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeUserDataRegisteredITuTT35(
+ strmData_t *pStrmData,
+ seiUserDataRegisteredItuTT35_t *pUserDataRegisteredItuTT35,
+ u32 payloadSize)
+{
+
+/* Variables */
+
+ u32 tmp, i, j;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pUserDataRegisteredItuTT35);
+ ASSERT(payloadSize);
+
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pUserDataRegisteredItuTT35->ituTT35CountryCode = tmp;
+
+ if (pUserDataRegisteredItuTT35->ituTT35CountryCode != 0xFF)
+ i = 1;
+ else
+ {
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pUserDataRegisteredItuTT35->ituTT35CountryCodeExtensionByte = tmp;
+ i = 2;
+ }
+
+ /* where corresponding FREE() ??? */
+ ALLOCATE(pUserDataRegisteredItuTT35->ituTT35PayloadByte,payloadSize-i,u8);
+ pUserDataRegisteredItuTT35->numPayloadBytes = payloadSize - i;
+ if (pUserDataRegisteredItuTT35->ituTT35PayloadByte == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+
+ j = 0;
+ do
+ {
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pUserDataRegisteredItuTT35->ituTT35PayloadByte[j] = (u8)tmp;
+ i++;
+ j++;
+ } while (i < payloadSize);
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeUserDataUnregistered
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeUserDataUnregistered(
+ strmData_t *pStrmData,
+ seiUserDataUnregistered_t *pUserDataUnregistered,
+ u32 payloadSize)
+{
+
+/* Variables */
+
+ u32 i, tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pUserDataUnregistered);
+
+
+ for (i = 0; i < 4; i++)
+ {
+ pUserDataUnregistered->uuidIsoIec11578[i] = h264bsdShowBits32(pStrmData);
+ if (h264bsdFlushBits(pStrmData,32) == END_OF_STREAM)
+ return(HANTRO_NOK);
+ }
+
+ /* where corresponding FREE() ??? */
+ ALLOCATE(pUserDataUnregistered->userDataPayloadByte, payloadSize - 16, u8);
+ if (pUserDataUnregistered->userDataPayloadByte == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+
+ pUserDataUnregistered->numPayloadBytes = payloadSize - 16;
+
+ for (i = 0; i < payloadSize - 16; i++)
+ {
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pUserDataUnregistered->userDataPayloadByte[i] = (u8)tmp;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeRecoveryPoint
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeRecoveryPoint(
+ strmData_t *pStrmData,
+ seiRecoveryPoint_t *pRecoveryPoint)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pRecoveryPoint);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pRecoveryPoint->recoveryFrameCnt);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pRecoveryPoint->exactMatchFlag = tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pRecoveryPoint->brokenLinkFlag = tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 2);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp > 2)
+ return(HANTRO_NOK);
+ pRecoveryPoint->changingSliceGroupIdc = tmp;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeDecRefPicMarkingRepetition
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeDecRefPicMarkingRepetition(
+ strmData_t *pStrmData,
+ seiDecRefPicMarkingRepetition_t *pDecRefPicMarkingRepetition,
+ u32 numRefFrames)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pDecRefPicMarkingRepetition);
+
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pDecRefPicMarkingRepetition->originalIdrFlag = tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pDecRefPicMarkingRepetition->originalFrameNum);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* frame_mbs_only_flag assumed always true so some field related syntax
+ * elements are skipped, see H.264 standard */
+ // tmp = h264bsdDecRefPicMarking(pStrmData,
+ // &pDecRefPicMarkingRepetition->decRefPicMarking, NAL_SEI, numRefFrames);
+ return(HANTRO_NOK);
+
+ return(tmp);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeSparePic
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeSparePic(
+ strmData_t *pStrmData,
+ seiSparePic_t *pSparePic,
+ u32 picSizeInMapUnits)
+{
+
+/* Variables */
+
+ u32 tmp, i, j, mapUnitCnt;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSparePic);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSparePic->targetFrameNum);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSparePic->spareFieldFlag = tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+ /* do not accept fields */
+ if (pSparePic->spareFieldFlag)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &pSparePic->numSparePics);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSparePic->numSparePics++;
+ if (pSparePic->numSparePics > MAX_NUM_SPARE_PICS)
+ return(HANTRO_NOK);
+
+ for (i = 0; i < pSparePic->numSparePics; i++)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSparePic->deltaSpareFrameNum[i]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSparePic->spareAreaIdc[i]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pSparePic->spareAreaIdc[i] > 2)
+ return(HANTRO_NOK);
+
+ if (pSparePic->spareAreaIdc[i] == 1)
+ {
+ /* where corresponding FREE() ??? */
+ ALLOCATE(pSparePic->spareUnitFlag[i], picSizeInMapUnits, u32);
+ if (pSparePic->spareUnitFlag[i] == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+ pSparePic->zeroRunLength[i] = NULL;
+
+ for (j = 0; j < picSizeInMapUnits; j++)
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSparePic->spareUnitFlag[i][j] = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+ }
+ }
+ else if (pSparePic->spareAreaIdc[i] == 2)
+ {
+ /* where corresponding FREE() ??? */
+ ALLOCATE(pSparePic->zeroRunLength[i], picSizeInMapUnits, u32);
+ if (pSparePic->zeroRunLength[i] == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+ pSparePic->spareUnitFlag[i] = NULL;
+
+ for (j = 0, mapUnitCnt = 0; mapUnitCnt < picSizeInMapUnits; j++)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSparePic->zeroRunLength[i][j]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ mapUnitCnt += pSparePic->zeroRunLength[i][j] + 1;
+ }
+ }
+ }
+
+ /* set rest to null */
+ for (i = pSparePic->numSparePics; i < MAX_NUM_SPARE_PICS; i++)
+ {
+ pSparePic->spareUnitFlag[i] = NULL;
+ pSparePic->zeroRunLength[i] = NULL;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeSceneInfo
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeSceneInfo(
+ strmData_t *pStrmData,
+ seiSceneInfo_t *pSceneInfo)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSceneInfo);
+
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSceneInfo->sceneInfoPresentFlag = tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pSceneInfo->sceneInfoPresentFlag)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &pSceneInfo->sceneId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSceneInfo->sceneTransitionType);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pSceneInfo->sceneTransitionType > 6)
+ return(HANTRO_NOK);
+
+ if (pSceneInfo->sceneTransitionType)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSceneInfo->secondSceneId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeSubSeqInfo
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+-----------------------------------------------------------------------------*/
+
+static u32 DecodeSubSeqInfo(
+ strmData_t *pStrmData,
+ seiSubSeqInfo_t *pSubSeqInfo)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSubSeqInfo);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSubSeqInfo->subSeqLayerNum);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pSubSeqInfo->subSeqLayerNum > 255)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &pSubSeqInfo->subSeqId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pSubSeqInfo->subSeqId > 65535)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqInfo->firstRefPicFlag = tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqInfo->leadingNonRefPicFlag = tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqInfo->lastPicFlag = tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqInfo->subSeqFrameNumFlag = tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pSubSeqInfo->subSeqFrameNumFlag)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSubSeqInfo->subSeqFrameNum);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeSubSeqLayerCharacteristics
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeSubSeqLayerCharacteristics(
+ strmData_t *pStrmData,
+ seiSubSeqLayerCharacteristics_t *pSubSeqLayerCharacteristics)
+{
+
+/* Variables */
+
+ u32 tmp, i;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSubSeqLayerCharacteristics);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSubSeqLayerCharacteristics->numSubSeqLayers);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSubSeqLayerCharacteristics->numSubSeqLayers++;
+ if (pSubSeqLayerCharacteristics->numSubSeqLayers > MAX_NUM_SUB_SEQ_LAYERS)
+ return(HANTRO_NOK);
+
+ for (i = 0; i < pSubSeqLayerCharacteristics->numSubSeqLayers; i++)
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqLayerCharacteristics->accurateStatisticsFlag[i] =
+ tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 16);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqLayerCharacteristics->averageBitRate[i] = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 16);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqLayerCharacteristics->averageFrameRate[i] = tmp;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeSubSeqCharacteristics
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeSubSeqCharacteristics(
+ strmData_t *pStrmData,
+ seiSubSeqCharacteristics_t *pSubSeqCharacteristics)
+{
+
+/* Variables */
+
+ u32 tmp, i;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSubSeqCharacteristics);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSubSeqCharacteristics->subSeqLayerNum);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pSubSeqCharacteristics->subSeqLayerNum > MAX_NUM_SUB_SEQ_LAYERS-1)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSubSeqCharacteristics->subSeqId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pSubSeqCharacteristics->subSeqId > 65535)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqCharacteristics->durationFlag = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pSubSeqCharacteristics->durationFlag)
+ {
+ pSubSeqCharacteristics->subSeqDuration = h264bsdShowBits32(pStrmData);
+ if (h264bsdFlushBits(pStrmData,32) == END_OF_STREAM)
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqCharacteristics->averageRateFlag = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pSubSeqCharacteristics->averageRateFlag)
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqCharacteristics->accurateStatisticsFlag =
+ tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 16);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqCharacteristics->averageBitRate = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 16);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqCharacteristics->averageFrameRate = tmp;
+ }
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSubSeqCharacteristics->numReferencedSubseqs);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pSubSeqCharacteristics->numReferencedSubseqs > MAX_NUM_SUB_SEQ_LAYERS-1)
+ return(HANTRO_NOK);
+
+ for (i = 0; i < pSubSeqCharacteristics->numReferencedSubseqs; i++)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSubSeqCharacteristics->refSubSeqLayerNum[i]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSubSeqCharacteristics->refSubSeqId[i]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSubSeqCharacteristics->refSubSeqDirection[i] = tmp;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeFullFrameFreeze
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeFullFrameFreeze(
+ strmData_t *pStrmData,
+ seiFullFrameFreeze_t *pFullFrameFreeze)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pFullFrameFreeze);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pFullFrameFreeze->fullFrameFreezeRepetitionPeriod);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pFullFrameFreeze->fullFrameFreezeRepetitionPeriod > 16384)
+ return(HANTRO_NOK);
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeFullFrameSnapshot
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeFullFrameSnapshot(
+ strmData_t *pStrmData,
+ seiFullFrameSnapshot_t *pFullFrameSnapshot)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pFullFrameSnapshot);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pFullFrameSnapshot->snapShotId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeProgressiveRefinementSegmentStart
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeProgressiveRefinementSegmentStart(
+ strmData_t *pStrmData,
+ seiProgressiveRefinementSegmentStart_t *pProgressiveRefinementSegmentStart)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pProgressiveRefinementSegmentStart);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pProgressiveRefinementSegmentStart->progressiveRefinementId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pProgressiveRefinementSegmentStart->numRefinementSteps);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pProgressiveRefinementSegmentStart->numRefinementSteps++;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeProgressiveRefinementSegmentEnd
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeProgressiveRefinementSegmentEnd(
+ strmData_t *pStrmData,
+ seiProgressiveRefinementSegmentEnd_t *pProgressiveRefinementSegmentEnd)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pProgressiveRefinementSegmentEnd);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pProgressiveRefinementSegmentEnd->progressiveRefinementId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeMotionConstrainedSliceGroupSet
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeMotionConstrainedSliceGroupSet(
+ strmData_t *pStrmData,
+ seiMotionConstrainedSliceGroupSet_t *pMotionConstrainedSliceGroupSet,
+ u32 numSliceGroups)
+{
+
+/* Variables */
+
+ u32 tmp,i;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pMotionConstrainedSliceGroupSet);
+ ASSERT(numSliceGroups < MAX_NUM_SLICE_GROUPS);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pMotionConstrainedSliceGroupSet->numSliceGroupsInSet);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pMotionConstrainedSliceGroupSet->numSliceGroupsInSet++;
+ if (pMotionConstrainedSliceGroupSet->numSliceGroupsInSet > numSliceGroups)
+ return(HANTRO_NOK);
+
+ for (i = 0; i < pMotionConstrainedSliceGroupSet->numSliceGroupsInSet; i++)
+ {
+ tmp = h264bsdGetBits(pStrmData,
+ ceilLog2NumSliceGroups[numSliceGroups]);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pMotionConstrainedSliceGroupSet->sliceGroupId[i] = tmp;
+ if (pMotionConstrainedSliceGroupSet->sliceGroupId[i] >
+ pMotionConstrainedSliceGroupSet->numSliceGroupsInSet-1)
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pMotionConstrainedSliceGroupSet->exactSampleValueMatchFlag =
+ tmp == 1 ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pMotionConstrainedSliceGroupSet->panScanRectFlag = tmp == 1 ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pMotionConstrainedSliceGroupSet->panScanRectFlag)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pMotionConstrainedSliceGroupSet->panScanRectId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeReservedSeiMessage
+
+ Functional description:
+ <++>
+ Inputs:
+ <++>
+ Outputs:
+ <++>
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeReservedSeiMessage(
+ strmData_t *pStrmData,
+ seiReservedSeiMessage_t *pReservedSeiMessage,
+ u32 payloadSize)
+{
+
+/* Variables */
+
+ u32 i, tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pReservedSeiMessage);
+
+
+ /* where corresponding FREE() ??? */
+ ALLOCATE(pReservedSeiMessage->reservedSeiMessagePayloadByte,payloadSize,u8);
+ if (pReservedSeiMessage->reservedSeiMessagePayloadByte == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+
+ pReservedSeiMessage->numPayloadBytes = payloadSize;
+
+ for (i = 0; i < payloadSize; i++)
+ {
+ tmp = h264bsdGetBits(pStrmData,8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pReservedSeiMessage->reservedSeiMessagePayloadByte[i] = (u8)tmp;
+ }
+
+ return(HANTRO_OK);
+
+}
+
--- /dev/null
+++ b/src/h264bsd_sei.h
@@ -1,0 +1,253 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_SEI_H
+#define H264SWDEC_SEI_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_seq_param_set.h"
+#include "h264bsd_vui.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+#define MAX_PAN_SCAN_CNT 32
+#define MAX_NUM_SPARE_PICS 16
+#define MAX_NUM_CLOCK_TS 3
+#define MAX_NUM_SUB_SEQ_LAYERS 256
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+typedef struct
+{
+ u32 seqParameterSetId;
+ u32 initialCpbRemovalDelay[MAX_CPB_CNT];
+ u32 initialCpbRemovalDelayOffset[MAX_CPB_CNT];
+} seiBufferingPeriod_t;
+
+typedef struct
+{
+ u32 cpbRemovalDelay;
+ u32 dpbOutputDelay;
+ u32 picStruct;
+ u32 clockTimeStampFlag[MAX_NUM_CLOCK_TS];
+ u32 clockTimeStamp[MAX_NUM_CLOCK_TS];
+ u32 ctType[MAX_NUM_CLOCK_TS];
+ u32 nuitFieldBasedFlag[MAX_NUM_CLOCK_TS];
+ u32 countingType[MAX_NUM_CLOCK_TS];
+ u32 fullTimeStampFlag[MAX_NUM_CLOCK_TS];
+ u32 discontinuityFlag[MAX_NUM_CLOCK_TS];
+ u32 cntDroppedFlag[MAX_NUM_CLOCK_TS];
+ u32 nFrames[MAX_NUM_CLOCK_TS];
+ u32 secondsFlag[MAX_NUM_CLOCK_TS];
+ u32 secondsValue[MAX_NUM_CLOCK_TS];
+ u32 minutesFlag[MAX_NUM_CLOCK_TS];
+ u32 minutesValue[MAX_NUM_CLOCK_TS];
+ u32 hoursFlag[MAX_NUM_CLOCK_TS];
+ u32 hoursValue[MAX_NUM_CLOCK_TS];
+ i32 timeOffset[MAX_NUM_CLOCK_TS];
+} seiPicTiming_t;
+
+typedef struct
+{
+ u32 panScanRectId;
+ u32 panScanRectCancelFlag;
+ u32 panScanCnt;
+ i32 panScanRectLeftOffset[MAX_PAN_SCAN_CNT];
+ i32 panScanRectRightOffset[MAX_PAN_SCAN_CNT];
+ i32 panScanRectTopOffset[MAX_PAN_SCAN_CNT];
+ i32 panScanRectBottomOffset[MAX_PAN_SCAN_CNT];
+ u32 panScanRectRepetitionPeriod;
+} seiPanScanRect_t;
+
+typedef struct
+{
+ u32 ituTT35CountryCode;
+ u32 ituTT35CountryCodeExtensionByte;
+ u8 *ituTT35PayloadByte;
+ u32 numPayloadBytes;
+} seiUserDataRegisteredItuTT35_t;
+
+typedef struct
+{
+ u32 uuidIsoIec11578[4];
+ u8 *userDataPayloadByte;
+ u32 numPayloadBytes;
+} seiUserDataUnregistered_t;
+
+typedef struct
+{
+ u32 recoveryFrameCnt;
+ u32 exactMatchFlag;
+ u32 brokenLinkFlag;
+ u32 changingSliceGroupIdc;
+} seiRecoveryPoint_t;
+
+typedef struct
+{
+ u32 originalIdrFlag;
+ u32 originalFrameNum;
+ decRefPicMarking_t decRefPicMarking;
+} seiDecRefPicMarkingRepetition_t;
+
+typedef struct
+{
+ u32 targetFrameNum;
+ u32 spareFieldFlag;
+ u32 targetBottomFieldFlag;
+ u32 numSparePics;
+ u32 deltaSpareFrameNum[MAX_NUM_SPARE_PICS];
+ u32 spareBottomFieldFlag[MAX_NUM_SPARE_PICS];
+ u32 spareAreaIdc[MAX_NUM_SPARE_PICS];
+ u32 *spareUnitFlag[MAX_NUM_SPARE_PICS];
+ u32 *zeroRunLength[MAX_NUM_SPARE_PICS];
+} seiSparePic_t;
+
+typedef struct
+{
+ u32 sceneInfoPresentFlag;
+ u32 sceneId;
+ u32 sceneTransitionType;
+ u32 secondSceneId;
+} seiSceneInfo_t;
+
+typedef struct
+{
+ u32 subSeqLayerNum;
+ u32 subSeqId;
+ u32 firstRefPicFlag;
+ u32 leadingNonRefPicFlag;
+ u32 lastPicFlag;
+ u32 subSeqFrameNumFlag;
+ u32 subSeqFrameNum;
+} seiSubSeqInfo_t;
+
+typedef struct
+{
+ u32 numSubSeqLayers;
+ u32 accurateStatisticsFlag[MAX_NUM_SUB_SEQ_LAYERS];
+ u32 averageBitRate[MAX_NUM_SUB_SEQ_LAYERS];
+ u32 averageFrameRate[MAX_NUM_SUB_SEQ_LAYERS];
+} seiSubSeqLayerCharacteristics_t;
+
+typedef struct
+{
+ u32 subSeqLayerNum;
+ u32 subSeqId;
+ u32 durationFlag;
+ u32 subSeqDuration;
+ u32 averageRateFlag;
+ u32 accurateStatisticsFlag;
+ u32 averageBitRate;
+ u32 averageFrameRate;
+ u32 numReferencedSubseqs;
+ u32 refSubSeqLayerNum[MAX_NUM_SUB_SEQ_LAYERS];
+ u32 refSubSeqId[MAX_NUM_SUB_SEQ_LAYERS];
+ u32 refSubSeqDirection[MAX_NUM_SUB_SEQ_LAYERS];
+} seiSubSeqCharacteristics_t;
+
+typedef struct
+{
+ u32 fullFrameFreezeRepetitionPeriod;
+} seiFullFrameFreeze_t;
+
+typedef struct
+{
+ u32 snapShotId;
+} seiFullFrameSnapshot_t;
+
+typedef struct
+{
+ u32 progressiveRefinementId;
+ u32 numRefinementSteps;
+} seiProgressiveRefinementSegmentStart_t;
+
+typedef struct
+{
+ u32 progressiveRefinementId;
+} seiProgressiveRefinementSegmentEnd_t;
+
+typedef struct
+{
+ u32 numSliceGroupsInSet;
+ u32 sliceGroupId[MAX_NUM_SLICE_GROUPS];
+ u32 exactSampleValueMatchFlag;
+ u32 panScanRectFlag;
+ u32 panScanRectId;
+} seiMotionConstrainedSliceGroupSet_t;
+
+typedef struct
+{
+ u8 *reservedSeiMessagePayloadByte;
+ u32 numPayloadBytes;
+} seiReservedSeiMessage_t;
+
+typedef struct
+{
+ u32 payloadType;
+ seiBufferingPeriod_t bufferingPeriod;
+ seiPicTiming_t picTiming;
+ seiPanScanRect_t panScanRect;
+ seiUserDataRegisteredItuTT35_t userDataRegisteredItuTT35;
+ seiUserDataUnregistered_t userDataUnregistered;
+ seiRecoveryPoint_t recoveryPoint;
+ seiDecRefPicMarkingRepetition_t decRefPicMarkingRepetition;
+ seiSparePic_t sparePic;
+ seiSceneInfo_t sceneInfo;
+ seiSubSeqInfo_t subSeqInfo;
+ seiSubSeqLayerCharacteristics_t subSeqLayerCharacteristics;
+ seiSubSeqCharacteristics_t subSeqCharacteristics;
+ seiFullFrameFreeze_t fullFrameFreeze;
+ seiFullFrameSnapshot_t fullFrameSnapshot;
+ seiProgressiveRefinementSegmentStart_t progressiveRefinementSegmentStart;
+ seiProgressiveRefinementSegmentEnd_t progressiveRefinementSegmentEnd;
+ seiMotionConstrainedSliceGroupSet_t motionConstrainedSliceGroupSet;
+ seiReservedSeiMessage_t reservedSeiMessage;
+} seiMessage_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeSeiMessage(
+ strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet,
+ seiMessage_t *pSeiMessage,
+ u32 numSliceGroups);
+
+#endif /* #ifdef H264SWDEC_SEI_H */
+
--- /dev/null
+++ b/src/h264bsd_seq_param_set.c
@@ -1,0 +1,578 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodeSeqParamSet
+ GetDpbSize
+ h264bsdCompareSeqParamSets
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_seq_param_set.h"
+#include "h264bsd_util.h"
+#include "h264bsd_vlc.h"
+#include "h264bsd_vui.h"
+#include "h264bsd_cfg.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* enumeration to indicate invalid return value from the GetDpbSize function */
+enum {INVALID_DPB_SIZE = 0x7FFFFFFF};
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 GetDpbSize(u32 picSizeInMbs, u32 levelIdc);
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdDecodeSeqParamSet
+
+ Functional description:
+ Decode sequence parameter set information from the stream.
+
+ Function allocates memory for offsetForRefFrame array if
+ picture order count type is 1 and numRefFramesInPicOrderCntCycle
+ is greater than zero.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ pSeqParamSet decoded information is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, invalid information or end of stream
+ MEMORY_ALLOCATION_ERROR for memory allocation failure
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeSeqParamSet(strmData_t *pStrmData, seqParamSet_t *pSeqParamSet)
+{
+
+/* Variables */
+
+ u32 tmp, i, value;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSeqParamSet);
+
+ memset(pSeqParamSet, 0, sizeof(seqParamSet_t));
+
+ /* profile_idc */
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp != 66)
+ {
+ DEBUG(("NOT BASELINE PROFILE %d\n", tmp));
+ }
+ pSeqParamSet->profileIdc = tmp;
+
+ /* constrained_set0_flag */
+ tmp = h264bsdGetBits(pStrmData, 1);
+ /* constrained_set1_flag */
+ tmp = h264bsdGetBits(pStrmData, 1);
+ /* constrained_set2_flag */
+ tmp = h264bsdGetBits(pStrmData, 1);
+
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ /* reserved_zero_5bits, values of these bits shall be ignored */
+ tmp = h264bsdGetBits(pStrmData, 5);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSeqParamSet->levelIdc = tmp;
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSeqParamSet->seqParameterSetId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pSeqParamSet->seqParameterSetId >= MAX_NUM_SEQ_PARAM_SETS)
+ {
+ EPRINT("seq_param_set_id");
+ return(HANTRO_NOK);
+ }
+
+ /* log2_max_frame_num_minus4 */
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (value > 12)
+ {
+ EPRINT("log2_max_frame_num_minus4");
+ return(HANTRO_NOK);
+ }
+ /* maxFrameNum = 2^(log2_max_frame_num_minus4 + 4) */
+ pSeqParamSet->maxFrameNum = 1 << (value+4);
+
+ /* valid POC types are 0, 1 and 2 */
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (value > 2)
+ {
+ EPRINT("pic_order_cnt_type");
+ return(HANTRO_NOK);
+ }
+ pSeqParamSet->picOrderCntType = value;
+
+ if (pSeqParamSet->picOrderCntType == 0)
+ {
+ /* log2_max_pic_order_cnt_lsb_minus4 */
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (value > 12)
+ {
+ EPRINT("log2_max_pic_order_cnt_lsb_minus4");
+ return(HANTRO_NOK);
+ }
+ /* maxPicOrderCntLsb = 2^(log2_max_pic_order_cnt_lsb_minus4 + 4) */
+ pSeqParamSet->maxPicOrderCntLsb = 1 << (value+4);
+ }
+ else if (pSeqParamSet->picOrderCntType == 1)
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSeqParamSet->deltaPicOrderAlwaysZeroFlag = (tmp == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData,
+ &pSeqParamSet->offsetForNonRefPic);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData,
+ &pSeqParamSet->offsetForTopToBottomField);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSeqParamSet->numRefFramesInPicOrderCntCycle);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pSeqParamSet->numRefFramesInPicOrderCntCycle > 255)
+ {
+ EPRINT("num_ref_frames_in_pic_order_cnt_cycle");
+ return(HANTRO_NOK);
+ }
+
+ if (pSeqParamSet->numRefFramesInPicOrderCntCycle)
+ {
+ /* NOTE: This has to be freed somewhere! */
+ ALLOCATE(pSeqParamSet->offsetForRefFrame,
+ pSeqParamSet->numRefFramesInPicOrderCntCycle, i32);
+ if (pSeqParamSet->offsetForRefFrame == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+
+ for (i = 0; i < pSeqParamSet->numRefFramesInPicOrderCntCycle; i++)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData,
+ pSeqParamSet->offsetForRefFrame + i);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ }
+ else
+ {
+ pSeqParamSet->offsetForRefFrame = NULL;
+ }
+ }
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSeqParamSet->numRefFrames);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pSeqParamSet->numRefFrames > MAX_NUM_REF_PICS)
+ {
+ EPRINT("num_ref_frames");
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSeqParamSet->gapsInFrameNumValueAllowedFlag = (tmp == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSeqParamSet->picWidthInMbs = value + 1;
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSeqParamSet->picHeightInMbs = value + 1;
+
+ /* frame_mbs_only_flag, shall be 1 for baseline profile */
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (!tmp)
+ {
+ EPRINT("frame_mbs_only_flag");
+ return(HANTRO_NOK);
+ }
+
+ /* direct_8x8_inference_flag */
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSeqParamSet->frameCroppingFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pSeqParamSet->frameCroppingFlag)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSeqParamSet->frameCropLeftOffset);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSeqParamSet->frameCropRightOffset);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSeqParamSet->frameCropTopOffset);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pSeqParamSet->frameCropBottomOffset);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* check that frame cropping params are valid, parameters shall
+ * specify non-negative area within the original picture */
+ if ( ( (i32)pSeqParamSet->frameCropLeftOffset >
+ ( 8 * (i32)pSeqParamSet->picWidthInMbs -
+ ((i32)pSeqParamSet->frameCropRightOffset + 1) ) ) ||
+ ( (i32)pSeqParamSet->frameCropTopOffset >
+ ( 8 * (i32)pSeqParamSet->picHeightInMbs -
+ ((i32)pSeqParamSet->frameCropBottomOffset + 1) ) ) )
+ {
+ EPRINT("frame_cropping");
+ return(HANTRO_NOK);
+ }
+ }
+
+ /* check that image dimensions and levelIdc match */
+ tmp = pSeqParamSet->picWidthInMbs * pSeqParamSet->picHeightInMbs;
+ value = GetDpbSize(tmp, pSeqParamSet->levelIdc);
+ if (value == INVALID_DPB_SIZE || pSeqParamSet->numRefFrames > value)
+ {
+ DEBUG(("WARNING! Invalid DPB size based on SPS Level!\n"));
+ DEBUG(("WARNING! Using num_ref_frames =%d for DPB size!\n",
+ pSeqParamSet->numRefFrames));
+ value = pSeqParamSet->numRefFrames;
+ }
+ pSeqParamSet->maxDpbSize = value;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSeqParamSet->vuiParametersPresentFlag = (tmp == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ /* VUI */
+ if (pSeqParamSet->vuiParametersPresentFlag)
+ {
+ ALLOCATE(pSeqParamSet->vuiParameters, 1, vuiParameters_t);
+ if (pSeqParamSet->vuiParameters == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+ tmp = h264bsdDecodeVuiParameters(pStrmData,
+ pSeqParamSet->vuiParameters);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ /* check numReorderFrames and maxDecFrameBuffering */
+ if (pSeqParamSet->vuiParameters->bitstreamRestrictionFlag)
+ {
+ if (pSeqParamSet->vuiParameters->numReorderFrames >
+ pSeqParamSet->vuiParameters->maxDecFrameBuffering ||
+ pSeqParamSet->vuiParameters->maxDecFrameBuffering <
+ pSeqParamSet->numRefFrames ||
+ pSeqParamSet->vuiParameters->maxDecFrameBuffering >
+ pSeqParamSet->maxDpbSize)
+ {
+ return(HANTRO_NOK);
+ }
+
+ /* standard says that "the sequence shall not require a DPB with
+ * size of more than max(1, maxDecFrameBuffering) */
+ pSeqParamSet->maxDpbSize =
+ MAX(1, pSeqParamSet->vuiParameters->maxDecFrameBuffering);
+ }
+ }
+
+ tmp = h264bsdRbspTrailingBits(pStrmData);
+
+ /* ignore possible errors in trailing bits of parameters sets */
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: GetDpbSize
+
+ Functional description:
+ Get size of the DPB in frames. Size is determined based on the
+ picture size and MaxDPB for the specified level. These determine
+ how many pictures may fit into to the buffer. However, the size
+ is also limited to a maximum of 16 frames and therefore function
+ returns the minimum of the determined size and 16.
+
+ Inputs:
+ picSizeInMbs number of macroblocks in the picture
+ levelIdc indicates the level
+
+ Outputs:
+ none
+
+ Returns:
+ size of the DPB in frames
+ INVALID_DPB_SIZE when invalid levelIdc specified or picSizeInMbs
+ is higher than supported by the level in question
+
+------------------------------------------------------------------------------*/
+
+u32 GetDpbSize(u32 picSizeInMbs, u32 levelIdc)
+{
+
+/* Variables */
+
+ u32 tmp;
+ u32 maxPicSizeInMbs;
+
+/* Code */
+
+ ASSERT(picSizeInMbs);
+
+ /* use tmp as the size of the DPB in bytes, computes as 1024 * MaxDPB
+ * (from table A-1 in Annex A) */
+ switch (levelIdc)
+ {
+ case 10:
+ tmp = 152064;
+ maxPicSizeInMbs = 99;
+ break;
+
+ case 11:
+ tmp = 345600;
+ maxPicSizeInMbs = 396;
+ break;
+
+ case 12:
+ tmp = 912384;
+ maxPicSizeInMbs = 396;
+ break;
+
+ case 13:
+ tmp = 912384;
+ maxPicSizeInMbs = 396;
+ break;
+
+ case 20:
+ tmp = 912384;
+ maxPicSizeInMbs = 396;
+ break;
+
+ case 21:
+ tmp = 1824768;
+ maxPicSizeInMbs = 792;
+ break;
+
+ case 22:
+ tmp = 3110400;
+ maxPicSizeInMbs = 1620;
+ break;
+
+ case 30:
+ tmp = 3110400;
+ maxPicSizeInMbs = 1620;
+ break;
+
+ case 31:
+ tmp = 6912000;
+ maxPicSizeInMbs = 3600;
+ break;
+
+ case 32:
+ tmp = 7864320;
+ maxPicSizeInMbs = 5120;
+ break;
+
+ case 40:
+ tmp = 12582912;
+ maxPicSizeInMbs = 8192;
+ break;
+
+ case 41:
+ tmp = 12582912;
+ maxPicSizeInMbs = 8192;
+ break;
+
+ case 42:
+ tmp = 34816*384;
+ maxPicSizeInMbs = 8704;
+ break;
+
+ case 50:
+ /* standard says 42301440 here, but corrigendum "corrects" this to
+ * 42393600 */
+ tmp = 42393600;
+ maxPicSizeInMbs = 22080;
+ break;
+
+ case 51:
+ tmp = 70778880;
+ maxPicSizeInMbs = 36864;
+ break;
+
+ default:
+ return(INVALID_DPB_SIZE);
+ }
+
+ /* this is not "correct" return value! However, it results in error in
+ * decoding and this was easiest place to check picture size */
+ if (picSizeInMbs > maxPicSizeInMbs)
+ return(INVALID_DPB_SIZE);
+
+ tmp /= (picSizeInMbs*384);
+
+ return(MIN(tmp, 16));
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdCompareSeqParamSets
+
+ Functional description:
+ Compare two sequence parameter sets.
+
+ Inputs:
+ pSps1 pointer to a sequence parameter set
+ pSps2 pointer to another sequence parameter set
+
+ Outputs:
+ 0 sequence parameter sets are equal
+ 1 otherwise
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCompareSeqParamSets(seqParamSet_t *pSps1, seqParamSet_t *pSps2)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(pSps1);
+ ASSERT(pSps2);
+
+ /* first compare parameters whose existence does not depend on other
+ * parameters and only compare the rest of the params if these are equal */
+ if (pSps1->profileIdc == pSps2->profileIdc &&
+ pSps1->levelIdc == pSps2->levelIdc &&
+ pSps1->maxFrameNum == pSps2->maxFrameNum &&
+ pSps1->picOrderCntType == pSps2->picOrderCntType &&
+ pSps1->numRefFrames == pSps2->numRefFrames &&
+ pSps1->gapsInFrameNumValueAllowedFlag ==
+ pSps2->gapsInFrameNumValueAllowedFlag &&
+ pSps1->picWidthInMbs == pSps2->picWidthInMbs &&
+ pSps1->picHeightInMbs == pSps2->picHeightInMbs &&
+ pSps1->frameCroppingFlag == pSps2->frameCroppingFlag &&
+ pSps1->vuiParametersPresentFlag == pSps2->vuiParametersPresentFlag)
+ {
+ if (pSps1->picOrderCntType == 0)
+ {
+ if (pSps1->maxPicOrderCntLsb != pSps2->maxPicOrderCntLsb)
+ return 1;
+ }
+ else if (pSps1->picOrderCntType == 1)
+ {
+ if (pSps1->deltaPicOrderAlwaysZeroFlag !=
+ pSps2->deltaPicOrderAlwaysZeroFlag ||
+ pSps1->offsetForNonRefPic != pSps2->offsetForNonRefPic ||
+ pSps1->offsetForTopToBottomField !=
+ pSps2->offsetForTopToBottomField ||
+ pSps1->numRefFramesInPicOrderCntCycle !=
+ pSps2->numRefFramesInPicOrderCntCycle)
+ {
+ return 1;
+ }
+ else
+ {
+ for (i = 0; i < pSps1->numRefFramesInPicOrderCntCycle; i++)
+ if (pSps1->offsetForRefFrame[i] !=
+ pSps2->offsetForRefFrame[i])
+ {
+ return 1;
+ }
+ }
+ }
+ if (pSps1->frameCroppingFlag)
+ {
+ if (pSps1->frameCropLeftOffset != pSps2->frameCropLeftOffset ||
+ pSps1->frameCropRightOffset != pSps2->frameCropRightOffset ||
+ pSps1->frameCropTopOffset != pSps2->frameCropTopOffset ||
+ pSps1->frameCropBottomOffset != pSps2->frameCropBottomOffset)
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+ }
+
+ return 1;
+}
+
--- /dev/null
+++ b/src/h264bsd_seq_param_set.h
@@ -1,0 +1,87 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_SEQ_PARAM_SET_H
+#define H264SWDEC_SEQ_PARAM_SET_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+#include "h264bsd_vui.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/* structure to store sequence parameter set information decoded from the
+ * stream */
+typedef struct
+{
+ u32 profileIdc;
+ u32 levelIdc;
+ u32 seqParameterSetId;
+ u32 maxFrameNum;
+ u32 picOrderCntType;
+ u32 maxPicOrderCntLsb;
+ u32 deltaPicOrderAlwaysZeroFlag;
+ i32 offsetForNonRefPic;
+ i32 offsetForTopToBottomField;
+ u32 numRefFramesInPicOrderCntCycle;
+ i32 *offsetForRefFrame;
+ u32 numRefFrames;
+ u32 gapsInFrameNumValueAllowedFlag;
+ u32 picWidthInMbs;
+ u32 picHeightInMbs;
+ u32 frameCroppingFlag;
+ u32 frameCropLeftOffset;
+ u32 frameCropRightOffset;
+ u32 frameCropTopOffset;
+ u32 frameCropBottomOffset;
+ u32 vuiParametersPresentFlag;
+ vuiParameters_t *vuiParameters;
+ u32 maxDpbSize;
+} seqParamSet_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeSeqParamSet(strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet);
+
+u32 h264bsdCompareSeqParamSets(seqParamSet_t *pSps1, seqParamSet_t *pSps2);
+
+#endif /* #ifdef H264SWDEC_SEQ_PARAM_SET_H */
+
--- /dev/null
+++ b/src/h264bsd_slice_data.c
@@ -1,0 +1,355 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodeSliceData
+ SetMbParams
+ h264bsdMarkSliceCorrupted
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_slice_data.h"
+#include "h264bsd_util.h"
+#include "h264bsd_vlc.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static void SetMbParams(mbStorage_t *pMb, sliceHeader_t *pSlice, u32 sliceId,
+ i32 chromaQpIndexOffset);
+
+/*------------------------------------------------------------------------------
+
+ 5.1 Function name: h264bsdDecodeSliceData
+
+ Functional description:
+ Decode one slice. Function decodes stream data, i.e. macroblocks
+ and possible skip_run fields. h264bsdDecodeMacroblock function is
+ called to handle all other macroblock related processing.
+ Macroblock to slice group mapping is considered when next
+ macroblock to process is determined (h264bsdNextMbAddress function)
+ map
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ pStorage pointer to storage structure
+ currImage pointer to current processed picture, needed for
+ intra prediction of the macroblocks
+ pSliceHeader pointer to slice header of the current slice
+
+ Outputs:
+ currImage processed macroblocks are written to current image
+ pStorage mbStorage structure of each processed macroblock
+ is updated here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeSliceData(strmData_t *pStrmData, storage_t *pStorage,
+ image_t *currImage, sliceHeader_t *pSliceHeader)
+{
+
+/* Variables */
+
+ u8 mbData[384 + 15 + 32];
+ u8 *data;
+ u32 tmp;
+ u32 skipRun;
+ u32 prevSkipped;
+ u32 currMbAddr;
+ u32 moreMbs;
+ u32 mbCount;
+ i32 qpY;
+ macroblockLayer_t *mbLayer;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSliceHeader);
+ ASSERT(pStorage);
+ ASSERT(pSliceHeader->firstMbInSlice < pStorage->picSizeInMbs);
+
+ /* ensure 16-byte alignment */
+ data = (u8*)ALIGN(mbData, 16);
+
+ mbLayer = pStorage->mbLayer;
+
+ currMbAddr = pSliceHeader->firstMbInSlice;
+ skipRun = 0;
+ prevSkipped = HANTRO_FALSE;
+
+ /* increment slice index, will be one for decoding of the first slice of
+ * the picture */
+ pStorage->slice->sliceId++;
+
+ /* lastMbAddr stores address of the macroblock that was last successfully
+ * decoded, needed for error handling */
+ pStorage->slice->lastMbAddr = 0;
+
+ mbCount = 0;
+ /* initial quantization parameter for the slice is obtained as the sum of
+ * initial QP for the picture and sliceQpDelta for the current slice */
+ qpY = (i32)pStorage->activePps->picInitQp + pSliceHeader->sliceQpDelta;
+ do
+ {
+ /* primary picture and already decoded macroblock -> error */
+ if (!pSliceHeader->redundantPicCnt && pStorage->mb[currMbAddr].decoded)
+ {
+ EPRINT("Primary and already decoded");
+ return(HANTRO_NOK);
+ }
+
+ SetMbParams(pStorage->mb + currMbAddr, pSliceHeader,
+ pStorage->slice->sliceId, pStorage->activePps->chromaQpIndexOffset);
+
+ if (!IS_I_SLICE(pSliceHeader->sliceType))
+ {
+ if (!prevSkipped)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &skipRun);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ /* skip_run shall be less than or equal to number of
+ * macroblocks left */
+ if (skipRun > (pStorage->picSizeInMbs - currMbAddr))
+ {
+ EPRINT("skip_run");
+ return(HANTRO_NOK);
+ }
+ if (skipRun)
+ {
+ prevSkipped = HANTRO_TRUE;
+ memset(&mbLayer->mbPred, 0, sizeof(mbPred_t));
+ /* mark current macroblock skipped */
+ mbLayer->mbType = P_Skip;
+ }
+ }
+ }
+
+ if (skipRun)
+ {
+ DEBUG(("Skipping macroblock %d\n", currMbAddr));
+ skipRun--;
+ }
+ else
+ {
+ prevSkipped = HANTRO_FALSE;
+ tmp = h264bsdDecodeMacroblockLayer(pStrmData, mbLayer,
+ pStorage->mb + currMbAddr, pSliceHeader->sliceType,
+ pSliceHeader->numRefIdxL0Active);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("macroblock_layer");
+ return(tmp);
+ }
+ }
+
+ tmp = h264bsdDecodeMacroblock(pStorage->mb + currMbAddr, mbLayer,
+ currImage, pStorage->dpb, &qpY, currMbAddr,
+ pStorage->activePps->constrainedIntraPredFlag, data);
+ if (tmp != HANTRO_OK)
+ {
+ EPRINT("MACRO_BLOCK");
+ return(tmp);
+ }
+
+ /* increment macroblock count only for macroblocks that were decoded
+ * for the first time (redundant slices) */
+ if (pStorage->mb[currMbAddr].decoded == 1)
+ mbCount++;
+
+ /* keep on processing as long as there is stream data left or
+ * processing of macroblocks to be skipped based on the last skipRun is
+ * not finished */
+ moreMbs = (h264bsdMoreRbspData(pStrmData) || skipRun) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ /* lastMbAddr is only updated for intra slices (all macroblocks of
+ * inter slices will be lost in case of an error) */
+ if (IS_I_SLICE(pSliceHeader->sliceType))
+ pStorage->slice->lastMbAddr = currMbAddr;
+
+ currMbAddr = h264bsdNextMbAddress(pStorage->sliceGroupMap,
+ pStorage->picSizeInMbs, currMbAddr);
+ /* data left in the buffer but no more macroblocks for current slice
+ * group -> error */
+ if (moreMbs && !currMbAddr)
+ {
+ EPRINT("Next mb address");
+ return(HANTRO_NOK);
+ }
+
+ } while (moreMbs);
+
+ if ((pStorage->slice->numDecodedMbs + mbCount) > pStorage->picSizeInMbs)
+ {
+ EPRINT("Num decoded mbs");
+ return(HANTRO_NOK);
+ }
+
+ pStorage->slice->numDecodedMbs += mbCount;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ 5.2 Function: SetMbParams
+
+ Functional description:
+ Set macroblock parameters that remain constant for this slice
+
+ Inputs:
+ pSlice pointer to current slice header
+ sliceId id of the current slice
+ chromaQpIndexOffset
+
+ Outputs:
+ pMb pointer to macroblock structure which is updated
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void SetMbParams(mbStorage_t *pMb, sliceHeader_t *pSlice, u32 sliceId,
+ i32 chromaQpIndexOffset)
+{
+
+/* Variables */
+ u32 tmp1;
+ i32 tmp2, tmp3;
+
+/* Code */
+
+ tmp1 = pSlice->disableDeblockingFilterIdc;
+ tmp2 = pSlice->sliceAlphaC0Offset;
+ tmp3 = pSlice->sliceBetaOffset;
+ pMb->sliceId = sliceId;
+ pMb->disableDeblockingFilterIdc = tmp1;
+ pMb->filterOffsetA = tmp2;
+ pMb->filterOffsetB = tmp3;
+ pMb->chromaQpIndexOffset = chromaQpIndexOffset;
+
+}
+
+/*------------------------------------------------------------------------------
+
+ 5.3 Function name: h264bsdMarkSliceCorrupted
+
+ Functional description:
+ Mark macroblocks of the slice corrupted. If lastMbAddr in the slice
+ storage is set -> picWidhtInMbs (or at least 10) macroblocks back
+ from the lastMbAddr are marked corrupted. However, if lastMbAddr
+ is not set -> all macroblocks of the slice are marked.
+
+ Inputs:
+ pStorage pointer to storage structure
+ firstMbInSlice address of the first macroblock in the slice, this
+ identifies the slice to be marked corrupted
+
+ Outputs:
+ pStorage mbStorage for the corrupted macroblocks updated
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdMarkSliceCorrupted(storage_t *pStorage, u32 firstMbInSlice)
+{
+
+/* Variables */
+
+ u32 tmp, i;
+ u32 sliceId;
+ u32 currMbAddr;
+
+/* Code */
+
+ ASSERT(pStorage);
+ ASSERT(firstMbInSlice < pStorage->picSizeInMbs);
+
+ currMbAddr = firstMbInSlice;
+
+ sliceId = pStorage->slice->sliceId;
+
+ /* DecodeSliceData sets lastMbAddr for I slices -> if it was set, go back
+ * MAX(picWidthInMbs, 10) macroblocks and start marking from there */
+ if (pStorage->slice->lastMbAddr)
+ {
+ ASSERT(pStorage->mb[pStorage->slice->lastMbAddr].sliceId == sliceId);
+ i = pStorage->slice->lastMbAddr - 1;
+ tmp = 0;
+ while (i > currMbAddr)
+ {
+ if (pStorage->mb[i].sliceId == sliceId)
+ {
+ tmp++;
+ if (tmp >= MAX(pStorage->activeSps->picWidthInMbs, 10))
+ break;
+ }
+ i--;
+ }
+ currMbAddr = i;
+ }
+
+ do
+ {
+
+ if ( (pStorage->mb[currMbAddr].sliceId == sliceId) &&
+ (pStorage->mb[currMbAddr].decoded) )
+ {
+ pStorage->mb[currMbAddr].decoded--;
+ }
+ else
+ {
+ break;
+ }
+
+ currMbAddr = h264bsdNextMbAddress(pStorage->sliceGroupMap,
+ pStorage->picSizeInMbs, currMbAddr);
+
+ } while (currMbAddr);
+
+}
+
--- /dev/null
+++ b/src/h264bsd_slice_data.h
@@ -1,0 +1,60 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_SLICE_DATA_H
+#define H264SWDEC_SLICE_DATA_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+#include "h264bsd_cfg.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_storage.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeSliceData(strmData_t *pStrmData, storage_t *pStorage,
+ image_t *currImage, sliceHeader_t *pSliceHeader);
+
+void h264bsdMarkSliceCorrupted(storage_t *pStorage, u32 firstMbInSlice);
+
+#endif /* #ifdef H264SWDEC_SLICE_DATA_H */
+
--- /dev/null
+++ b/src/h264bsd_slice_group_map.c
@@ -1,0 +1,590 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ DecodeInterleavedMap
+ DecodeDispersedMap
+ DecodeForegroundLeftOverMap
+ DecodeBoxOutMap
+ DecodeRasterScanMap
+ DecodeWipeMap
+ h264bsdDecodeSliceGroupMap
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_slice_group_map.h"
+#include "h264bsd_cfg.h"
+#include "h264bsd_pic_param_set.h"
+#include "h264bsd_util.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static void DecodeInterleavedMap(
+ u32 *map,
+ u32 numSliceGroups,
+ u32 *runLength,
+ u32 picSize);
+
+static void DecodeDispersedMap(
+ u32 *map,
+ u32 numSliceGroups,
+ u32 picWidth,
+ u32 picHeight);
+
+static void DecodeForegroundLeftOverMap(
+ u32 *map,
+ u32 numSliceGroups,
+ u32 *topLeft,
+ u32 *bottomRight,
+ u32 picWidth,
+ u32 picHeight);
+
+static void DecodeBoxOutMap(
+ u32 *map,
+ u32 sliceGroupChangeDirectionFlag,
+ u32 unitsInSliceGroup0,
+ u32 picWidth,
+ u32 picHeight);
+
+static void DecodeRasterScanMap(
+ u32 *map,
+ u32 sliceGroupChangeDirectionFlag,
+ u32 sizeOfUpperLeftGroup,
+ u32 picSize);
+
+static void DecodeWipeMap(
+ u32 *map,
+ u32 sliceGroupChangeDirectionFlag,
+ u32 sizeOfUpperLeftGroup,
+ u32 picWidth,
+ u32 picHeight);
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeInterleavedMap
+
+ Functional description:
+ Function to decode interleaved slice group map type, i.e. slice
+ group map type 0.
+
+ Inputs:
+ map pointer to the map
+ numSliceGroups number of slice groups
+ runLength run_length[] values for each slice group
+ picSize picture size in macroblocks
+
+ Outputs:
+ map slice group map is stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void DecodeInterleavedMap(
+ u32 *map,
+ u32 numSliceGroups,
+ u32 *runLength,
+ u32 picSize)
+{
+
+/* Variables */
+
+ u32 i,j, group;
+
+/* Code */
+
+ ASSERT(map);
+ ASSERT(numSliceGroups >= 1 && numSliceGroups <= MAX_NUM_SLICE_GROUPS);
+ ASSERT(runLength);
+
+ i = 0;
+
+ do {
+ for (group = 0; group < numSliceGroups && i < picSize;
+ i += runLength[group++])
+ {
+ ASSERT(runLength[group] <= picSize);
+ for (j = 0; j < runLength[group] && i + j < picSize; j++)
+ map[i+j] = group;
+ }
+ } while (i < picSize);
+
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeDispersedMap
+
+ Functional description:
+ Function to decode dispersed slice group map type, i.e. slice
+ group map type 1.
+
+ Inputs:
+ map pointer to the map
+ numSliceGroups number of slice groups
+ picWidth picture width in macroblocks
+ picHeight picture height in macroblocks
+
+ Outputs:
+ map slice group map is stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void DecodeDispersedMap(
+ u32 *map,
+ u32 numSliceGroups,
+ u32 picWidth,
+ u32 picHeight)
+{
+
+/* Variables */
+
+ u32 i, picSize;
+
+/* Code */
+
+ ASSERT(map);
+ ASSERT(numSliceGroups >= 1 && numSliceGroups <= MAX_NUM_SLICE_GROUPS);
+ ASSERT(picWidth);
+ ASSERT(picHeight);
+
+ picSize = picWidth * picHeight;
+
+ for (i = 0; i < picSize; i++)
+ map[i] = ((i % picWidth) + (((i / picWidth) * numSliceGroups) >> 1)) %
+ numSliceGroups;
+
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeForegroundLeftOverMap
+
+ Functional description:
+ Function to decode foreground with left-over slice group map type,
+ i.e. slice group map type 2.
+
+ Inputs:
+ map pointer to the map
+ numSliceGroups number of slice groups
+ topLeft top_left[] values
+ bottomRight bottom_right[] values
+ picWidth picture width in macroblocks
+ picHeight picture height in macroblocks
+
+ Outputs:
+ map slice group map is stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void DecodeForegroundLeftOverMap(
+ u32 *map,
+ u32 numSliceGroups,
+ u32 *topLeft,
+ u32 *bottomRight,
+ u32 picWidth,
+ u32 picHeight)
+{
+
+/* Variables */
+
+ u32 i,y,x,yTopLeft,yBottomRight,xTopLeft,xBottomRight, picSize;
+ u32 group;
+
+/* Code */
+
+ ASSERT(map);
+ ASSERT(numSliceGroups >= 1 && numSliceGroups <= MAX_NUM_SLICE_GROUPS);
+ ASSERT(topLeft);
+ ASSERT(bottomRight);
+ ASSERT(picWidth);
+ ASSERT(picHeight);
+
+ picSize = picWidth * picHeight;
+
+ for (i = 0; i < picSize; i++)
+ map[i] = numSliceGroups - 1;
+
+ for (group = numSliceGroups - 1; group--; )
+ {
+ ASSERT( topLeft[group] <= bottomRight[group] &&
+ bottomRight[group] < picSize );
+ yTopLeft = topLeft[group] / picWidth;
+ xTopLeft = topLeft[group] % picWidth;
+ yBottomRight = bottomRight[group] / picWidth;
+ xBottomRight = bottomRight[group] % picWidth;
+ ASSERT(xTopLeft <= xBottomRight);
+
+ for (y = yTopLeft; y <= yBottomRight; y++)
+ for (x = xTopLeft; x <= xBottomRight; x++)
+ map[ y * picWidth + x ] = group;
+ }
+
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeBoxOutMap
+
+ Functional description:
+ Function to decode box-out slice group map type, i.e. slice group
+ map type 3.
+
+ Inputs:
+ map pointer to the map
+ sliceGroupChangeDirectionFlag slice_group_change_direction_flag
+ unitsInSliceGroup0 mbs on slice group 0
+ picWidth picture width in macroblocks
+ picHeight picture height in macroblocks
+
+ Outputs:
+ map slice group map is stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void DecodeBoxOutMap(
+ u32 *map,
+ u32 sliceGroupChangeDirectionFlag,
+ u32 unitsInSliceGroup0,
+ u32 picWidth,
+ u32 picHeight)
+{
+
+/* Variables */
+
+ u32 i, k, picSize;
+ i32 x, y, xDir, yDir, leftBound, topBound, rightBound, bottomBound;
+ u32 mapUnitVacant;
+
+/* Code */
+
+ ASSERT(map);
+ ASSERT(picWidth);
+ ASSERT(picHeight);
+
+ picSize = picWidth * picHeight;
+ ASSERT(unitsInSliceGroup0 <= picSize);
+
+ for (i = 0; i < picSize; i++)
+ map[i] = 1;
+
+ x = (picWidth - (u32)sliceGroupChangeDirectionFlag) >> 1;
+ y = (picHeight - (u32)sliceGroupChangeDirectionFlag) >> 1;
+
+ leftBound = x;
+ topBound = y;
+
+ rightBound = x;
+ bottomBound = y;
+
+ xDir = (i32)sliceGroupChangeDirectionFlag - 1;
+ yDir = (i32)sliceGroupChangeDirectionFlag;
+
+ for (k = 0; k < unitsInSliceGroup0; k += mapUnitVacant ? 1 : 0)
+ {
+ mapUnitVacant = (map[ (u32)y * picWidth + (u32)x ] == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (mapUnitVacant)
+ map[ (u32)y * picWidth + (u32)x ] = 0;
+
+ if (xDir == -1 && x == leftBound)
+ {
+ leftBound = MAX(leftBound - 1, 0);
+ x = leftBound;
+ xDir = 0;
+ yDir = 2 * (i32)sliceGroupChangeDirectionFlag - 1;
+ }
+ else if (xDir == 1 && x == rightBound)
+ {
+ rightBound = MIN(rightBound + 1, (i32)picWidth - 1);
+ x = rightBound;
+ xDir = 0;
+ yDir = 1 - 2 * (i32)sliceGroupChangeDirectionFlag;
+ }
+ else if (yDir == -1 && y == topBound)
+ {
+ topBound = MAX(topBound - 1, 0);
+ y = topBound;
+ xDir = 1 - 2 * (i32)sliceGroupChangeDirectionFlag;
+ yDir = 0;
+ }
+ else if (yDir == 1 && y == bottomBound)
+ {
+ bottomBound = MIN(bottomBound + 1, (i32)picHeight - 1);
+ y = bottomBound;
+ xDir = 2 * (i32)sliceGroupChangeDirectionFlag - 1;
+ yDir = 0;
+ }
+ else
+ {
+ x += xDir;
+ y += yDir;
+ }
+ }
+
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeRasterScanMap
+
+ Functional description:
+ Function to decode raster scan slice group map type, i.e. slice
+ group map type 4.
+
+ Inputs:
+ map pointer to the map
+ sliceGroupChangeDirectionFlag slice_group_change_direction_flag
+ sizeOfUpperLeftGroup mbs in upperLeftGroup
+ picSize picture size in macroblocks
+
+ Outputs:
+ map slice group map is stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void DecodeRasterScanMap(
+ u32 *map,
+ u32 sliceGroupChangeDirectionFlag,
+ u32 sizeOfUpperLeftGroup,
+ u32 picSize)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(map);
+ ASSERT(picSize);
+ ASSERT(sizeOfUpperLeftGroup <= picSize);
+
+ for (i = 0; i < picSize; i++)
+ if (i < sizeOfUpperLeftGroup)
+ map[i] = (u32)sliceGroupChangeDirectionFlag;
+ else
+ map[i] = 1 - (u32)sliceGroupChangeDirectionFlag;
+
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeWipeMap
+
+ Functional description:
+ Function to decode wipe slice group map type, i.e. slice group map
+ type 5.
+
+ Inputs:
+ sliceGroupChangeDirectionFlag slice_group_change_direction_flag
+ sizeOfUpperLeftGroup mbs in upperLeftGroup
+ picWidth picture width in macroblocks
+ picHeight picture height in macroblocks
+
+ Outputs:
+ map slice group map is stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void DecodeWipeMap(
+ u32 *map,
+ u32 sliceGroupChangeDirectionFlag,
+ u32 sizeOfUpperLeftGroup,
+ u32 picWidth,
+ u32 picHeight)
+{
+
+/* Variables */
+
+ u32 i,j,k;
+
+/* Code */
+
+ ASSERT(map);
+ ASSERT(picWidth);
+ ASSERT(picHeight);
+ ASSERT(sizeOfUpperLeftGroup <= picWidth * picHeight);
+
+ k = 0;
+ for (j = 0; j < picWidth; j++)
+ for (i = 0; i < picHeight; i++)
+ if (k++ < sizeOfUpperLeftGroup)
+ map[ i * picWidth + j ] = (u32)sliceGroupChangeDirectionFlag;
+ else
+ map[ i * picWidth + j ] = 1 -
+ (u32)sliceGroupChangeDirectionFlag;
+
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdDecodeSliceGroupMap
+
+ Functional description:
+ Function to decode macroblock to slice group map. Construction
+ of different slice group map types is handled by separate
+ functions defined above. See standard for details how slice group
+ maps are computed.
+
+ Inputs:
+ pps active picture parameter set
+ sliceGroupChangeCycle slice_group_change_cycle
+ picWidth picture width in macroblocks
+ picHeight picture height in macroblocks
+
+ Outputs:
+ map slice group map is stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdDecodeSliceGroupMap(
+ u32 *map,
+ picParamSet_t *pps,
+ u32 sliceGroupChangeCycle,
+ u32 picWidth,
+ u32 picHeight)
+{
+
+/* Variables */
+
+ u32 i, picSize, unitsInSliceGroup0 = 0, sizeOfUpperLeftGroup = 0;
+
+/* Code */
+
+ ASSERT(map);
+ ASSERT(pps);
+ ASSERT(picWidth);
+ ASSERT(picHeight);
+ ASSERT(pps->sliceGroupMapType < 7);
+
+ picSize = picWidth * picHeight;
+
+ /* just one slice group -> all macroblocks belong to group 0 */
+ if (pps->numSliceGroups == 1)
+ {
+ memset(map, 0, picSize * sizeof(u32));
+ return;
+ }
+
+ if (pps->sliceGroupMapType > 2 && pps->sliceGroupMapType < 6)
+ {
+ ASSERT(pps->sliceGroupChangeRate &&
+ pps->sliceGroupChangeRate <= picSize);
+
+ unitsInSliceGroup0 =
+ MIN(sliceGroupChangeCycle * pps->sliceGroupChangeRate, picSize);
+
+ if (pps->sliceGroupMapType == 4 || pps->sliceGroupMapType == 5)
+ sizeOfUpperLeftGroup = pps->sliceGroupChangeDirectionFlag ?
+ (picSize - unitsInSliceGroup0) : unitsInSliceGroup0;
+ }
+
+ switch (pps->sliceGroupMapType)
+ {
+ case 0:
+ DecodeInterleavedMap(map, pps->numSliceGroups,
+ pps->runLength, picSize);
+ break;
+
+ case 1:
+ DecodeDispersedMap(map, pps->numSliceGroups, picWidth,
+ picHeight);
+ break;
+
+ case 2:
+ DecodeForegroundLeftOverMap(map, pps->numSliceGroups,
+ pps->topLeft, pps->bottomRight, picWidth, picHeight);
+ break;
+
+ case 3:
+ DecodeBoxOutMap(map, pps->sliceGroupChangeDirectionFlag,
+ unitsInSliceGroup0, picWidth, picHeight);
+ break;
+
+ case 4:
+ DecodeRasterScanMap(map,
+ pps->sliceGroupChangeDirectionFlag, sizeOfUpperLeftGroup,
+ picSize);
+ break;
+
+ case 5:
+ DecodeWipeMap(map, pps->sliceGroupChangeDirectionFlag,
+ sizeOfUpperLeftGroup, picWidth, picHeight);
+ break;
+
+ default:
+ ASSERT(pps->sliceGroupId);
+ for (i = 0; i < picSize; i++)
+ {
+ ASSERT(pps->sliceGroupId[i] < pps->numSliceGroups);
+ map[i] = pps->sliceGroupId[i];
+ }
+ break;
+ }
+
+}
+
--- /dev/null
+++ b/src/h264bsd_slice_group_map.h
@@ -1,0 +1,61 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_SLICE_GROUP_MAP_H
+#define H264SWDEC_SLICE_GROUP_MAP_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_pic_param_set.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+void h264bsdDecodeSliceGroupMap(
+ u32 *map,
+ picParamSet_t *pps,
+ u32 sliceGroupChangeCycle,
+ u32 picWidth,
+ u32 picHeight);
+
+#endif /* #ifdef H264SWDEC_SLICE_GROUP_MAP_H */
+
--- /dev/null
+++ b/src/h264bsd_slice_header.c
@@ -1,0 +1,1512 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodeSliceHeader
+ NumSliceGroupChangeCycleBits
+ RefPicListReordering
+ DecRefPicMarking
+ CheckPpsId
+ CheckFrameNum
+ CheckIdrPicId
+ CheckPicOrderCntLsb
+ CheckDeltaPicOrderCntBottom
+ CheckDeltaPicOrderCnt
+ CheckRedundantPicCnt
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_slice_header.h"
+#include "h264bsd_util.h"
+#include "h264bsd_vlc.h"
+#include "h264bsd_nal_unit.h"
+#include "h264bsd_dpb.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 RefPicListReordering(strmData_t *, refPicListReordering_t *,
+ u32, u32);
+
+static u32 NumSliceGroupChangeCycleBits(u32 picSizeInMbs,
+ u32 sliceGroupChangeRate);
+
+static u32 DecRefPicMarking(strmData_t *pStrmData,
+ decRefPicMarking_t *pDecRefPicMarking, nalUnitType_e nalUnitType,
+ u32 numRefFrames);
+
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdDecodeSliceHeader
+
+ Functional description:
+ Decode slice header data from the stream.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ pSeqParamSet pointer to active sequence parameter set
+ pPicParamSet pointer to active picture parameter set
+ pNalUnit pointer to current NAL unit structure
+
+ Outputs:
+ pSliceHeader decoded data is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data or end of stream
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeSliceHeader(strmData_t *pStrmData, sliceHeader_t *pSliceHeader,
+ seqParamSet_t *pSeqParamSet, picParamSet_t *pPicParamSet,
+ nalUnit_t *pNalUnit)
+{
+
+/* Variables */
+
+ u32 tmp, i, value;
+ i32 itmp;
+ u32 picSizeInMbs;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSliceHeader);
+ ASSERT(pSeqParamSet);
+ ASSERT(pPicParamSet);
+ ASSERT( pNalUnit->nalUnitType == NAL_CODED_SLICE ||
+ pNalUnit->nalUnitType == NAL_CODED_SLICE_IDR );
+
+
+ memset(pSliceHeader, 0, sizeof(sliceHeader_t));
+
+ picSizeInMbs = pSeqParamSet->picWidthInMbs * pSeqParamSet->picHeightInMbs;
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSliceHeader->firstMbInSlice = value;
+ if (value >= picSizeInMbs)
+ {
+ EPRINT("first_mb_in_slice");
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSliceHeader->sliceType = value;
+ /* slice type has to be either I or P slice. P slice is not allowed when
+ * current NAL unit is an IDR NAL unit or num_ref_frames is 0 */
+ if ( !IS_I_SLICE(pSliceHeader->sliceType) &&
+ ( !IS_P_SLICE(pSliceHeader->sliceType) ||
+ IS_IDR_NAL_UNIT(pNalUnit) ||
+ !pSeqParamSet->numRefFrames ) )
+ {
+ EPRINT("slice_type");
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSliceHeader->picParameterSetId = value;
+ if (pSliceHeader->picParameterSetId != pPicParamSet->picParameterSetId)
+ {
+ EPRINT("pic_parameter_set_id");
+ return(HANTRO_NOK);
+ }
+
+ /* log2(maxFrameNum) -> num bits to represent frame_num */
+ i = 0;
+ while (pSeqParamSet->maxFrameNum >> i)
+ i++;
+ i--;
+
+ tmp = h264bsdGetBits(pStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (IS_IDR_NAL_UNIT(pNalUnit) && tmp != 0)
+ {
+ EPRINT("frame_num");
+ return(HANTRO_NOK);
+ }
+ pSliceHeader->frameNum = tmp;
+
+ if (IS_IDR_NAL_UNIT(pNalUnit))
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSliceHeader->idrPicId = value;
+ if (value > 65535)
+ {
+ EPRINT("idr_pic_id");
+ return(HANTRO_NOK);
+ }
+ }
+
+ if (pSeqParamSet->picOrderCntType == 0)
+ {
+ /* log2(maxPicOrderCntLsb) -> num bits to represent pic_order_cnt_lsb */
+ i = 0;
+ while (pSeqParamSet->maxPicOrderCntLsb >> i)
+ i++;
+ i--;
+
+ tmp = h264bsdGetBits(pStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSliceHeader->picOrderCntLsb = tmp;
+
+ if (pPicParamSet->picOrderPresentFlag)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSliceHeader->deltaPicOrderCntBottom = itmp;
+ }
+
+ /* check that picOrderCnt for IDR picture will be zero. See
+ * DecodePicOrderCnt function to understand the logic here */
+ if ( IS_IDR_NAL_UNIT(pNalUnit) &&
+ ( (pSliceHeader->picOrderCntLsb >
+ pSeqParamSet->maxPicOrderCntLsb/2) ||
+ MIN((i32)pSliceHeader->picOrderCntLsb,
+ (i32)pSliceHeader->picOrderCntLsb +
+ pSliceHeader->deltaPicOrderCntBottom) != 0 ) )
+ {
+ return(HANTRO_NOK);
+ }
+ }
+
+ if ( (pSeqParamSet->picOrderCntType == 1) &&
+ !pSeqParamSet->deltaPicOrderAlwaysZeroFlag )
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSliceHeader->deltaPicOrderCnt[0] = itmp;
+
+ if (pPicParamSet->picOrderPresentFlag)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSliceHeader->deltaPicOrderCnt[1] = itmp;
+ }
+
+ /* check that picOrderCnt for IDR picture will be zero. See
+ * DecodePicOrderCnt function to understand the logic here */
+ if ( IS_IDR_NAL_UNIT(pNalUnit) &&
+ MIN(pSliceHeader->deltaPicOrderCnt[0],
+ pSliceHeader->deltaPicOrderCnt[0] +
+ pSeqParamSet->offsetForTopToBottomField +
+ pSliceHeader->deltaPicOrderCnt[1]) != 0)
+ {
+ return(HANTRO_NOK);
+ }
+ }
+
+ if (pPicParamSet->redundantPicCntPresentFlag)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSliceHeader->redundantPicCnt = value;
+ if (value > 127)
+ {
+ EPRINT("redundant_pic_cnt");
+ return(HANTRO_NOK);
+ }
+ }
+
+ if (IS_P_SLICE(pSliceHeader->sliceType))
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSliceHeader->numRefIdxActiveOverrideFlag = tmp;
+
+ if (pSliceHeader->numRefIdxActiveOverrideFlag)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (value > 15)
+ {
+ EPRINT("num_ref_idx_l0_active_minus1");
+ return(HANTRO_NOK);
+ }
+ pSliceHeader->numRefIdxL0Active = value + 1;
+ }
+ /* set numRefIdxL0Active from pic param set */
+ else
+ {
+ /* if value (minus1) in picture parameter set exceeds 15 it should
+ * have been overridden here */
+ if (pPicParamSet->numRefIdxL0Active > 16)
+ {
+ EPRINT("num_ref_idx_active_override_flag");
+ return(HANTRO_NOK);
+ }
+ pSliceHeader->numRefIdxL0Active = pPicParamSet->numRefIdxL0Active;
+ }
+ }
+
+ if (IS_P_SLICE(pSliceHeader->sliceType))
+ {
+ tmp = RefPicListReordering(pStrmData,
+ &pSliceHeader->refPicListReordering,
+ pSliceHeader->numRefIdxL0Active,
+ pSeqParamSet->maxFrameNum);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ if (pNalUnit->nalRefIdc != 0)
+ {
+ tmp = DecRefPicMarking(pStrmData, &pSliceHeader->decRefPicMarking,
+ pNalUnit->nalUnitType, pSeqParamSet->numRefFrames);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ /* decode sliceQpDelta and check that initial QP for the slice will be on
+ * the range [0, 51] */
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSliceHeader->sliceQpDelta = itmp;
+ itmp += (i32)pPicParamSet->picInitQp;
+ if ( (itmp < 0) || (itmp > 51) )
+ {
+ EPRINT("slice_qp_delta");
+ return(HANTRO_NOK);
+ }
+
+ if (pPicParamSet->deblockingFilterControlPresentFlag)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSliceHeader->disableDeblockingFilterIdc = value;
+ if (pSliceHeader->disableDeblockingFilterIdc > 2)
+ {
+ EPRINT("disable_deblocking_filter_idc");
+ return(HANTRO_NOK);
+ }
+
+ if (pSliceHeader->disableDeblockingFilterIdc != 1)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if ( (itmp < -6) || (itmp > 6) )
+ {
+ EPRINT("slice_alpha_c0_offset_div2");
+ return(HANTRO_NOK);
+ }
+ pSliceHeader->sliceAlphaC0Offset = itmp * 2;
+
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if ( (itmp < -6) || (itmp > 6) )
+ {
+ EPRINT("slice_beta_offset_div2");
+ return(HANTRO_NOK);
+ }
+ pSliceHeader->sliceBetaOffset = itmp * 2;
+ }
+ }
+
+ if ( (pPicParamSet->numSliceGroups > 1) &&
+ (pPicParamSet->sliceGroupMapType >= 3) &&
+ (pPicParamSet->sliceGroupMapType <= 5) )
+ {
+ /* set tmp to number of bits used to represent slice_group_change_cycle
+ * in the stream */
+ tmp = NumSliceGroupChangeCycleBits(picSizeInMbs,
+ pPicParamSet->sliceGroupChangeRate);
+ value = h264bsdGetBits(pStrmData, tmp);
+ if (value == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pSliceHeader->sliceGroupChangeCycle = value;
+
+ /* corresponds to tmp = Ceil(picSizeInMbs / sliceGroupChangeRate) */
+ tmp = (picSizeInMbs + pPicParamSet->sliceGroupChangeRate - 1) /
+ pPicParamSet->sliceGroupChangeRate;
+ if (pSliceHeader->sliceGroupChangeCycle > tmp)
+ {
+ EPRINT("slice_group_change_cycle");
+ return(HANTRO_NOK);
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: NumSliceGroupChangeCycleBits
+
+ Functional description:
+ Determine number of bits needed to represent
+ slice_group_change_cycle in the stream. The standard states that
+ slice_group_change_cycle is represented by
+ Ceil( Log2( (picSizeInMbs / sliceGroupChangeRate) + 1) )
+
+ bits. Division "/" in the equation is non-truncating division.
+
+ Inputs:
+ picSizeInMbs picture size in macroblocks
+ sliceGroupChangeRate
+
+ Outputs:
+ none
+
+ Returns:
+ number of bits needed
+
+------------------------------------------------------------------------------*/
+
+u32 NumSliceGroupChangeCycleBits(u32 picSizeInMbs, u32 sliceGroupChangeRate)
+{
+
+/* Variables */
+
+ u32 tmp,numBits,mask;
+
+/* Code */
+
+ ASSERT(picSizeInMbs);
+ ASSERT(sliceGroupChangeRate);
+ ASSERT(sliceGroupChangeRate <= picSizeInMbs);
+
+ /* compute (picSizeInMbs / sliceGroupChangeRate + 1), rounded up */
+ if (picSizeInMbs % sliceGroupChangeRate)
+ tmp = 2 + picSizeInMbs/sliceGroupChangeRate;
+ else
+ tmp = 1 + picSizeInMbs/sliceGroupChangeRate;
+
+ numBits = 0;
+ mask = ~0U;
+
+ /* set numBits to position of right-most non-zero bit */
+ while (tmp & (mask<<++numBits))
+ ;
+ numBits--;
+
+ /* add one more bit if value greater than 2^numBits */
+ if (tmp & ((1<<numBits)-1))
+ numBits++;
+
+ return(numBits);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: RefPicListReordering
+
+ Functional description:
+ Decode reference picture list reordering syntax elements from
+ the stream. Max number of reordering commands is numRefIdxActive.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ numRefIdxActive number of active reference indices to be used for
+ current slice
+ maxPicNum maxFrameNum from the active SPS
+
+ Outputs:
+ pRefPicListReordering decoded data is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 RefPicListReordering(strmData_t *pStrmData,
+ refPicListReordering_t *pRefPicListReordering, u32 numRefIdxActive,
+ u32 maxPicNum)
+{
+
+/* Variables */
+
+ u32 tmp, value, i;
+ u32 command;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pRefPicListReordering);
+ ASSERT(numRefIdxActive);
+ ASSERT(maxPicNum);
+
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ pRefPicListReordering->refPicListReorderingFlagL0 = tmp;
+
+ if (pRefPicListReordering->refPicListReorderingFlagL0)
+ {
+ i = 0;
+
+ do
+ {
+ if (i > numRefIdxActive)
+ {
+ EPRINT("Too many reordering commands");
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &command);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (command > 3)
+ {
+ EPRINT("reordering_of_pic_nums_idc");
+ return(HANTRO_NOK);
+ }
+
+ pRefPicListReordering->command[i].reorderingOfPicNumsIdc = command;
+
+ if ((command == 0) || (command == 1))
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (value >= maxPicNum)
+ {
+ EPRINT("abs_diff_pic_num_minus1");
+ return(HANTRO_NOK);
+ }
+ pRefPicListReordering->command[i].absDiffPicNum = value + 1;
+ }
+ else if (command == 2)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pRefPicListReordering->command[i].longTermPicNum = value;
+ }
+ i++;
+ } while (command != 3);
+
+ /* there shall be at least one reordering command if
+ * refPicListReorderingFlagL0 was set */
+ if (i == 1)
+ {
+ EPRINT("ref_pic_list_reordering");
+ return(HANTRO_NOK);
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecRefPicMarking
+
+ Functional description:
+ Decode decoded reference picture marking syntax elements from
+ the stream.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ nalUnitType type of the current NAL unit
+ numRefFrames max number of reference frames from the active SPS
+
+ Outputs:
+ pDecRefPicMarking decoded data is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 DecRefPicMarking(strmData_t *pStrmData,
+ decRefPicMarking_t *pDecRefPicMarking, nalUnitType_e nalUnitType,
+ u32 numRefFrames)
+{
+
+/* Variables */
+
+ u32 tmp, value;
+ u32 i;
+ u32 operation;
+ /* variables for error checking purposes, store number of memory
+ * management operations of certain type */
+ u32 num4 = 0, num5 = 0, num6 = 0, num1to3 = 0;
+
+/* Code */
+
+ ASSERT( nalUnitType == NAL_CODED_SLICE_IDR ||
+ nalUnitType == NAL_CODED_SLICE ||
+ nalUnitType == NAL_SEI );
+
+
+ if (nalUnitType == NAL_CODED_SLICE_IDR)
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pDecRefPicMarking->noOutputOfPriorPicsFlag = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pDecRefPicMarking->longTermReferenceFlag = tmp;
+ if (!numRefFrames && pDecRefPicMarking->longTermReferenceFlag)
+ {
+ EPRINT("long_term_reference_flag");
+ return(HANTRO_NOK);
+ }
+ }
+ else
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pDecRefPicMarking->adaptiveRefPicMarkingModeFlag = tmp;
+ if (pDecRefPicMarking->adaptiveRefPicMarkingModeFlag)
+ {
+ i = 0;
+ do
+ {
+ /* see explanation of the MAX_NUM_MMC_OPERATIONS in
+ * slice_header.h */
+ if (i > (2 * numRefFrames + 2))
+ {
+ EPRINT("Too many management operations");
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &operation);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (operation > 6)
+ {
+ EPRINT("memory_management_control_operation");
+ return(HANTRO_NOK);
+ }
+
+ pDecRefPicMarking->operation[i].
+ memoryManagementControlOperation = operation;
+ if ((operation == 1) || (operation == 3))
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pDecRefPicMarking->operation[i].differenceOfPicNums =
+ value + 1;
+ }
+ if (operation == 2)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pDecRefPicMarking->operation[i].longTermPicNum = value;
+ }
+ if ((operation == 3) || (operation == 6))
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pDecRefPicMarking->operation[i].longTermFrameIdx =
+ value;
+ }
+ if (operation == 4)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ /* value shall be in range [0, numRefFrames] */
+ if (value > numRefFrames)
+ {
+ EPRINT("max_long_term_frame_idx_plus1");
+ return(HANTRO_NOK);
+ }
+ if (value == 0)
+ {
+ pDecRefPicMarking->operation[i].
+ maxLongTermFrameIdx =
+ NO_LONG_TERM_FRAME_INDICES;
+ }
+ else
+ {
+ pDecRefPicMarking->operation[i].
+ maxLongTermFrameIdx = value - 1;
+ }
+ num4++;
+ }
+ if (operation == 5)
+ {
+ num5++;
+ }
+ if (operation && operation <= 3)
+ num1to3++;
+ if (operation == 6)
+ num6++;
+
+ i++;
+ } while (operation != 0);
+
+ /* error checking */
+ if (num4 > 1 || num5 > 1 || num6 > 1 || (num1to3 && num5))
+ return(HANTRO_NOK);
+
+ }
+ }
+
+ return(HANTRO_OK);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdCheckPpsId
+
+ Functional description:
+ Peek value of pic_parameter_set_id from the slice header. Function
+ does not modify current stream positions but copies the stream
+ data structure to tmp structure which is used while accessing
+ stream data.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ picParamSetId value is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckPpsId(strmData_t *pStrmData, u32 *picParamSetId)
+{
+
+/* Variables */
+
+ u32 tmp, value;
+ strmData_t tmpStrmData[1];
+
+/* Code */
+
+ ASSERT(pStrmData);
+
+ /* don't touch original stream position params */
+ *tmpStrmData = *pStrmData;
+
+ /* first_mb_in_slice */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* slice_type */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (value >= MAX_NUM_PIC_PARAM_SETS)
+ return(HANTRO_NOK);
+
+ *picParamSetId = value;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckFrameNum
+
+ Functional description:
+ Peek value of frame_num from the slice header. Function does not
+ modify current stream positions but copies the stream data
+ structure to tmp structure which is used while accessing stream
+ data.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ maxFrameNum
+
+ Outputs:
+ frameNum value is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckFrameNum(
+ strmData_t *pStrmData,
+ u32 maxFrameNum,
+ u32 *frameNum)
+{
+
+/* Variables */
+
+ u32 tmp, value, i;
+ strmData_t tmpStrmData[1];
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(maxFrameNum);
+ ASSERT(frameNum);
+
+ /* don't touch original stream position params */
+ *tmpStrmData = *pStrmData;
+
+ /* skip first_mb_in_slice */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip slice_type */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip pic_parameter_set_id */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* log2(maxFrameNum) -> num bits to represent frame_num */
+ i = 0;
+ while (maxFrameNum >> i)
+ i++;
+ i--;
+
+ /* frame_num */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ *frameNum = tmp;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckIdrPicId
+
+ Functional description:
+ Peek value of idr_pic_id from the slice header. Function does not
+ modify current stream positions but copies the stream data
+ structure to tmp structure which is used while accessing stream
+ data.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ maxFrameNum max frame number from active SPS
+ nalUnitType type of the current NAL unit
+
+ Outputs:
+ idrPicId value is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckIdrPicId(
+ strmData_t *pStrmData,
+ u32 maxFrameNum,
+ nalUnitType_e nalUnitType,
+ u32 *idrPicId)
+{
+
+/* Variables */
+
+ u32 tmp, value, i;
+ strmData_t tmpStrmData[1];
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(maxFrameNum);
+ ASSERT(idrPicId);
+
+ /* nalUnitType must be equal to 5 because otherwise idrPicId is not
+ * present */
+ if (nalUnitType != NAL_CODED_SLICE_IDR)
+ return(HANTRO_NOK);
+
+ /* don't touch original stream position params */
+ *tmpStrmData = *pStrmData;
+
+ /* skip first_mb_in_slice */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip slice_type */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip pic_parameter_set_id */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* log2(maxFrameNum) -> num bits to represent frame_num */
+ i = 0;
+ while (maxFrameNum >> i)
+ i++;
+ i--;
+
+ /* skip frame_num */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ /* idr_pic_id */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, idrPicId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckPicOrderCntLsb
+
+ Functional description:
+ Peek value of pic_order_cnt_lsb from the slice header. Function
+ does not modify current stream positions but copies the stream
+ data structure to tmp structure which is used while accessing
+ stream data.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ pSeqParamSet pointer to active SPS
+ nalUnitType type of the current NAL unit
+
+ Outputs:
+ picOrderCntLsb value is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckPicOrderCntLsb(
+ strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet,
+ nalUnitType_e nalUnitType,
+ u32 *picOrderCntLsb)
+{
+
+/* Variables */
+
+ u32 tmp, value, i;
+ strmData_t tmpStrmData[1];
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSeqParamSet);
+ ASSERT(picOrderCntLsb);
+
+ /* picOrderCntType must be equal to 0 */
+ ASSERT(pSeqParamSet->picOrderCntType == 0);
+ ASSERT(pSeqParamSet->maxFrameNum);
+ ASSERT(pSeqParamSet->maxPicOrderCntLsb);
+
+ /* don't touch original stream position params */
+ *tmpStrmData = *pStrmData;
+
+ /* skip first_mb_in_slice */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip slice_type */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip pic_parameter_set_id */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* log2(maxFrameNum) -> num bits to represent frame_num */
+ i = 0;
+ while (pSeqParamSet->maxFrameNum >> i)
+ i++;
+ i--;
+
+ /* skip frame_num */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ /* skip idr_pic_id when necessary */
+ if (nalUnitType == NAL_CODED_SLICE_IDR)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ /* log2(maxPicOrderCntLsb) -> num bits to represent pic_order_cnt_lsb */
+ i = 0;
+ while (pSeqParamSet->maxPicOrderCntLsb >> i)
+ i++;
+ i--;
+
+ /* pic_order_cnt_lsb */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ *picOrderCntLsb = tmp;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckDeltaPicOrderCntBottom
+
+ Functional description:
+ Peek value of delta_pic_order_cnt_bottom from the slice header.
+ Function does not modify current stream positions but copies the
+ stream data structure to tmp structure which is used while
+ accessing stream data.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ pSeqParamSet pointer to active SPS
+ nalUnitType type of the current NAL unit
+
+ Outputs:
+ deltaPicOrderCntBottom value is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckDeltaPicOrderCntBottom(
+ strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet,
+ nalUnitType_e nalUnitType,
+ i32 *deltaPicOrderCntBottom)
+{
+
+/* Variables */
+
+ u32 tmp, value, i;
+ strmData_t tmpStrmData[1];
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSeqParamSet);
+ ASSERT(deltaPicOrderCntBottom);
+
+ /* picOrderCntType must be equal to 0 and picOrderPresentFlag must be TRUE
+ * */
+ ASSERT(pSeqParamSet->picOrderCntType == 0);
+ ASSERT(pSeqParamSet->maxFrameNum);
+ ASSERT(pSeqParamSet->maxPicOrderCntLsb);
+
+ /* don't touch original stream position params */
+ *tmpStrmData = *pStrmData;
+
+ /* skip first_mb_in_slice */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip slice_type */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip pic_parameter_set_id */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* log2(maxFrameNum) -> num bits to represent frame_num */
+ i = 0;
+ while (pSeqParamSet->maxFrameNum >> i)
+ i++;
+ i--;
+
+ /* skip frame_num */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ /* skip idr_pic_id when necessary */
+ if (nalUnitType == NAL_CODED_SLICE_IDR)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ /* log2(maxPicOrderCntLsb) -> num bits to represent pic_order_cnt_lsb */
+ i = 0;
+ while (pSeqParamSet->maxPicOrderCntLsb >> i)
+ i++;
+ i--;
+
+ /* skip pic_order_cnt_lsb */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ /* delta_pic_order_cnt_bottom */
+ tmp = h264bsdDecodeExpGolombSigned(tmpStrmData, deltaPicOrderCntBottom);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckDeltaPicOrderCnt
+
+ Functional description:
+ Peek values delta_pic_order_cnt[0] and delta_pic_order_cnt[1]
+ from the slice header. Function does not modify current stream
+ positions but copies the stream data structure to tmp structure
+ which is used while accessing stream data.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ pSeqParamSet pointer to active SPS
+ nalUnitType type of the current NAL unit
+ picOrderPresentFlag flag indicating if delta_pic_order_cnt[1]
+ is present in the stream
+
+ Outputs:
+ deltaPicOrderCnt values are stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckDeltaPicOrderCnt(
+ strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet,
+ nalUnitType_e nalUnitType,
+ u32 picOrderPresentFlag,
+ i32 *deltaPicOrderCnt)
+{
+
+/* Variables */
+
+ u32 tmp, value, i;
+ strmData_t tmpStrmData[1];
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSeqParamSet);
+ ASSERT(deltaPicOrderCnt);
+
+ /* picOrderCntType must be equal to 1 and deltaPicOrderAlwaysZeroFlag must
+ * be FALSE */
+ ASSERT(pSeqParamSet->picOrderCntType == 1);
+ ASSERT(!pSeqParamSet->deltaPicOrderAlwaysZeroFlag);
+ ASSERT(pSeqParamSet->maxFrameNum);
+
+ /* don't touch original stream position params */
+ *tmpStrmData = *pStrmData;
+
+ /* skip first_mb_in_slice */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip slice_type */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip pic_parameter_set_id */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* log2(maxFrameNum) -> num bits to represent frame_num */
+ i = 0;
+ while (pSeqParamSet->maxFrameNum >> i)
+ i++;
+ i--;
+
+ /* skip frame_num */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ /* skip idr_pic_id when necessary */
+ if (nalUnitType == NAL_CODED_SLICE_IDR)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ /* delta_pic_order_cnt[0] */
+ tmp = h264bsdDecodeExpGolombSigned(tmpStrmData, &deltaPicOrderCnt[0]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* delta_pic_order_cnt[1] if present */
+ if (picOrderPresentFlag)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(tmpStrmData, &deltaPicOrderCnt[1]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckRedundantPicCnt
+
+ Functional description:
+ Peek value of redundant_pic_cnt from the slice header. Function
+ does not modify current stream positions but copies the stream
+ data structure to tmp structure which is used while accessing
+ stream data.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ pSeqParamSet pointer to active SPS
+ pPicParamSet pointer to active PPS
+ nalUnitType type of the current NAL unit
+
+ Outputs:
+ redundantPicCnt value is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckRedundantPicCnt(
+ strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet,
+ picParamSet_t *pPicParamSet,
+ nalUnitType_e nalUnitType,
+ u32 *redundantPicCnt)
+{
+
+/* Variables */
+
+ u32 tmp, value, i;
+ i32 ivalue;
+ strmData_t tmpStrmData[1];
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSeqParamSet);
+ ASSERT(pPicParamSet);
+ ASSERT(redundantPicCnt);
+
+ /* redundant_pic_cnt_flag must be TRUE */
+ ASSERT(pPicParamSet->redundantPicCntPresentFlag);
+ ASSERT(pSeqParamSet->maxFrameNum);
+ ASSERT(pSeqParamSet->picOrderCntType > 0 ||
+ pSeqParamSet->maxPicOrderCntLsb);
+
+ /* don't touch original stream position params */
+ *tmpStrmData = *pStrmData;
+
+ /* skip first_mb_in_slice */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip slice_type */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* skip pic_parameter_set_id */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* log2(maxFrameNum) -> num bits to represent frame_num */
+ i = 0;
+ while (pSeqParamSet->maxFrameNum >> i)
+ i++;
+ i--;
+
+ /* skip frame_num */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ /* skip idr_pic_id when necessary */
+ if (nalUnitType == NAL_CODED_SLICE_IDR)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+
+ if (pSeqParamSet->picOrderCntType == 0)
+ {
+ /* log2(maxPicOrderCntLsb) -> num bits to represent pic_order_cnt_lsb */
+ i = 0;
+ while (pSeqParamSet->maxPicOrderCntLsb >> i)
+ i++;
+ i--;
+
+ /* pic_order_cnt_lsb */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ if (pPicParamSet->picOrderPresentFlag)
+ {
+ /* skip delta_pic_order_cnt_bottom */
+ tmp = h264bsdDecodeExpGolombSigned(tmpStrmData, &ivalue);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ }
+
+ if (pSeqParamSet->picOrderCntType == 1 &&
+ !pSeqParamSet->deltaPicOrderAlwaysZeroFlag)
+ {
+ /* delta_pic_order_cnt[0] */
+ tmp = h264bsdDecodeExpGolombSigned(tmpStrmData, &ivalue);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* delta_pic_order_cnt[1] if present */
+ if (pPicParamSet->picOrderPresentFlag)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(tmpStrmData, &ivalue);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ }
+
+ /* redundant_pic_cnt */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, redundantPicCnt);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ return(HANTRO_OK);
+
+}
+
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckPriorPicsFlag
+
+ Functional description:
+ Peek value of no_output_of_prior_pics_flag from the slice header.
+ Function does not modify current stream positions but copies
+ the stream data structure to tmp structure which is used while
+ accessing stream data.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ pSeqParamSet pointer to active SPS
+ pPicParamSet pointer to active PPS
+ nalUnitType type of the current NAL unit
+
+ Outputs:
+ noOutputOfPriorPicsFlag value is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+/*lint -e715 disable lint info nalUnitType not referenced */
+u32 h264bsdCheckPriorPicsFlag(u32 * noOutputOfPriorPicsFlag,
+ const strmData_t * pStrmData,
+ const seqParamSet_t * pSeqParamSet,
+ const picParamSet_t * pPicParamSet,
+ nalUnitType_e nalUnitType)
+{
+/* Variables */
+
+ u32 tmp, value, i;
+ i32 ivalue;
+ strmData_t tmpStrmData[1];
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSeqParamSet);
+ ASSERT(pPicParamSet);
+ ASSERT(noOutputOfPriorPicsFlag);
+
+ /* must be IDR lsice */
+ ASSERT(nalUnitType == NAL_CODED_SLICE_IDR);
+
+ /* don't touch original stream position params */
+ *tmpStrmData = *pStrmData;
+
+ /* skip first_mb_in_slice */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if(tmp != HANTRO_OK)
+ return (tmp);
+
+ /* slice_type */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if(tmp != HANTRO_OK)
+ return (tmp);
+
+ /* skip pic_parameter_set_id */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if(tmp != HANTRO_OK)
+ return (tmp);
+
+ /* log2(maxFrameNum) -> num bits to represent frame_num */
+ i = 0;
+ while(pSeqParamSet->maxFrameNum >> i)
+ i++;
+ i--;
+
+ /* skip frame_num */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if(tmp == END_OF_STREAM)
+ return (HANTRO_NOK);
+
+ /* skip idr_pic_id */
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if(tmp != HANTRO_OK)
+ return (tmp);
+
+ if(pSeqParamSet->picOrderCntType == 0)
+ {
+ /* log2(maxPicOrderCntLsb) -> num bits to represent pic_order_cnt_lsb */
+ i = 0;
+ while(pSeqParamSet->maxPicOrderCntLsb >> i)
+ i++;
+ i--;
+
+ /* skip pic_order_cnt_lsb */
+ tmp = h264bsdGetBits(tmpStrmData, i);
+ if(tmp == END_OF_STREAM)
+ return (HANTRO_NOK);
+
+ if(pPicParamSet->picOrderPresentFlag)
+ {
+ /* skip delta_pic_order_cnt_bottom */
+ tmp = h264bsdDecodeExpGolombSigned(tmpStrmData, &ivalue);
+ if(tmp != HANTRO_OK)
+ return (tmp);
+ }
+ }
+
+ if(pSeqParamSet->picOrderCntType == 1 &&
+ !pSeqParamSet->deltaPicOrderAlwaysZeroFlag)
+ {
+ /* skip delta_pic_order_cnt[0] */
+ tmp = h264bsdDecodeExpGolombSigned(tmpStrmData, &ivalue);
+ if(tmp != HANTRO_OK)
+ return (tmp);
+
+ /* skip delta_pic_order_cnt[1] if present */
+ if(pPicParamSet->picOrderPresentFlag)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(tmpStrmData, &ivalue);
+ if(tmp != HANTRO_OK)
+ return (tmp);
+ }
+ }
+
+ /* skip redundant_pic_cnt */
+ if(pPicParamSet->redundantPicCntPresentFlag)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(tmpStrmData, &value);
+ if(tmp != HANTRO_OK)
+ return (tmp);
+ }
+
+ *noOutputOfPriorPicsFlag = h264bsdGetBits(tmpStrmData, 1);
+ if(*noOutputOfPriorPicsFlag == END_OF_STREAM)
+ return (HANTRO_NOK);
+
+ return (HANTRO_OK);
+
+}
+/*lint +e715 */
+
+
--- /dev/null
+++ b/src/h264bsd_slice_header.h
@@ -1,0 +1,187 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_SLICE_HEADER_H
+#define H264SWDEC_SLICE_HEADER_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+#include "h264bsd_cfg.h"
+#include "h264bsd_seq_param_set.h"
+#include "h264bsd_pic_param_set.h"
+#include "h264bsd_nal_unit.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+enum {
+ P_SLICE = 0,
+ I_SLICE = 2
+};
+
+enum {NO_LONG_TERM_FRAME_INDICES = 0xFFFF};
+
+/* macro to determine if slice is an inter slice, sliceTypes 0 and 5 */
+#define IS_P_SLICE(sliceType) (((sliceType) == P_SLICE) || \
+ ((sliceType) == P_SLICE + 5))
+
+/* macro to determine if slice is an intra slice, sliceTypes 2 and 7 */
+#define IS_I_SLICE(sliceType) (((sliceType) == I_SLICE) || \
+ ((sliceType) == I_SLICE + 5))
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/* structure to store data of one reference picture list reordering operation */
+typedef struct
+{
+ u32 reorderingOfPicNumsIdc;
+ u32 absDiffPicNum;
+ u32 longTermPicNum;
+} refPicListReorderingOperation_t;
+
+/* structure to store reference picture list reordering operations */
+typedef struct
+{
+ u32 refPicListReorderingFlagL0;
+ refPicListReorderingOperation_t command[MAX_NUM_REF_PICS+1];
+} refPicListReordering_t;
+
+/* structure to store data of one DPB memory management control operation */
+typedef struct
+{
+ u32 memoryManagementControlOperation;
+ u32 differenceOfPicNums;
+ u32 longTermPicNum;
+ u32 longTermFrameIdx;
+ u32 maxLongTermFrameIdx;
+} memoryManagementOperation_t;
+
+/* worst case scenario: all MAX_NUM_REF_PICS pictures in the buffer are
+ * short term pictures, each one of them is first marked as long term
+ * reference picture which is then marked as unused for reference.
+ * Additionally, max long-term frame index is set and current picture is
+ * marked as long term reference picture. Last position reserved for
+ * end memory_management_control_operation command */
+#define MAX_NUM_MMC_OPERATIONS (2*MAX_NUM_REF_PICS+2+1)
+
+/* structure to store decoded reference picture marking data */
+typedef struct
+{
+ u32 noOutputOfPriorPicsFlag;
+ u32 longTermReferenceFlag;
+ u32 adaptiveRefPicMarkingModeFlag;
+ memoryManagementOperation_t operation[MAX_NUM_MMC_OPERATIONS];
+} decRefPicMarking_t;
+
+/* structure to store slice header data decoded from the stream */
+typedef struct
+{
+ u32 firstMbInSlice;
+ u32 sliceType;
+ u32 picParameterSetId;
+ u32 frameNum;
+ u32 idrPicId;
+ u32 picOrderCntLsb;
+ i32 deltaPicOrderCntBottom;
+ i32 deltaPicOrderCnt[2];
+ u32 redundantPicCnt;
+ u32 numRefIdxActiveOverrideFlag;
+ u32 numRefIdxL0Active;
+ i32 sliceQpDelta;
+ u32 disableDeblockingFilterIdc;
+ i32 sliceAlphaC0Offset;
+ i32 sliceBetaOffset;
+ u32 sliceGroupChangeCycle;
+ refPicListReordering_t refPicListReordering;
+ decRefPicMarking_t decRefPicMarking;
+} sliceHeader_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeSliceHeader(strmData_t *pStrmData,
+ sliceHeader_t *pSliceHeader,
+ seqParamSet_t *pSeqParamSet,
+ picParamSet_t *pPicParamSet,
+ nalUnit_t *pNalUnit);
+
+u32 h264bsdCheckPpsId(strmData_t *pStrmData, u32 *ppsId);
+
+u32 h264bsdCheckFrameNum(
+ strmData_t *pStrmData,
+ u32 maxFrameNum,
+ u32 *frameNum);
+
+u32 h264bsdCheckIdrPicId(
+ strmData_t *pStrmData,
+ u32 maxFrameNum,
+ nalUnitType_e nalUnitType,
+ u32 *idrPicId);
+
+u32 h264bsdCheckPicOrderCntLsb(
+ strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet,
+ nalUnitType_e nalUnitType,
+ u32 *picOrderCntLsb);
+
+u32 h264bsdCheckDeltaPicOrderCntBottom(
+ strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet,
+ nalUnitType_e nalUnitType,
+ i32 *deltaPicOrderCntBottom);
+
+u32 h264bsdCheckDeltaPicOrderCnt(
+ strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet,
+ nalUnitType_e nalUnitType,
+ u32 picOrderPresentFlag,
+ i32 *deltaPicOrderCnt);
+
+u32 h264bsdCheckRedundantPicCnt(
+ strmData_t *pStrmData,
+ seqParamSet_t *pSeqParamSet,
+ picParamSet_t *pPicParamSet,
+ nalUnitType_e nalUnitType,
+ u32 *redundantPicCnt);
+
+u32 h264bsdCheckPriorPicsFlag(u32 * noOutputOfPriorPicsFlag,
+ const strmData_t * pStrmData,
+ const seqParamSet_t * pSeqParamSet,
+ const picParamSet_t * pPicParamSet,
+ nalUnitType_e nalUnitType);
+
+#endif /* #ifdef H264SWDEC_SLICE_HEADER_H */
+
--- /dev/null
+++ b/src/h264bsd_storage.c
@@ -1,0 +1,889 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdInitStorage
+ h264bsdStoreSeqParamSet
+ h264bsdStorePicParamSet
+ h264bsdActivateParamSets
+ h264bsdResetStorage
+ h264bsdIsStartOfPicture
+ h264bsdIsEndOfPicture
+ h264bsdComputeSliceGroupMap
+ h264bsdCheckAccessUnitBoundary
+ CheckPps
+ h264bsdValidParamSets
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_storage.h"
+#include "h264bsd_util.h"
+#include "h264bsd_neighbour.h"
+#include "h264bsd_slice_group_map.h"
+#include "h264bsd_dpb.h"
+#include "h264bsd_nal_unit.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_seq_param_set.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 CheckPps(picParamSet_t *pps, seqParamSet_t *sps);
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdInitStorage
+
+ Functional description:
+ Initialize storage structure. Sets contents of the storage to '0'
+ except for the active parameter set ids, which are initialized
+ to invalid values.
+
+ Inputs:
+
+ Outputs:
+ pStorage initialized data stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInitStorage(storage_t *pStorage)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ memset(pStorage, 0, sizeof(storage_t));
+
+ pStorage->activeSpsId = MAX_NUM_SEQ_PARAM_SETS;
+ pStorage->activePpsId = MAX_NUM_PIC_PARAM_SETS;
+
+ pStorage->aub->firstCallFlag = HANTRO_TRUE;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdStoreSeqParamSet
+
+ Functional description:
+ Store sequence parameter set into the storage. If active SPS is
+ overwritten -> check if contents changes and if it does, set
+ parameters to force reactivation of parameter sets
+
+ Inputs:
+ pStorage pointer to storage structure
+ pSeqParamSet pointer to param set to be stored
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_OK success
+ MEMORY_ALLOCATION_ERROR failure in memory allocation
+
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdStoreSeqParamSet(storage_t *pStorage, seqParamSet_t *pSeqParamSet)
+{
+
+/* Variables */
+
+ u32 id;
+
+/* Code */
+
+ ASSERT(pStorage);
+ ASSERT(pSeqParamSet);
+ ASSERT(pSeqParamSet->seqParameterSetId < MAX_NUM_SEQ_PARAM_SETS);
+
+ id = pSeqParamSet->seqParameterSetId;
+
+ /* seq parameter set with id not used before -> allocate memory */
+ if (pStorage->sps[id] == NULL)
+ {
+ ALLOCATE(pStorage->sps[id], 1, seqParamSet_t);
+ if (pStorage->sps[id] == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+ }
+ /* sequence parameter set with id equal to id of active sps */
+ else if (id == pStorage->activeSpsId)
+ {
+ /* if seq parameter set contents changes
+ * -> overwrite and re-activate when next IDR picture decoded
+ * ids of active param sets set to invalid values to force
+ * re-activation. Memories allocated for old sps freed
+ * otherwise free memeries allocated for just decoded sps and
+ * continue */
+ if (h264bsdCompareSeqParamSets(pSeqParamSet, pStorage->activeSps) != 0)
+ {
+ FREE(pStorage->sps[id]->offsetForRefFrame);
+ FREE(pStorage->sps[id]->vuiParameters);
+ pStorage->activeSpsId = MAX_NUM_SEQ_PARAM_SETS + 1;
+ pStorage->activePpsId = MAX_NUM_PIC_PARAM_SETS + 1;
+ pStorage->activeSps = NULL;
+ pStorage->activePps = NULL;
+ }
+ else
+ {
+ FREE(pSeqParamSet->offsetForRefFrame);
+ FREE(pSeqParamSet->vuiParameters);
+ return(HANTRO_OK);
+ }
+ }
+ /* overwrite seq param set other than active one -> free memories
+ * allocated for old param set */
+ else
+ {
+ FREE(pStorage->sps[id]->offsetForRefFrame);
+ FREE(pStorage->sps[id]->vuiParameters);
+ }
+
+ *pStorage->sps[id] = *pSeqParamSet;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdStorePicParamSet
+
+ Functional description:
+ Store picture parameter set into the storage. If active PPS is
+ overwritten -> check if active SPS changes and if it does -> set
+ parameters to force reactivation of parameter sets
+
+ Inputs:
+ pStorage pointer to storage structure
+ pPicParamSet pointer to param set to be stored
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_OK success
+ MEMORY_ALLOCATION_ERROR failure in memory allocation
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdStorePicParamSet(storage_t *pStorage, picParamSet_t *pPicParamSet)
+{
+
+/* Variables */
+
+ u32 id;
+
+/* Code */
+
+ ASSERT(pStorage);
+ ASSERT(pPicParamSet);
+ ASSERT(pPicParamSet->picParameterSetId < MAX_NUM_PIC_PARAM_SETS);
+ ASSERT(pPicParamSet->seqParameterSetId < MAX_NUM_SEQ_PARAM_SETS);
+
+ id = pPicParamSet->picParameterSetId;
+
+ /* pic parameter set with id not used before -> allocate memory */
+ if (pStorage->pps[id] == NULL)
+ {
+ ALLOCATE(pStorage->pps[id], 1, picParamSet_t);
+ if (pStorage->pps[id] == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+ }
+ /* picture parameter set with id equal to id of active pps */
+ else if (id == pStorage->activePpsId)
+ {
+ /* check whether seq param set changes, force re-activation of
+ * param set if it does. Set activeSpsId to invalid value to
+ * accomplish this */
+ if (pPicParamSet->seqParameterSetId != pStorage->activeSpsId)
+ {
+ pStorage->activePpsId = MAX_NUM_PIC_PARAM_SETS + 1;
+ }
+ /* free memories allocated for old param set */
+ FREE(pStorage->pps[id]->runLength);
+ FREE(pStorage->pps[id]->topLeft);
+ FREE(pStorage->pps[id]->bottomRight);
+ FREE(pStorage->pps[id]->sliceGroupId);
+ }
+ /* overwrite pic param set other than active one -> free memories
+ * allocated for old param set */
+ else
+ {
+ FREE(pStorage->pps[id]->runLength);
+ FREE(pStorage->pps[id]->topLeft);
+ FREE(pStorage->pps[id]->bottomRight);
+ FREE(pStorage->pps[id]->sliceGroupId);
+ }
+
+ *pStorage->pps[id] = *pPicParamSet;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdActivateParamSets
+
+ Functional description:
+ Activate certain SPS/PPS combination. This function shall be
+ called in the beginning of each picture. Picture parameter set
+ can be changed as wanted, but sequence parameter set may only be
+ changed when the starting picture is an IDR picture.
+
+ When new SPS is activated the function allocates memory for
+ macroblock storages and slice group map and (re-)initializes the
+ decoded picture buffer. If this is not the first activation the old
+ allocations are freed and FreeDpb called before new allocations.
+
+ Inputs:
+ pStorage pointer to storage data structure
+ ppsId identifies the PPS to be activated, SPS id obtained
+ from the PPS
+ isIdr flag to indicate if the picture is an IDR picture
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK non-existing or invalid param set combination,
+ trying to change SPS with non-IDR picture
+ MEMORY_ALLOCATION_ERROR failure in memory allocation
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdActivateParamSets(storage_t *pStorage, u32 ppsId, u32 isIdr)
+{
+
+/* Variables */
+
+ u32 tmp;
+ u32 flag;
+
+/* Code */
+
+ ASSERT(pStorage);
+ ASSERT(ppsId < MAX_NUM_PIC_PARAM_SETS);
+
+ /* check that pps and corresponding sps exist */
+ if ( (pStorage->pps[ppsId] == NULL) ||
+ (pStorage->sps[pStorage->pps[ppsId]->seqParameterSetId] == NULL) )
+ {
+ return(HANTRO_NOK);
+ }
+
+ /* check that pps parameters do not violate picture size constraints */
+ tmp = CheckPps(pStorage->pps[ppsId],
+ pStorage->sps[pStorage->pps[ppsId]->seqParameterSetId]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* first activation part1 */
+ if (pStorage->activePpsId == MAX_NUM_PIC_PARAM_SETS)
+ {
+ pStorage->activePpsId = ppsId;
+ pStorage->activePps = pStorage->pps[ppsId];
+ pStorage->activeSpsId = pStorage->activePps->seqParameterSetId;
+ pStorage->activeSps = pStorage->sps[pStorage->activeSpsId];
+ pStorage->picSizeInMbs =
+ pStorage->activeSps->picWidthInMbs *
+ pStorage->activeSps->picHeightInMbs;
+
+ pStorage->currImage->width = pStorage->activeSps->picWidthInMbs;
+ pStorage->currImage->height = pStorage->activeSps->picHeightInMbs;
+
+ pStorage->pendingActivation = HANTRO_TRUE;
+ }
+ /* first activation part2 */
+ else if (pStorage->pendingActivation)
+ {
+ pStorage->pendingActivation = HANTRO_FALSE;
+
+ FREE(pStorage->mb);
+ FREE(pStorage->sliceGroupMap);
+
+ ALLOCATE(pStorage->mb, pStorage->picSizeInMbs, mbStorage_t);
+ ALLOCATE(pStorage->sliceGroupMap, pStorage->picSizeInMbs, u32);
+ if (pStorage->mb == NULL || pStorage->sliceGroupMap == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+
+ memset(pStorage->mb, 0,
+ pStorage->picSizeInMbs * sizeof(mbStorage_t));
+
+ h264bsdInitMbNeighbours(pStorage->mb,
+ pStorage->activeSps->picWidthInMbs,
+ pStorage->picSizeInMbs);
+
+ /* dpb output reordering disabled if
+ * 1) application set noReordering flag
+ * 2) POC type equal to 2
+ * 3) num_reorder_frames in vui equal to 0 */
+ if ( pStorage->noReordering ||
+ pStorage->activeSps->picOrderCntType == 2 ||
+ (pStorage->activeSps->vuiParametersPresentFlag &&
+ pStorage->activeSps->vuiParameters->bitstreamRestrictionFlag &&
+ !pStorage->activeSps->vuiParameters->numReorderFrames) )
+ flag = HANTRO_TRUE;
+ else
+ flag = HANTRO_FALSE;
+
+ tmp = h264bsdResetDpb(pStorage->dpb,
+ pStorage->activeSps->picWidthInMbs *
+ pStorage->activeSps->picHeightInMbs,
+ pStorage->activeSps->maxDpbSize,
+ pStorage->activeSps->numRefFrames,
+ pStorage->activeSps->maxFrameNum,
+ flag);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ else if (ppsId != pStorage->activePpsId)
+ {
+ /* sequence parameter set shall not change but before an IDR picture */
+ if (pStorage->pps[ppsId]->seqParameterSetId != pStorage->activeSpsId)
+ {
+ DEBUG(("SEQ PARAM SET CHANGING...\n"));
+ if (isIdr)
+ {
+ pStorage->activePpsId = ppsId;
+ pStorage->activePps = pStorage->pps[ppsId];
+ pStorage->activeSpsId = pStorage->activePps->seqParameterSetId;
+ pStorage->activeSps = pStorage->sps[pStorage->activeSpsId];
+ pStorage->picSizeInMbs =
+ pStorage->activeSps->picWidthInMbs *
+ pStorage->activeSps->picHeightInMbs;
+
+ pStorage->currImage->width = pStorage->activeSps->picWidthInMbs;
+ pStorage->currImage->height =
+ pStorage->activeSps->picHeightInMbs;
+
+ pStorage->pendingActivation = HANTRO_TRUE;
+ }
+ else
+ {
+ DEBUG(("TRYING TO CHANGE SPS IN NON-IDR SLICE\n"));
+ return(HANTRO_NOK);
+ }
+ }
+ else
+ {
+ pStorage->activePpsId = ppsId;
+ pStorage->activePps = pStorage->pps[ppsId];
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdResetStorage
+
+ Functional description:
+ Reset contents of the storage. This should be called before
+ processing of new image is started.
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ none
+
+ Returns:
+ none
+
+
+------------------------------------------------------------------------------*/
+
+void h264bsdResetStorage(storage_t *pStorage)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ pStorage->slice->numDecodedMbs = 0;
+ pStorage->slice->sliceId = 0;
+
+ for (i = 0; i < pStorage->picSizeInMbs; i++)
+ {
+ pStorage->mb[i].sliceId = 0;
+ pStorage->mb[i].decoded = 0;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdIsStartOfPicture
+
+ Functional description:
+ Determine if the decoder is in the start of a picture. This
+ information is needed to decide if h264bsdActivateParamSets and
+ h264bsdCheckGapsInFrameNum functions should be called. Function
+ considers that new picture is starting if no slice headers
+ have been successfully decoded for the current access unit.
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_TRUE new picture is starting
+ HANTRO_FALSE not starting
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdIsStartOfPicture(storage_t *pStorage)
+{
+
+/* Variables */
+
+
+/* Code */
+
+ if (pStorage->validSliceInAccessUnit == HANTRO_FALSE)
+ return(HANTRO_TRUE);
+ else
+ return(HANTRO_FALSE);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdIsEndOfPicture
+
+ Functional description:
+ Determine if the decoder is in the end of a picture. This
+ information is needed to determine when deblocking filtering
+ and reference picture marking processes should be performed.
+
+ If the decoder is processing primary slices the return value
+ is determined by checking the value of numDecodedMbs in the
+ storage. On the other hand, if the decoder is processing
+ redundant slices the numDecodedMbs may not contain valid
+ informationa and each macroblock has to be checked separately.
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_TRUE end of picture
+ HANTRO_FALSE noup
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdIsEndOfPicture(storage_t *pStorage)
+{
+
+/* Variables */
+
+ u32 i, tmp;
+
+/* Code */
+
+ /* primary picture */
+ if (!pStorage->sliceHeader[0].redundantPicCnt)
+ {
+ if (pStorage->slice->numDecodedMbs == pStorage->picSizeInMbs)
+ return(HANTRO_TRUE);
+ }
+ else
+ {
+ for (i = 0, tmp = 0; i < pStorage->picSizeInMbs; i++)
+ tmp += pStorage->mb[i].decoded ? 1 : 0;
+
+ if (tmp == pStorage->picSizeInMbs)
+ return(HANTRO_TRUE);
+ }
+
+ return(HANTRO_FALSE);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdComputeSliceGroupMap
+
+ Functional description:
+ Compute slice group map. Just call h264bsdDecodeSliceGroupMap with
+ appropriate parameters.
+
+ Inputs:
+ pStorage pointer to storage structure
+ sliceGroupChangeCycle
+
+ Outputs:
+ none
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdComputeSliceGroupMap(storage_t *pStorage, u32 sliceGroupChangeCycle)
+{
+
+/* Variables */
+
+
+/* Code */
+
+ h264bsdDecodeSliceGroupMap(pStorage->sliceGroupMap,
+ pStorage->activePps, sliceGroupChangeCycle,
+ pStorage->activeSps->picWidthInMbs,
+ pStorage->activeSps->picHeightInMbs);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckAccessUnitBoundary
+
+ Functional description:
+ Check if next NAL unit starts a new access unit. Following
+ conditions specify start of a new access unit:
+
+ -NAL unit types 6-11, 13-18 (e.g. SPS, PPS)
+
+ following conditions checked only for slice NAL units, values
+ compared to ones obtained from previous slice:
+
+ -NAL unit type differs (slice / IDR slice)
+ -frame_num differs
+ -nal_ref_idc differs and one of the values is 0
+ -POC information differs
+ -both are IDR slices and idr_pic_id differs
+
+ Inputs:
+ strm pointer to stream data structure
+ nuNext pointer to NAL unit structure
+ storage pointer to storage structure
+
+ Outputs:
+ accessUnitBoundaryFlag the result is stored here, TRUE for
+ access unit boundary, FALSE otherwise
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, invalid stream data
+ PARAM_SET_ERROR invalid param set usage
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckAccessUnitBoundary(
+ strmData_t *strm,
+ nalUnit_t *nuNext,
+ storage_t *storage,
+ u32 *accessUnitBoundaryFlag)
+{
+
+/* Variables */
+
+ u32 tmp, ppsId, frameNum, idrPicId, picOrderCntLsb;
+ i32 deltaPicOrderCntBottom, deltaPicOrderCnt[2];
+ seqParamSet_t *sps;
+ picParamSet_t *pps;
+
+/* Code */
+
+ ASSERT(strm);
+ ASSERT(nuNext);
+ ASSERT(storage);
+ ASSERT(storage->sps);
+ ASSERT(storage->pps);
+
+ /* initialize default output to FALSE */
+ *accessUnitBoundaryFlag = HANTRO_FALSE;
+
+ if ( ( (nuNext->nalUnitType > 5) && (nuNext->nalUnitType < 12) ) ||
+ ( (nuNext->nalUnitType > 12) && (nuNext->nalUnitType <= 18) ) )
+ {
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ return(HANTRO_OK);
+ }
+ else if ( nuNext->nalUnitType != NAL_CODED_SLICE &&
+ nuNext->nalUnitType != NAL_CODED_SLICE_IDR )
+ {
+ return(HANTRO_OK);
+ }
+
+ /* check if this is the very first call to this function */
+ if (storage->aub->firstCallFlag)
+ {
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ storage->aub->firstCallFlag = HANTRO_FALSE;
+ }
+
+ /* get picture parameter set id */
+ tmp = h264bsdCheckPpsId(strm, &ppsId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* store sps and pps in separate pointers just to make names shorter */
+ pps = storage->pps[ppsId];
+ if ( pps == NULL || storage->sps[pps->seqParameterSetId] == NULL ||
+ (storage->activeSpsId != MAX_NUM_SEQ_PARAM_SETS &&
+ pps->seqParameterSetId != storage->activeSpsId &&
+ nuNext->nalUnitType != NAL_CODED_SLICE_IDR) )
+ return(PARAM_SET_ERROR);
+ sps = storage->sps[pps->seqParameterSetId];
+
+ if (storage->aub->nuPrev->nalRefIdc != nuNext->nalRefIdc &&
+ (storage->aub->nuPrev->nalRefIdc == 0 || nuNext->nalRefIdc == 0))
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+
+ if ((storage->aub->nuPrev->nalUnitType == NAL_CODED_SLICE_IDR &&
+ nuNext->nalUnitType != NAL_CODED_SLICE_IDR) ||
+ (storage->aub->nuPrev->nalUnitType != NAL_CODED_SLICE_IDR &&
+ nuNext->nalUnitType == NAL_CODED_SLICE_IDR))
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+
+ tmp = h264bsdCheckFrameNum(strm, sps->maxFrameNum, &frameNum);
+ if (tmp != HANTRO_OK)
+ return(HANTRO_NOK);
+
+ if (storage->aub->prevFrameNum != frameNum)
+ {
+ storage->aub->prevFrameNum = frameNum;
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ }
+
+ if (nuNext->nalUnitType == NAL_CODED_SLICE_IDR)
+ {
+ tmp = h264bsdCheckIdrPicId(strm, sps->maxFrameNum, nuNext->nalUnitType,
+ &idrPicId);
+ if (tmp != HANTRO_OK)
+ return(HANTRO_NOK);
+
+ if (storage->aub->nuPrev->nalUnitType == NAL_CODED_SLICE_IDR &&
+ storage->aub->prevIdrPicId != idrPicId)
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+
+ storage->aub->prevIdrPicId = idrPicId;
+ }
+
+ if (sps->picOrderCntType == 0)
+ {
+ tmp = h264bsdCheckPicOrderCntLsb(strm, sps, nuNext->nalUnitType,
+ &picOrderCntLsb);
+ if (tmp != HANTRO_OK)
+ return(HANTRO_NOK);
+
+ if (storage->aub->prevPicOrderCntLsb != picOrderCntLsb)
+ {
+ storage->aub->prevPicOrderCntLsb = picOrderCntLsb;
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ }
+
+ if (pps->picOrderPresentFlag)
+ {
+ tmp = h264bsdCheckDeltaPicOrderCntBottom(strm, sps,
+ nuNext->nalUnitType, &deltaPicOrderCntBottom);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ if (storage->aub->prevDeltaPicOrderCntBottom !=
+ deltaPicOrderCntBottom)
+ {
+ storage->aub->prevDeltaPicOrderCntBottom =
+ deltaPicOrderCntBottom;
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ }
+ }
+ }
+ else if (sps->picOrderCntType == 1 && !sps->deltaPicOrderAlwaysZeroFlag)
+ {
+ tmp = h264bsdCheckDeltaPicOrderCnt(strm, sps, nuNext->nalUnitType,
+ pps->picOrderPresentFlag, deltaPicOrderCnt);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ if (storage->aub->prevDeltaPicOrderCnt[0] != deltaPicOrderCnt[0])
+ {
+ storage->aub->prevDeltaPicOrderCnt[0] = deltaPicOrderCnt[0];
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ }
+
+ if (pps->picOrderPresentFlag)
+ if (storage->aub->prevDeltaPicOrderCnt[1] != deltaPicOrderCnt[1])
+ {
+ storage->aub->prevDeltaPicOrderCnt[1] = deltaPicOrderCnt[1];
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ }
+ }
+
+ *storage->aub->nuPrev = *nuNext;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: CheckPps
+
+ Functional description:
+ Check picture parameter set. Contents of the picture parameter
+ set information that depends on the image dimensions is checked
+ against the dimensions in the sps.
+
+ Inputs:
+ pps pointer to picture paramter set
+ sps pointer to sequence parameter set
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_OK everything ok
+ HANTRO_NOK invalid data in picture parameter set
+
+------------------------------------------------------------------------------*/
+u32 CheckPps(picParamSet_t *pps, seqParamSet_t *sps)
+{
+
+ u32 i;
+ u32 picSize;
+
+ picSize = sps->picWidthInMbs * sps->picHeightInMbs;
+
+ /* check slice group params */
+ if (pps->numSliceGroups > 1)
+ {
+ if (pps->sliceGroupMapType == 0)
+ {
+ ASSERT(pps->runLength);
+ for (i = 0; i < pps->numSliceGroups; i++)
+ {
+ if (pps->runLength[i] > picSize)
+ return(HANTRO_NOK);
+ }
+ }
+ else if (pps->sliceGroupMapType == 2)
+ {
+ ASSERT(pps->topLeft);
+ ASSERT(pps->bottomRight);
+ for (i = 0; i < pps->numSliceGroups-1; i++)
+ {
+ if (pps->topLeft[i] > pps->bottomRight[i] ||
+ pps->bottomRight[i] >= picSize)
+ return(HANTRO_NOK);
+
+ if ( (pps->topLeft[i] % sps->picWidthInMbs) >
+ (pps->bottomRight[i] % sps->picWidthInMbs) )
+ return(HANTRO_NOK);
+ }
+ }
+ else if (pps->sliceGroupMapType > 2 && pps->sliceGroupMapType < 6)
+ {
+ if (pps->sliceGroupChangeRate > picSize)
+ return(HANTRO_NOK);
+ }
+ else if (pps->sliceGroupMapType == 6 &&
+ pps->picSizeInMapUnits < picSize)
+ return(HANTRO_NOK);
+ }
+
+ return(HANTRO_OK);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdValidParamSets
+
+ Functional description:
+ Check if any valid SPS/PPS combination exists in the storage.
+ Function tries each PPS in the buffer and checks if corresponding
+ SPS exists and calls CheckPps to determine if the PPS conforms
+ to image dimensions of the SPS.
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ HANTRO_OK there is at least one valid combination
+ HANTRO_NOK no valid combinations found
+
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdValidParamSets(storage_t *pStorage)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ for (i = 0; i < MAX_NUM_PIC_PARAM_SETS; i++)
+ {
+ if ( pStorage->pps[i] &&
+ pStorage->sps[pStorage->pps[i]->seqParameterSetId] &&
+ CheckPps(pStorage->pps[i],
+ pStorage->sps[pStorage->pps[i]->seqParameterSetId]) ==
+ HANTRO_OK)
+ {
+ return(HANTRO_OK);
+ }
+ }
+
+ return(HANTRO_NOK);
+
+}
+
--- /dev/null
+++ b/src/h264bsd_storage.h
@@ -1,0 +1,175 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_STORAGE_H
+#define H264SWDEC_STORAGE_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_cfg.h"
+#include "h264bsd_seq_param_set.h"
+#include "h264bsd_pic_param_set.h"
+#include "h264bsd_macroblock_layer.h"
+#include "h264bsd_nal_unit.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_seq_param_set.h"
+#include "h264bsd_dpb.h"
+#include "h264bsd_pic_order_cnt.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+typedef struct
+{
+ u32 sliceId;
+ u32 numDecodedMbs;
+ u32 lastMbAddr;
+} sliceStorage_t;
+
+/* structure to store parameters needed for access unit boundary checking */
+typedef struct
+{
+ nalUnit_t nuPrev[1];
+ u32 prevFrameNum;
+ u32 prevIdrPicId;
+ u32 prevPicOrderCntLsb;
+ i32 prevDeltaPicOrderCntBottom;
+ i32 prevDeltaPicOrderCnt[2];
+ u32 firstCallFlag;
+} aubCheck_t;
+
+/* storage data structure, holds all data of a decoder instance */
+typedef struct storage
+{
+ /* active paramet set ids and pointers */
+ u32 oldSpsId;
+ u32 activePpsId;
+ u32 activeSpsId;
+ picParamSet_t *activePps;
+ seqParamSet_t *activeSps;
+ seqParamSet_t *sps[MAX_NUM_SEQ_PARAM_SETS];
+ picParamSet_t *pps[MAX_NUM_PIC_PARAM_SETS];
+
+ /* current slice group map, recomputed for each slice */
+ u32 *sliceGroupMap;
+
+ u32 picSizeInMbs;
+
+ /* this flag is set after all macroblocks of a picture successfully
+ * decoded -> redundant slices not decoded */
+ u32 skipRedundantSlices;
+ u32 picStarted;
+
+ /* flag to indicate if current access unit contains any valid slices */
+ u32 validSliceInAccessUnit;
+
+ /* store information needed for handling of slice decoding */
+ sliceStorage_t slice[1];
+
+ /* number of concealed macroblocks in the current image */
+ u32 numConcealedMbs;
+
+ /* picId given by application */
+ u32 currentPicId;
+
+ /* macroblock specific storages, size determined by image dimensions */
+ mbStorage_t *mb;
+
+ /* flag to store noOutputReordering flag set by the application */
+ u32 noReordering;
+
+ /* DPB */
+ dpbStorage_t dpb[1];
+
+ /* structure to store picture order count related information */
+ pocStorage_t poc[1];
+
+ /* access unit boundary checking related data */
+ aubCheck_t aub[1];
+
+ /* current processed image */
+ image_t currImage[1];
+
+ /* last valid NAL unit header is stored here */
+ nalUnit_t prevNalUnit[1];
+
+ /* slice header, second structure used as a temporary storage while
+ * decoding slice header, first one stores last successfully decoded
+ * slice header */
+ sliceHeader_t sliceHeader[2];
+
+ /* fields to store old stream buffer pointers, needed when only part of
+ * a stream buffer is processed by h264bsdDecode function */
+ u32 prevBufNotFinished;
+ u8 *prevBufPointer;
+ u32 prevBytesConsumed;
+ strmData_t strm[1];
+
+ /* macroblock layer structure, there is no need to store this but it
+ * would have increased the stack size excessively and needed to be
+ * allocated from head -> easiest to put it here */
+ macroblockLayer_t *mbLayer;
+
+ u32 pendingActivation; /* Activate parameter sets after returning
+ HEADERS_RDY to the user */
+ u32 intraConcealmentFlag; /* 0 gray picture for corrupted intra
+ 1 previous frame used if available */
+} storage_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+void h264bsdInitStorage(storage_t *pStorage);
+void h264bsdResetStorage(storage_t *pStorage);
+u32 h264bsdIsStartOfPicture(storage_t *pStorage);
+u32 h264bsdIsEndOfPicture(storage_t *pStorage);
+u32 h264bsdStoreSeqParamSet(storage_t *pStorage, seqParamSet_t *pSeqParamSet);
+u32 h264bsdStorePicParamSet(storage_t *pStorage, picParamSet_t *pPicParamSet);
+u32 h264bsdActivateParamSets(storage_t *pStorage, u32 ppsId, u32 isIdr);
+void h264bsdComputeSliceGroupMap(storage_t *pStorage,
+ u32 sliceGroupChangeCycle);
+
+u32 h264bsdCheckAccessUnitBoundary(
+ strmData_t *strm,
+ nalUnit_t *nuNext,
+ storage_t *storage,
+ u32 *accessUnitBoundaryFlag);
+
+u32 h264bsdValidParamSets(storage_t *pStorage);
+
+#endif /* #ifdef H264SWDEC_STORAGE_H */
+
--- /dev/null
+++ b/src/h264bsd_stream.c
@@ -1,0 +1,243 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdGetBits
+ h264bsdShowBits32
+ h264bsdFlushBits
+ h264bsdIsByteAligned
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_util.h"
+#include "h264bsd_stream.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdGetBits
+
+ Functional description:
+ Read and remove bits from the stream buffer.
+
+ Input:
+ pStrmData pointer to stream data structure
+ numBits number of bits to read
+
+ Output:
+ none
+
+ Returns:
+ bits read from stream
+ END_OF_STREAM if not enough bits left
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdGetBits(strmData_t *pStrmData, u32 numBits)
+{
+
+ u32 out;
+
+ ASSERT(pStrmData);
+ ASSERT(numBits < 32);
+
+ out = h264bsdShowBits32(pStrmData) >> (32 - numBits);
+
+ if (h264bsdFlushBits(pStrmData, numBits) == HANTRO_OK)
+ {
+ return(out);
+ }
+ else
+ {
+ return(END_OF_STREAM);
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdShowBits32
+
+ Functional description:
+ Read 32 bits from the stream buffer. Buffer is left as it is, i.e.
+ no bits are removed. First bit read from the stream is the MSB of
+ the return value. If there is not enough bits in the buffer ->
+ bits beyong the end of the stream are set to '0' in the return
+ value.
+
+ Input:
+ pStrmData pointer to stream data structure
+
+ Output:
+ none
+
+ Returns:
+ bits read from stream
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdShowBits32(strmData_t *pStrmData)
+{
+
+ i32 bits, shift;
+ u32 out;
+ u8 *pStrm;
+
+ ASSERT(pStrmData);
+ ASSERT(pStrmData->pStrmCurrPos);
+ ASSERT(pStrmData->bitPosInWord < 8);
+ ASSERT(pStrmData->bitPosInWord ==
+ (pStrmData->strmBuffReadBits & 0x7));
+
+ pStrm = pStrmData->pStrmCurrPos;
+
+ /* number of bits left in the buffer */
+ bits = (i32)pStrmData->strmBuffSize*8 - (i32)pStrmData->strmBuffReadBits;
+
+ /* at least 32-bits in the buffer */
+ if (bits >= 32)
+ {
+ u32 bitPosInWord = pStrmData->bitPosInWord;
+ out = ((u32)pStrm[0] << 24) | ((u32)pStrm[1] << 16) |
+ ((u32)pStrm[2] << 8) | ((u32)pStrm[3]);
+
+ if (bitPosInWord)
+ {
+ u32 byte = (u32)pStrm[4];
+ u32 tmp = (8-bitPosInWord);
+ out <<= bitPosInWord;
+ out |= byte>>tmp;
+ }
+ return (out);
+ }
+ /* at least one bit in the buffer */
+ else if (bits > 0)
+ {
+ shift = (i32)(24 + pStrmData->bitPosInWord);
+ out = (u32)(*pStrm++) << shift;
+ bits -= (i32)(8 - pStrmData->bitPosInWord);
+ while (bits > 0)
+ {
+ shift -= 8;
+ out |= (u32)(*pStrm++) << shift;
+ bits -= 8;
+ }
+ return (out);
+ }
+ else
+ return (0);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdFlushBits
+
+ Functional description:
+ Remove bits from the stream buffer
+
+ Input:
+ pStrmData pointer to stream data structure
+ numBits number of bits to remove
+
+ Output:
+ none
+
+ Returns:
+ HANTRO_OK success
+ END_OF_STREAM not enough bits left
+
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_NEON
+u32 h264bsdFlushBits(strmData_t *pStrmData, u32 numBits)
+{
+
+ ASSERT(pStrmData);
+ ASSERT(pStrmData->pStrmBuffStart);
+ ASSERT(pStrmData->pStrmCurrPos);
+ ASSERT(pStrmData->bitPosInWord < 8);
+ ASSERT(pStrmData->bitPosInWord == (pStrmData->strmBuffReadBits & 0x7));
+
+ pStrmData->strmBuffReadBits += numBits;
+ pStrmData->bitPosInWord = pStrmData->strmBuffReadBits & 0x7;
+ if ( (pStrmData->strmBuffReadBits ) <= (8*pStrmData->strmBuffSize) )
+ {
+ pStrmData->pStrmCurrPos = pStrmData->pStrmBuffStart +
+ (pStrmData->strmBuffReadBits >> 3);
+ return(HANTRO_OK);
+ }
+ else
+ return(END_OF_STREAM);
+
+}
+#endif
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdIsByteAligned
+
+ Functional description:
+ Check if current stream position is byte aligned.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ none
+
+ Returns:
+ TRUE stream is byte aligned
+ FALSE stream is not byte aligned
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdIsByteAligned(strmData_t *pStrmData)
+{
+
+/* Variables */
+
+/* Code */
+
+ if (!pStrmData->bitPosInWord)
+ return(HANTRO_TRUE);
+ else
+ return(HANTRO_FALSE);
+
+}
+
--- /dev/null
+++ b/src/h264bsd_stream.h
@@ -1,0 +1,68 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_STREAM_H
+#define H264SWDEC_STREAM_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+typedef struct
+{
+ u8 *pStrmBuffStart; /* pointer to start of stream buffer */
+ u8 *pStrmCurrPos; /* current read address in stream buffer */
+ u32 bitPosInWord; /* bit position in stream buffer byte */
+ u32 strmBuffSize; /* size of stream buffer (bytes) */
+ u32 strmBuffReadBits; /* number of bits read from stream buffer */
+} strmData_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdGetBits(strmData_t *pStrmData, u32 numBits);
+
+u32 h264bsdShowBits32(strmData_t *pStrmData);
+
+u32 h264bsdFlushBits(strmData_t *pStrmData, u32 numBits);
+
+u32 h264bsdIsByteAligned(strmData_t *);
+
+#endif /* #ifdef H264SWDEC_STREAM_H */
+
--- /dev/null
+++ b/src/h264bsd_transform.c
@@ -1,0 +1,405 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+
+
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdProcessBlock
+ h264bsdProcessLumaDc
+ h264bsdProcessChromaDc
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_transform.h"
+#include "h264bsd_util.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* Switch off the following Lint messages for this file:
+ * Info 701: Shift left of signed quantity (int)
+ * Info 702: Shift right of signed quantity (int)
+ */
+/*lint -e701 -e702 */
+
+/* LevelScale function */
+static const i32 levelScale[6][3] = {
+ {10,13,16}, {11,14,18}, {13,16,20}, {14,18,23}, {16,20,25}, {18,23,29}};
+
+/* qp % 6 as a function of qp */
+static const u8 qpMod6[52] = {0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,
+ 0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3};
+
+/* qp / 6 as a function of qp */
+static const u8 qpDiv6[52] = {0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,
+ 4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8};
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdProcessBlock
+
+ Functional description:
+ Function performs inverse zig-zag scan, inverse scaling and
+ inverse transform for a luma or a chroma residual block
+
+ Inputs:
+ data pointer to data to be processed
+ qp quantization parameter
+ skip skip processing of data[0], set to non-zero value
+ if dc coeff hanled separately
+ coeffMap 16 lsb's indicate which coeffs are non-zero,
+ bit 0 (lsb) for coeff 0, bit 1 for coeff 1 etc.
+
+ Outputs:
+ data processed data
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK processed data not in valid range [-512, 511]
+
+------------------------------------------------------------------------------*/
+u32 h264bsdProcessBlock(i32 *data, u32 qp, u32 skip, u32 coeffMap)
+{
+
+/* Variables */
+
+ i32 tmp0, tmp1, tmp2, tmp3;
+ i32 d1, d2, d3;
+ u32 row,col;
+ u32 qpDiv;
+ i32 *ptr;
+
+/* Code */
+
+ qpDiv = qpDiv6[qp];
+ tmp1 = levelScale[qpMod6[qp]][0] << qpDiv;
+ tmp2 = levelScale[qpMod6[qp]][1] << qpDiv;
+ tmp3 = levelScale[qpMod6[qp]][2] << qpDiv;
+
+ if (!skip)
+ data[0] = (data[0] * tmp1);
+
+ /* at least one of the rows 1, 2 or 3 contain non-zero coeffs, mask takes
+ * the scanning order into account */
+ if (coeffMap & 0xFF9C)
+ {
+ /* do the zig-zag scan and inverse quantization */
+ d1 = data[1];
+ d2 = data[14];
+ d3 = data[15];
+ data[1] = (d1 * tmp2);
+ data[14] = (d2 * tmp2);
+ data[15] = (d3 * tmp3);
+
+ d1 = data[2];
+ d2 = data[5];
+ d3 = data[4];
+ data[4] = (d1 * tmp2);
+ data[2] = (d2 * tmp1);
+ data[5] = (d3 * tmp3);
+
+ d1 = data[8];
+ d2 = data[3];
+ d3 = data[6];
+ tmp0 = (d1 * tmp2);
+ data[8] = (d2 * tmp1);
+ data[3] = (d3 * tmp2);
+ d1 = data[7];
+ d2 = data[12];
+ d3 = data[9];
+ data[6] = (d1 * tmp2);
+ data[7] = (d2 * tmp3);
+ data[12] = (d3 * tmp2);
+ data[9] = tmp0;
+
+ d1 = data[10];
+ d2 = data[11];
+ d3 = data[13];
+ data[13] = (d1 * tmp3);
+ data[10] = (d2 * tmp1);
+ data[11] = (d3 * tmp2);
+
+ /* horizontal transform */
+ for (row = 4, ptr = data; row--; ptr += 4)
+ {
+ tmp0 = ptr[0] + ptr[2];
+ tmp1 = ptr[0] - ptr[2];
+ tmp2 = (ptr[1] >> 1) - ptr[3];
+ tmp3 = ptr[1] + (ptr[3] >> 1);
+ ptr[0] = tmp0 + tmp3;
+ ptr[1] = tmp1 + tmp2;
+ ptr[2] = tmp1 - tmp2;
+ ptr[3] = tmp0 - tmp3;
+ }
+
+ /*lint +e661 +e662*/
+ /* then vertical transform */
+ for (col = 4; col--; data++)
+ {
+ tmp0 = data[0] + data[8];
+ tmp1 = data[0] - data[8];
+ tmp2 = (data[4] >> 1) - data[12];
+ tmp3 = data[4] + (data[12] >> 1);
+ data[0 ] = (tmp0 + tmp3 + 32)>>6;
+ data[4 ] = (tmp1 + tmp2 + 32)>>6;
+ data[8 ] = (tmp1 - tmp2 + 32)>>6;
+ data[12] = (tmp0 - tmp3 + 32)>>6;
+ /* check that each value is in the range [-512,511] */
+ if (((u32)(data[0] + 512) > 1023) ||
+ ((u32)(data[4] + 512) > 1023) ||
+ ((u32)(data[8] + 512) > 1023) ||
+ ((u32)(data[12] + 512) > 1023) )
+ return(HANTRO_NOK);
+ }
+ }
+ else /* rows 1, 2 and 3 are zero */
+ {
+ /* only dc-coeff is non-zero, i.e. coeffs at original positions
+ * 1, 5 and 6 are zero */
+ if ((coeffMap & 0x62) == 0)
+ {
+ tmp0 = (data[0] + 32) >> 6;
+ /* check that value is in the range [-512,511] */
+ if ((u32)(tmp0 + 512) > 1023)
+ return(HANTRO_NOK);
+ data[0] = data[1] = data[2] = data[3] = data[4] = data[5] =
+ data[6] = data[7] = data[8] = data[9] = data[10] =
+ data[11] = data[12] = data[13] = data[14] = data[15] =
+ tmp0;
+ }
+ else /* at least one of the coeffs 1, 5 or 6 is non-zero */
+ {
+ data[1] = (data[1] * tmp2);
+ data[2] = (data[5] * tmp1);
+ data[3] = (data[6] * tmp2);
+ tmp0 = data[0] + data[2];
+ tmp1 = data[0] - data[2];
+ tmp2 = (data[1] >> 1) - data[3];
+ tmp3 = data[1] + (data[3] >> 1);
+ data[0] = (tmp0 + tmp3 + 32)>>6;
+ data[1] = (tmp1 + tmp2 + 32)>>6;
+ data[2] = (tmp1 - tmp2 + 32)>>6;
+ data[3] = (tmp0 - tmp3 + 32)>>6;
+ data[4] = data[8] = data[12] = data[0];
+ data[5] = data[9] = data[13] = data[1];
+ data[6] = data[10] = data[14] = data[2];
+ data[7] = data[11] = data[15] = data[3];
+ /* check that each value is in the range [-512,511] */
+ if (((u32)(data[0] + 512) > 1023) ||
+ ((u32)(data[1] + 512) > 1023) ||
+ ((u32)(data[2] + 512) > 1023) ||
+ ((u32)(data[3] + 512) > 1023) )
+ return(HANTRO_NOK);
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdProcessLumaDc
+
+ Functional description:
+ Function performs inverse zig-zag scan, inverse transform and
+ inverse scaling for a luma DC coefficients block
+
+ Inputs:
+ data pointer to data to be processed
+ qp quantization parameter
+
+ Outputs:
+ data processed data
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+void h264bsdProcessLumaDc(i32 *data, u32 qp)
+{
+
+/* Variables */
+
+ i32 tmp0, tmp1, tmp2, tmp3;
+ u32 row,col;
+ u32 qpMod, qpDiv;
+ i32 levScale;
+ i32 *ptr;
+
+/* Code */
+
+ qpMod = qpMod6[qp];
+ qpDiv = qpDiv6[qp];
+
+ /* zig-zag scan */
+ tmp0 = data[2];
+ data[2] = data[5];
+ data[5] = data[4];
+ data[4] = tmp0;
+
+ tmp0 = data[8];
+ data[8] = data[3];
+ data[3] = data[6];
+ data[6] = data[7];
+ data[7] = data[12];
+ data[12] = data[9];
+ data[9] = tmp0;
+
+ tmp0 = data[10];
+ data[10] = data[11];
+ data[11] = data[13];
+ data[13] = tmp0;
+
+ /* horizontal transform */
+ for (row = 4, ptr = data; row--; ptr += 4)
+ {
+ tmp0 = ptr[0] + ptr[2];
+ tmp1 = ptr[0] - ptr[2];
+ tmp2 = ptr[1] - ptr[3];
+ tmp3 = ptr[1] + ptr[3];
+ ptr[0] = tmp0 + tmp3;
+ ptr[1] = tmp1 + tmp2;
+ ptr[2] = tmp1 - tmp2;
+ ptr[3] = tmp0 - tmp3;
+ }
+
+ /*lint +e661 +e662*/
+ /* then vertical transform and inverse scaling */
+ levScale = levelScale[ qpMod ][0];
+ if (qp >= 12)
+ {
+ levScale <<= (qpDiv-2);
+ for (col = 4; col--; data++)
+ {
+ tmp0 = data[0] + data[8 ];
+ tmp1 = data[0] - data[8 ];
+ tmp2 = data[4] - data[12];
+ tmp3 = data[4] + data[12];
+ data[0 ] = ((tmp0 + tmp3)*levScale);
+ data[4 ] = ((tmp1 + tmp2)*levScale);
+ data[8 ] = ((tmp1 - tmp2)*levScale);
+ data[12] = ((tmp0 - tmp3)*levScale);
+ }
+ }
+ else
+ {
+ i32 tmp;
+ tmp = ((1 - qpDiv) == 0) ? 1 : 2;
+ for (col = 4; col--; data++)
+ {
+ tmp0 = data[0] + data[8 ];
+ tmp1 = data[0] - data[8 ];
+ tmp2 = data[4] - data[12];
+ tmp3 = data[4] + data[12];
+ data[0 ] = ((tmp0 + tmp3)*levScale+tmp) >> (2-qpDiv);
+ data[4 ] = ((tmp1 + tmp2)*levScale+tmp) >> (2-qpDiv);
+ data[8 ] = ((tmp1 - tmp2)*levScale+tmp) >> (2-qpDiv);
+ data[12] = ((tmp0 - tmp3)*levScale+tmp) >> (2-qpDiv);
+ }
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdProcessChromaDc
+
+ Functional description:
+ Function performs inverse transform and inverse scaling for a
+ chroma DC coefficients block
+
+ Inputs:
+ data pointer to data to be processed
+ qp quantization parameter
+
+ Outputs:
+ data processed data
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+void h264bsdProcessChromaDc(i32 *data, u32 qp)
+{
+
+/* Variables */
+
+ i32 tmp0, tmp1, tmp2, tmp3;
+ u32 qpDiv;
+ i32 levScale;
+ u32 levShift;
+
+/* Code */
+
+ qpDiv = qpDiv6[qp];
+ levScale = levelScale[ qpMod6[qp] ][0];
+
+ if (qp >= 6)
+ {
+ levScale <<= (qpDiv-1);
+ levShift = 0;
+ }
+ else
+ {
+ levShift = 1;
+ }
+
+ tmp0 = data[0] + data[2];
+ tmp1 = data[0] - data[2];
+ tmp2 = data[1] - data[3];
+ tmp3 = data[1] + data[3];
+ data[0] = ((tmp0 + tmp3) * levScale) >> levShift;
+ data[1] = ((tmp0 - tmp3) * levScale) >> levShift;
+ data[2] = ((tmp1 + tmp2) * levScale) >> levShift;
+ data[3] = ((tmp1 - tmp2) * levScale) >> levShift;
+ tmp0 = data[4] + data[6];
+ tmp1 = data[4] - data[6];
+ tmp2 = data[5] - data[7];
+ tmp3 = data[5] + data[7];
+ data[4] = ((tmp0 + tmp3) * levScale) >> levShift;
+ data[5] = ((tmp0 - tmp3) * levScale) >> levShift;
+ data[6] = ((tmp1 + tmp2) * levScale) >> levShift;
+ data[7] = ((tmp1 - tmp2) * levScale) >> levShift;
+
+}
+
+/*lint +e701 +e702 */
+
+
--- /dev/null
+++ b/src/h264bsd_transform.h
@@ -1,0 +1,55 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_TRANSFORM_H
+#define H264SWDEC_TRANSFORM_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdProcessBlock(i32 *data, u32 qp, u32 skip, u32 coeffMap);
+void h264bsdProcessLumaDc(i32 *data, u32 qp);
+void h264bsdProcessChromaDc(i32 *data, u32 qp);
+
+#endif /* #ifdef H264SWDEC_TRANSFORM_H */
+
--- /dev/null
+++ b/src/h264bsd_util.c
@@ -1,0 +1,285 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdCountLeadingZeros
+ h264bsdRbspTrailingBits
+ h264bsdMoreRbspData
+ h264bsdNextMbAddress
+ h264bsdSetCurrImageMbPointers
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_util.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* look-up table for expected values of stuffing bits */
+static const u32 stuffingTable[8] = {0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80};
+
+/* look-up table for chroma quantization parameter as a function of luma QP */
+const u32 h264bsdQpC[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};
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ 5.1 Function: h264bsdCountLeadingZeros
+
+ Functional description:
+ Count leading zeros in a code word. Code word is assumed to be
+ right-aligned, last bit of the code word in the lsb of the value.
+
+ Inputs:
+ value code word
+ length number of bits in the code word
+
+ Outputs:
+ none
+
+ Returns:
+ number of leading zeros in the code word
+
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_NEON
+u32 h264bsdCountLeadingZeros(u32 value, u32 length)
+{
+
+/* Variables */
+
+ u32 zeros = 0;
+ u32 mask = 1 << (length - 1);
+
+/* Code */
+
+ ASSERT(length <= 32);
+
+ while (mask && !(value & mask))
+ {
+ zeros++;
+ mask >>= 1;
+ }
+ return(zeros);
+
+}
+#endif
+/*------------------------------------------------------------------------------
+
+ 5.2 Function: h264bsdRbspTrailingBits
+
+ Functional description:
+ Check Raw Byte Stream Payload (RBSP) trailing bits, i.e. stuffing.
+ Rest of the current byte (whole byte if allready byte aligned)
+ in the stream buffer shall contain a '1' bit followed by zero or
+ more '0' bits.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_OK RBSP trailing bits found
+ HANTRO_NOK otherwise
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdRbspTrailingBits(strmData_t *pStrmData)
+{
+
+/* Variables */
+
+ u32 stuffing;
+ u32 stuffingLength;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pStrmData->bitPosInWord < 8);
+
+ stuffingLength = 8 - pStrmData->bitPosInWord;
+
+ stuffing = h264bsdGetBits(pStrmData, stuffingLength);
+ if (stuffing == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ if (stuffing != stuffingTable[stuffingLength - 1])
+ return(HANTRO_NOK);
+ else
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ 5.3 Function: h264bsdMoreRbspData
+
+ Functional description:
+ Check if there is more data in the current RBSP. The standard
+ defines this function so that there is more data if
+ -more than 8 bits left or
+ -last bits are not RBSP trailing bits
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_TRUE there is more data
+ HANTRO_FALSE no more data
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdMoreRbspData(strmData_t *pStrmData)
+{
+
+/* Variables */
+
+ u32 bits;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pStrmData->strmBuffReadBits <= 8 * pStrmData->strmBuffSize);
+
+ bits = pStrmData->strmBuffSize * 8 - pStrmData->strmBuffReadBits;
+
+ if (bits == 0)
+ return(HANTRO_FALSE);
+
+ if ( (bits > 8) ||
+ ((h264bsdShowBits32(pStrmData)>>(32-bits)) != (1 << (bits-1))) )
+ return(HANTRO_TRUE);
+ else
+ return(HANTRO_FALSE);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ 5.4 Function: h264bsdNextMbAddress
+
+ Functional description:
+ Get address of the next macroblock in the current slice group.
+
+ Inputs:
+ pSliceGroupMap slice group for each macroblock
+ picSizeInMbs size of the picture
+ currMbAddr where to start
+
+ Outputs:
+ none
+
+ Returns:
+ address of the next macroblock
+ 0 if none of the following macroblocks belong to same slice
+ group as currMbAddr
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdNextMbAddress(u32 *pSliceGroupMap, u32 picSizeInMbs, u32 currMbAddr)
+{
+
+/* Variables */
+
+ u32 i, sliceGroup, tmp;
+
+/* Code */
+
+ ASSERT(pSliceGroupMap);
+ ASSERT(picSizeInMbs);
+ ASSERT(currMbAddr < picSizeInMbs);
+
+ sliceGroup = pSliceGroupMap[currMbAddr];
+
+ i = currMbAddr + 1;
+ tmp = pSliceGroupMap[i];
+ while ((i < picSizeInMbs) && (tmp != sliceGroup))
+ {
+ i++;
+ tmp = pSliceGroupMap[i];
+ }
+
+ if (i == picSizeInMbs)
+ i = 0;
+
+ return(i);
+
+}
+
+
+/*------------------------------------------------------------------------------
+
+ 5.5 Function: h264bsdSetCurrImageMbPointers
+
+ Functional description:
+ Set luma and chroma pointers in image_t for current MB
+
+ Inputs:
+ image Current image
+ mbNum number of current MB
+
+ Outputs:
+ none
+
+ Returns:
+ none
+------------------------------------------------------------------------------*/
+void h264bsdSetCurrImageMbPointers(image_t *image, u32 mbNum)
+{
+ u32 width, height;
+ u32 picSize;
+ u32 row, col;
+ u32 tmp;
+
+ width = image->width;
+ height = image->height;
+ row = mbNum / width;
+ col = mbNum % width;
+
+ tmp = row * width;
+ picSize = width * height;
+
+ image->luma = (u8*)(image->data + col * 16 + tmp * 256);
+ image->cb = (u8*)(image->data + picSize * 256 + tmp * 64 + col * 8);
+ image->cr = (u8*)(image->cb + picSize * 64);
+}
--- /dev/null
+++ b/src/h264bsd_util.h
@@ -1,0 +1,181 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_UTIL_H
+#define H264SWDEC_UTIL_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_cfg.h"
+#include "h264bsd_stream.h"
+#include "h264bsd_image.h"
+
+#ifdef _ASSERT_USED
+#include <assert.h>
+#endif
+
+#if defined(_RANGE_CHECK) || defined(_DEBUG_PRINT) || defined(_ERROR_PRINT)
+#include <stdio.h>
+#endif
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+#define HANTRO_OK 0
+#define HANTRO_NOK 1
+
+#define HANTRO_TRUE (1)
+#define HANTRO_FALSE (0)
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define MEMORY_ALLOCATION_ERROR 0xFFFF
+#define PARAM_SET_ERROR 0xFFF0
+
+/* value to be returned by GetBits if stream buffer is empty */
+#define END_OF_STREAM 0xFFFFFFFFU
+
+#define EMPTY_RESIDUAL_INDICATOR 0xFFFFFF
+
+/* macro to mark a residual block empty, i.e. contain zero coefficients */
+#define MARK_RESIDUAL_EMPTY(residual) ((residual)[0] = EMPTY_RESIDUAL_INDICATOR)
+/* macro to check if residual block is empty */
+#define IS_RESIDUAL_EMPTY(residual) ((residual)[0] == EMPTY_RESIDUAL_INDICATOR)
+
+/* macro for assertion, used only if compiler flag _ASSERT_USED is defined */
+#ifdef _ASSERT_USED
+#define ASSERT(expr) assert(expr)
+#else
+#define ASSERT(expr)
+#endif
+
+/* macro for range checking an value, used only if compiler flag _RANGE_CHECK
+ * is defined */
+#ifdef _RANGE_CHECK
+#define RANGE_CHECK(value, minBound, maxBound) \
+{ \
+ if ((value) < (minBound) || (value) > (maxBound)) \
+ fprintf(stderr, "Warning: Value exceeds given limit(s)!\n"); \
+}
+#else
+#define RANGE_CHECK(value, minBound, maxBound)
+#endif
+
+/* macro for range checking an array, used only if compiler flag _RANGE_CHECK
+ * is defined */
+#ifdef _RANGE_CHECK
+#define RANGE_CHECK_ARRAY(array, minBound, maxBound, length) \
+{ \
+ i32 i; \
+ for (i = 0; i < (length); i++) \
+ if ((array)[i] < (minBound) || (array)[i] > (maxBound)) \
+ fprintf(stderr,"Warning: Value [%d] exceeds given limit(s)!\n",i); \
+}
+#else
+#define RANGE_CHECK_ARRAY(array, minBound, maxBound, length)
+#endif
+
+/* macro for debug printing, used only if compiler flag _DEBUG_PRINT is
+ * defined */
+#ifdef _DEBUG_PRINT
+#define DEBUG(args) printf args
+#else
+#define DEBUG(args)
+#endif
+
+/* macro for error printing, used only if compiler flag _ERROR_PRINT is
+ * defined */
+#ifdef _ERROR_PRINT
+#define EPRINT(msg) fprintf(stderr,"ERROR: %s\n",msg)
+#else
+#define EPRINT(msg)
+#endif
+
+/* macro to get smaller of two values */
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+/* macro to get greater of two values */
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+/* macro to get absolute value */
+#define ABS(a) (((a) < 0) ? -(a) : (a))
+
+/* macro to clip a value z, so that x <= z =< y */
+#define CLIP3(x,y,z) (((z) < (x)) ? (x) : (((z) > (y)) ? (y) : (z)))
+
+/* macro to clip a value z, so that 0 <= z =< 255 */
+#define CLIP1(z) (((z) < 0) ? 0 : (((z) > 255) ? 255 : (z)))
+
+/* macro to allocate memory */
+#define ALLOCATE(ptr, count, type) \
+{ \
+ (ptr) = malloc((count) * sizeof(type)); \
+}
+
+/* macro to free allocated memory */
+#define FREE(ptr) \
+{ \
+ free((ptr)); (ptr) = NULL; \
+}
+
+#define ALIGN(ptr, bytePos) \
+ (ptr + ( ((bytePos - (int)ptr) & (bytePos - 1)) / sizeof(*ptr) ))
+
+extern const u32 h264bsdQpC[52];
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+#ifndef H264DEC_NEON
+u32 h264bsdCountLeadingZeros(u32 value, u32 length);
+#else
+u32 h264bsdCountLeadingZeros(u32 value);
+#endif
+u32 h264bsdRbspTrailingBits(strmData_t *strmData);
+
+u32 h264bsdMoreRbspData(strmData_t *strmData);
+
+u32 h264bsdNextMbAddress(u32 *pSliceGroupMap, u32 picSizeInMbs, u32 currMbAddr);
+
+void h264bsdSetCurrImageMbPointers(image_t *image, u32 mbNum);
+
+i32 abs(i32 a);
+i32 clip(i32 x, i32 y, i32 z);
+
+#endif /* #ifdef H264SWDEC_UTIL_H */
+
--- /dev/null
+++ b/src/h264bsd_vlc.c
@@ -1,0 +1,393 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodeExpGolombUnsigned
+ h264bsdDecodeExpGolombSigned
+ h264bsdDecodeExpGolombMapped
+ h264bsdDecodeExpGolombTruncated
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_vlc.h"
+#include "basetype.h"
+#include "h264bsd_stream.h"
+#include "h264bsd_util.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/* definition of special code num, this along with the return value is used
+ * to handle code num in the range [0, 2^32] in the DecodeExpGolombUnsigned
+ * function */
+#define BIG_CODE_NUM 0xFFFFFFFFU
+
+/* Mapping tables for coded_block_pattern, used for decoding of mapped
+ * Exp-Golomb codes */
+static const u8 codedBlockPatternIntra4x4[48] = {
+ 47,31,15,0,23,27,29,30,7,11,13,14,39,43,45,46,16,3,5,10,12,19,21,26,28,35,
+ 37,42,44,1,2,4,8,17,18,20,24,6,9,22,25,32,33,34,36,40,38,41};
+
+static const u8 codedBlockPatternInter[48] = {
+ 0,16,1,2,4,8,32,3,5,10,12,15,47,7,11,13,14,6,9,31,35,37,42,44,33,34,36,40,
+ 39,43,45,46,17,18,20,24,19,21,26,28,23,27,29,30,22,25,38,41};
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ 5.1 Function: h264bsdDecodeExpGolombUnsigned
+
+ Functional description:
+ Decode unsigned Exp-Golomb code. This is the same as codeNum used
+ in other Exp-Golomb code mappings. Code num (i.e. the decoded
+ symbol) is determined as
+
+ codeNum = 2^leadingZeros - 1 + GetBits(leadingZeros)
+
+ Normal decoded symbols are in the range [0, 2^32 - 2]. Symbol
+ 2^32-1 is indicated by BIG_CODE_NUM with return value HANTRO_OK
+ while symbol 2^32 is indicated by BIG_CODE_NUM with return value
+ HANTRO_NOK. These two symbols are special cases with code length
+ of 65, i.e. 32 '0' bits, a '1' bit, and either 0 or 1 represented
+ by 32 bits.
+
+ Symbol 2^32 is out of unsigned 32-bit range but is needed for
+ DecodeExpGolombSigned to express value -2^31.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ codeNum decoded code word is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, no valid code word found, note exception
+ with BIG_CODE_NUM
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeExpGolombUnsigned(strmData_t *pStrmData, u32 *codeNum)
+{
+
+/* Variables */
+
+ u32 bits, numZeros;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(codeNum);
+
+ bits = h264bsdShowBits32(pStrmData);
+
+ /* first bit is 1 -> code length 1 */
+ if (bits >= 0x80000000)
+ {
+ h264bsdFlushBits(pStrmData, 1);
+ *codeNum = 0;
+ return(HANTRO_OK);
+ }
+ /* second bit is 1 -> code length 3 */
+ else if (bits >= 0x40000000)
+ {
+ if (h264bsdFlushBits(pStrmData, 3) == END_OF_STREAM)
+ return(HANTRO_NOK);
+ *codeNum = 1 + ((bits >> 29) & 0x1);
+ return(HANTRO_OK);
+ }
+ /* third bit is 1 -> code length 5 */
+ else if (bits >= 0x20000000)
+ {
+ if (h264bsdFlushBits(pStrmData, 5) == END_OF_STREAM)
+ return(HANTRO_NOK);
+ *codeNum = 3 + ((bits >> 27) & 0x3);
+ return(HANTRO_OK);
+ }
+ /* fourth bit is 1 -> code length 7 */
+ else if (bits >= 0x10000000)
+ {
+ if (h264bsdFlushBits(pStrmData, 7) == END_OF_STREAM)
+ return(HANTRO_NOK);
+ *codeNum = 7 + ((bits >> 25) & 0x7);
+ return(HANTRO_OK);
+ }
+ /* other code lengths */
+ else
+ {
+#ifndef H264DEC_NEON
+ numZeros = 4 + h264bsdCountLeadingZeros(bits, 28);
+#else
+ numZeros = h264bsdCountLeadingZeros(bits);
+#endif
+ /* all 32 bits are zero */
+ if (numZeros == 32)
+ {
+ *codeNum = 0;
+ h264bsdFlushBits(pStrmData,32);
+ bits = h264bsdGetBits(pStrmData, 1);
+ /* check 33rd bit, must be 1 */
+ if (bits == 1)
+ {
+ /* cannot use h264bsdGetBits, limited to 31 bits */
+ bits = h264bsdShowBits32(pStrmData);
+ if (h264bsdFlushBits(pStrmData, 32) == END_OF_STREAM)
+ return(HANTRO_NOK);
+ /* code num 2^32 - 1, needed for unsigned mapping */
+ if (bits == 0)
+ {
+ *codeNum = BIG_CODE_NUM;
+ return(HANTRO_OK);
+ }
+ /* code num 2^32, needed for unsigned mapping
+ * (results in -2^31) */
+ else if (bits == 1)
+ {
+ *codeNum = BIG_CODE_NUM;
+ return(HANTRO_NOK);
+ }
+ }
+ /* if more zeros than 32, it is an error */
+ return(HANTRO_NOK);
+ }
+ else
+ h264bsdFlushBits(pStrmData,numZeros+1);
+
+ bits = h264bsdGetBits(pStrmData, numZeros);
+ if (bits == END_OF_STREAM)
+ return(HANTRO_NOK);
+
+ *codeNum = (1 << numZeros) - 1 + bits;
+
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ 5.2 Function: h264bsdDecodeExpGolombSigned
+
+ Functional description:
+ Decode signed Exp-Golomb code. Code num is determined by
+ h264bsdDecodeExpGolombUnsigned and then mapped to signed
+ representation as
+
+ symbol = (-1)^(codeNum+1) * (codeNum+1)/2
+
+ Signed symbols shall be in the range [-2^31, 2^31 - 1]. Symbol
+ -2^31 is obtained when codeNum is 2^32, which cannot be expressed
+ by unsigned 32-bit value. This is signaled as a special case from
+ the h264bsdDecodeExpGolombUnsigned by setting codeNum to
+ BIG_CODE_NUM and returning HANTRO_NOK status.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ value decoded code word is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, no valid code word found
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeExpGolombSigned(strmData_t *pStrmData, i32 *value)
+{
+
+/* Variables */
+
+ u32 status, codeNum = 0;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(value);
+
+ status = h264bsdDecodeExpGolombUnsigned(pStrmData, &codeNum);
+
+ if (codeNum == BIG_CODE_NUM)
+ {
+ /* BIG_CODE_NUM and HANTRO_OK status means codeNum 2^32-1 which would
+ * result in signed integer valued 2^31 (i.e. out of 32-bit signed
+ * integer range) */
+ if (status == HANTRO_OK)
+ return(HANTRO_NOK);
+ /* BIG_CODE_NUM and HANTRO_NOK status means codeNum 2^32 which results
+ * in signed integer valued -2^31 */
+ else
+ {
+ *value = (i32)(2147483648U);
+ return (HANTRO_OK);
+ }
+ }
+ else if (status == HANTRO_OK)
+ {
+ /* (-1)^(codeNum+1) results in positive sign if codeNum is odd,
+ * negative when it is even. (codeNum+1)/2 is obtained as
+ * (codeNum+1)>>1 when value is positive and as (-codeNum)>>1 for
+ * negative value */
+ /*lint -e702 */
+ *value = (codeNum & 0x1) ? (i32)((codeNum + 1) >> 1) :
+ -(i32)((codeNum + 1) >> 1);
+ /*lint +e702 */
+ return(HANTRO_OK);
+ }
+
+ return(HANTRO_NOK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ 5.3 Function: h264bsdDecodeExpGolombMapped
+
+ Functional description:
+ Decode mapped Exp-Golomb code. Code num is determined by
+ h264bsdDecodeExpGolombUnsigned and then mapped to codedBlockPattern
+ either for intra or inter macroblock. The mapping is implemented by
+ look-up tables defined in the beginning of the file.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ isIntra flag to indicate if intra or inter mapping is to
+ be used
+
+ Outputs:
+ value decoded code word is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, no valid code word found
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeExpGolombMapped(strmData_t *pStrmData, u32 *value,
+ u32 isIntra)
+{
+
+/* Variables */
+
+ u32 status, codeNum;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(value);
+
+ status = h264bsdDecodeExpGolombUnsigned(pStrmData, &codeNum);
+
+ if (status != HANTRO_OK)
+ return (HANTRO_NOK);
+ else
+ {
+ /* range of valid codeNums [0,47] */
+ if (codeNum > 47)
+ return (HANTRO_NOK);
+ if (isIntra)
+ *value = codedBlockPatternIntra4x4[codeNum];
+ else
+ *value = codedBlockPatternInter[codeNum];
+ return(HANTRO_OK);
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ 5.4 Function: h264bsdDecodeExpGolombTruncated
+
+ Functional description:
+ Decode truncated Exp-Golomb code. greaterThanOne flag indicates
+ the range of the symbol to be decoded as follows:
+ FALSE -> [0,1]
+ TRUE -> [0,2^32-1]
+
+ If flag is false the decoding is performed by reading one bit
+ from the stream with h264bsdGetBits and mapping this to decoded
+ symbol as
+ symbol = bit ? 0 : 1
+
+ Otherwise, i.e. when flag is TRUE, code num is determined by
+ h264bsdDecodeExpGolombUnsigned and this is used as the decoded
+ symbol.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ greaterThanOne flag to indicate if range is wider than [0,1]
+
+ Outputs:
+ value decoded code word is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, no valid code word found
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeExpGolombTruncated(
+ strmData_t *pStrmData,
+ u32 *value,
+ u32 greaterThanOne)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(value);
+
+ if (greaterThanOne)
+ {
+ return(h264bsdDecodeExpGolombUnsigned(pStrmData, value));
+ }
+ else
+ {
+ *value = h264bsdGetBits(pStrmData,1);
+ if (*value == END_OF_STREAM)
+ return (HANTRO_NOK);
+ *value ^= 0x1;
+ }
+
+ return (HANTRO_OK);
+
+}
+
--- /dev/null
+++ b/src/h264bsd_vlc.h
@@ -1,0 +1,64 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_VLC_H
+#define H264SWDEC_VLC_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+#include "h264bsd_transform.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeExpGolombUnsigned(strmData_t *pStrmData, u32 *value);
+
+u32 h264bsdDecodeExpGolombSigned(strmData_t *pStrmData, i32 *value);
+
+u32 h264bsdDecodeExpGolombMapped(strmData_t *pStrmData, u32 *value,
+ u32 isIntra);
+
+u32 h264bsdDecodeExpGolombTruncated(strmData_t *pStrmData, u32 *value,
+ u32 greaterThanOne);
+
+#endif /* #ifdef H264SWDEC_VLC_H */
+
--- /dev/null
+++ b/src/h264bsd_vui.c
@@ -1,0 +1,492 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodeVuiParameters
+ DecodeHrdParameters
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_vui.h"
+#include "basetype.h"
+#include "h264bsd_vlc.h"
+#include "h264bsd_stream.h"
+#include "h264bsd_cfg.h"
+#include "h264bsd_util.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+#define MAX_DPB_SIZE 16
+#define MAX_BR 240000 /* for level 5.1 */
+#define MAX_CPB 240000 /* for level 5.1 */
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 DecodeHrdParameters(
+ strmData_t *pStrmData,
+ hrdParameters_t *pHrdParameters);
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdDecodeVuiParameters
+
+ Functional description:
+ Decode VUI parameters from the stream. See standard for details.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ pVuiParameters decoded information is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data or end of stream
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeVuiParameters(strmData_t *pStrmData,
+ vuiParameters_t *pVuiParameters)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pVuiParameters);
+
+ memset(pVuiParameters, 0, sizeof(vuiParameters_t));
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->aspectRatioPresentFlag = (tmp == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pVuiParameters->aspectRatioPresentFlag)
+ {
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->aspectRatioIdc = tmp;
+
+ if (pVuiParameters->aspectRatioIdc == ASPECT_RATIO_EXTENDED_SAR)
+ {
+ tmp = h264bsdGetBits(pStrmData, 16);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->sarWidth = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 16);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->sarHeight = tmp;
+ }
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->overscanInfoPresentFlag = (tmp == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pVuiParameters->overscanInfoPresentFlag)
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->overscanAppropriateFlag = (tmp == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->videoSignalTypePresentFlag = (tmp == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pVuiParameters->videoSignalTypePresentFlag)
+ {
+ tmp = h264bsdGetBits(pStrmData, 3);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->videoFormat = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->videoFullRangeFlag = (tmp == 1) ?
+ HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->colourDescriptionPresentFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pVuiParameters->colourDescriptionPresentFlag)
+ {
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->colourPrimaries = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->transferCharacteristics = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 8);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->matrixCoefficients = tmp;
+ }
+ else
+ {
+ pVuiParameters->colourPrimaries = 2;
+ pVuiParameters->transferCharacteristics = 2;
+ pVuiParameters->matrixCoefficients = 2;
+ }
+ }
+ else
+ {
+ pVuiParameters->videoFormat = 5;
+ pVuiParameters->colourPrimaries = 2;
+ pVuiParameters->transferCharacteristics = 2;
+ pVuiParameters->matrixCoefficients = 2;
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->chromaLocInfoPresentFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pVuiParameters->chromaLocInfoPresentFlag)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pVuiParameters->chromaSampleLocTypeTopField);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pVuiParameters->chromaSampleLocTypeTopField > 5)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pVuiParameters->chromaSampleLocTypeBottomField);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pVuiParameters->chromaSampleLocTypeBottomField > 5)
+ return(HANTRO_NOK);
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->timingInfoPresentFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pVuiParameters->timingInfoPresentFlag)
+ {
+ tmp = h264bsdShowBits32(pStrmData);
+ if (h264bsdFlushBits(pStrmData, 32) == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp == 0)
+ return(HANTRO_NOK);
+ pVuiParameters->numUnitsInTick = tmp;
+
+ tmp = h264bsdShowBits32(pStrmData);
+ if (h264bsdFlushBits(pStrmData, 32) == END_OF_STREAM)
+ return(HANTRO_NOK);
+ if (tmp == 0)
+ return(HANTRO_NOK);
+ pVuiParameters->timeScale = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->fixedFrameRateFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->nalHrdParametersPresentFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pVuiParameters->nalHrdParametersPresentFlag)
+ {
+ tmp = DecodeHrdParameters(pStrmData, &pVuiParameters->nalHrdParameters);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ else
+ {
+ pVuiParameters->nalHrdParameters.cpbCnt = 1;
+ /* MaxBR and MaxCPB should be the values correspondig to the levelIdc
+ * in the SPS containing these VUI parameters. However, these values
+ * are not used anywhere and maximum for any level will be used here */
+ pVuiParameters->nalHrdParameters.bitRateValue[0] = 1200 * MAX_BR + 1;
+ pVuiParameters->nalHrdParameters.cpbSizeValue[0] = 1200 * MAX_CPB + 1;
+ pVuiParameters->nalHrdParameters.initialCpbRemovalDelayLength = 24;
+ pVuiParameters->nalHrdParameters.cpbRemovalDelayLength = 24;
+ pVuiParameters->nalHrdParameters.dpbOutputDelayLength = 24;
+ pVuiParameters->nalHrdParameters.timeOffsetLength = 24;
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->vclHrdParametersPresentFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pVuiParameters->vclHrdParametersPresentFlag)
+ {
+ tmp = DecodeHrdParameters(pStrmData, &pVuiParameters->vclHrdParameters);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ else
+ {
+ pVuiParameters->vclHrdParameters.cpbCnt = 1;
+ /* MaxBR and MaxCPB should be the values correspondig to the levelIdc
+ * in the SPS containing these VUI parameters. However, these values
+ * are not used anywhere and maximum for any level will be used here */
+ pVuiParameters->vclHrdParameters.bitRateValue[0] = 1000 * MAX_BR + 1;
+ pVuiParameters->vclHrdParameters.cpbSizeValue[0] = 1000 * MAX_CPB + 1;
+ pVuiParameters->vclHrdParameters.initialCpbRemovalDelayLength = 24;
+ pVuiParameters->vclHrdParameters.cpbRemovalDelayLength = 24;
+ pVuiParameters->vclHrdParameters.dpbOutputDelayLength = 24;
+ pVuiParameters->vclHrdParameters.timeOffsetLength = 24;
+ }
+
+ if (pVuiParameters->nalHrdParametersPresentFlag ||
+ pVuiParameters->vclHrdParametersPresentFlag)
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->lowDelayHrdFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->picStructPresentFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->bitstreamRestrictionFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ if (pVuiParameters->bitstreamRestrictionFlag)
+ {
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pVuiParameters->motionVectorsOverPicBoundariesFlag =
+ (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pVuiParameters->maxBytesPerPicDenom);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pVuiParameters->maxBytesPerPicDenom > 16)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pVuiParameters->maxBitsPerMbDenom);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pVuiParameters->maxBitsPerMbDenom > 16)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pVuiParameters->log2MaxMvLengthHorizontal);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pVuiParameters->log2MaxMvLengthHorizontal > 16)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pVuiParameters->log2MaxMvLengthVertical);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pVuiParameters->log2MaxMvLengthVertical > 16)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pVuiParameters->numReorderFrames);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pVuiParameters->maxDecFrameBuffering);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ else
+ {
+ pVuiParameters->motionVectorsOverPicBoundariesFlag = HANTRO_TRUE;
+ pVuiParameters->maxBytesPerPicDenom = 2;
+ pVuiParameters->maxBitsPerMbDenom = 1;
+ pVuiParameters->log2MaxMvLengthHorizontal = 16;
+ pVuiParameters->log2MaxMvLengthVertical = 16;
+ pVuiParameters->numReorderFrames = MAX_DPB_SIZE;
+ pVuiParameters->maxDecFrameBuffering = MAX_DPB_SIZE;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeHrdParameters
+
+ Functional description:
+ Decode HRD parameters from the stream. See standard for details.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+
+ Outputs:
+ pHrdParameters decoded information is stored here
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK invalid stream data
+
+------------------------------------------------------------------------------*/
+
+static u32 DecodeHrdParameters(
+ strmData_t *pStrmData,
+ hrdParameters_t *pHrdParameters)
+{
+
+/* Variables */
+
+ u32 tmp, i;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pHrdParameters);
+
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &pHrdParameters->cpbCnt);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ /* cpbCount = cpb_cnt_minus1 + 1 */
+ pHrdParameters->cpbCnt++;
+ if (pHrdParameters->cpbCnt > MAX_CPB_CNT)
+ return(HANTRO_NOK);
+
+ tmp = h264bsdGetBits(pStrmData, 4);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pHrdParameters->bitRateScale = tmp;
+
+ tmp = h264bsdGetBits(pStrmData, 4);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pHrdParameters->cpbSizeScale = tmp;
+
+ for (i = 0; i < pHrdParameters->cpbCnt; i++)
+ {
+ /* bit_rate_value_minus1 in the range [0, 2^32 - 2] */
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pHrdParameters->bitRateValue[i]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pHrdParameters->bitRateValue[i] > 4294967294U)
+ return(HANTRO_NOK);
+ pHrdParameters->bitRateValue[i]++;
+ /* this may result in overflow, but this value is not used for
+ * anything */
+ pHrdParameters->bitRateValue[i] *=
+ 1 << (6 + pHrdParameters->bitRateScale);
+
+ /* cpb_size_value_minus1 in the range [0, 2^32 - 2] */
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
+ &pHrdParameters->cpbSizeValue[i]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ if (pHrdParameters->cpbSizeValue[i] > 4294967294U)
+ return(HANTRO_NOK);
+ pHrdParameters->cpbSizeValue[i]++;
+ /* this may result in overflow, but this value is not used for
+ * anything */
+ pHrdParameters->cpbSizeValue[i] *=
+ 1 << (4 + pHrdParameters->cpbSizeScale);
+
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pHrdParameters->cbrFlag[i] = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
+ }
+
+ tmp = h264bsdGetBits(pStrmData, 5);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pHrdParameters->initialCpbRemovalDelayLength = tmp + 1;
+
+ tmp = h264bsdGetBits(pStrmData, 5);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pHrdParameters->cpbRemovalDelayLength = tmp + 1;
+
+ tmp = h264bsdGetBits(pStrmData, 5);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pHrdParameters->dpbOutputDelayLength = tmp + 1;
+
+ tmp = h264bsdGetBits(pStrmData, 5);
+ if (tmp == END_OF_STREAM)
+ return(HANTRO_NOK);
+ pHrdParameters->timeOffsetLength = tmp;
+
+ return(HANTRO_OK);
+
+}
+
--- /dev/null
+++ b/src/h264bsd_vui.h
@@ -1,0 +1,131 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Modified for use by h264bsd standalone library
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. Module defines
+ 3. Data types
+ 4. Function prototypes
+
+------------------------------------------------------------------------------*/
+
+#ifndef H264SWDEC_VUI_H
+#define H264SWDEC_VUI_H
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "basetype.h"
+#include "h264bsd_stream.h"
+
+/*------------------------------------------------------------------------------
+ 2. Module defines
+------------------------------------------------------------------------------*/
+
+#define MAX_CPB_CNT 32
+
+/*------------------------------------------------------------------------------
+ 3. Data types
+------------------------------------------------------------------------------*/
+
+/* enumerated sample aspect ratios, ASPECT_RATIO_M_N means M:N */
+enum
+{
+ ASPECT_RATIO_UNSPECIFIED = 0,
+ ASPECT_RATIO_1_1,
+ ASPECT_RATIO_12_11,
+ ASPECT_RATIO_10_11,
+ ASPECT_RATIO_16_11,
+ ASPECT_RATIO_40_33,
+ ASPECT_RATIO_24_11,
+ ASPECT_RATIO_20_11,
+ ASPECT_RATIO_32_11,
+ ASPECT_RATIO_80_33,
+ ASPECT_RATIO_18_11,
+ ASPECT_RATIO_15_11,
+ ASPECT_RATIO_64_33,
+ ASPECT_RATIO_160_99,
+ ASPECT_RATIO_EXTENDED_SAR = 255
+};
+
+/* structure to store Hypothetical Reference Decoder (HRD) parameters */
+typedef struct
+{
+ u32 cpbCnt;
+ u32 bitRateScale;
+ u32 cpbSizeScale;
+ u32 bitRateValue[MAX_CPB_CNT];
+ u32 cpbSizeValue[MAX_CPB_CNT];
+ u32 cbrFlag[MAX_CPB_CNT];
+ u32 initialCpbRemovalDelayLength;
+ u32 cpbRemovalDelayLength;
+ u32 dpbOutputDelayLength;
+ u32 timeOffsetLength;
+} hrdParameters_t;
+
+/* storage for VUI parameters */
+typedef struct
+{
+ u32 aspectRatioPresentFlag;
+ u32 aspectRatioIdc;
+ u32 sarWidth;
+ u32 sarHeight;
+ u32 overscanInfoPresentFlag;
+ u32 overscanAppropriateFlag;
+ u32 videoSignalTypePresentFlag;
+ u32 videoFormat;
+ u32 videoFullRangeFlag;
+ u32 colourDescriptionPresentFlag;
+ u32 colourPrimaries;
+ u32 transferCharacteristics;
+ u32 matrixCoefficients;
+ u32 chromaLocInfoPresentFlag;
+ u32 chromaSampleLocTypeTopField;
+ u32 chromaSampleLocTypeBottomField;
+ u32 timingInfoPresentFlag;
+ u32 numUnitsInTick;
+ u32 timeScale;
+ u32 fixedFrameRateFlag;
+ u32 nalHrdParametersPresentFlag;
+ hrdParameters_t nalHrdParameters;
+ u32 vclHrdParametersPresentFlag;
+ hrdParameters_t vclHrdParameters;
+ u32 lowDelayHrdFlag;
+ u32 picStructPresentFlag;
+ u32 bitstreamRestrictionFlag;
+ u32 motionVectorsOverPicBoundariesFlag;
+ u32 maxBytesPerPicDenom;
+ u32 maxBitsPerMbDenom;
+ u32 log2MaxMvLengthHorizontal;
+ u32 log2MaxMvLengthVertical;
+ u32 numReorderFrames;
+ u32 maxDecFrameBuffering;
+} vuiParameters_t;
+
+/*------------------------------------------------------------------------------
+ 4. Function prototypes
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeVuiParameters(strmData_t *pStrmData,
+ vuiParameters_t *pVuiParameters);
+
+#endif /* #ifdef H264SWDEC_VUI_H */
+
--- /dev/null
+++ b/win/h264bsd.def
@@ -1,0 +1,16 @@
+LIBRARY H264BSD
+EXPORTS
+ h264bsdInit
+ h264bsdDecode
+ h264bsdShutdown
+ h264bsdNextOutputPicture
+ h264bsdPicWidth
+ h264bsdPicHeight
+ h264bsdVideoRange
+ h264bsdMatrixCoefficients
+ h264bsdCroppingParams
+ h264bsdSampleAspectRatio
+ h264bsdCheckValidParamSets
+ h264bsdFlushBuffer
+ h264bsdAlloc
+ h264bsdFree
--- /dev/null
+++ b/win/h264bsd.sln
@@ -1,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h264bsd", "h264bsd.vcxproj", "{FC89E991-5229-4CEB-94AF-96C09943FCA4}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {FC89E991-5229-4CEB-94AF-96C09943FCA4}.Debug|Win32.ActiveCfg = Debug|Win32
+ {FC89E991-5229-4CEB-94AF-96C09943FCA4}.Debug|Win32.Build.0 = Debug|Win32
+ {FC89E991-5229-4CEB-94AF-96C09943FCA4}.Debug|x64.ActiveCfg = Debug|x64
+ {FC89E991-5229-4CEB-94AF-96C09943FCA4}.Debug|x64.Build.0 = Debug|x64
+ {FC89E991-5229-4CEB-94AF-96C09943FCA4}.Release|Win32.ActiveCfg = Release|Win32
+ {FC89E991-5229-4CEB-94AF-96C09943FCA4}.Release|Win32.Build.0 = Release|Win32
+ {FC89E991-5229-4CEB-94AF-96C09943FCA4}.Release|x64.ActiveCfg = Release|x64
+ {FC89E991-5229-4CEB-94AF-96C09943FCA4}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
--- /dev/null
+++ b/win/h264bsd.vcxproj
@@ -1,0 +1,210 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{FC89E991-5229-4CEB-94AF-96C09943FCA4}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>h264bsd</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)\$(Platform)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)\$(Platform)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)\$(Platform)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)\$(Platform)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;H264BSD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ModuleDefinitionFile>h264bsd.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;H264BSD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ModuleDefinitionFile>h264bsd.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;H264BSD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <ModuleDefinitionFile>h264bsd.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;H264BSD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <ModuleDefinitionFile>h264bsd.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <None Include="h264bsd.def" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\src\h264bsd_byte_stream.c" />
+ <ClCompile Include="..\src\h264bsd_cavlc.c" />
+ <ClCompile Include="..\src\h264bsd_conceal.c" />
+ <ClCompile Include="..\src\h264bsd_deblocking.c" />
+ <ClCompile Include="..\src\h264bsd_decoder.c" />
+ <ClCompile Include="..\src\h264bsd_dpb.c" />
+ <ClCompile Include="..\src\h264bsd_image.c" />
+ <ClCompile Include="..\src\h264bsd_inter_prediction.c" />
+ <ClCompile Include="..\src\h264bsd_intra_prediction.c" />
+ <ClCompile Include="..\src\h264bsd_macroblock_layer.c" />
+ <ClCompile Include="..\src\h264bsd_nal_unit.c" />
+ <ClCompile Include="..\src\h264bsd_neighbour.c" />
+ <ClCompile Include="..\src\h264bsd_pic_order_cnt.c" />
+ <ClCompile Include="..\src\h264bsd_pic_param_set.c" />
+ <ClCompile Include="..\src\h264bsd_reconstruct.c" />
+ <ClCompile Include="..\src\h264bsd_sei.c" />
+ <ClCompile Include="..\src\h264bsd_seq_param_set.c" />
+ <ClCompile Include="..\src\h264bsd_slice_data.c" />
+ <ClCompile Include="..\src\h264bsd_slice_group_map.c" />
+ <ClCompile Include="..\src\h264bsd_slice_header.c" />
+ <ClCompile Include="..\src\h264bsd_storage.c" />
+ <ClCompile Include="..\src\h264bsd_stream.c" />
+ <ClCompile Include="..\src\h264bsd_transform.c" />
+ <ClCompile Include="..\src\h264bsd_util.c" />
+ <ClCompile Include="..\src\h264bsd_vlc.c" />
+ <ClCompile Include="..\src\h264bsd_vui.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\src\basetype.h" />
+ <ClInclude Include="..\src\h264bsd_byte_stream.h" />
+ <ClInclude Include="..\src\h264bsd_cavlc.h" />
+ <ClInclude Include="..\src\h264bsd_cfg.h" />
+ <ClInclude Include="..\src\h264bsd_conceal.h" />
+ <ClInclude Include="..\src\h264bsd_container.h" />
+ <ClInclude Include="..\src\h264bsd_deblocking.h" />
+ <ClInclude Include="..\src\h264bsd_decoder.h" />
+ <ClInclude Include="..\src\h264bsd_dpb.h" />
+ <ClInclude Include="..\src\h264bsd_image.h" />
+ <ClInclude Include="..\src\h264bsd_inter_prediction.h" />
+ <ClInclude Include="..\src\h264bsd_intra_prediction.h" />
+ <ClInclude Include="..\src\h264bsd_macroblock_layer.h" />
+ <ClInclude Include="..\src\h264bsd_nal_unit.h" />
+ <ClInclude Include="..\src\h264bsd_neighbour.h" />
+ <ClInclude Include="..\src\h264bsd_pic_order_cnt.h" />
+ <ClInclude Include="..\src\h264bsd_pic_param_set.h" />
+ <ClInclude Include="..\src\h264bsd_reconstruct.h" />
+ <ClInclude Include="..\src\h264bsd_sei.h" />
+ <ClInclude Include="..\src\h264bsd_seq_param_set.h" />
+ <ClInclude Include="..\src\h264bsd_slice_data.h" />
+ <ClInclude Include="..\src\h264bsd_slice_group_map.h" />
+ <ClInclude Include="..\src\h264bsd_slice_header.h" />
+ <ClInclude Include="..\src\h264bsd_storage.h" />
+ <ClInclude Include="..\src\h264bsd_stream.h" />
+ <ClInclude Include="..\src\h264bsd_transform.h" />
+ <ClInclude Include="..\src\h264bsd_util.h" />
+ <ClInclude Include="..\src\h264bsd_vlc.h" />
+ <ClInclude Include="..\src\h264bsd_vui.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
--- /dev/null
+++ b/win/h264bsd.vcxproj.filters
@@ -1,0 +1,191 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="h264bsd.def">
+ <Filter>Source Files</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\src\h264bsd_slice_group_map.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_slice_header.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_storage.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_stream.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_transform.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_util.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_vlc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_vui.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_byte_stream.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_cavlc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_conceal.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_deblocking.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_decoder.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_dpb.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_image.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_inter_prediction.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_intra_prediction.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_macroblock_layer.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_nal_unit.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_neighbour.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_pic_order_cnt.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_pic_param_set.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_reconstruct.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_sei.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_seq_param_set.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\h264bsd_slice_data.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\src\h264bsd_slice_group_map.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_slice_header.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_storage.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_stream.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_transform.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_util.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_vlc.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_vui.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\basetype.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_byte_stream.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_cavlc.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_cfg.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_conceal.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_container.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_deblocking.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_decoder.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_dpb.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_image.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_inter_prediction.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_intra_prediction.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_macroblock_layer.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_nal_unit.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_neighbour.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_pic_order_cnt.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_pic_param_set.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_reconstruct.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_sei.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_seq_param_set.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\src\h264bsd_slice_data.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project>
\ No newline at end of file