summaryrefslogtreecommitdiff
path: root/omx/ti_omx_config_parser
diff options
context:
space:
mode:
authorRebecca Schultz Zavin <rebecca@android.com>2009-07-16 17:22:42 -0700
committerRebecca Schultz Zavin <rebecca@android.com>2009-07-17 15:51:24 -0700
commitfb3766f18a2c18b6f4798a6a631fdb88fcacd1dc (patch)
treec80a73eb905c31aced77165149c31271138812ff /omx/ti_omx_config_parser
parent48c9cf0ad8ae8e3f754e54790857fd57eb79c48d (diff)
downloadomap3-fb3766f18a2c18b6f4798a6a631fdb88fcacd1dc.tar.gz
Adding omap3 omx code
Signed-off-by: Rebecca Schultz Zavin <rebecca@android.com>
Diffstat (limited to 'omx/ti_omx_config_parser')
-rw-r--r--omx/ti_omx_config_parser/Android.mk56
-rw-r--r--omx/ti_omx_config_parser/inc/ti_m4v_config_parser.h129
-rw-r--r--omx/ti_omx_config_parser/inc/ti_omx_config_parser.h56
-rw-r--r--omx/ti_omx_config_parser/inc/ti_video_config_parser.h46
-rw-r--r--omx/ti_omx_config_parser/src/ti_m4v_config_parser.cpp1237
-rw-r--r--omx/ti_omx_config_parser/src/ti_omx_config_parser.cpp179
-rw-r--r--omx/ti_omx_config_parser/src/ti_video_config_parser.cpp287
7 files changed, 1990 insertions, 0 deletions
diff --git a/omx/ti_omx_config_parser/Android.mk b/omx/ti_omx_config_parser/Android.mk
new file mode 100644
index 0000000..c0e642e
--- /dev/null
+++ b/omx/ti_omx_config_parser/Android.mk
@@ -0,0 +1,56 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+$(call add-prebuilt-files, ETC)
+LOCAL_PRELINK_MODULE := false
+LOCAL_SRC_FILES := \
+ src/ti_video_config_parser.cpp \
+ src/ti_m4v_config_parser.cpp \
+ src/ti_omx_config_parser.cpp
+
+LOCAL_MODULE := libVendor_ti_omx_config_parser
+
+PV_TOP := external/opencore
+
+PV_COPY_HEADERS_TO := libpv
+
+PV_INCLUDES := \
+ $(PV_TOP)/android \
+ $(PV_TOP)/extern_libs_v2/khronos/openmax/include \
+ $(PV_TOP)/engines/common/include \
+ $(PV_TOP)/engines/player/config/android \
+ $(PV_TOP)/engines/player/include \
+ $(PV_TOP)/nodes/pvmediaoutputnode/include \
+ $(PV_TOP)/nodes/pvdownloadmanagernode/config/opencore \
+ $(PV_TOP)/pvmi/pvmf/include \
+ $(PV_TOP)/fileformats/mp4/parser/config/opencore \
+ $(PV_TOP)/oscl/oscl/config/android \
+ $(PV_TOP)/oscl/oscl/config/shared \
+ $(PV_TOP)/engines/author/include \
+ $(PV_TOP)/android/drm/oma1/src \
+ $(PV_TOP)/build_config/opencore_dynamic \
+ $(PV_TOP)/codecs_v2/omx/omx_common/src \
+ $(PV_TOP)/codecs_v2/omx/omx_common/include \
+ $(PV_TOP)/extern_libs_v2/khronos/openmax/include \
+ $(PV_TOP)/pvmi/pvmf/include \
+ $(PV_TOP)/oscl/oscl/osclutil/src \
+ $(TARGET_OUT_HEADERS)/$(PV_COPY_HEADERS_TO)
+
+LOCAL_CFLAGS := $(PV_CFLAGS)
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_COPY_HEADERS := \
+ inc/ti_video_config_parser.h \
+ inc/ti_m4v_config_parser.h \
+ inc/ti_omx_config_parser.h
+
+LOCAL_C_INCLUDES := \
+ $(PV_INCLUDES)
+
+-include $(PV_TOP)/Android_platform_extras.mk
+
+-include $(PV_TOP)/Android_system_extras.mk
+
+LOCAL_SHARED_LIBRARIES += libopencore_common
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/omx/ti_omx_config_parser/inc/ti_m4v_config_parser.h b/omx/ti_omx_config_parser/inc/ti_m4v_config_parser.h
new file mode 100644
index 0000000..ee979e4
--- /dev/null
+++ b/omx/ti_omx_config_parser/inc/ti_m4v_config_parser.h
@@ -0,0 +1,129 @@
+/* ------------------------------------------------------------------
+ * Copyright (C) 1998-2009 PacketVideo
+ *
+ * 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 TI_M4V_CONFIG_PARSER_H_INCLUDED
+#define TI_M4V_CONFIG_PARSER_H_INCLUDED
+
+#include "oscl_base.h"
+#include "oscl_types.h"
+
+#define USE_LATER 0 // for some code that will be needed in the future
+
+#define MP4_INVALID_VOL_PARAM -1
+#define SHORT_HEADER_MODE -4
+
+
+#define VISUAL_OBJECT_SEQUENCE_START_CODE 0x01B0
+#define VISUAL_OBJECT_SEQUENCE_END_CODE 0x01B1
+#define VISUAL_OBJECT_START_CODE 0x01B5
+#define VO_START_CODE 0x8
+#define VO_HEADER_LENGTH 32
+#define VOL_START_CODE 0x12
+#define VOL_START_CODE_LENGTH 28
+
+#define GROUP_START_CODE 0x01B3
+#define GROUP_START_CODE_LENGTH 32
+
+#define VOP_ID_CODE_LENGTH 5
+#define VOP_TEMP_REF_CODE_LENGTH 16
+
+#define USER_DATA_START_CODE 0x01B2
+#define USER_DATA_START_CODE_LENGTH 32
+
+#define SHORT_VIDEO_START_MARKER 0x20
+#define SHORT_VIDEO_START_MARKER_LENGTH 22
+
+typedef struct
+{
+ uint8 *data;
+ uint32 numBytes;
+ uint32 bytePos;
+ uint32 bitBuf;
+ uint32 dataBitPos;
+ uint32 bitPos;
+} mp4StreamType;
+
+
+int16 ShowBits(
+ mp4StreamType *pStream,
+ uint8 ucNBits,
+ uint32 *pulOutData
+);
+
+int16 FlushBits(
+ mp4StreamType *pStream,
+ uint8 ucNBits
+);
+
+int16 ReadBits(
+ mp4StreamType *pStream,
+ uint8 ucNBits,
+ uint32 *pulOutData
+);
+
+int16 ByteAlign(
+ mp4StreamType *pStream
+);
+
+ OSCL_IMPORT_REF int16 iDecodeVOLHeader(
+ mp4StreamType *psBits,
+ int32 *width,
+ int32 *height,
+ int32 *,
+ int32 *,
+ int32 *profilelevel);
+ OSCL_IMPORT_REF int16 iGetM4VConfigInfo(
+ uint8 *buffer,
+ int32 length,
+ int32 *width,
+ int32 *height,
+ int32 *,
+ int32 *);
+
+int16 DecodeUserData(mp4StreamType *pStream);
+
+ OSCL_IMPORT_REF int16 iDecodeShortHeader(
+ mp4StreamType *psBits,
+ int32 *width,
+ int32 *height,
+ int32 *,
+ int32 *);
+ OSCL_IMPORT_REF int16 iGetAVCConfigInfo(
+ uint8 *buffer,
+ int32 length,
+ int32 *width,
+ int32 *height,
+ int32 *,
+ int32 *,
+ int32 *profile,
+ int32 *level);
+
+int32 FindNAL(uint8** nal_pnt, uint8* buffer, int32 length);
+int16 DecodeSPS(mp4StreamType *psBits, int32 *width, int32 *height, int32 *display_width, int32 *display_height, int32 *profile_idc, int32 *level_idc);
+#if USE_LATER
+int32 DecodeHRD(mp4StreamType *psBits);
+int32 DecodeVUI(mp4StreamType *psBits);
+#endif
+int32 DecodePPS(mp4StreamType *psBits);
+
+void ue_v(mp4StreamType *psBits, uint32 *codeNum);
+void se_v(mp4StreamType *psBits, int32 *value);
+void Parser_EBSPtoRBSP(uint8 *nal_unit, int32 *size);
+
+#endif //TI_M4V_CONFIG_PARSER_H_INCLUDED
+
+
diff --git a/omx/ti_omx_config_parser/inc/ti_omx_config_parser.h b/omx/ti_omx_config_parser/inc/ti_omx_config_parser.h
new file mode 100644
index 0000000..cf4b4ec
--- /dev/null
+++ b/omx/ti_omx_config_parser/inc/ti_omx_config_parser.h
@@ -0,0 +1,56 @@
+/* ------------------------------------------------------------------
+ * Copyright (C) 1998-2009 PacketVideo
+ *
+ * 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 TI_OMX_CONFIG_PARSER_H_INCLUDED
+#define TI_OMX_CONFIG_PARSER_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C"
+{
+ OSCL_IMPORT_REF OMX_BOOL TIOMXConfigParser(
+ OMX_PTR aInputParameters,
+ OMX_PTR aOutputParameters);
+
+}
+#endif
+
+
+typedef struct
+{
+ OMX_U8* inPtr; //pointer to codec configuration header
+ OMX_U32 inBytes; //length of codec configuration header
+ OMX_STRING cComponentRole; //OMX component codec type
+ OMX_STRING cComponentName; //OMX component name
+} OMXConfigParserInputs;
+
+typedef struct
+{
+ OMX_U16 Channels;
+ OMX_U16 BitsPerSample;
+ OMX_U32 SamplesPerSec;
+} AudioOMXConfigParserOutputs;
+
+typedef struct
+{
+ OMX_U32 width;
+ OMX_U32 height;
+ OMX_U32 profile;
+ OMX_U32 level;
+} VideoOMXConfigParserOutputs;
+
+#endif
+
diff --git a/omx/ti_omx_config_parser/inc/ti_video_config_parser.h b/omx/ti_omx_config_parser/inc/ti_video_config_parser.h
new file mode 100644
index 0000000..5b226e4
--- /dev/null
+++ b/omx/ti_omx_config_parser/inc/ti_video_config_parser.h
@@ -0,0 +1,46 @@
+/* ------------------------------------------------------------------
+ * Copyright (C) 1998-2009 PacketVideo
+ *
+ * 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 TI_VIDEO_CONFIG_PARSER_H_INCLUDED
+#define TI_VIDEO_CONFIG_PARSER_H_INCLUDED
+
+#include "oscl_base.h"
+#include "oscl_types.h"
+#include "pvmf_format_type.h"
+
+typedef struct
+{
+ uint8 *inPtr;
+ uint32 inBytes;
+ PVMFFormatType iMimeType;
+} tiVideoConfigParserInputs;
+
+typedef struct _tiVideoConfigParserOutputs
+{
+ uint32 width;
+ uint32 height;
+ uint32 profile;
+ uint32 level;
+} tiVideoConfigParserOutputs;
+
+OSCL_IMPORT_REF int16 ti_video_config_parser(
+ tiVideoConfigParserInputs *aInputs,
+ tiVideoConfigParserOutputs *aOutputs);
+
+#endif //TI_VIDEO_CONFIG_PARSER_H_INCLUDED
+
+
diff --git a/omx/ti_omx_config_parser/src/ti_m4v_config_parser.cpp b/omx/ti_omx_config_parser/src/ti_m4v_config_parser.cpp
new file mode 100644
index 0000000..4250003
--- /dev/null
+++ b/omx/ti_omx_config_parser/src/ti_m4v_config_parser.cpp
@@ -0,0 +1,1237 @@
+/* ------------------------------------------------------------------
+ * Copyright (C) 1998-2009 PacketVideo
+ *
+ * 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.
+ * -------------------------------------------------------------------
+ */
+
+#include "ti_m4v_config_parser.h"
+#include "oscl_mem.h"
+#include "oscl_dll.h"
+OSCL_DLL_ENTRY_POINT_DEFAULT()
+
+#define PV_CLZ(A,B) while (((B) & 0x8000) == 0) {(B) <<=1; A++;}
+
+static const uint32 mask[33] =
+{
+ 0x00000000, 0x00000001, 0x00000003, 0x00000007,
+ 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
+ 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
+ 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
+ 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
+ 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
+ 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
+ 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
+ 0xffffffff
+};
+
+int32 LocateFrameHeader(uint8 *ptr, int32 size)
+{
+ int32 count = 0;
+ int32 i = size;
+
+ if (size < 1)
+ {
+ return 0;
+ }
+ while (i--)
+ {
+ if ((count > 1) && (*ptr == 0x01))
+ {
+ i += 2;
+ break;
+ }
+
+ if (*ptr++)
+ count = 0;
+ else
+ count++;
+ }
+ return (size - (i + 1));
+}
+
+void movePointerTo(mp4StreamType *psBits, int32 pos)
+{
+ uint32 byte_pos;
+ if (pos < 0)
+ {
+ pos = 0;
+ }
+
+ byte_pos = pos >> 3;
+
+ if (byte_pos > (psBits->numBytes - psBits->bytePos))
+ {
+ byte_pos = (psBits->numBytes - psBits->bytePos);
+ }
+
+ psBits->bytePos = byte_pos & -4;
+ psBits->dataBitPos = psBits->bytePos << 3;
+ FlushBits(psBits, ((pos & 0x7) + ((byte_pos & 0x3) << 3)));
+}
+
+int16 SearchNextM4VFrame(mp4StreamType *psBits)
+{
+ int16 status = 0;
+ uint8 *ptr;
+ int32 i;
+ uint32 initial_byte_aligned_position = (psBits->dataBitPos + 7) >> 3;
+
+ ptr = psBits->data + initial_byte_aligned_position;
+
+ i = LocateFrameHeader(ptr, psBits->numBytes - initial_byte_aligned_position);
+ if (psBits->numBytes <= initial_byte_aligned_position + i)
+ {
+ status = -1;
+ }
+ (void)movePointerTo(psBits, ((i + initial_byte_aligned_position) << 3)); /* ptr + i */
+ return status;
+}
+
+OSCL_EXPORT_REF int16 iGetM4VConfigInfo(uint8 *buffer, int32 length, int32 *width, int32 *height, int32 *display_width, int32 *display_height)
+{
+ int16 status;
+ mp4StreamType psBits;
+ psBits.data = buffer;
+ psBits.numBytes = length;
+ psBits.bitBuf = 0;
+ psBits.bitPos = 32;
+ psBits.bytePos = 0;
+ psBits.dataBitPos = 0;
+ *width = *height = *display_height = *display_width = 0;
+
+ if (length == 0)
+ {
+ return MP4_INVALID_VOL_PARAM;
+ }
+ int32 profilelevel = 0; // dummy value discarded here
+ status = iDecodeVOLHeader(&psBits, width, height, display_width, display_height, &profilelevel);
+ return status;
+}
+
+// name: iDecodeVOLHeader
+// Purpose: decode VOL header
+// return: error code
+OSCL_EXPORT_REF int16 iDecodeVOLHeader(mp4StreamType *psBits, int32 *width, int32 *height, int32 *display_width, int32 *display_height, int32 *profilelevel)
+{
+ int16 iErrorStat;
+ uint32 codeword;
+ int32 time_increment_resolution, nbits_time_increment;
+ int32 i, j;
+
+ *profilelevel = 0x0000FFFF; // init to some invalid value. When this value is returned, then no profilelevel info is available
+
+ ShowBits(psBits, 32, &codeword);
+
+ if (codeword == VISUAL_OBJECT_SEQUENCE_START_CODE)
+ {
+ //DV: this is the wrong way to skip bits, use FLush or Read psBits->dataBitPos += 32;
+ ReadBits(psBits, 32, &codeword); // skip 32 bits of the Start code
+
+ ReadBits(psBits, 8, &codeword);
+
+ // record profile and level
+ *profilelevel = (int) codeword;
+
+ ShowBits(psBits, 32, &codeword);
+ if (codeword == USER_DATA_START_CODE)
+ {
+ iErrorStat = DecodeUserData(psBits);
+ if (iErrorStat) return MP4_INVALID_VOL_PARAM;
+ }
+
+
+ ReadBits(psBits, 32, &codeword);
+ if (codeword != VISUAL_OBJECT_START_CODE) return MP4_INVALID_VOL_PARAM;
+
+ /* is_visual_object_identifier */
+ ReadBits(psBits, 1, &codeword);
+
+ if (codeword)
+ {
+ /* visual_object_verid */
+ ReadBits(psBits, 4, &codeword);
+ /* visual_object_priority */
+ ReadBits(psBits, 3, &codeword);
+ }
+ /* visual_object_type */
+ ReadBits(psBits, 4, &codeword);
+
+ if (codeword == 1)
+ { /* video_signal_type */
+ ReadBits(psBits, 1, &codeword);
+ if (codeword == 1)
+ {
+ /* video_format */
+ ReadBits(psBits, 3, &codeword);
+ /* video_range */
+ ReadBits(psBits, 1, &codeword);
+ /* color_description */
+ ReadBits(psBits, 1, &codeword);
+ if (codeword == 1)
+ {
+ /* color_primaries */
+ ReadBits(psBits, 8, &codeword);;
+ /* transfer_characteristics */
+ ReadBits(psBits, 8, &codeword);
+ /* matrix_coefficients */
+ ReadBits(psBits, 8, &codeword);
+ }
+ }
+ }
+ else
+ {
+ int16 status = 0;
+ do
+ {
+ /* Search for VOL_HEADER */
+ status = SearchNextM4VFrame(psBits); /* search 0x00 0x00 0x01 */
+ if (status != 0)
+ return MP4_INVALID_VOL_PARAM;
+
+ status = ReadBits(psBits, VOL_START_CODE_LENGTH, &codeword);
+ }
+ while ((codeword != VOL_START_CODE) && (status == 0));
+ goto decode_vol;
+ }
+ /* next_start_code() */
+ ByteAlign(psBits);
+
+ ShowBits(psBits, 32, &codeword);
+ if (codeword == USER_DATA_START_CODE)
+ {
+ iErrorStat = DecodeUserData(psBits);
+ if (iErrorStat) return MP4_INVALID_VOL_PARAM;
+ }
+ ShowBits(psBits, 27, &codeword);
+ }
+ else
+ {
+ ShowBits(psBits, 27, &codeword);
+ }
+
+ if (codeword == VO_START_CODE)
+ {
+
+ ReadBits(psBits, 32, &codeword);
+
+ /* video_object_layer_start_code */
+ ReadBits(psBits, 28, &codeword);
+ if (codeword != VOL_START_CODE)
+ {
+ if (psBits->dataBitPos >= (psBits->numBytes << 3))
+ {
+ return SHORT_HEADER_MODE; /* SH */
+ }
+ else
+ {
+ int16 status = 0;
+ do
+ {
+ /* Search for VOL_HEADER */
+ status = SearchNextM4VFrame(psBits); /* search 0x00 0x00 0x01 */
+ if (status != 0)
+ return MP4_INVALID_VOL_PARAM;
+
+ status = ReadBits(psBits, VOL_START_CODE_LENGTH, &codeword);
+ }
+ while ((codeword != VOL_START_CODE) && (status == 0));
+ goto decode_vol;
+ }
+ }
+decode_vol:
+
+ uint32 vol_id;
+
+ /* vol_id (4 bits) */
+ ReadBits(psBits, 4, & vol_id);
+
+ // RandomAccessibleVOLFlag
+ ReadBits(psBits, 1, &codeword);
+
+ //Video Object Type Indication
+ ReadBits(psBits, 8, &codeword);
+ if (codeword != 1)
+ {
+ //return MP4_INVALID_VOL_PARAM; //TI supports this feature
+ }
+
+ // is_object_layer_identifier
+ ReadBits(psBits, 1, &codeword);
+
+ if (codeword)
+ {
+ ReadBits(psBits, 4, &codeword);
+ ReadBits(psBits, 3, &codeword);
+ }
+
+ // aspect ratio
+ ReadBits(psBits, 4, &codeword);
+
+ if (codeword == 0xF)
+ {
+ // Extended Parameter
+ /* width */
+ ReadBits(psBits, 8, &codeword);
+ /* height */
+ ReadBits(psBits, 8, &codeword);
+ }
+
+ ReadBits(psBits, 1, &codeword);
+
+ if (codeword)
+ {
+ ReadBits(psBits, 2, &codeword);
+ if (codeword != 1)
+ {
+ return MP4_INVALID_VOL_PARAM;
+ }
+
+ ReadBits(psBits, 1, &codeword);
+
+ if (!codeword)
+ {
+ //return MP4_INVALID_VOL_PARAM; //TI supports this feature
+ }
+
+ ReadBits(psBits, 1, &codeword);
+ if (codeword) /* if (vbv_parameters) {}, page 36 */
+ {
+ ReadBits(psBits, 15, &codeword);
+ ReadBits(psBits, 1, &codeword);
+ if (codeword != 1)
+ {
+ return MP4_INVALID_VOL_PARAM;
+ }
+
+ ReadBits(psBits, 15, &codeword);
+ ReadBits(psBits, 1, &codeword);
+ if (codeword != 1)
+ {
+ return MP4_INVALID_VOL_PARAM;
+ }
+
+
+ ReadBits(psBits, 19, &codeword);
+ if (!(codeword & 0x8))
+ {
+ return MP4_INVALID_VOL_PARAM;
+ }
+
+ ReadBits(psBits, 11, &codeword);
+ ReadBits(psBits, 1, &codeword);
+ if (codeword != 1)
+ {
+ return MP4_INVALID_VOL_PARAM;
+ }
+
+ ReadBits(psBits, 15, &codeword);
+ ReadBits(psBits, 1, &codeword);
+ if (codeword != 1)
+ {
+ return MP4_INVALID_VOL_PARAM;
+ }
+ }
+
+ }
+
+ ReadBits(psBits, 2, &codeword);
+
+ if (codeword != 0)
+ {
+ return MP4_INVALID_VOL_PARAM;
+ }
+
+ ReadBits(psBits, 1, &codeword);
+ if (codeword != 1)
+ {
+ return MP4_INVALID_VOL_PARAM;
+ }
+
+ ReadBits(psBits, 16, &codeword);
+ time_increment_resolution = codeword;
+
+
+ ReadBits(psBits, 1, &codeword);
+ if (codeword != 1)
+ {
+ return MP4_INVALID_VOL_PARAM;
+ }
+
+
+
+ ReadBits(psBits, 1, &codeword);
+
+ if (codeword && time_increment_resolution > 2)
+ {
+ i = time_increment_resolution - 1;
+ j = 1;
+ while (i >>= 1)
+ {
+ j++;
+ }
+ nbits_time_increment = j;
+
+ ReadBits(psBits, nbits_time_increment, &codeword);
+ }
+
+ ReadBits(psBits, 1, &codeword);
+ if (codeword != 1)
+ {
+ return MP4_INVALID_VOL_PARAM;
+ }
+
+ /* this should be 176 for QCIF */
+ ReadBits(psBits, 13, &codeword);
+ *display_width = (int32)codeword;
+ ReadBits(psBits, 1, &codeword);
+ if (codeword != 1)
+ {
+ return MP4_INVALID_VOL_PARAM;
+ }
+
+ /* this should be 144 for QCIF */
+ ReadBits(psBits, 13, &codeword);
+ *display_height = (int32)codeword;
+
+ *width = (*display_width + 15) & -16;
+ *height = (*display_height + 15) & -16;
+ }
+ else
+ {
+ /* SHORT_HEADER */
+ ShowBits(psBits, SHORT_VIDEO_START_MARKER_LENGTH, &codeword);
+ if (codeword == SHORT_VIDEO_START_MARKER)
+ {
+ iDecodeShortHeader(psBits, width, height, display_width, display_height);
+ }
+ else
+ {
+ int16 status = 0;
+ do
+ {
+ /* Search for VOL_HEADER */
+ status = SearchNextM4VFrame(psBits); /* search 0x00 0x00 0x01 */
+ if (status != 0)
+ {
+ return MP4_INVALID_VOL_PARAM;
+ }
+
+ status = ReadBits(psBits, VOL_START_CODE_LENGTH, &codeword);
+ }
+ while ((codeword != VOL_START_CODE) && (status == 0));
+ goto decode_vol;
+ }
+ }
+ return 0;
+}
+
+
+
+OSCL_EXPORT_REF
+int16 iDecodeShortHeader(mp4StreamType *psBits,
+ int32 *width,
+ int32 *height,
+ int32 *display_width,
+ int32 *display_height)
+{
+ uint32 codeword;
+ int32 extended_PTYPE = 0;
+ int32 UFEP = 0;
+ int32 custom_PFMT = 0;
+
+ ShowBits(psBits, 22, &codeword);
+
+ if (codeword != 0x20)
+ {
+ return MP4_INVALID_VOL_PARAM;
+ }
+ FlushBits(psBits, 22);
+ ReadBits(psBits, 8, &codeword);
+
+ ReadBits(psBits, 1, &codeword);
+ if (codeword == 0) return MP4_INVALID_VOL_PARAM;
+
+ ReadBits(psBits, 1, &codeword);
+ if (codeword == 1) return MP4_INVALID_VOL_PARAM;
+
+ ReadBits(psBits, 1, &codeword);
+ if (codeword == 1) return MP4_INVALID_VOL_PARAM;
+
+ ReadBits(psBits, 1, &codeword);
+ if (codeword == 1) return MP4_INVALID_VOL_PARAM;
+
+ ReadBits(psBits, 1, &codeword);
+ if (codeword == 1) return MP4_INVALID_VOL_PARAM;
+
+ /* source format */
+ ReadBits(psBits, 3, &codeword);
+ switch (codeword)
+ {
+ case 1:
+ *width = 128;
+ *height = 96;
+ break;
+
+ case 2:
+ *width = 176;
+ *height = 144;
+ break;
+
+ case 3:
+ *width = 352;
+ *height = 288;
+ break;
+
+ case 4:
+ *width = 704;
+ *height = 576;
+ break;
+
+ case 5:
+ *width = 1408;
+ *height = 1152;
+ break;
+
+ case 7:
+ extended_PTYPE = 1;
+ break;
+ default:
+ /* Msg("H.263 source format not legal\n"); */
+ return MP4_INVALID_VOL_PARAM;
+ }
+
+ if (extended_PTYPE == 0)
+ {
+ *display_width = *width;
+ *display_height = *height;
+ return 0;
+ }
+ /* source format */
+ ReadBits(psBits, 3, &codeword);
+ UFEP = codeword;
+ if (UFEP == 1)
+ {
+ ReadBits(psBits, 3, &codeword);
+ switch (codeword)
+ {
+ case 1:
+ *width = 128;
+ *height = 96;
+ break;
+
+ case 2:
+ *width = 176;
+ *height = 144;
+ break;
+
+ case 3:
+ *width = 352;
+ *height = 288;
+ break;
+
+ case 4:
+ *width = 704;
+ *height = 576;
+ break;
+
+ case 5:
+ *width = 1408;
+ *height = 1152;
+ break;
+
+ case 6:
+ custom_PFMT = 1;
+ break;
+ default:
+ /* Msg("H.263 source format not legal\n"); */
+ return MP4_INVALID_VOL_PARAM;
+ }
+ if (custom_PFMT == 0)
+ {
+ *display_width = *width;
+ *display_height = *height;
+ return 0;
+ }
+ ReadBits(psBits, 1, &codeword);
+ ReadBits(psBits, 1, &codeword);
+ if (codeword) return MP4_INVALID_VOL_PARAM;
+ ReadBits(psBits, 1, &codeword);
+ if (codeword) return MP4_INVALID_VOL_PARAM;
+ ReadBits(psBits, 1, &codeword);
+ if (codeword) return MP4_INVALID_VOL_PARAM;
+ ReadBits(psBits, 3, &codeword);
+ ReadBits(psBits, 3, &codeword);
+ if (codeword) return MP4_INVALID_VOL_PARAM; /* RPS, ISD, AIV */
+ ReadBits(psBits, 1, &codeword);
+ ReadBits(psBits, 4, &codeword);
+ if (codeword != 8) return MP4_INVALID_VOL_PARAM;
+ }
+ if (UFEP == 0 || UFEP == 1)
+ {
+ ReadBits(psBits, 3, &codeword);
+ if (codeword > 1) return MP4_INVALID_VOL_PARAM;
+ ReadBits(psBits, 1, &codeword);
+ if (codeword) return MP4_INVALID_VOL_PARAM;
+ ReadBits(psBits, 1, &codeword);
+ if (codeword) return MP4_INVALID_VOL_PARAM;
+ ReadBits(psBits, 1, &codeword);
+ ReadBits(psBits, 3, &codeword);
+ if (codeword != 1) return MP4_INVALID_VOL_PARAM;
+ }
+ else
+ {
+ return MP4_INVALID_VOL_PARAM;
+ }
+ ReadBits(psBits, 1, &codeword);
+ if (codeword) return MP4_INVALID_VOL_PARAM; /* CPM */
+ if (custom_PFMT == 1 && UFEP == 1)
+ {
+ ReadBits(psBits, 4, &codeword);
+ if (codeword == 0) return MP4_INVALID_VOL_PARAM;
+ if (codeword == 0xf)
+ {
+ ReadBits(psBits, 8, &codeword);
+ ReadBits(psBits, 8, &codeword);
+ }
+ ReadBits(psBits, 9, &codeword);
+ *display_width = (codeword + 1) << 2;
+ *width = (*display_width + 15) & -16;
+ ReadBits(psBits, 1, &codeword);
+ if (codeword != 1) return MP4_INVALID_VOL_PARAM;
+ ReadBits(psBits, 9, &codeword);
+ if (codeword == 0) return MP4_INVALID_VOL_PARAM;
+ *display_height = codeword << 2;
+ *height = (*display_height + 15) & -16;
+ }
+
+ return 0;
+}
+
+
+int16 ShowBits(
+ mp4StreamType *pStream, /* Input Stream */
+ uint8 ucNBits, /* nr of bits to read */
+ uint32 *pulOutData /* output target */
+)
+{
+ uint8 *bits;
+ uint32 dataBitPos = pStream->dataBitPos;
+ uint32 bitPos = pStream->bitPos;
+ uint32 dataBytePos;
+
+ uint i;
+
+ if (ucNBits > (32 - bitPos)) /* not enough bits */
+ {
+ dataBytePos = dataBitPos >> 3; /* Byte Aligned Position */
+ bitPos = dataBitPos & 7; /* update bit position */
+ if (dataBytePos > pStream->numBytes - 4)
+ {
+ pStream->bitBuf = 0;
+ for (i = 0;i < pStream->numBytes - dataBytePos;i++)
+ {
+ pStream->bitBuf |= pStream->data[dataBytePos+i];
+ pStream->bitBuf <<= 8;
+ }
+ pStream->bitBuf <<= 8 * (3 - i);
+ }
+ else
+ {
+ bits = &pStream->data[dataBytePos];
+ pStream->bitBuf = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3];
+ }
+ pStream->bitPos = bitPos;
+ }
+
+ bitPos += ucNBits;
+
+ *pulOutData = (pStream->bitBuf >> (32 - bitPos)) & mask[(uint16)ucNBits];
+
+
+ return 0;
+}
+
+int16 FlushBits(
+ mp4StreamType *pStream, /* Input Stream */
+ uint8 ucNBits /* number of bits to flush */
+)
+{
+ uint8 *bits;
+ uint32 dataBitPos = pStream->dataBitPos;
+ uint32 bitPos = pStream->bitPos;
+ uint32 dataBytePos;
+
+
+ if ((dataBitPos + ucNBits) > (uint32)(pStream->numBytes << 3))
+ return (-2); // Buffer over run
+
+ dataBitPos += ucNBits;
+ bitPos += ucNBits;
+
+ if (bitPos > 32)
+ {
+ dataBytePos = dataBitPos >> 3; /* Byte Aligned Position */
+ bitPos = dataBitPos & 7; /* update bit position */
+ bits = &pStream->data[dataBytePos];
+ pStream->bitBuf = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3];
+ }
+
+ pStream->dataBitPos = dataBitPos;
+ pStream->bitPos = bitPos;
+
+ return 0;
+}
+
+int16 ReadBits(
+ mp4StreamType *pStream, /* Input Stream */
+ uint8 ucNBits, /* nr of bits to read */
+ uint32 *pulOutData /* output target */
+)
+{
+ uint8 *bits;
+ uint32 dataBitPos = pStream->dataBitPos;
+ uint32 bitPos = pStream->bitPos;
+ uint32 dataBytePos;
+
+
+ if ((dataBitPos + ucNBits) > (pStream->numBytes << 3))
+ {
+ *pulOutData = 0;
+ return (-2); // Buffer over run
+ }
+
+ // dataBitPos += ucNBits;
+
+ if (ucNBits > (32 - bitPos)) /* not enough bits */
+ {
+ dataBytePos = dataBitPos >> 3; /* Byte Aligned Position */
+ bitPos = dataBitPos & 7; /* update bit position */
+ bits = &pStream->data[dataBytePos];
+ pStream->bitBuf = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3];
+ }
+
+ pStream->dataBitPos += ucNBits;
+ pStream->bitPos = (unsigned char)(bitPos + ucNBits);
+
+ *pulOutData = (pStream->bitBuf >> (32 - pStream->bitPos)) & mask[(uint16)ucNBits];
+
+ return 0;
+}
+
+
+
+int16 ByteAlign(
+ mp4StreamType *pStream /* Input Stream */
+)
+{
+ uint8 *bits;
+ uint32 dataBitPos = pStream->dataBitPos;
+ uint32 bitPos = pStream->bitPos;
+ uint32 dataBytePos;
+ uint32 leftBits;
+
+ leftBits = 8 - (dataBitPos & 0x7);
+ if (leftBits == 8)
+ {
+ if ((dataBitPos + 8) > (uint32)(pStream->numBytes << 3))
+ return (-2); // Buffer over run
+ dataBitPos += 8;
+ bitPos += 8;
+ }
+ else
+ {
+ dataBytePos = dataBitPos >> 3;
+ dataBitPos += leftBits;
+ bitPos += leftBits;
+ }
+
+
+ if (bitPos > 32)
+ {
+ dataBytePos = dataBitPos >> 3; /* Byte Aligned Position */
+ bits = &pStream->data[dataBytePos];
+ pStream->bitBuf = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3];
+ }
+
+ pStream->dataBitPos = dataBitPos;
+ pStream->bitPos = bitPos;
+
+ return 0;
+}
+
+int16 DecodeUserData(mp4StreamType *pStream)
+{
+
+ uint32 codeword;
+ int16 iErrorStat;
+
+ iErrorStat = ReadBits(pStream, 32, &codeword);
+ if (iErrorStat) return iErrorStat;
+ iErrorStat = ShowBits(pStream, 24, &codeword);
+ if (iErrorStat) return iErrorStat;
+
+ while (codeword != 1)
+ {
+ /* Discard user data for now. */
+ iErrorStat = ReadBits(pStream, 8, &codeword);
+ if (iErrorStat) return iErrorStat;
+ iErrorStat = ShowBits(pStream, 24, &codeword);
+ if (iErrorStat) return iErrorStat;
+ }
+ return 0;
+}
+
+
+OSCL_EXPORT_REF int16 iGetAVCConfigInfo(uint8 *buffer, int32 length, int32 *width, int32 *height, int32 *display_width, int32 *display_height, int32 *profile_idc, int32 *level_idc)
+{
+ int16 status;
+ mp4StreamType psBits;
+ uint16 sps_length, pps_length;
+ int32 size;
+ int32 i = 0;
+ uint8* sps = NULL;
+ uint8* temp = (uint8 *)OSCL_MALLOC(sizeof(uint8) * length);
+ uint8* pps = NULL;
+
+
+ if (temp)
+ {
+ sps = temp; // Make a copy of the original pointer to be freed later
+ // Successfull allocation... copy input buffer
+ oscl_memcpy(sps, buffer, length);
+ }
+ else
+ {
+ // Allocation failed
+ return MP4_INVALID_VOL_PARAM;
+ }
+
+ if (length < 3)
+ {
+ OSCL_FREE(temp);
+ return MP4_INVALID_VOL_PARAM;
+ }
+
+ *width = *height = *display_height = *display_width = 0;
+
+ if (sps[0] == 0 && sps[1] == 0)
+ {
+ /* find SC at the beginning of the NAL */
+ while (sps[i++] == 0 && i < length)
+ {
+ }
+
+ if (sps[i-1] == 1)
+ {
+ sps += i;
+
+ sps_length = 0;
+ // search for the next start code
+ while (!(sps[sps_length] == 0 && sps[sps_length+1] == 0 && sps[sps_length+2] == 1) &&
+ sps_length < length - i - 2)
+ {
+ sps_length++;
+ }
+
+ if (sps_length >= length - i - 2)
+ {
+ OSCL_FREE(temp);
+ return MP4_INVALID_VOL_PARAM;
+ }
+
+ pps_length = length - i - sps_length - 3;
+ pps = sps + sps_length + 3;
+ }
+ else
+ {
+ OSCL_FREE(temp);
+ return MP4_INVALID_VOL_PARAM;
+ }
+ }
+ else
+ {
+ sps_length = (uint16)(sps[1] << 8) | sps[0];
+ sps += 2;
+ pps = sps + sps_length;
+ pps_length = (uint16)(pps[1] << 8) | pps[0];
+ pps += 2;
+ }
+
+ if (sps_length + pps_length > length)
+ {
+ OSCL_FREE(temp);
+ return MP4_INVALID_VOL_PARAM;
+ }
+
+ size = sps_length;
+
+ Parser_EBSPtoRBSP(sps, &size);
+
+ psBits.data = sps;
+ psBits.numBytes = size;
+ psBits.bitBuf = 0;
+ psBits.bitPos = 32;
+ psBits.bytePos = 0;
+ psBits.dataBitPos = 0;
+
+ if (DecodeSPS(&psBits, width, height, display_width, display_height, profile_idc, level_idc))
+ {
+ OSCL_FREE(temp);
+ return MP4_INVALID_VOL_PARAM;
+ }
+
+ // now do PPS
+ size = pps_length;
+
+ Parser_EBSPtoRBSP(pps, &size);
+ psBits.data = pps;
+ psBits.numBytes = size;
+ psBits.bitBuf = 0;
+ psBits.bitPos = 32;
+ psBits.bytePos = 0;
+ psBits.dataBitPos = 0;
+
+ status = DecodePPS(&psBits);
+
+ OSCL_FREE(temp);
+
+ return status;
+}
+
+
+int16 DecodeSPS(mp4StreamType *psBits, int32 *width, int32 *height, int32 *display_width, int32 *display_height, int32 *profile_idc, int32 *level_idc)
+{
+ uint32 temp;
+ int32 temp0;
+ uint left_offset, right_offset, top_offset, bottom_offset;
+ uint i;
+
+ ReadBits(psBits, 8, &temp);
+
+
+
+ if ((temp & 0x1F) != 7) return MP4_INVALID_VOL_PARAM;
+
+ ReadBits(psBits, 8, &temp);
+
+ *profile_idc = temp;
+
+ ReadBits(psBits, 1, &temp);
+ ReadBits(psBits, 1, &temp);
+ ReadBits(psBits, 1, &temp);
+ ReadBits(psBits, 5, &temp);
+ ReadBits(psBits, 8, &temp);
+
+ *level_idc = temp;
+
+ if (temp > 51)
+ return MP4_INVALID_VOL_PARAM;
+
+ ue_v(psBits, &temp);
+ ue_v(psBits, &temp);
+ ue_v(psBits, &temp);
+
+ if (temp == 0)
+ {
+ ue_v(psBits, &temp);
+ }
+ else if (temp == 1)
+ {
+ ReadBits(psBits, 1, &temp);
+ se_v(psBits, &temp0);
+ se_v(psBits, &temp0);
+ ue_v(psBits, &temp);
+
+ for (i = 0; i < temp; i++)
+ {
+ se_v(psBits, &temp0);
+ }
+ }
+ ue_v(psBits, &temp);
+
+
+ ReadBits(psBits, 1, &temp);
+ ue_v(psBits, &temp);
+ *display_width = *width = (temp + 1) << 4;
+ ue_v(psBits, &temp);
+ *display_height = *height = (temp + 1) << 4;
+
+
+ ReadBits(psBits, 1, &temp);
+ if (!temp)
+ {
+ // we do not support if frame_mb_only_flag is off
+ return MP4_INVALID_VOL_PARAM;
+ //ReadBits(psBits,1, &temp);
+ }
+
+ ReadBits(psBits, 1, &temp);
+
+ ReadBits(psBits, 1, &temp);
+
+ if (temp)
+ {
+ ue_v(psBits, (uint32*)&left_offset);
+ ue_v(psBits, (uint32*)&right_offset);
+ ue_v(psBits, (uint32*)&top_offset);
+ ue_v(psBits, (uint32*)&bottom_offset);
+
+ *display_width = *width - 2 * (right_offset + left_offset);
+ *display_height = *height - 2 * (top_offset + bottom_offset);
+ }
+
+ /* no need to check further */
+#if USE_LATER
+ ReadBits(psBits, 1, &temp);
+ if (temp)
+ {
+ if (!DecodeVUI(psBits))
+ {
+ return MP4_INVALID_VOL_PARAM;
+ }
+ }
+#endif
+ return 0; // return 0 for success
+}
+
+#if USE_LATER
+/* unused for now */
+int32 DecodeVUI(mp4StreamType *psBits)
+{
+ uint temp;
+ uint32 temp32;
+ uint aspect_ratio_idc, overscan_appopriate_flag, video_format, video_full_range_flag;
+ int32 status;
+
+ ReadBits(psBits, 1, &temp); /* aspect_ratio_info_present_flag */
+ if (temp)
+ {
+ ReadBits(psBits, 8, &aspect_ratio_idc);
+ if (aspect_ratio_idc == 255)
+ {
+ ReadBits(psBits, 16, &temp); /* sar_width */
+ ReadBits(psBits, 16, &temp); /* sar_height */
+ }
+ }
+ ReadBits(psBits, 1, &temp); /* overscan_info_present */
+ if (temp)
+ {
+ ReadBits(psBits, 1, &overscan_appopriate_flag);
+ }
+ ReadBits(psBits, 1, &temp); /* video_signal_type_present_flag */
+ if (temp)
+ {
+ ReadBits(psBits, 3, &video_format);
+ ReadBits(psBits, 1, &video_full_range_flag);
+ ReadBits(psBits, 1, &temp); /* colour_description_present_flag */
+ if (temp)
+ {
+ ReadBits(psBits, 8, &temp); /* colour_primaries */
+ ReadBits(psBits, 8, &temp); /* transfer_characteristics */
+ ReadBits(psBits, 8, &temp); /* matrix coefficients */
+ }
+ }
+ ReadBits(psBits, 1, &temp);/* chroma_loc_info_present_flag */
+ if (temp)
+ {
+ ue_v(psBits, &temp); /* chroma_sample_loc_type_top_field */
+ ue_v(psBits, &temp); /* chroma_sample_loc_type_bottom_field */
+ }
+
+ ReadBits(psBits, 1, &temp); /* timing_info_present_flag*/
+ if (temp)
+ {
+ ReadBits(psBits, 32, &temp32); /* num_unit_in_tick*/
+ ReadBits(psBits, 32, &temp32); /* time_scale */
+ ReadBits(psBits, 1, &temp); /* fixed_frame_rate_flag */
+ }
+
+ ReadBits(psBits, 1, &temp); /* nal_hrd_parameters_present_flag */
+ if (temp)
+ {
+ if (!DecodeHRD(psBits))
+ {
+ return 1;
+ }
+ }
+ ReadBits(psBits, 1, &temp32); /* vcl_hrd_parameters_present_flag*/
+ if (temp32)
+ {
+ if (!DecodeHRD(psBits))
+ {
+ return 1;
+ }
+ }
+ if (temp || temp32)
+ {
+ ReadBits(psBits, 1, &temp); /* low_delay_hrd_flag */
+ }
+ ReadBits(psBits, 1, &temp); /* pic_struct_present_flag */
+ status = ReadBits(psBits, 1, &temp); /* _restriction_flag */
+ if (status != 0) // buffer overrun
+ {
+ return 1;
+ }
+
+ if (temp)
+ {
+ ReadBits(psBits, 1, &temp); /* motion_vectors_over_pic_boundaries_flag */
+ ue_v(psBits, &temp); /* max_bytes_per_pic_denom */
+ ue_v(psBits, &temp); /* max_bits_per_mb_denom */
+ ue_v(psBits, &temp); /* log2_max_mv_length_horizontal */
+ ue_v(psBits, &temp); /* log2_max_mv_length_vertical */
+ ue_v(psBits, &temp); /* num_reorder_frames */
+ ue_v(psBits, &temp); /* max_dec_frame_buffering */
+ }
+
+ return 0; // 0 for success
+}
+
+/* unused for now */
+int32 DecodeHRD(mp4StreamType *psBits)
+{
+ uint temp;
+ uint cpb_cnt_minus1;
+ uint i;
+ int32 status;
+
+ ue_v(psBits, &cpb_cnt_minus1);
+ ReadBits(psBits, 4, &temp); /* bit_rate_scale */
+ ReadBits(psBits, 4, &temp); /* cpb_size_scale */
+ for (i = 0; i <= cpb_cnt_minus1; i++)
+ {
+ ue_v(psBits, &temp); /* bit_rate_value_minus1[i] */
+ ue_v(psBits, &temp); /* cpb_size_value_minus1[i] */
+ ue_v(psBits, &temp); /* cbr_flag[i] */
+ }
+ ReadBits(psBits, 5, &temp); /* initial_cpb_removal_delay_length_minus1 */
+ ReadBits(psBits, 5, &temp); /* cpb_removal_delay_length_minus1 */
+ ReadBits(psBits, 5, &temp); /* dpb_output_delay_length_minus1 */
+ status = ReadBits(psBits, 5, &temp); /* time_offset_length */
+
+ if (status != 0) // buffer overrun
+ {
+ return 1;
+ }
+
+ return 0; // 0 for success
+}
+#endif
+
+// only check for entropy coding mode
+int32 DecodePPS(mp4StreamType *psBits)
+{
+ uint32 temp, pic_parameter_set_id, seq_parameter_set_id, entropy_coding_mode_flag;
+
+ ReadBits(psBits, 8, &temp);
+
+ if ((temp & 0x1F) != 8) return MP4_INVALID_VOL_PARAM;
+
+ ue_v(psBits, &pic_parameter_set_id);
+ ue_v(psBits, &seq_parameter_set_id);
+
+ ReadBits(psBits, 1, &entropy_coding_mode_flag);
+ if (entropy_coding_mode_flag)
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+void ue_v(mp4StreamType *psBits, uint32 *codeNum)
+{
+ uint32 temp;
+ uint tmp_cnt;
+ int32 leading_zeros = 0;
+ ShowBits(psBits, 16, &temp);
+ tmp_cnt = temp | 0x1;
+
+ PV_CLZ(leading_zeros, tmp_cnt)
+
+ if (leading_zeros < 8)
+ {
+ *codeNum = (temp >> (15 - (leading_zeros << 1))) - 1;
+ FlushBits(psBits, (leading_zeros << 1) + 1);
+ }
+ else
+ {
+ ReadBits(psBits, (leading_zeros << 1) + 1, &temp);
+ *codeNum = temp - 1;
+ }
+
+}
+
+
+void se_v(mp4StreamType *psBits, int32 *value)
+{
+ int32 leadingZeros = 0;
+ uint32 temp;
+
+ OSCL_UNUSED_ARG(value);
+
+ ReadBits(psBits, 1, &temp);
+ while (!temp)
+ {
+ leadingZeros++;
+ if (ReadBits(psBits, 1, &temp))
+ {
+ break;
+ }
+ }
+ ReadBits(psBits, leadingZeros, &temp);
+}
+
+void Parser_EBSPtoRBSP(uint8 *nal_unit, int32 *size)
+{
+ int32 i, j;
+ int32 count = 0;
+
+
+ for (i = 0; i < *size; i++)
+ {
+ if (count == 2 && nal_unit[i] == 0x03)
+ {
+ break;
+ }
+
+ if (nal_unit[i])
+ count = 0;
+ else
+ count++;
+ }
+
+ count = 0;
+ j = i++;
+ for (;i < *size; i++)
+ {
+ if (count == 2 && nal_unit[i] == 0x03)
+ {
+ i++;
+ count = 0;
+ }
+ nal_unit[j] = nal_unit[i];
+ if (nal_unit[i])
+ count = 0;
+ else
+ count++;
+ j++;
+ }
+
+ *size = j;
+}
+
+
+
diff --git a/omx/ti_omx_config_parser/src/ti_omx_config_parser.cpp b/omx/ti_omx_config_parser/src/ti_omx_config_parser.cpp
new file mode 100644
index 0000000..1b4a6a3
--- /dev/null
+++ b/omx/ti_omx_config_parser/src/ti_omx_config_parser.cpp
@@ -0,0 +1,179 @@
+/* ------------------------------------------------------------------
+ * Copyright (C) 1998-2009 PacketVideo
+ *
+ * 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.
+ * -------------------------------------------------------------------
+ */
+
+#define __USE_MISC
+#include "oscl_stdstring.h"
+
+// Use default DLL entry point
+#ifndef OSCL_DLL_H_INCLUDED
+#include "oscl_dll.h"
+#endif
+
+#ifndef PV_OMXDEFS_H_INCLUDED
+#include "pv_omxdefs.h"
+#endif
+
+#ifndef PV_OMX_QUEUE_H_INCLUDED
+#include "pv_omx_queue.h"
+#endif
+
+#ifndef OMX_Types_h
+#include "omx_types.h"
+#endif
+
+#ifndef OSCL_BASE_INCLUDED_H
+#include "oscl_base.h"
+#endif
+
+#ifndef OMX_Core_h
+#include "omx_core.h"
+#endif
+
+#ifndef PV_AUDIO_CONFIG_PARSER_H
+#include "pv_audio_config_parser.h"
+#endif
+
+#ifndef PV_VIDEO_CONFIG_PARSER_H
+#include "pv_video_config_parser.h"
+#endif
+
+#include "ti_omx_config_parser.h"
+#include "ti_video_config_parser.h"
+
+OSCL_EXPORT_REF OMX_BOOL TIOMXConfigParser(
+ OMX_PTR aInputParameters,
+ OMX_PTR aOutputParameters)
+
+{
+ OMXConfigParserInputs* pInputs;
+
+ pInputs = (OMXConfigParserInputs*) aInputParameters;
+
+
+ if (NULL != pInputs->cComponentRole)
+ {
+ if (0 == oscl_strncmp(pInputs->cComponentRole, (OMX_STRING)"audio_decoder", oscl_strlen("audio_decoder")))
+ {
+ OMX_S32 Status;
+ pvAudioConfigParserInputs aInputs;
+
+ aInputs.inPtr = pInputs->inPtr;
+ aInputs.inBytes = pInputs->inBytes;
+
+ if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"audio_decoder.wma"))
+ {
+ aInputs.iMimeType = PVMF_MIME_WMA;
+
+ }
+ else if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"audio_decoder.aac"))
+ {
+ aInputs.iMimeType = PVMF_MIME_AAC_SIZEHDR;
+
+ }
+ else if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"audio_decoder.amr"))
+ {
+ aInputs.iMimeType = PVMF_MIME_AMR;
+
+ }
+ else if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"audio_decoder.amrnb"))
+ {
+ aInputs.iMimeType = PVMF_MIME_AMR;
+
+ }
+ else if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"audio_decoder.amrwb"))
+ {
+ aInputs.iMimeType = PVMF_MIME_AMRWB;
+
+ }
+ else if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"audio_decoder.mp3"))
+ {
+ aInputs.iMimeType = PVMF_MIME_MP3;
+
+ }
+ else
+ {
+ return OMX_FALSE;
+ }
+
+ Status = pv_audio_config_parser(&aInputs, (pvAudioConfigParserOutputs *)aOutputParameters);
+ if (0 == Status)
+ {
+ return OMX_FALSE;
+ }
+ }
+ else if (0 == oscl_strncmp(pInputs->cComponentRole, (OMX_STRING)"video_decoder", oscl_strlen("video_decoder")))
+ {
+
+ OMX_S32 Status;
+ pvVideoConfigParserInputs aInputs;
+
+ aInputs.inPtr = pInputs->inPtr;
+ aInputs.inBytes = pInputs->inBytes;
+
+ if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"video_decoder.wmv"))
+ {
+ aInputs.iMimeType = PVMF_MIME_WMV;
+
+ }
+ else if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"video_decoder.avc"))
+ {
+ aInputs.iMimeType = PVMF_MIME_H264_VIDEO;
+
+ }
+ else if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"video_decoder.mpeg4"))
+ {
+ aInputs.iMimeType = PVMF_MIME_M4V;
+
+ }
+ else if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"video_decoder.h263"))
+ {
+ aInputs.iMimeType = PVMF_MIME_H2632000;
+
+ }
+ else
+ {
+ return OMX_FALSE;
+ }
+
+ if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"video_decoder.mpeg4"))
+ {
+ Status = ti_video_config_parser((tiVideoConfigParserInputs *)&aInputs, (tiVideoConfigParserOutputs *)aOutputParameters);
+ }
+ else
+ {
+ Status = pv_video_config_parser(&aInputs, (pvVideoConfigParserOutputs *)aOutputParameters);
+ }
+ if (0 != Status)
+ {
+ return OMX_FALSE;
+ }
+ }
+ else
+ {
+ return OMX_FALSE;
+ }
+
+ }
+ else
+ {
+ return OMX_FALSE;
+ }
+
+ return OMX_TRUE;
+}
+
diff --git a/omx/ti_omx_config_parser/src/ti_video_config_parser.cpp b/omx/ti_omx_config_parser/src/ti_video_config_parser.cpp
new file mode 100644
index 0000000..183fcc8
--- /dev/null
+++ b/omx/ti_omx_config_parser/src/ti_video_config_parser.cpp
@@ -0,0 +1,287 @@
+/* ------------------------------------------------------------------
+ * Copyright (C) 1998-2009 PacketVideo
+ *
+ * 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.
+ * -------------------------------------------------------------------
+ */
+
+#include "ti_video_config_parser.h"
+#include "ti_m4v_config_parser.h"
+#include "oscl_mem.h"
+
+#include "oscl_dll.h"
+
+#define GetUnalignedWord( pb, w ) \
+ (w) = ((uint16) *(pb + 1) << 8) + *pb;
+
+#define GetUnalignedDword( pb, dw ) \
+ (dw) = ((uint32) *(pb + 3) << 24) + \
+ ((uint32) *(pb + 2) << 16) + \
+ ((uint16) *(pb + 1) << 8) + *pb;
+
+#define GetUnalignedWordEx( pb, w ) GetUnalignedWord( pb, w ); (pb) += sizeof(uint16);
+#define GetUnalignedDwordEx( pb, dw ) GetUnalignedDword( pb, dw ); (pb) += sizeof(uint32);
+#define GetUnalignedQwordEx( pb, qw ) GetUnalignedQword( pb, qw ); (pb) += sizeof(uint64);
+
+#define LoadBYTE( b, p ) b = *(uint8 *)p; p += sizeof( uint8 )
+
+#define LoadWORD( w, p ) GetUnalignedWordEx( p, w )
+#define LoadDWORD( dw, p ) GetUnalignedDwordEx( p, dw )
+#define LoadQWORD( qw, p ) GetUnalignedQwordEx( p, qw )
+
+#ifndef MAKEFOURCC_WMC
+#define MAKEFOURCC_WMC(ch0, ch1, ch2, ch3) \
+ ((uint32)(uint8)(ch0) | ((uint32)(uint8)(ch1) << 8) | \
+ ((uint32)(uint8)(ch2) << 16) | ((uint32)(uint8)(ch3) << 24 ))
+
+#define mmioFOURCC_WMC(ch0, ch1, ch2, ch3) MAKEFOURCC_WMC(ch0, ch1, ch2, ch3)
+#endif
+
+#define FOURCC_WMV2 mmioFOURCC_WMC('W','M','V','2')
+#define FOURCC_WMV3 mmioFOURCC_WMC('W','M','V','3')
+#define FOURCC_WMVA mmioFOURCC_WMC('W','M','V','A')
+#define FOURCC_WVC1 mmioFOURCC_WMC('W','V','C','1')
+//For WMVA
+#define ASFBINDING_SIZE 1 // size of ASFBINDING is 1 byte
+#define FOURCC_MP42 mmioFOURCC_WMC('M','P','4','2')
+#define FOURCC_MP43 mmioFOURCC_WMC('M','P','4','3')
+#define FOURCC_mp42 mmioFOURCC_WMC('m','p','4','2')
+#define FOURCC_mp43 mmioFOURCC_WMC('m','p','4','3')
+
+OSCL_DLL_ENTRY_POINT_DEFAULT()
+
+int32 GetNAL_Config(uint8** bitstream, int32* size);
+
+OSCL_EXPORT_REF int16 ti_video_config_parser(tiVideoConfigParserInputs *aInputs, tiVideoConfigParserOutputs *aOutputs)
+{
+ if (aInputs->iMimeType == PVMF_MIME_M4V) //m4v
+ {
+ mp4StreamType psBits;
+ psBits.data = aInputs->inPtr;
+ if (aInputs->inBytes <= 0)
+ {
+ return -1;
+ }
+ psBits.numBytes = aInputs->inBytes;
+ psBits.bytePos = 0;
+ psBits.bitBuf = 0;
+ psBits.dataBitPos = 0;
+ psBits.bitPos = 32;
+
+ int32 width, height, display_width, display_height = 0;
+ int32 profile_level = 0;
+ int16 retval = 0;
+ retval = iDecodeVOLHeader(&psBits, &width, &height, &display_width, &display_height, &profile_level);
+ if (retval != 0)
+ {
+ return retval;
+ }
+ aOutputs->width = (uint32)display_width;
+ aOutputs->height = (uint32)display_height;
+ aOutputs->profile = (uint32)profile_level; // for mp4, profile/level info is packed
+ aOutputs->level = 0;
+ }
+ else if (aInputs->iMimeType == PVMF_MIME_H2631998 ||
+ aInputs->iMimeType == PVMF_MIME_H2632000)//h263
+ {
+ // Nothing to do for h263
+ aOutputs->width = 0;
+ aOutputs->height = 0;
+ aOutputs->profile = 0;
+ aOutputs->level = 0;
+ }
+ else if (aInputs->iMimeType == PVMF_MIME_H264_VIDEO ||
+ aInputs->iMimeType == PVMF_MIME_H264_VIDEO_MP4) //avc
+ {
+ int32 width, height, display_width, display_height = 0;
+ int32 profile_idc, level_idc = 0;
+
+ uint8 *tp = aInputs->inPtr;
+
+ if (aInputs->inBytes > 1)
+ {
+ if (tp[0] == 0 && tp[1] == 0)
+ {
+ // ByteStream Format
+ uint8* tmp_ptr = tp;
+ uint8* buffer_begin = tp;
+ int16 length = 0;
+ int initbufsize = aInputs->inBytes;
+ int tConfigSize = 0;
+ do
+ {
+ tmp_ptr += length;
+ length = GetNAL_Config(&tmp_ptr, &initbufsize);
+ buffer_begin[0] = length & 0xFF;
+ buffer_begin[1] = (length >> 8) & 0xFF;
+ oscl_memcpy(buffer_begin + 2, tmp_ptr, length);
+ buffer_begin += (length + 2);
+ tConfigSize += (length + 2);
+ }
+ while (initbufsize > 0);
+ }
+ }
+
+ // check codec info and get settings
+ int16 retval;
+ retval = iGetAVCConfigInfo(tp,
+ aInputs->inBytes,
+ (int*) & width,
+ (int*) & height,
+ (int*) & display_width,
+ (int*) & display_height,
+ (int*) & profile_idc,
+ (int*) & level_idc);
+ if (retval != 0)
+ {
+ return retval;
+ }
+ aOutputs->width = (uint32)display_width;
+ aOutputs->height = (uint32)display_height;
+ aOutputs->profile = (uint32)profile_idc;
+ aOutputs->level = (uint32) level_idc;
+ }
+ else if (aInputs->iMimeType == PVMF_MIME_WMV) //wmv
+ {
+ uint32 dwdat;
+ uint16 wdat;
+ uint8 bdat;
+ uint8 *pData = aInputs->inPtr;
+
+ LoadDWORD(dwdat, pData); // Window width
+ LoadDWORD(dwdat, pData); // Window height
+ LoadBYTE(bdat, pData);
+ LoadWORD(wdat, pData); // Size of image info.
+
+ // BITMAPINFOHEADER
+ LoadDWORD(dwdat, pData); // Size of BMAPINFOHDR
+ LoadDWORD(dwdat, pData);
+ aOutputs->width = dwdat;
+ LoadDWORD(dwdat, pData);
+ aOutputs->height = dwdat;
+
+ /* WMV1 and WMV2 are not supported. Rejected here. */
+ /* Code to Check if comp is WMV1 then return not supported */
+ pData += 4;
+ LoadDWORD(dwdat, pData);
+ uint32 NewCompression = dwdat;
+ uint32 NewSeqHeader = 0;
+ uint32 NewProfile = 0;
+ // in case of WMV store "Compression Type as Level"
+ aOutputs->level = NewCompression;
+
+ if (NewCompression != FOURCC_WMV2 &&
+ NewCompression != FOURCC_WMV3 &&
+ NewCompression != FOURCC_WVC1 &&
+ NewCompression != FOURCC_WMVA &&
+ NewCompression != FOURCC_MP42 &&
+ NewCompression != FOURCC_MP43 &&
+ NewCompression != FOURCC_mp42 &&
+ NewCompression != FOURCC_mp43)
+ {
+ return -1;
+ }
+ // get profile etc.
+ // Check sequence header
+ switch (NewCompression)
+ {
+ case FOURCC_WMV3:
+ {
+ // start fresh
+ pData = aInputs->inPtr;
+ pData += (11 + 40); //sizeof(BITMAPINFOHEADER); // position to sequence header
+
+ LoadDWORD(dwdat, pData);
+ NewSeqHeader = dwdat; // this is little endian read sequence header
+
+ NewProfile = (NewSeqHeader & 0xC0) >> 6; // 0 - simple , 1- main, 3 - complex, 2-forbidden
+
+ break;
+ }
+ case FOURCC_WMVA:
+ {
+ pData = aInputs->inPtr;
+ pData += (11 + 40 + ASFBINDING_SIZE); //sizeof(BITMAPINFOHEADER); // position to sequence header
+
+ LoadDWORD(dwdat, pData); // prefix // this is little endian read sequence header
+ LoadDWORD(dwdat, pData);
+ NewSeqHeader = dwdat;
+
+ NewProfile = (NewSeqHeader & 0xC0) >> 6; // this must be 3
+ }
+ break;
+
+ default:
+
+ NewProfile = 0;
+ break;
+ }
+
+ aOutputs->profile = NewProfile;
+
+ }
+ else
+ {
+ return -1;
+ }
+ return 0;
+}
+
+
+/* This function finds a nal from the SC's, moves the bitstream pointer to the beginning of the NAL unit, returns the
+size of the NAL, and at the same time, updates the remaining size in the bitstream buffer that is passed in */
+int32 GetNAL_Config(uint8** bitstream, int32* size)
+{
+ int i = 0;
+ int j;
+ uint8* nal_unit = *bitstream;
+ int count = 0;
+
+ /* find SC at the beginning of the NAL */
+ while (nal_unit[i++] == 0 && i < *size)
+ {
+ }
+
+ if (nal_unit[i-1] == 1)
+ {
+ *bitstream = nal_unit + i;
+ }
+ else
+ {
+ j = *size;
+ *size = 0;
+ return j; // no SC at the beginning, not supposed to happen
+ }
+
+ j = i;
+
+ /* found the SC at the beginning of the NAL, now find the SC at the beginning of the next NAL */
+ while (i < *size)
+ {
+ if (count == 2 && nal_unit[i] == 0x01)
+ {
+ i -= 2;
+ break;
+ }
+
+ if (nal_unit[i])
+ count = 0;
+ else
+ count++;
+ i++;
+ }
+
+ *size -= i;
+ return (i -j);
+}