diff options
author | Rebecca Schultz Zavin <rebecca@android.com> | 2009-07-16 17:22:42 -0700 |
---|---|---|
committer | Rebecca Schultz Zavin <rebecca@android.com> | 2009-07-17 15:51:24 -0700 |
commit | fb3766f18a2c18b6f4798a6a631fdb88fcacd1dc (patch) | |
tree | c80a73eb905c31aced77165149c31271138812ff /omx/ti_omx_config_parser | |
parent | 48c9cf0ad8ae8e3f754e54790857fd57eb79c48d (diff) | |
download | omap3-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.mk | 56 | ||||
-rw-r--r-- | omx/ti_omx_config_parser/inc/ti_m4v_config_parser.h | 129 | ||||
-rw-r--r-- | omx/ti_omx_config_parser/inc/ti_omx_config_parser.h | 56 | ||||
-rw-r--r-- | omx/ti_omx_config_parser/inc/ti_video_config_parser.h | 46 | ||||
-rw-r--r-- | omx/ti_omx_config_parser/src/ti_m4v_config_parser.cpp | 1237 | ||||
-rw-r--r-- | omx/ti_omx_config_parser/src/ti_omx_config_parser.cpp | 179 | ||||
-rw-r--r-- | omx/ti_omx_config_parser/src/ti_video_config_parser.cpp | 287 |
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); +} |