Initial checkins of the mpeg4 and h263 software decoders based on PV
diff --git a/media/libstagefright/codecs/m4v_h263/Android.mk b/media/libstagefright/codecs/m4v_h263/Android.mk
new file mode 100644
index 0000000..2e431205
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/Android.mk
@@ -0,0 +1,4 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/libstagefright/codecs/m4v_h263/dec/Android.mk b/media/libstagefright/codecs/m4v_h263/dec/Android.mk
new file mode 100644
index 0000000..403da58
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/Android.mk
@@ -0,0 +1,50 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ M4vH263Decoder.cpp \
+ src/adaptive_smooth_no_mmx.cpp \
+ src/bitstream.cpp \
+ src/block_idct.cpp \
+ src/cal_dc_scaler.cpp \
+ src/chvr_filter.cpp \
+ src/chv_filter.cpp \
+ src/combined_decode.cpp \
+ src/conceal.cpp \
+ src/datapart_decode.cpp \
+ src/dcac_prediction.cpp \
+ src/dec_pred_intra_dc.cpp \
+ src/deringing_chroma.cpp \
+ src/deringing_luma.cpp \
+ src/find_min_max.cpp \
+ src/get_pred_adv_b_add.cpp \
+ src/get_pred_outside.cpp \
+ src/idct.cpp \
+ src/idct_vca.cpp \
+ src/mb_motion_comp.cpp \
+ src/mb_utils.cpp \
+ src/packet_util.cpp \
+ src/post_filter.cpp \
+ src/post_proc_semaphore.cpp \
+ src/pp_semaphore_chroma_inter.cpp \
+ src/pp_semaphore_luma.cpp \
+ src/pvdec_api.cpp \
+ src/scaling_tab.cpp \
+ src/vlc_decode.cpp \
+ src/vlc_dequant.cpp \
+ src/vlc_tab.cpp \
+ src/vop.cpp \
+ src/zigzag_tab.cpp
+
+
+LOCAL_MODULE := libstagefright_m4vh263dec
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/src \
+ $(LOCAL_PATH)/include \
+ $(TOP)/frameworks/base/media/libstagefright/include \
+ $(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include
+
+LOCAL_CFLAGS := -DOSCL_EXPORT_REF= -DOSCL_IMPORT_REF=
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/media/libstagefright/codecs/m4v_h263/dec/M4vH263Decoder.cpp b/media/libstagefright/codecs/m4v_h263/dec/M4vH263Decoder.cpp
new file mode 100644
index 0000000..efd8390
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/M4vH263Decoder.cpp
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * 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 LOG_NDEBUG 0
+#define LOG_TAG "M4vH263Decoder"
+
+#include "ESDS.h"
+#include "M4vH263Decoder.h"
+
+#include "mp4dec_api.h"
+
+#include <OMX_Component.h>
+#include <media/stagefright/MediaBufferGroup.h>
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
+
+namespace android {
+
+M4vH263Decoder::M4vH263Decoder(const sp<MediaSource> &source)
+ : mSource(source),
+ mStarted(false),
+ mHandle(new tagvideoDecControls),
+ mInputBuffer(NULL),
+ mNumSamplesOutput(0) {
+ memset(mHandle, 0, sizeof(tagvideoDecControls));
+
+ mFormat = new MetaData;
+ mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
+ CHECK(mSource->getFormat()->findInt32(kKeyWidth, &mWidth));
+ CHECK(mSource->getFormat()->findInt32(kKeyHeight, &mHeight));
+ mFormat->setInt32(kKeyWidth, mWidth);
+ mFormat->setInt32(kKeyHeight, mHeight);
+ mFormat->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420Planar);
+ mFormat->setCString(kKeyDecoderComponent, "M4vH263Decoder");
+
+}
+
+M4vH263Decoder::~M4vH263Decoder() {
+ if (mStarted) {
+ stop();
+ }
+
+ delete mHandle;
+ mHandle = NULL;
+}
+
+status_t M4vH263Decoder::start(MetaData *) {
+ CHECK(!mStarted);
+
+ const char *mime = NULL;
+ CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime));
+
+ MP4DecodingMode mode;
+ if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
+ mode = MPEG4_MODE;
+ } else {
+ CHECK(!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime));
+ mode = H263_MODE;
+ }
+
+ uint32_t type;
+ const void *data = NULL;
+ size_t size = 0;
+ uint8_t *vol_data = NULL;
+ int32_t vol_size = 0;
+ if (mSource->getFormat()->findData(kKeyESDS, &type, &data, &size)) {
+ ESDS esds((const uint8_t *)data, size);
+ CHECK_EQ(esds.InitCheck(), OK);
+
+ const void *codec_specific_data;
+ size_t codec_specific_data_size;
+ esds.getCodecSpecificInfo(&codec_specific_data, &codec_specific_data_size);
+
+ vol_data = (uint8_t *) codec_specific_data;
+ vol_size = codec_specific_data_size;
+ } else {
+ vol_data = NULL;
+ vol_size = 0;
+ }
+ CHECK_EQ(PV_TRUE, PVInitVideoDecoder(
+ mHandle, &vol_data, &vol_size, 1, mWidth, mHeight, mode));
+ MP4DecodingMode actualMode = PVGetDecBitstreamMode(mHandle);
+ CHECK_EQ(mode, actualMode);
+
+ PVSetPostProcType((VideoDecControls *) mHandle, 0);
+ size_t frameSize = (((mWidth + 15) & - 16) * ((mHeight + 15) & - 16) * 3) / 2;
+ for (uint32_t i = 0; i < 2; ++i) {
+ mFrames[i] = new MediaBuffer(frameSize);
+ mFrames[i]->setObserver(this);
+ }
+ PVSetReferenceYUV(mHandle, (uint8_t *)mFrames[1]->data());
+
+ mSource->start();
+
+ mNumSamplesOutput = 0;
+ mStarted = true;
+
+ return OK;
+}
+
+status_t M4vH263Decoder::stop() {
+ CHECK(mStarted);
+
+ if (mInputBuffer) {
+ mInputBuffer->release();
+ mInputBuffer = NULL;
+ }
+
+ mSource->stop();
+
+ releaseFrames();
+
+ mStarted = false;
+ return (PVCleanUpVideoDecoder(mHandle) == PV_TRUE)? OK: UNKNOWN_ERROR;
+}
+
+sp<MetaData> M4vH263Decoder::getFormat() {
+ return mFormat;
+}
+
+status_t M4vH263Decoder::read(
+ MediaBuffer **out, const ReadOptions *options) {
+ *out = NULL;
+
+ int64_t seekTimeUs;
+ if (options && options->getSeekTo(&seekTimeUs)) {
+ CHECK_EQ(PVResetVideoDecoder(mHandle), PV_TRUE);
+ }
+
+ MediaBuffer *inputBuffer = NULL;
+ status_t err = mSource->read(&inputBuffer, options);
+ if (err != OK) {
+ return err;
+ }
+
+ uint8_t *bitstream = (uint8_t *) inputBuffer->data() + inputBuffer->range_offset();
+ uint32_t timestamp = 0xFFFFFFFF;
+ int32_t bufferSize = inputBuffer->range_length();
+ uint32_t useExtTimestamp = 0;
+ CHECK_EQ(PV_TRUE, PVDecodeVideoFrame(mHandle, &bitstream, ×tamp, &bufferSize,
+ &useExtTimestamp, (uint8_t *)mFrames[mNumSamplesOutput & 0x01]->data()));
+
+ // Check whether video dimension is changed.
+ // If so, notify the client about the change.
+ int32_t width, height;
+ PVGetVideoDimensions(mHandle, &width, &height);
+ if (mWidth != width || mHeight != height) {
+ mFormat->setInt32(kKeyWidth, width);
+ mFormat->setInt32(kKeyHeight, height);
+ return INFO_FORMAT_CHANGED;
+ }
+
+ PVSetReferenceYUV(mHandle, (uint8_t *)mFrames[mNumSamplesOutput & 0x01]->data());
+ *out = mFrames[mNumSamplesOutput & 0x01];
+ (*out)->add_ref();
+
+ int64_t timeUs;
+ CHECK(inputBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
+ (*out)->meta_data()->setInt64(kKeyTime, timeUs);
+
+ ++mNumSamplesOutput;
+ inputBuffer->release();
+
+ return OK;
+}
+
+void M4vH263Decoder::releaseFrames() {
+ for (size_t i = 0; i < sizeof(mFrames) / sizeof(mFrames[0]); ++i) {
+ MediaBuffer *buffer = mFrames[i];
+
+ buffer->setObserver(NULL);
+ buffer->release();
+
+ mFrames[i] = NULL;
+ }
+}
+
+void M4vH263Decoder::signalBufferReturned(MediaBuffer *buffer) {
+ LOGV("signalBufferReturned");
+}
+
+
+} // namespace android
diff --git a/media/libstagefright/codecs/m4v_h263/dec/include/m4vh263_decoder_pv_types.h b/media/libstagefright/codecs/m4v_h263/dec/include/m4vh263_decoder_pv_types.h
new file mode 100644
index 0000000..e427b64
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/include/m4vh263_decoder_pv_types.h
@@ -0,0 +1,66 @@
+/* ------------------------------------------------------------------
+ * 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 M4V_H263_DECODER_PV_TYPES_H_
+#define M4V_H263_DECODER_PV_TYPES_H_
+
+#include <stdint.h>
+#include <string.h>
+
+// Redefine the int types
+typedef uint8_t uint8;
+typedef uint16_t uint16;
+typedef int16_t int16;
+typedef uint32_t uint32;
+typedef int32_t int32;
+typedef unsigned int uint;
+
+// Redefine the oscl memory management routines
+#define oscl_memcpy memcpy
+#define oscl_memset memset
+#define oscl_malloc malloc
+#define oscl_free free
+#define oscl_memcmp memcmp
+#define OSCL_DELETE(ptr) { delete(ptr); }
+
+// Request status values. These are negative so that
+// they won't conflict with system error codes.
+const int32 OSCL_REQUEST_ERR_NONE = 0;
+const int32 OSCL_REQUEST_PENDING = (-0x7fffffff);
+const int32 OSCL_REQUEST_ERR_CANCEL = (-1);
+const int32 OSCL_REQUEST_ERR_GENERAL = (-2);
+
+// Request status type
+class OsclAOStatus
+{
+ public:
+ OsclAOStatus();
+ OsclAOStatus(int32 aStatus);
+ int32 operator=(int32 aStatus);
+ int32 operator==(int32 aStatus) const;
+ int32 operator!=(int32 aStatus) const;
+ int32 operator>=(int32 aStatus) const;
+ int32 operator<=(int32 aStatus) const;
+ int32 operator>(int32 aStatus) const;
+ int32 operator<(int32 aStatus) const;
+ int32 Value() const;
+ private:
+ int32 iStatus;
+};
+
+#endif // M4V_H263_DECODER_PV_TYPES_H_
diff --git a/media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h b/media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h
new file mode 100644
index 0000000..ef09900
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h
@@ -0,0 +1,180 @@
+/* ------------------------------------------------------------------
+ * 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 _MP4DEC_API_H_
+#define _MP4DEC_API_H_
+
+#include "m4vh263_decoder_pv_types.h"
+
+#define PV_TOLERATE_VOL_ERRORS
+#define PV_MEMORY_POOL
+
+#ifndef _PV_TYPES_
+#define _PV_TYPES_
+
+typedef uint Bool;
+
+#define PV_CODEC_INIT 0
+#define PV_CODEC_STOP 1
+#endif
+
+#define PV_TRUE 1
+#define PV_FALSE 0
+
+/* flag for post-processing 4/25/00 */
+
+#ifdef DEC_NOPOSTPROC
+#undef PV_POSTPROC_ON /* enable compilation of post-processing code */
+#else
+#define PV_POSTPROC_ON
+#endif
+
+#define PV_NO_POST_PROC 0
+#define PV_DEBLOCK 1
+#define PV_DERING 2
+
+
+
+#include "visual_header.h" // struct VolInfo is defined
+
+
+/**@name Structure and Data Types
+ * These type definitions specify the input / output from the PVMessage
+ * library.
+ */
+
+/*@{*/
+/* The application has to allocate space for this structure */
+typedef struct tagOutputFrame
+{
+ uint8 *data; /* pointer to output YUV buffer */
+ uint32 timeStamp; /* time stamp */
+} OutputFrame;
+
+typedef struct tagApplicationData
+{
+ int layer; /* current video layer */
+ void *object; /* some optional data field */
+} applicationData;
+
+/* Application controls, this structed shall be allocated */
+/* and initialized in the application. */
+typedef struct tagvideoDecControls
+{
+ /* The following fucntion pointer is copied to BitstreamDecVideo structure */
+ /* upon initialization and never used again. */
+ int (*readBitstreamData)(uint8 *buf, int nbytes_required, void *appData);
+ applicationData appData;
+
+ uint8 *outputFrame;
+ void *videoDecoderData; /* this is an internal pointer that is only used */
+ /* in the decoder library. */
+#ifdef PV_MEMORY_POOL
+ int32 size;
+#endif
+ int nLayers;
+ /* pointers to VOL data for frame-based decoding. */
+ uint8 *volbuf[2]; /* maximum of 2 layers for now */
+ int32 volbuf_size[2];
+
+} VideoDecControls;
+
+typedef enum
+{
+ H263_MODE = 0, MPEG4_MODE, UNKNOWN_MODE
+} MP4DecodingMode;
+
+typedef enum
+{
+ MP4_I_FRAME, MP4_P_FRAME, MP4_B_FRAME, MP4_BAD_FRAME
+} MP4FrameType;
+
+typedef struct tagVopHeaderInfo
+{
+ int currLayer;
+ uint32 timestamp;
+ MP4FrameType frameType;
+ int refSelCode;
+ int16 quantizer;
+} VopHeaderInfo;
+
+/*--------------------------------------------------------------------------*
+ * VideoRefCopyInfo:
+ * OMAP DSP specific typedef structure, to support the user (ARM) copying
+ * of a Reference Frame into the Video Decoder.
+ *--------------------------------------------------------------------------*/
+typedef struct tagVideoRefCopyInfoPtr
+{
+ uint8 *yChan; /* The Y component frame the user can copy a new reference to */
+ uint8 *uChan; /* The U component frame the user can copy a new reference to */
+ uint8 *vChan; /* The V component frame the user can copy a new reference to */
+ uint8 *currentVop; /* The Vop for video the user can copy a new reference to */
+} VideoRefCopyInfoPtr;
+
+typedef struct tagVideoRefCopyInfoData
+{
+ int16 width; /* Width */
+ int16 height; /* Height */
+ int16 realWidth; /* Non-padded width, not a multiple of 16. */
+ int16 realHeight; /* Non-padded height, not a multiple of 16. */
+} VideoRefCopyInfoData;
+
+typedef struct tagVideoRefCopyInfo
+{
+ VideoRefCopyInfoData data;
+ VideoRefCopyInfoPtr ptrs;
+} VideoRefCopyInfo;
+
+/*@}*/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+ OSCL_IMPORT_REF Bool PVInitVideoDecoder(VideoDecControls *decCtrl, uint8 *volbuf[], int32 *volbuf_size, int nLayers, int width, int height, MP4DecodingMode mode);
+ Bool PVAllocVideoData(VideoDecControls *decCtrl, int width, int height, int nLayers);
+ OSCL_IMPORT_REF Bool PVCleanUpVideoDecoder(VideoDecControls *decCtrl);
+ Bool PVResetVideoDecoder(VideoDecControls *decCtrl);
+ OSCL_IMPORT_REF void PVSetReferenceYUV(VideoDecControls *decCtrl, uint8 *refYUV);
+ Bool PVDecSetReference(VideoDecControls *decCtrl, uint8 *refYUV, uint32 timestamp);
+ Bool PVDecSetEnhReference(VideoDecControls *decCtrl, uint8 *refYUV, uint32 timestamp);
+ OSCL_IMPORT_REF Bool PVDecodeVideoFrame(VideoDecControls *decCtrl, uint8 *bitstream[], uint32 *timestamp, int32 *buffer_size, uint use_ext_timestamp[], uint8* currYUV);
+ Bool PVDecodeVopHeader(VideoDecControls *decCtrl, uint8 *buffer[], uint32 timestamp[], int32 buffer_size[], VopHeaderInfo *header_info, uint use_ext_timestamp[], uint8 *currYUV);
+ Bool PVDecodeVopBody(VideoDecControls *decCtrl, int32 buffer_size[]);
+ void PVDecPostProcess(VideoDecControls *decCtrl, uint8 *outputYUV);
+ OSCL_IMPORT_REF void PVGetVideoDimensions(VideoDecControls *decCtrl, int32 *display_width, int32 *display_height);
+ OSCL_IMPORT_REF void PVSetPostProcType(VideoDecControls *decCtrl, int mode);
+ uint32 PVGetVideoTimeStamp(VideoDecControls *decoderControl);
+ int PVGetDecBitrate(VideoDecControls *decCtrl);
+ int PVGetDecFramerate(VideoDecControls *decCtrl);
+ uint8 *PVGetDecOutputFrame(VideoDecControls *decCtrl);
+ int PVGetLayerID(VideoDecControls *decCtrl);
+ int32 PVGetDecMemoryUsage(VideoDecControls *decCtrl);
+ OSCL_IMPORT_REF MP4DecodingMode PVGetDecBitstreamMode(VideoDecControls *decCtrl);
+ Bool PVExtractVolHeader(uint8 *video_buffer, uint8 *vol_header, int32 *vol_header_size);
+ int32 PVLocateFrameHeader(uint8 *video_buffer, int32 vop_size);
+ int32 PVLocateH263FrameHeader(uint8 *video_buffer, int32 vop_size);
+ Bool PVGetVolInfo(VideoDecControls *decCtrl, VolInfo *pVolInfo); // BX 6/24/04
+ Bool IsIntraFrame(VideoDecControls *decoderControl);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _MP4DEC_API_H_ */
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/include/visual_header.h b/media/libstagefright/codecs/m4v_h263/dec/include/visual_header.h
new file mode 100644
index 0000000..48da0dc
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/include/visual_header.h
@@ -0,0 +1,51 @@
+/* ------------------------------------------------------------------
+ * 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 _VISUAL_HEADER_H
+#define _VISUAL_HEADER_H
+
+#ifndef _PV_TYPES_ // In order to compile in MDF wrapper
+#define _PV_TYPES_
+
+#include "m4vh263_decoder_pv_types.h"
+
+typedef uint Bool;
+
+#endif // #ifndef _PV_TYPES_
+
+
+typedef struct tagVolInfo
+{
+ int32 shortVideoHeader; /* shortVideoHeader mode */
+
+ /* Error Resilience Flags */
+ int32 errorResDisable; /* VOL disable error resilence mode(Use Resynch markers) */
+ int32 useReverseVLC; /* VOL reversible VLCs */
+ int32 dataPartitioning; /* VOL data partitioning */
+
+ /* Parameters used for scalability */
+ int32 scalability; /* VOL scalability (flag) */
+
+ int32 nbitsTimeIncRes; /* number of bits for time increment () */
+
+ int32 profile_level_id; /* profile and level */
+
+
+} VolInfo;
+
+#endif // #ifndef _VISUAL_HEADER_H
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/adaptive_smooth_no_mmx.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/adaptive_smooth_no_mmx.cpp
new file mode 100644
index 0000000..e2761eb
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/adaptive_smooth_no_mmx.cpp
@@ -0,0 +1,421 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+/*
+
+ Description: Separated modules into one function per file and put into
+ new template.
+
+ Description: Optimizing C code and adding comments. Also changing variable
+ names to make them more meaningful.
+
+ Who: Date:
+ Description:
+
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+
+ Rec_Y = pointer to 0th position in buffer containing luminance values
+ of type uint8.
+ y_start = value of y coordinate of type int that specifies the first
+ row of pixels to be used in the filter algorithm.
+ x_start = value of x coordinate of type int that specifies the first
+ column of pixels to be used in the filter algorithm.
+ y_blk_start = value of the y coordinate of type int that specifies the
+ row of pixels which contains the start of a block. The row
+ specified by y_blk_start+BLK_SIZE is the last row of pixels
+ that are used in the filter algorithm.
+ x_blk_start = value of the x coordinate of type int that specifies the
+ column of pixels which contains the start of a block. The
+ column specified by x_blk_start+BLK_SIZE is the last column of
+ pixels that are used in the filter algorithm.
+ thr = value of type int that is compared to the elements in Rec_Y to
+ determine if a particular value in Rec_Y will be modified by
+ the filter or not
+ width = value of type int that specifies the width of the display
+ in pixels (or pels, equivalently).
+ max_diff = value of type int that specifies the value that may be added
+ or subtracted from the pixel in Rec_Y that is being filtered
+ if the filter algorithm decides to change that particular
+ pixel's luminance value.
+
+
+ Local Stores/Buffers/Pointers Needed:
+ None
+
+ Global Stores/Buffers/Pointers Needed:
+ None
+
+ Outputs:
+ None
+
+ Pointers and Buffers Modified:
+ Buffer pointed to by Rec_Y is modified with the filtered
+ luminance values.
+
+ Local Stores Modified:
+ None
+
+ Global Stores Modified:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function implements a motion compensated noise filter using adaptive
+ weighted averaging of luminance values. *Rec_Y contains the luminance values
+ that are being filtered.
+
+ The picture below depicts a 3x3 group of pixel luminance values. The "u", "c",
+ and "l" stand for "upper", "center" and "lower", respectively. The location
+ of pelc0 is specified by x_start and y_start in the 1-D array "Rec_Y" as
+ follows (assuming x_start=0):
+
+ location of pelc0 = [(y_start+1) * width] + x_start
+
+ Moving up or down 1 row (moving from pelu2 to pelc2, for example) is done by
+ incrementing or decrementing "width" elements within Rec_Y.
+
+ The coordinates of the upper left hand corner of a block (not the group of
+ 9 pixels depicted in the figure below) is specified by
+ (y_blk_start, x_blk_start). The width and height of the block is BLKSIZE.
+ (y_start,x_start) may be specified independently of (y_blk_start, x_blk_start).
+
+ (y_start,x_start)
+ -----------|--------------------------
+ | | | | |
+ | X | pelu1 | pelu2 |
+ | pelu0 | | |
+ | | | |
+ --------------------------------------
+ | | | |
+ | pelc0 | pelc1 | pelc2 |
+ | | | |
+ | | | |
+ --------------------------------------
+ | | | |
+ | pell0 | pell1 | pell2 |
+ | | | |
+ | | | |
+ --------------------------------------
+
+ The filtering of the luminance values is achieved by comparing the 9
+ luminance values to a threshold value ("thr") and then changing the
+ luminance value of pelc1 if all of the values are above or all of the values
+ are below the threshold. The amount that the luminance value is changed
+ depends on a weighted sum of the 9 luminance values. The position of Pelc1
+ is then advanced to the right by one (as well as all of the surrounding pixels)
+ and the same calculation is performed again for the luminance value of the new
+ Pelc1. This continues row-wise until pixels in the last row of the block are
+ filtered.
+
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None.
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ ..\corelibs\decoder\common\src\post_proc.c
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+------------------------------------------------------------------------------
+ RESOURCES USED
+ When the code is written for a specific target processor the
+ the resources used should be documented below.
+
+ STACK USAGE: [stack count for this module] + [variable to represent
+ stack usage for each subroutine called]
+
+ where: [stack usage variable] = stack usage for [subroutine
+ name] (see [filename].ext)
+
+ DATA MEMORY USED: x words
+
+ PROGRAM MEMORY USED: x words
+
+ CLOCK CYCLES: [cycle count equation for this module] + [variable
+ used to represent cycle count for each subroutine
+ called]
+
+ where: [cycle count variable] = cycle count for [subroutine
+ name] (see [filename].ext)
+
+------------------------------------------------------------------------------
+*/
+
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "mp4dec_lib.h"
+#include "post_proc.h"
+#include "mp4def.h"
+
+#define OSCL_DISABLE_WARNING_CONV_POSSIBLE_LOSS_OF_DATA
+
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here. Include conditional
+; compile variables also.
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL FUNCTION DEFINITIONS
+; Function Prototype declaration
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL STORE/BUFFER/POINTER DEFINITIONS
+; Variable declaration - defined here and used outside this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL FUNCTION REFERENCES
+; Declare functions defined elsewhere and referenced in this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+#ifdef PV_POSTPROC_ON
+/*----------------------------------------------------------------------------
+; FUNCTION CODE
+----------------------------------------------------------------------------*/
+void AdaptiveSmooth_NoMMX(
+ uint8 *Rec_Y, /* i/o */
+ int y_start, /* i */
+ int x_start, /* i */
+ int y_blk_start, /* i */
+ int x_blk_start, /* i */
+ int thr, /* i */
+ int width, /* i */
+ int max_diff /* i */
+)
+{
+
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int sign_v[15];
+ int sum_v[15];
+ int *sum_V_ptr;
+ int *sign_V_ptr;
+ uint8 pelu;
+ uint8 pelc;
+ uint8 pell;
+ uint8 *pelp;
+ uint8 oldrow[15];
+ int sum;
+ int sum1;
+ uint8 *Rec_Y_ptr;
+ int32 addr_v;
+ int row_cntr;
+ int col_cntr;
+
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ /* first row
+ */
+ addr_v = (int32)(y_start + 1) * width; /* y coord of 1st element in the row /
+ /containing pelc pixel / */
+ Rec_Y_ptr = &Rec_Y[addr_v + x_start]; /* initializing pointer to
+ / pelc0 position */
+ sum_V_ptr = &sum_v[0]; /* initializing pointer to 0th element of array
+ / that will contain weighted sums of pixel
+ / luminance values */
+ sign_V_ptr = &sign_v[0]; /* initializing pointer to 0th element of
+ / array that will contain sums that indicate
+ / how many of the 9 pixels are above or below
+ / the threshold value (thr) */
+ pelp = &oldrow[0]; /* initializing pointer to the 0th element of array
+ / that will contain current values of pelc that
+ / are saved and used as values of pelu when the
+ / next row of pixels are filtered */
+
+ pelu = *(Rec_Y_ptr - width); /* assigning value of pelu0 to pelu */
+ *pelp++ = pelc = *Rec_Y_ptr; /* assigning value of pelc0 to pelc and
+ / storing this value in pelp which
+ / will be used as value of pelu0 when
+ / next row is filtered */
+ pell = *(Rec_Y_ptr + width); /* assigning value of pell0 to pell */
+ Rec_Y_ptr++; /* advancing pointer from pelc0 to pelc1 */
+ *sum_V_ptr++ = pelu + (pelc << 1) + pell; /* weighted sum of pelu0,
+ / pelc0 and pell0 */
+ /* sum of 0's and 1's (0 if pixel value is below thr, 1 if value
+ /is above thr) */
+ *sign_V_ptr++ = INDEX(pelu, thr) + INDEX(pelc, thr) + INDEX(pell, thr);
+
+
+ pelu = *(Rec_Y_ptr - width); /* assigning value of pelu1 to pelu */
+ *pelp++ = pelc = *Rec_Y_ptr; /* assigning value of pelc1 to pelc and
+ / storing this value in pelp which
+ / will be used as the value of pelu1 when
+ / next row is filtered */
+ pell = *(Rec_Y_ptr + width); /* assigning value of pell1 to pell */
+ Rec_Y_ptr++; /* advancing pointer from pelc1 to pelc2 */
+ *sum_V_ptr++ = pelu + (pelc << 1) + pell; /* weighted sum of pelu1,
+ / pelc1 and pell1 */
+ /* sum of 0's and 1's (0 if pixel value is below thr, 1 if value
+ /is above thr) */
+ *sign_V_ptr++ = INDEX(pelu, thr) + INDEX(pelc, thr) + INDEX(pell, thr);
+
+ /* The loop below performs the filtering for the first row of
+ / pixels in the region. It steps across the remaining pixels in
+ / the row and alters the luminance value of pelc1 if necessary,
+ / depending on the luminance values of the adjacent pixels*/
+
+ for (col_cntr = (x_blk_start + BLKSIZE - 1) - x_start; col_cntr > 0; col_cntr--)
+ {
+ pelu = *(Rec_Y_ptr - width); /* assigning value of pelu2 to
+ / pelu */
+ *pelp++ = pelc = *Rec_Y_ptr; /* assigning value of pelc2 to pelc
+ / and storing this value in pelp
+ / which will be used as value of pelu2
+ / when next row is filtered */
+ pell = *(Rec_Y_ptr + width); /* assigning value of pell2 to pell */
+
+ /* weighted sum of pelu1, pelc1 and pell1 */
+ *sum_V_ptr = pelu + (pelc << 1) + pell;
+ /* sum of 0's and 1's (0 if pixel value is below thr,
+ /1 if value is above thr) */
+ *sign_V_ptr = INDEX(pelu, thr) + INDEX(pelc, thr) +
+ INDEX(pell, thr);
+ /* the value of sum1 indicates how many of the 9 pixels'
+ /luminance values are above or equal to thr */
+ sum1 = *(sign_V_ptr - 2) + *(sign_V_ptr - 1) + *sign_V_ptr;
+
+ /* alter the luminance value of pelc1 if all 9 luminance values
+ /are above or equal to thr or if all 9 values are below thr */
+ if (sum1 == 0 || sum1 == 9)
+ {
+ /* sum is a weighted average of the 9 pixel luminance
+ /values */
+ sum = (*(sum_V_ptr - 2) + (*(sum_V_ptr - 1) << 1) +
+ *sum_V_ptr + 8) >> 4;
+
+ Rec_Y_ptr--; /* move pointer back to pelc1 */
+ /* If luminance value of pelc1 is larger than
+ / sum by more than max_diff, then subract max_diff
+ / from luminance value of pelc1*/
+ if ((int)(*Rec_Y_ptr - sum) > max_diff)
+ {
+ sum = *Rec_Y_ptr - max_diff;
+ }
+ /* If luminance value of pelc1 is smaller than
+ / sum by more than max_diff, then add max_diff
+ / to luminance value of pelc1*/
+ else if ((int)(*Rec_Y_ptr - sum) < -max_diff)
+ {
+ sum = *Rec_Y_ptr + max_diff;
+ }
+ *Rec_Y_ptr++ = sum; /* assign value of sum to pelc1
+ and advance pointer to pelc2 */
+ }
+ Rec_Y_ptr++; /* advance pointer to new value of pelc2
+ / old pelc2 is now treated as pelc1*/
+ sum_V_ptr++; /* pointer is advanced so next weighted sum may
+ / be saved */
+ sign_V_ptr++; /* pointer is advanced so next sum of 0's and
+ / 1's may be saved */
+ }
+
+ /* The nested loops below perform the filtering for the remaining rows */
+
+ addr_v = (y_start + 2) * width; /* advance addr_v to the next row
+ / (corresponding to pell0)*/
+ /* The outer loop steps throught the rows. */
+ for (row_cntr = (y_blk_start + BLKSIZE) - (y_start + 2); row_cntr > 0; row_cntr--)
+ {
+ Rec_Y_ptr = &Rec_Y[addr_v + x_start]; /* advance pointer to
+ /the old pell0, which has become the new pelc0 */
+ addr_v += width; /* move addr_v down 1 row */
+ sum_V_ptr = &sum_v[0]; /* re-initializing pointer */
+ sign_V_ptr = &sign_v[0]; /* re-initilaizing pointer */
+ pelp = &oldrow[0]; /* re-initializing pointer */
+
+ pelu = *pelp; /* setting pelu0 to old value of pelc0 */
+ *pelp++ = pelc = *Rec_Y_ptr;
+ pell = *(Rec_Y_ptr + width);
+ Rec_Y_ptr++;
+ *sum_V_ptr++ = pelu + (pelc << 1) + pell;
+ *sign_V_ptr++ = INDEX(pelu, thr) + INDEX(pelc, thr) +
+ INDEX(pell, thr);
+
+ pelu = *pelp; /* setting pelu1 to old value of pelc1 */
+ *pelp++ = pelc = *Rec_Y_ptr;
+ pell = *(Rec_Y_ptr + width);
+ Rec_Y_ptr++;
+ *sum_V_ptr++ = pelu + (pelc << 1) + pell;
+ *sign_V_ptr++ = INDEX(pelu, thr) + INDEX(pelc, thr) +
+ INDEX(pell, thr);
+ /* The inner loop steps through the columns */
+ for (col_cntr = (x_blk_start + BLKSIZE - 1) - x_start; col_cntr > 0; col_cntr--)
+ {
+ pelu = *pelp; /* setting pelu2 to old value of pelc2 */
+ *pelp++ = pelc = *Rec_Y_ptr;
+ pell = *(Rec_Y_ptr + width);
+
+ *sum_V_ptr = pelu + (pelc << 1) + pell;
+ *sign_V_ptr = INDEX(pelu, thr) + INDEX(pelc, thr) +
+ INDEX(pell, thr);
+
+ sum1 = *(sign_V_ptr - 2) + *(sign_V_ptr - 1) + *sign_V_ptr;
+ /* the "if" statement below is the same as the one in
+ / the first loop */
+ if (sum1 == 0 || sum1 == 9)
+ {
+ sum = (*(sum_V_ptr - 2) + (*(sum_V_ptr - 1) << 1) +
+ *sum_V_ptr + 8) >> 4;
+
+ Rec_Y_ptr--;
+ if ((int)(*Rec_Y_ptr - sum) > max_diff)
+ {
+ sum = *Rec_Y_ptr - max_diff;
+ }
+ else if ((int)(*Rec_Y_ptr - sum) < -max_diff)
+ {
+ sum = *Rec_Y_ptr + max_diff;
+ }
+ *Rec_Y_ptr++ = (uint8) sum;
+ }
+ Rec_Y_ptr++;
+ sum_V_ptr++;
+ sign_V_ptr++;
+ }
+ }
+
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return;
+}
+#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/bitstream.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/bitstream.cpp
new file mode 100644
index 0000000..37250f3
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/bitstream.cpp
@@ -0,0 +1,1001 @@
+/* ------------------------------------------------------------------
+ * 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 "bitstream.h"
+#include "mp4dec_lib.h"
+
+
+#define OSCL_DISABLE_WARNING_CONDITIONAL_IS_CONSTANT
+/* to mask the n least significant bits of an integer */
+static const uint32 msk[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
+};
+
+
+/* ======================================================================== */
+/* Function : BitstreamFillCache() */
+/* Date : 08/29/2000 */
+/* Purpose : Read more bitstream data into buffer & the 24-byte cache. */
+/* This function is different from BitstreamFillBuffer in */
+/* that the buffer is the frame-based buffer provided by */
+/* the application. */
+/* In/out : */
+/* Return : PV_SUCCESS if successed, PV_FAIL if failed. */
+/* Modified : 4/16/01 : removed return of PV_END_OF_BUFFER */
+/* ======================================================================== */
+PV_STATUS BitstreamFillCache(BitstreamDecVideo *stream)
+{
+ uint8 *bitstreamBuffer = stream->bitstreamBuffer;
+ uint8 *v;
+ int num_bits, i;
+
+ stream->curr_word |= (stream->next_word >> stream->incnt); // stream->incnt cannot be 32
+ stream->next_word <<= (31 - stream->incnt);
+ stream->next_word <<= 1;
+ num_bits = stream->incnt_next + stream->incnt;
+ if (num_bits >= 32)
+ {
+ stream->incnt_next -= (32 - stream->incnt);
+ stream->incnt = 32;
+ return PV_SUCCESS;
+ }
+ /* this check can be removed if there is additional extra 4 bytes at the end of the bitstream */
+ v = bitstreamBuffer + stream->read_point;
+
+ if (stream->read_point > stream->data_end_pos - 4)
+ {
+ if (stream->data_end_pos <= stream->read_point)
+ {
+ stream->incnt = num_bits;
+ stream->incnt_next = 0;
+ return PV_SUCCESS;
+ }
+
+ stream->next_word = 0;
+
+ for (i = 0; i < stream->data_end_pos - stream->read_point; i++)
+ {
+ stream->next_word |= (v[i] << ((3 - i) << 3));
+ }
+
+ stream->read_point = stream->data_end_pos;
+ stream->curr_word |= (stream->next_word >> num_bits); // this is safe
+
+ stream->next_word <<= (31 - num_bits);
+ stream->next_word <<= 1;
+ num_bits = i << 3;
+ stream->incnt += stream->incnt_next;
+ stream->incnt_next = num_bits - (32 - stream->incnt);
+ if (stream->incnt_next < 0)
+ {
+ stream->incnt += num_bits;
+ stream->incnt_next = 0;
+ }
+ else
+ {
+ stream->incnt = 32;
+ }
+ return PV_SUCCESS;
+ }
+
+ stream->next_word = ((uint32)v[0] << 24) | (v[1] << 16) | (v[2] << 8) | v[3];
+ stream->read_point += 4;
+
+ stream->curr_word |= (stream->next_word >> num_bits); // this is safe
+ stream->next_word <<= (31 - num_bits);
+ stream->next_word <<= 1;
+ stream->incnt_next += stream->incnt;
+ stream->incnt = 32;
+ return PV_SUCCESS;
+}
+
+
+/* ======================================================================== */
+/* Function : BitstreamReset() */
+/* Date : 08/29/2000 */
+/* Purpose : Initialize the bitstream buffer for frame-based decoding. */
+/* In/out : */
+/* Return : */
+/* Modified : */
+/* ======================================================================== */
+void BitstreamReset(BitstreamDecVideo *stream, uint8 *buffer, int32 buffer_size)
+{
+ /* set up frame-based bitstream buffer */
+ oscl_memset(stream, 0, sizeof(BitstreamDecVideo));
+ stream->data_end_pos = buffer_size;
+ stream->bitstreamBuffer = buffer;
+}
+
+
+/* ======================================================================== */
+/* Function : BitstreamOpen() */
+/* Purpose : Initialize the bitstream data structure. */
+/* In/out : */
+/* Return : */
+/* Modified : */
+/* ======================================================================== */
+int BitstreamOpen(BitstreamDecVideo *stream, int)
+{
+ int buffer_size = 0;
+ /* set up linear bitstream buffer */
+// stream->currentBytePos = 0;
+ stream->data_end_pos = 0;
+
+ stream->incnt = 0;
+ stream->incnt_next = 0;
+ stream->bitcnt = 0;
+ stream->curr_word = stream->next_word = 0;
+ stream->read_point = stream->data_end_pos;
+ return buffer_size;
+}
+
+
+/* ======================================================================== */
+/* Function : BitstreamClose() */
+/* Purpose : Cleanup the bitstream data structure. */
+/* In/out : */
+/* Return : */
+/* Modified : */
+/* ======================================================================== */
+void BitstreamClose(BitstreamDecVideo *)
+{
+ return;
+}
+
+
+/***********************************************************CommentBegin******
+*
+* -- BitstreamShowBits32HC
+* Shows 32 bits
+***********************************************************CommentEnd********/
+
+PV_STATUS BitstreamShowBits32HC(BitstreamDecVideo *stream, uint32 *code)
+{
+ PV_STATUS status = PV_SUCCESS;
+
+ if (stream->incnt < 32)
+ {
+ /* frame-based decoding */
+ status = BitstreamFillCache(stream);
+ }
+ *code = stream->curr_word;
+ return status;
+}
+
+/***********************************************************CommentBegin******
+*
+* -- BitstreamShowBits32
+* Shows upto and including 31 bits
+***********************************************************CommentEnd********/
+PV_STATUS BitstreamShowBits32(BitstreamDecVideo *stream, int nbits, uint32 *code)
+{
+ PV_STATUS status = PV_SUCCESS;
+
+ if (stream->incnt < nbits)
+ {
+ /* frame-based decoding */
+ status = BitstreamFillCache(stream);
+ }
+ *code = stream->curr_word >> (32 - nbits);
+ return status;
+}
+
+
+#ifndef PV_BS_INLINE
+/*========================================================================= */
+/* Function: BitstreamShowBits16() */
+/* Date: 12/18/2000 */
+/* Purpose: To see the next "nbits"(nbits<=16) bitstream bits */
+/* without advancing the read pointer */
+/* */
+/* =========================================================================*/
+PV_STATUS BitstreamShowBits16(BitstreamDecVideo *stream, int nbits, uint *code)
+{
+ PV_STATUS status = PV_SUCCESS;
+
+
+ if (stream->incnt < nbits)
+ {
+ /* frame-based decoding */
+ status = BitstreamFillCache(stream);
+ }
+
+ *code = stream->curr_word >> (32 - nbits);
+ return status;
+}
+
+
+/*========================================================================= */
+/* Function: BitstreamShow15Bits() */
+/* Date: 01/23/2001 */
+/* Purpose: To see the next 15 bitstream bits */
+/* without advancing the read pointer */
+/* */
+/* =========================================================================*/
+PV_STATUS BitstreamShow15Bits(BitstreamDecVideo *stream, uint *code)
+{
+ PV_STATUS status = PV_SUCCESS;
+
+ if (stream->incnt < 15)
+ {
+ /* frame-based decoding */
+ status = BitstreamFillCache(stream);
+ }
+ *code = stream->curr_word >> 17;
+ return status;
+}
+/*========================================================================= */
+/* Function: BitstreamShow13Bits */
+/* Date: 050923 */
+/* Purpose: Faciliate and speed up showing 13 bit from bitstream */
+/* used in VlcTCOEFF decoding */
+/* Modified: */
+/* =========================================================================*/
+PV_STATUS BitstreamShow13Bits(BitstreamDecVideo *stream, uint *code)
+{
+ PV_STATUS status = PV_SUCCESS;
+
+ if (stream->incnt < 13)
+ {
+ /* frame-based decoding */
+ status = BitstreamFillCache(stream);
+ }
+ *code = stream->curr_word >> 19;
+ return status;
+}
+
+uint BitstreamReadBits16_INLINE(BitstreamDecVideo *stream, int nbits)
+{
+ uint code;
+ PV_STATUS status;
+
+ if (stream->incnt < nbits)
+ {
+ /* frame-based decoding */
+ status = BitstreamFillCache(stream);
+ }
+ code = stream->curr_word >> (32 - nbits);
+ PV_BitstreamFlushBits(stream, nbits);
+ return code;
+}
+
+
+uint BitstreamRead1Bits_INLINE(BitstreamDecVideo *stream)
+{
+ PV_STATUS status = PV_SUCCESS;
+ uint code;
+
+
+ if (stream->incnt < 1)
+ {
+ /* frame-based decoding */
+ status = BitstreamFillCache(stream);
+ }
+ code = stream->curr_word >> 31;
+ PV_BitstreamFlushBits(stream, 1);
+
+ return code;
+}
+
+#endif
+
+/* ======================================================================== */
+/* Function : BitstreamReadBits16() */
+/* Purpose : Read bits (nbits <=16) from bitstream buffer. */
+/* In/out : */
+/* Return : */
+/* ======================================================================== */
+uint BitstreamReadBits16(BitstreamDecVideo *stream, int nbits)
+{
+ uint code;
+
+ if (stream->incnt < nbits)
+ {
+ /* frame-based decoding */
+ BitstreamFillCache(stream);
+ }
+ code = stream->curr_word >> (32 - nbits);
+ PV_BitstreamFlushBits(stream, nbits);
+ return code;
+}
+
+/* ======================================================================== */
+/* Function : BitstreamRead1Bits() */
+/* Date : 10/23/2000 */
+/* Purpose : Faciliate and speed up reading 1 bit from bitstream. */
+/* In/out : */
+/* Return : */
+/* ======================================================================== */
+
+uint BitstreamRead1Bits(BitstreamDecVideo *stream)
+{
+ uint code;
+
+ if (stream->incnt < 1)
+ {
+ /* frame-based decoding */
+ BitstreamFillCache(stream);
+ }
+ code = stream->curr_word >> 31;
+ PV_BitstreamFlushBits(stream, 1);
+
+ return code;
+}
+
+/* ======================================================================== */
+/* Function : PV_BitstreamFlushBitsCheck() */
+/* Purpose : Flush nbits bits from bitstream buffer. Check for cache */
+/* In/out : */
+/* Return : */
+/* Modified : */
+/* ======================================================================== */
+PV_STATUS PV_BitstreamFlushBitsCheck(BitstreamDecVideo *stream, int nbits)
+{
+ PV_STATUS status = PV_SUCCESS;
+
+ stream->bitcnt += nbits;
+ stream->incnt -= nbits;
+ if (stream->incnt < 0)
+ {
+ /* frame-based decoding */
+ status = BitstreamFillCache(stream);
+
+ if (stream->incnt < 0)
+ {
+ stream->bitcnt += stream->incnt;
+ stream->incnt = 0;
+ }
+ }
+ stream->curr_word <<= nbits;
+ return status;
+}
+
+/* ======================================================================== */
+/* Function : BitstreamReadBits32() */
+/* Purpose : Read bits from bitstream buffer. */
+/* In/out : */
+/* Return : */
+/* ======================================================================== */
+uint32 BitstreamReadBits32(BitstreamDecVideo *stream, int nbits)
+{
+ uint32 code;
+
+ if (stream->incnt < nbits)
+ {
+ /* frame-based decoding */
+ BitstreamFillCache(stream);
+ }
+ code = stream->curr_word >> (32 - nbits);
+ PV_BitstreamFlushBits(stream, nbits);
+ return code;
+}
+
+uint32 BitstreamReadBits32HC(BitstreamDecVideo *stream)
+{
+ uint32 code;
+
+ BitstreamShowBits32HC(stream, &code);
+ stream->bitcnt += 32;
+ stream->incnt = 0;
+ stream->curr_word = 0;
+ return code;
+}
+
+/* ======================================================================== */
+/* Function : BitstreamCheckEndBuffer() */
+/* Date : 03/30/2001 */
+/* Purpose : Check to see if we are at the end of buffer */
+/* In/out : */
+/* Return : */
+/* Modified : */
+/* ======================================================================== */
+PV_STATUS BitstreamCheckEndBuffer(BitstreamDecVideo *stream)
+{
+ if (stream->read_point >= stream->data_end_pos && stream->incnt <= 0) return PV_END_OF_VOP;
+ return PV_SUCCESS;
+}
+
+
+PV_STATUS PV_BitstreamShowBitsByteAlign(BitstreamDecVideo *stream, int nbits, uint32 *code)
+{
+ PV_STATUS status = PV_SUCCESS;
+
+ int n_stuffed;
+
+ n_stuffed = 8 - (stream->bitcnt & 0x7); /* 07/05/01 */
+
+ if (stream->incnt < (nbits + n_stuffed))
+ {
+ /* frame-based decoding */
+ status = BitstreamFillCache(stream);
+ }
+
+ *code = (stream->curr_word << n_stuffed) >> (32 - nbits);
+ return status;
+}
+
+#ifdef PV_ANNEX_IJKT_SUPPORT
+PV_STATUS PV_BitstreamShowBitsByteAlignNoForceStuffing(BitstreamDecVideo *stream, int nbits, uint32 *code)
+{
+ PV_STATUS status = PV_SUCCESS;
+
+ int n_stuffed;
+
+ n_stuffed = (8 - (stream->bitcnt & 0x7)) & 7;
+
+ if (stream->incnt < (nbits + n_stuffed))
+ {
+ /* frame-based decoding */
+ status = BitstreamFillCache(stream);
+ }
+
+ *code = (stream->curr_word << n_stuffed) >> (32 - nbits);
+ return status;
+}
+#endif
+
+PV_STATUS PV_BitstreamByteAlign(BitstreamDecVideo *stream)
+{
+ PV_STATUS status = PV_SUCCESS;
+ int n_stuffed;
+
+ n_stuffed = 8 - (stream->bitcnt & 0x7); /* 07/05/01 */
+
+ /* We have to make sure we have enough bits in the cache. 08/15/2000 */
+ if (stream->incnt < n_stuffed)
+ {
+ /* frame-based decoding */
+ status = BitstreamFillCache(stream);
+ }
+
+
+ stream->bitcnt += n_stuffed;
+ stream->incnt -= n_stuffed;
+ stream->curr_word <<= n_stuffed;
+ if (stream->incnt < 0)
+ {
+ stream->bitcnt += stream->incnt;
+ stream->incnt = 0;
+ }
+ return status;
+}
+
+
+PV_STATUS BitstreamByteAlignNoForceStuffing(BitstreamDecVideo *stream)
+{
+ uint n_stuffed;
+
+ n_stuffed = (8 - (stream->bitcnt & 0x7)) & 0x7; /* 07/05/01 */
+
+ stream->bitcnt += n_stuffed;
+ stream->incnt -= n_stuffed;
+
+ if (stream->incnt < 0)
+ {
+ stream->bitcnt += stream->incnt;
+ stream->incnt = 0;
+ }
+ stream->curr_word <<= n_stuffed;
+ return PV_SUCCESS;
+}
+
+
+/* ==================================================================== */
+/* Function : getPointer() */
+/* Date : 10/98 */
+/* Purpose : get current position of file pointer */
+/* In/out : */
+/* Return : */
+/* ==================================================================== */
+int32 getPointer(BitstreamDecVideo *stream)
+{
+ return stream->bitcnt;
+}
+
+
+
+
+/* ====================================================================== /
+Function : movePointerTo()
+Date : 05/14/2004
+Purpose : move bitstream pointer to a desired position
+In/out :
+Return :
+Modified :
+/ ====================================================================== */
+PV_STATUS movePointerTo(BitstreamDecVideo *stream, int32 pos)
+{
+ int32 byte_pos;
+ if (pos < 0)
+ {
+ pos = 0;
+ }
+
+ byte_pos = pos >> 3;
+
+ if (byte_pos > stream->data_end_pos)
+ {
+ byte_pos = stream->data_end_pos;
+ }
+
+ stream->read_point = byte_pos & -4;
+ stream->bitcnt = stream->read_point << 3;;
+ stream->curr_word = 0;
+ stream->next_word = 0;
+ stream->incnt = 0;
+ stream->incnt_next = 0;
+ BitstreamFillCache(stream);
+ PV_BitstreamFlushBits(stream, ((pos & 0x7) + ((byte_pos & 0x3) << 3)));
+ return PV_SUCCESS;
+}
+
+
+/* ======================================================================== */
+/* Function : validStuffing() */
+/* Date : 04/11/2000 */
+/* Purpose : Check whether we have valid stuffing at current position. */
+/* In/out : */
+/* Return : PV_TRUE if successed, PV_FALSE if failed. */
+/* Modified : 12/18/2000 : changed the pattern type to uint */
+/* 04/01/2001 : removed PV_END_OF_BUFFER */
+/* ======================================================================== */
+Bool validStuffing(BitstreamDecVideo *stream)
+{
+ uint n_stuffed;
+ uint pattern;
+
+
+ n_stuffed = 8 - (stream->bitcnt & 0x7);
+ BitstreamShowBits16(stream, n_stuffed, &pattern);
+ if (pattern == msk[n_stuffed-1]) return PV_TRUE;
+ return PV_FALSE;
+}
+#ifdef PV_ANNEX_IJKT_SUPPORT
+Bool validStuffing_h263(BitstreamDecVideo *stream)
+{
+ uint n_stuffed;
+ uint pattern;
+
+
+ n_stuffed = (8 - (stream->bitcnt & 0x7)) & 7; // stream->incnt % 8
+ if (n_stuffed == 0)
+ {
+ return PV_TRUE;
+ }
+ BitstreamShowBits16(stream, n_stuffed, &pattern);
+ if (pattern == 0) return PV_TRUE;
+ return PV_FALSE;
+}
+#endif
+
+
+/* ======================================================================== */
+/* Function : PVSearchNextH263Frame() */
+/* Date : 04/08/2005 */
+/* Purpose : search for 0x00 0x00 0x80 */
+/* In/out : */
+/* Return : PV_SUCCESS if succeeded or PV_END_OF_VOP if failed */
+/* Modified : */
+/* ======================================================================== */
+PV_STATUS PVSearchNextH263Frame(BitstreamDecVideo *stream)
+{
+ PV_STATUS status = PV_SUCCESS;
+ uint8 *ptr;
+ int32 i;
+ int32 initial_byte_aligned_position = (stream->bitcnt + 7) >> 3;
+
+ ptr = stream->bitstreamBuffer + initial_byte_aligned_position;
+
+ i = PVLocateH263FrameHeader(ptr, stream->data_end_pos - initial_byte_aligned_position);
+ if (stream->data_end_pos <= initial_byte_aligned_position + i)
+ {
+ status = PV_END_OF_VOP;
+ }
+ (void)movePointerTo(stream, ((i + initial_byte_aligned_position) << 3)); /* ptr + i */
+ return status;
+}
+
+
+/* ======================================================================== */
+/* Function : PVSearchNextM4VFrame() */
+/* Date : 04/08/2005 */
+/* Purpose : search for 0x00 0x00 0x01 and move the pointer to the */
+/* beginning of the start code */
+/* In/out : */
+/* Return : PV_SUCCESS if succeeded or PV_END_OF_VOP if failed */
+/* Modified : */
+/* ======================================================================== */
+
+PV_STATUS PVSearchNextM4VFrame(BitstreamDecVideo *stream)
+{
+ PV_STATUS status = PV_SUCCESS;
+ uint8 *ptr;
+ int32 i;
+ int32 initial_byte_aligned_position = (stream->bitcnt + 7) >> 3;
+
+ ptr = stream->bitstreamBuffer + initial_byte_aligned_position;
+
+ i = PVLocateFrameHeader(ptr, stream->data_end_pos - initial_byte_aligned_position);
+ if (stream->data_end_pos <= initial_byte_aligned_position + i)
+ {
+ status = PV_END_OF_VOP;
+ }
+ (void)movePointerTo(stream, ((i + initial_byte_aligned_position) << 3)); /* ptr + i */
+ return status;
+}
+
+
+
+void PVLocateM4VFrameBoundary(BitstreamDecVideo *stream)
+{
+ uint8 *ptr;
+ int32 byte_pos = (stream->bitcnt >> 3);
+
+ stream->searched_frame_boundary = 1;
+ ptr = stream->bitstreamBuffer + byte_pos;
+
+ stream->data_end_pos = PVLocateFrameHeader(ptr, (int32)stream->data_end_pos - byte_pos) + byte_pos;
+}
+
+void PVLocateH263FrameBoundary(BitstreamDecVideo *stream)
+{
+ uint8 *ptr;
+ int32 byte_pos = (stream->bitcnt >> 3);
+
+ stream->searched_frame_boundary = 1;
+ ptr = stream->bitstreamBuffer + byte_pos;
+
+ stream->data_end_pos = PVLocateH263FrameHeader(ptr, (int32)stream->data_end_pos - byte_pos) + byte_pos;
+}
+
+/* ======================================================================== */
+/* Function : quickSearchVideoPacketHeader() */
+/* Date : 05/08/2000 */
+/* Purpose : Quick search for the next video packet header */
+/* In/out : */
+/* Return : PV_TRUE if successed, PV_FALSE if failed. */
+/* Modified : */
+/* ======================================================================== */
+PV_STATUS quickSearchVideoPacketHeader(BitstreamDecVideo *stream, int marker_length)
+{
+ PV_STATUS status = PV_SUCCESS;
+ uint32 tmpvar;
+
+
+ if (stream->searched_frame_boundary == 0)
+ {
+ PVLocateM4VFrameBoundary(stream);
+ }
+
+ do
+ {
+ status = BitstreamCheckEndBuffer(stream);
+ if (status == PV_END_OF_VOP) break;
+ PV_BitstreamShowBitsByteAlign(stream, marker_length, &tmpvar);
+ if (tmpvar == RESYNC_MARKER) break;
+ PV_BitstreamFlushBits(stream, 8);
+ }
+ while (status == PV_SUCCESS);
+
+ return status;
+}
+#ifdef PV_ANNEX_IJKT_SUPPORT
+PV_STATUS quickSearchH263SliceHeader(BitstreamDecVideo *stream)
+{
+ PV_STATUS status = PV_SUCCESS;
+ uint32 tmpvar;
+
+
+ if (stream->searched_frame_boundary == 0)
+ {
+ PVLocateH263FrameBoundary(stream);
+ }
+
+ do
+ {
+ status = BitstreamCheckEndBuffer(stream);
+ if (status == PV_END_OF_VOP) break;
+ PV_BitstreamShowBitsByteAlignNoForceStuffing(stream, 17, &tmpvar);
+ if (tmpvar == RESYNC_MARKER) break;
+ PV_BitstreamFlushBits(stream, 8);
+ }
+ while (status == PV_SUCCESS);
+
+ return status;
+}
+#endif
+/* ======================================================================== */
+/* The following functions are for Error Concealment. */
+/* ======================================================================== */
+
+/****************************************************/
+// 01/22/99 Quick search of Resync Marker
+// (actually the first part of it, i.e. 16 0's and a 1.
+
+/* We are not using the fastest algorithm possible. What this function does is
+to locate 11 consecutive 0's and then check if the 5 bits before them and
+the 1 bit after them are all 1's.
+*/
+
+// Table used for quick search of markers. Gives the last `1' in
+// 4 bits. The MSB is bit #1, the LSB is bit #4.
+const int lastOne[] =
+{
+ 0, 4, 3, 4, 2, 4, 3, 4,
+ 1, 4, 3, 4, 2, 4, 3, 4
+};
+
+// Table used for quick search of markers. Gives the last `0' in
+// 4 bits. The MSB is bit #1, the LSB is bit #4.
+/*const int lastZero[]=
+{
+ 4, 3, 4, 2, 4, 3, 4, 1,
+ 4, 3, 4, 2, 4, 3, 4, 0
+};
+*/
+// Table used for quick search of markers. Gives the first `0' in
+// 4 bits. The MSB is bit #1, the LSB is bit #4.
+const int firstZero[] =
+{
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 3, 3, 4, 0
+};
+
+// Table used for quick search of markers. Gives the first `1' in
+// 4 bits. The MSB is bit #1, the LSB is bit #4.
+const int firstOne[] =
+{
+ 0, 4, 3, 3, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1
+};
+
+
+/* ======================================================================== */
+/* Function : quickSearchMarkers() */
+/* Date : 01/25/99 */
+/* Purpose : Quick search for Motion marker */
+/* In/out : */
+/* Return : Boolean true of false */
+/* Modified : 12/18/2000 : 32-bit version */
+/* ======================================================================== */
+PV_STATUS quickSearchMotionMarker(BitstreamDecVideo *stream)
+// MM: (11111000000000001)
+{
+ PV_STATUS status;
+ uint32 tmpvar, tmpvar2;
+
+ if (stream->searched_frame_boundary == 0)
+ {
+ PVLocateM4VFrameBoundary(stream);
+ }
+
+ while (TRUE)
+ {
+ status = BitstreamCheckEndBuffer(stream);
+ if (status == PV_END_OF_VOP) return PV_END_OF_VOP;
+
+ BitstreamShowBits32(stream, 17, &tmpvar);
+ if (!tmpvar) return PV_FAIL;
+
+ if (tmpvar & 1) // Check if the 17th bit from the curr bit pos is a '1'
+ {
+ if (tmpvar == MOTION_MARKER_COMB)
+ {
+ return PV_SUCCESS; // Found
+ }
+ else
+ {
+ tmpvar >>= 1;
+ tmpvar &= 0xF;
+ PV_BitstreamFlushBits(stream, (int)(12 + firstZero[tmpvar]));
+ }
+ }
+ else
+ {
+ // 01/25/99 Get the first 16 bits
+ tmpvar >>= 1;
+ tmpvar2 = tmpvar & 0xF;
+
+ // 01/26/99 Check bits #13 ~ #16
+ if (tmpvar2)
+ {
+ PV_BitstreamFlushBits(stream, (int)(7 + lastOne[tmpvar2]));
+ }
+ else
+ {
+ tmpvar >>= 4;
+ tmpvar2 = tmpvar & 0xF;
+
+ // 01/26/99 Check bits #9 ~ #12
+ if (tmpvar2)
+ {
+ PV_BitstreamFlushBits(stream, (int)(3 + lastOne[tmpvar2]));
+ }
+ else
+ {
+ tmpvar >>= 4;
+ tmpvar2 = tmpvar & 0xF;
+
+ // 01/26/99 Check bits #5 ~ #8
+ // We don't need to check further
+ // for the first 5 bits should be all 1's
+ if (lastOne[tmpvar2] < 2)
+ {
+ /* we already have too many consecutive 0's. */
+ /* Go directly pass the last of the 17 bits. */
+ PV_BitstreamFlushBits(stream, 17);
+ }
+ else
+ {
+ PV_BitstreamFlushBits(stream, (int)(lastOne[tmpvar2] - 1));
+ }
+ }
+ }
+ }
+
+ }
+}
+
+/* ======================================================================== */
+/* Function : quickSearchDCM() */
+/* Date : 01/22/99 */
+/* Purpose : Quick search for DC Marker */
+/* We are not using the fastest algorithm possible. What this */
+/* function does is to locate 11 consecutive 0's and then */
+/* check if the 7 bits before them and the 1 bit after them */
+/* are correct. (actually the first part of it, i.e. 16 0's */
+/* and a 1. */
+/* In/out : */
+/* Return : Boolean true of false */
+/* Modified : 12/18/2000 : 32-bit version */
+/* ======================================================================== */
+PV_STATUS quickSearchDCM(BitstreamDecVideo *stream)
+// DCM: (110 1011 0000 0000 0001)
+{
+ PV_STATUS status;
+ uint32 tmpvar, tmpvar2;
+
+ if (stream->searched_frame_boundary == 0)
+ {
+ PVLocateM4VFrameBoundary(stream);
+ }
+
+ while (TRUE)
+ {
+ status = BitstreamCheckEndBuffer(stream);
+ if (status == PV_END_OF_VOP) return PV_END_OF_VOP;
+ BitstreamShowBits32(stream, 19, &tmpvar);
+
+ if (tmpvar & 1) // Check if the 17th bit from the curr bit pos is a '1'
+ {
+ if (tmpvar == DC_MARKER)
+ {
+ return PV_SUCCESS; // Found
+ }
+ else
+ {
+ // 01/25/99 We treat the last of the 19 bits as its 7th bit (which is
+ // also a `1'
+ PV_BitstreamFlushBits(stream, 12);
+ }
+ }
+ else
+ {
+ tmpvar >>= 1;
+ tmpvar2 = tmpvar & 0xF;
+
+ if (tmpvar2)
+ {
+ PV_BitstreamFlushBits(stream, (int)(7 + lastOne[tmpvar2]));
+ }
+ else
+ {
+ tmpvar >>= 4;
+ tmpvar2 = tmpvar & 0xF;
+ if (tmpvar2)
+ {
+ PV_BitstreamFlushBits(stream, (int)(3 + lastOne[tmpvar2]));
+ }
+ else
+ {
+ tmpvar >>= 4;
+ tmpvar2 = tmpvar & 0xF;
+ if (lastOne[tmpvar2] < 2)
+ {
+ /* we already have too many consecutive 0's. */
+ /* Go directly pass the last of the 17 bits. */
+ PV_BitstreamFlushBits(stream, 19);
+ }
+ else
+ {
+ PV_BitstreamFlushBits(stream, (int)(lastOne[tmpvar2] - 1));
+ }
+ }
+ }
+ }
+ }
+}
+
+/* ======================================================================== */
+/* Function : quickSearchGOBHeader() 0000 0000 0000 0000 1 */
+/* Date : 07/06/01 */
+/* Purpose : Quick search of GOBHeader (not byte aligned) */
+/* In/out : */
+/* Return : Integer value indicates type of marker found */
+/* Modified : */
+/* ======================================================================== */
+PV_STATUS quickSearchGOBHeader(BitstreamDecVideo *stream)
+{
+ PV_STATUS status;
+ int byte0, byte1, byte2, shift, tmpvar;
+
+ BitstreamByteAlignNoForceStuffing(stream);
+
+ if (stream->searched_frame_boundary == 0)
+ {
+ PVLocateH263FrameBoundary(stream);
+ }
+
+ while (TRUE)
+ {
+ status = BitstreamCheckEndBuffer(stream);
+ if (status == PV_END_OF_VOP) return PV_END_OF_VOP;
+
+ if (stream->incnt < 24)
+ {
+ status = BitstreamFillCache(stream);
+ }
+
+
+ byte1 = (stream->curr_word << 8) >> 24;
+ if (byte1 == 0)
+ {
+ byte2 = (stream->curr_word << 16) >> 24;
+ if (byte2)
+ {
+ tmpvar = byte2 >> 4;
+
+ if (tmpvar)
+ {
+ shift = 9 - firstOne[tmpvar];
+ }
+ else
+ {
+ shift = 5 - firstOne[byte2];
+ }
+ byte0 = stream->curr_word >> 24;
+ if ((byte0 & msk[shift]) == 0)
+ {
+ PV_BitstreamFlushBits(stream, 8 - shift);
+ return PV_SUCCESS;
+ }
+ PV_BitstreamFlushBits(stream, 8); /* third_byte is not zero */
+ }
+ }
+
+ PV_BitstreamFlushBits(stream, 8);
+ }
+}
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/bitstream.h b/media/libstagefright/codecs/m4v_h263/dec/src/bitstream.h
new file mode 100644
index 0000000..d52fa87
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/bitstream.h
@@ -0,0 +1,174 @@
+/* ------------------------------------------------------------------
+ * 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 _BITSTREAM_D_H_
+#define _BITSTREAM_D_H_
+
+#include "mp4dec_lib.h" /* video decoder function prototypes */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#define PV_BS_INLINE /* support inline bitstream functions */
+
+#define PV_BitstreamFlushBits(A,B) {(A)->bitcnt += (B); (A)->incnt -= (B); (A)->curr_word <<= (B);}
+
+ PV_STATUS BitstreamFillBuffer(BitstreamDecVideo *stream);
+ PV_STATUS BitstreamFillCache(BitstreamDecVideo *stream);
+ void BitstreamReset(BitstreamDecVideo *stream, uint8 *buffer, int32 buffer_size);
+ int BitstreamOpen(BitstreamDecVideo *stream, int layer);
+ void BitstreamClose(BitstreamDecVideo *stream);
+
+ PV_STATUS BitstreamShowBits32(BitstreamDecVideo *stream, int nbits, uint32 *code);
+ uint32 BitstreamReadBits32(BitstreamDecVideo *stream, int nbits);
+
+ uint BitstreamReadBits16(BitstreamDecVideo *stream, int nbits);
+ uint BitstreamRead1Bits(BitstreamDecVideo *stream);
+#ifndef PV_BS_INLINE
+ PV_STATUS BitstreamShowBits16(BitstreamDecVideo *stream, int nbits, uint *code);
+ PV_STATUS BitstreamShow15Bits(BitstreamDecVideo *stream, uint *code);
+ PV_STATUS BitstreamShow13Bits(BitstreamDecVideo *stream, uint *code);
+ uint BitstreamReadBits16_INLINE(BitstreamDecVideo *stream, int nbits);
+ uint BitstreamRead1Bits_INLINE(BitstreamDecVideo *stream);
+#else
+ __inline PV_STATUS BitstreamShowBits16(BitstreamDecVideo *stream, int nbits, uint *code)
+ {
+ PV_STATUS status = PV_SUCCESS;
+
+
+ if (stream->incnt < nbits)
+ {
+ /* frame-based decoding */
+ status = BitstreamFillCache(stream);
+ }
+
+ *code = stream->curr_word >> (32 - nbits);
+ return status;
+ }
+
+
+
+ /* =========================================================================*/
+ __inline PV_STATUS BitstreamShow15Bits(BitstreamDecVideo *stream, uint *code)
+ {
+ PV_STATUS status = PV_SUCCESS;
+
+ if (stream->incnt < 15)
+ {
+ /* frame-based decoding */
+ status = BitstreamFillCache(stream);
+ }
+ *code = stream->curr_word >> 17;
+ return status;
+ }
+
+
+ __inline PV_STATUS BitstreamShow13Bits(BitstreamDecVideo *stream, uint *code)
+ {
+ PV_STATUS status = PV_SUCCESS;
+
+ if (stream->incnt < 13)
+ {
+ /* frame-based decoding */
+ status = BitstreamFillCache(stream);
+ }
+ *code = stream->curr_word >> 19;
+ return status;
+ }
+ __inline uint BitstreamReadBits16_INLINE(BitstreamDecVideo *stream, int nbits)
+ {
+ uint code;
+
+ if (stream->incnt < nbits)
+ {
+ /* frame-based decoding */
+ BitstreamFillCache(stream);
+ }
+ code = stream->curr_word >> (32 - nbits);
+ PV_BitstreamFlushBits(stream, nbits);
+ return code;
+ }
+
+
+ __inline uint BitstreamRead1Bits_INLINE(BitstreamDecVideo *stream)
+ {
+ uint code;
+
+ if (stream->incnt < 1)
+ {
+ /* frame-based decoding */
+ BitstreamFillCache(stream);
+ }
+ code = stream->curr_word >> 31;
+ PV_BitstreamFlushBits(stream, 1);
+
+ return code;
+ }
+
+#endif
+
+
+
+
+
+
+
+ PV_STATUS PV_BitstreamFlushBitsCheck(BitstreamDecVideo *stream, int nbits);
+
+ uint32 BitstreamReadBits32HC(BitstreamDecVideo *stream);
+ PV_STATUS BitstreamShowBits32HC(BitstreamDecVideo *stream, uint32 *code);
+
+
+
+ PV_STATUS BitstreamCheckEndBuffer(BitstreamDecVideo *stream);
+
+ PV_STATUS PV_BitstreamShowBitsByteAlign(BitstreamDecVideo *stream, int nbits, uint32 *code);
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ PV_STATUS PV_BitstreamShowBitsByteAlignNoForceStuffing(BitstreamDecVideo *stream, int nbits, uint32 *code);
+ Bool validStuffing_h263(BitstreamDecVideo *stream);
+ PV_STATUS quickSearchH263SliceHeader(BitstreamDecVideo *stream);
+#endif
+ PV_STATUS PV_BitstreamByteAlign(BitstreamDecVideo *stream);
+ PV_STATUS BitstreamByteAlignNoForceStuffing(BitstreamDecVideo *stream);
+ Bool validStuffing(BitstreamDecVideo *stream);
+
+ PV_STATUS movePointerTo(BitstreamDecVideo *stream, int32 pos);
+ PV_STATUS PVSearchNextM4VFrame(BitstreamDecVideo *stream);
+ PV_STATUS PVSearchNextH263Frame(BitstreamDecVideo *stream);
+ PV_STATUS quickSearchVideoPacketHeader(BitstreamDecVideo *stream, int marker_length);
+
+
+ /* for error concealment & soft-decoding */
+ void PVLocateM4VFrameBoundary(BitstreamDecVideo *stream);
+ void PVSearchH263FrameBoundary(BitstreamDecVideo *stream);
+
+ PV_STATUS quickSearchMotionMarker(BitstreamDecVideo *stream);
+ PV_STATUS quickSearchDCM(BitstreamDecVideo *stream);
+ PV_STATUS quickSearchGOBHeader(BitstreamDecVideo *stream);
+ void BitstreamShowBuffer(BitstreamDecVideo *stream, int32 startbit, int32 endbit, uint8 *bitBfr);
+
+ /* 10/8/98 New prototyps. */
+ int32 getPointer(BitstreamDecVideo *stream);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _BITSTREAM_D_H_ */
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/block_idct.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/block_idct.cpp
new file mode 100644
index 0000000..a75483a
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/block_idct.cpp
@@ -0,0 +1,911 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+/*
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ [input_variable_name] = [description of the input to module, its type
+ definition, and length (when applicable)]
+
+ Local Stores/Buffers/Pointers Needed:
+ [local_store_name] = [description of the local store, its type
+ definition, and length (when applicable)]
+ [local_buffer_name] = [description of the local buffer, its type
+ definition, and length (when applicable)]
+ [local_ptr_name] = [description of the local pointer, its type
+ definition, and length (when applicable)]
+
+ Global Stores/Buffers/Pointers Needed:
+ [global_store_name] = [description of the global store, its type
+ definition, and length (when applicable)]
+ [global_buffer_name] = [description of the global buffer, its type
+ definition, and length (when applicable)]
+ [global_ptr_name] = [description of the global pointer, its type
+ definition, and length (when applicable)]
+
+ Outputs:
+ [return_variable_name] = [description of data/pointer returned
+ by module, its type definition, and length
+ (when applicable)]
+
+ Pointers and Buffers Modified:
+ [variable_bfr_ptr] points to the [describe where the
+ variable_bfr_ptr points to, its type definition, and length
+ (when applicable)]
+ [variable_bfr] contents are [describe the new contents of
+ variable_bfr]
+
+ Local Stores Modified:
+ [local_store_name] = [describe new contents, its type
+ definition, and length (when applicable)]
+
+ Global Stores Modified:
+ [global_store_name] = [describe new contents, its type
+ definition, and length (when applicable)]
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+------------------------------------------------------------------------------
+ RESOURCES USED
+ When the code is written for a specific target processor the
+ the resources used should be documented below.
+
+ STACK USAGE: [stack count for this module] + [variable to represent
+ stack usage for each subroutine called]
+
+ where: [stack usage variable] = stack usage for [subroutine
+ name] (see [filename].ext)
+
+ DATA MEMORY USED: x words
+
+ PROGRAM MEMORY USED: x words
+
+ CLOCK CYCLES: [cycle count equation for this module] + [variable
+ used to represent cycle count for each subroutine
+ called]
+
+ where: [cycle count variable] = cycle count for [subroutine
+ name] (see [filename].ext)
+
+------------------------------------------------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "mp4dec_lib.h"
+#include "idct.h"
+#include "motion_comp.h"
+
+#define OSCL_DISABLE_WARNING_CONV_POSSIBLE_LOSS_OF_DATA
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here. Include conditional
+; compile variables also.
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL FUNCTION DEFINITIONS
+; Function Prototype declaration
+----------------------------------------------------------------------------*/
+/* private prototypes */
+static void idctrow(int16 *blk, uint8 *pred, uint8 *dst, int width);
+static void idctrow_intra(int16 *blk, PIXEL *, int width);
+static void idctcol(int16 *blk);
+
+#ifdef FAST_IDCT
+// mapping from nz_coefs to functions to be used
+
+
+// ARM4 does not allow global data when they are not constant hence
+// an array of function pointers cannot be considered as array of constants
+// (actual addresses are only known when the dll is loaded).
+// So instead of arrays of function pointers, we'll store here
+// arrays of rows or columns and then call the idct function
+// corresponding to such the row/column number:
+
+
+static void (*const idctcolVCA[10][4])(int16*) =
+{
+ {&idctcol1, &idctcol0, &idctcol0, &idctcol0},
+ {&idctcol1, &idctcol1, &idctcol0, &idctcol0},
+ {&idctcol2, &idctcol1, &idctcol0, &idctcol0},
+ {&idctcol3, &idctcol1, &idctcol0, &idctcol0},
+ {&idctcol3, &idctcol2, &idctcol0, &idctcol0},
+ {&idctcol3, &idctcol2, &idctcol1, &idctcol0},
+ {&idctcol3, &idctcol2, &idctcol1, &idctcol1},
+ {&idctcol3, &idctcol2, &idctcol2, &idctcol1},
+ {&idctcol3, &idctcol3, &idctcol2, &idctcol1},
+ {&idctcol4, &idctcol3, &idctcol2, &idctcol1}
+};
+
+
+static void (*const idctrowVCA[10])(int16*, uint8*, uint8*, int) =
+{
+ &idctrow1,
+ &idctrow2,
+ &idctrow2,
+ &idctrow2,
+ &idctrow2,
+ &idctrow3,
+ &idctrow4,
+ &idctrow4,
+ &idctrow4,
+ &idctrow4
+};
+
+
+static void (*const idctcolVCA2[16])(int16*) =
+{
+ &idctcol0, &idctcol4, &idctcol3, &idctcol4,
+ &idctcol2, &idctcol4, &idctcol3, &idctcol4,
+ &idctcol1, &idctcol4, &idctcol3, &idctcol4,
+ &idctcol2, &idctcol4, &idctcol3, &idctcol4
+};
+
+static void (*const idctrowVCA2[8])(int16*, uint8*, uint8*, int) =
+{
+ &idctrow1, &idctrow4, &idctrow3, &idctrow4,
+ &idctrow2, &idctrow4, &idctrow3, &idctrow4
+};
+
+static void (*const idctrowVCA_intra[10])(int16*, PIXEL *, int) =
+{
+ &idctrow1_intra,
+ &idctrow2_intra,
+ &idctrow2_intra,
+ &idctrow2_intra,
+ &idctrow2_intra,
+ &idctrow3_intra,
+ &idctrow4_intra,
+ &idctrow4_intra,
+ &idctrow4_intra,
+ &idctrow4_intra
+};
+
+static void (*const idctrowVCA2_intra[8])(int16*, PIXEL *, int) =
+{
+ &idctrow1_intra, &idctrow4_intra, &idctrow3_intra, &idctrow4_intra,
+ &idctrow2_intra, &idctrow4_intra, &idctrow3_intra, &idctrow4_intra
+};
+#endif
+
+/*----------------------------------------------------------------------------
+; LOCAL STORE/BUFFER/POINTER DEFINITIONS
+; Variable declaration - defined here and used outside this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL FUNCTION REFERENCES
+; Declare functions defined elsewhere and referenced in this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; FUNCTION CODE
+----------------------------------------------------------------------------*/
+void MBlockIDCT(VideoDecData *video)
+{
+ Vop *currVop = video->currVop;
+ MacroBlock *mblock = video->mblock;
+ PIXEL *c_comp;
+ PIXEL *cu_comp;
+ PIXEL *cv_comp;
+ int x_pos = video->mbnum_col;
+ int y_pos = video->mbnum_row;
+ int width, width_uv;
+ int32 offset;
+ width = video->width;
+ width_uv = width >> 1;
+ offset = (int32)(y_pos << 4) * width + (x_pos << 4);
+
+ c_comp = currVop->yChan + offset;
+ cu_comp = currVop->uChan + (offset >> 2) + (x_pos << 2);
+ cv_comp = currVop->vChan + (offset >> 2) + (x_pos << 2);
+
+ BlockIDCT_intra(mblock, c_comp, 0, width);
+ BlockIDCT_intra(mblock, c_comp + 8, 1, width);
+ BlockIDCT_intra(mblock, c_comp + (width << 3), 2, width);
+ BlockIDCT_intra(mblock, c_comp + (width << 3) + 8, 3, width);
+ BlockIDCT_intra(mblock, cu_comp, 4, width_uv);
+ BlockIDCT_intra(mblock, cv_comp, 5, width_uv);
+}
+
+
+void BlockIDCT_intra(
+ MacroBlock *mblock, PIXEL *c_comp, int comp, int width)
+{
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int16 *coeff_in = mblock->block[comp];
+#ifdef INTEGER_IDCT
+#ifdef FAST_IDCT /* VCA IDCT using nzcoefs and bitmaps*/
+ int i, bmapr;
+ int nz_coefs = mblock->no_coeff[comp];
+ uint8 *bitmapcol = mblock->bitmapcol[comp];
+ uint8 bitmaprow = mblock->bitmaprow[comp];
+
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ if (nz_coefs <= 10)
+ {
+ bmapr = (nz_coefs - 1);
+
+ (*(idctcolVCA[bmapr]))(coeff_in);
+ (*(idctcolVCA[bmapr][1]))(coeff_in + 1);
+ (*(idctcolVCA[bmapr][2]))(coeff_in + 2);
+ (*(idctcolVCA[bmapr][3]))(coeff_in + 3);
+
+ (*idctrowVCA_intra[nz_coefs-1])(coeff_in, c_comp, width);
+ }
+ else
+ {
+ i = 8;
+ while (i--)
+ {
+ bmapr = (int)bitmapcol[i];
+ if (bmapr)
+ {
+ if ((bmapr&0xf) == 0) /* 07/18/01 */
+ {
+ (*(idctcolVCA2[bmapr>>4]))(coeff_in + i);
+ }
+ else
+ {
+ idctcol(coeff_in + i);
+ }
+ }
+ }
+ if ((bitmapcol[4] | bitmapcol[5] | bitmapcol[6] | bitmapcol[7]) == 0)
+ {
+ bitmaprow >>= 4;
+ (*(idctrowVCA2_intra[(int)bitmaprow]))(coeff_in, c_comp, width);
+ }
+ else
+ {
+ idctrow_intra(coeff_in, c_comp, width);
+ }
+ }
+#else
+ void idct_intra(int *block, uint8 *comp, int width);
+ idct_intra(coeff_in, c_comp, width);
+#endif
+#else
+ void idctref_intra(int *block, uint8 *comp, int width);
+ idctref_intra(coeff_in, c_comp, width);
+#endif
+
+
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return;
+}
+
+/* 08/04/05, no residue, just copy from pred to output */
+void Copy_Blk_to_Vop(uint8 *dst, uint8 *pred, int width)
+{
+ /* copy 4 bytes at a time */
+ width -= 4;
+ *((uint32*)dst) = *((uint32*)pred);
+ *((uint32*)(dst += 4)) = *((uint32*)(pred += 4));
+ *((uint32*)(dst += width)) = *((uint32*)(pred += 12));
+ *((uint32*)(dst += 4)) = *((uint32*)(pred += 4));
+ *((uint32*)(dst += width)) = *((uint32*)(pred += 12));
+ *((uint32*)(dst += 4)) = *((uint32*)(pred += 4));
+ *((uint32*)(dst += width)) = *((uint32*)(pred += 12));
+ *((uint32*)(dst += 4)) = *((uint32*)(pred += 4));
+ *((uint32*)(dst += width)) = *((uint32*)(pred += 12));
+ *((uint32*)(dst += 4)) = *((uint32*)(pred += 4));
+ *((uint32*)(dst += width)) = *((uint32*)(pred += 12));
+ *((uint32*)(dst += 4)) = *((uint32*)(pred += 4));
+ *((uint32*)(dst += width)) = *((uint32*)(pred += 12));
+ *((uint32*)(dst += 4)) = *((uint32*)(pred += 4));
+ *((uint32*)(dst += width)) = *((uint32*)(pred += 12));
+ *((uint32*)(dst += 4)) = *((uint32*)(pred += 4));
+
+ return ;
+}
+
+/* 08/04/05 compute IDCT and add prediction at the end */
+void BlockIDCT(
+ uint8 *dst, /* destination */
+ uint8 *pred, /* prediction block, pitch 16 */
+ int16 *coeff_in, /* DCT data, size 64 */
+ int width, /* width of dst */
+ int nz_coefs,
+ uint8 *bitmapcol,
+ uint8 bitmaprow
+)
+{
+#ifdef INTEGER_IDCT
+#ifdef FAST_IDCT /* VCA IDCT using nzcoefs and bitmaps*/
+ int i, bmapr;
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ if (nz_coefs <= 10)
+ {
+ bmapr = (nz_coefs - 1);
+ (*(idctcolVCA[bmapr]))(coeff_in);
+ (*(idctcolVCA[bmapr][1]))(coeff_in + 1);
+ (*(idctcolVCA[bmapr][2]))(coeff_in + 2);
+ (*(idctcolVCA[bmapr][3]))(coeff_in + 3);
+
+ (*idctrowVCA[nz_coefs-1])(coeff_in, pred, dst, width);
+ return ;
+ }
+ else
+ {
+ i = 8;
+
+ while (i--)
+ {
+ bmapr = (int)bitmapcol[i];
+ if (bmapr)
+ {
+ if ((bmapr&0xf) == 0) /* 07/18/01 */
+ {
+ (*(idctcolVCA2[bmapr>>4]))(coeff_in + i);
+ }
+ else
+ {
+ idctcol(coeff_in + i);
+ }
+ }
+ }
+ if ((bitmapcol[4] | bitmapcol[5] | bitmapcol[6] | bitmapcol[7]) == 0)
+ {
+ (*(idctrowVCA2[bitmaprow>>4]))(coeff_in, pred, dst, width);
+ }
+ else
+ {
+ idctrow(coeff_in, pred, dst, width);
+ }
+ return ;
+ }
+#else // FAST_IDCT
+ void idct(int *block, uint8 *pred, uint8 *dst, int width);
+ idct(coeff_in, pred, dst, width);
+ return;
+#endif // FAST_IDCT
+#else // INTEGER_IDCT
+ void idctref(int *block, uint8 *pred, uint8 *dst, int width);
+ idctref(coeff_in, pred, dst, width);
+ return;
+#endif // INTEGER_IDCT
+
+}
+/*----------------------------------------------------------------------------
+; End Function: block_idct
+----------------------------------------------------------------------------*/
+
+
+/****************************************************************************/
+
+/*
+------------------------------------------------------------------------------
+ FUNCTION NAME: idctrow
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS FOR idctrow
+
+ Inputs:
+ [input_variable_name] = [description of the input to module, its type
+ definition, and length (when applicable)]
+
+ Local Stores/Buffers/Pointers Needed:
+ [local_store_name] = [description of the local store, its type
+ definition, and length (when applicable)]
+ [local_buffer_name] = [description of the local buffer, its type
+ definition, and length (when applicable)]
+ [local_ptr_name] = [description of the local pointer, its type
+ definition, and length (when applicable)]
+
+ Global Stores/Buffers/Pointers Needed:
+ [global_store_name] = [description of the global store, its type
+ definition, and length (when applicable)]
+ [global_buffer_name] = [description of the global buffer, its type
+ definition, and length (when applicable)]
+ [global_ptr_name] = [description of the global pointer, its type
+ definition, and length (when applicable)]
+
+ Outputs:
+ [return_variable_name] = [description of data/pointer returned
+ by module, its type definition, and length
+ (when applicable)]
+
+ Pointers and Buffers Modified:
+ [variable_bfr_ptr] points to the [describe where the
+ variable_bfr_ptr points to, its type definition, and length
+ (when applicable)]
+ [variable_bfr] contents are [describe the new contents of
+ variable_bfr]
+
+ Local Stores Modified:
+ [local_store_name] = [describe new contents, its type
+ definition, and length (when applicable)]
+
+ Global Stores Modified:
+ [global_store_name] = [describe new contents, its type
+ definition, and length (when applicable)]
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION FOR idctrow
+
+------------------------------------------------------------------------------
+ REQUIREMENTS FOR idctrow
+
+------------------------------------------------------------------------------
+ REFERENCES FOR idctrow
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE FOR idctrow
+
+------------------------------------------------------------------------------
+ RESOURCES USED FOR idctrow
+ When the code is written for a specific target processor the
+ the resources used should be documented below.
+
+ STACK USAGE: [stack count for this module] + [variable to represent
+ stack usage for each subroutine called]
+
+ where: [stack usage variable] = stack usage for [subroutine
+ name] (see [filename].ext)
+
+ DATA MEMORY USED: x words
+
+ PROGRAM MEMORY USED: x words
+
+ CLOCK CYCLES: [cycle count equation for this module] + [variable
+ used to represent cycle count for each subroutine
+ called]
+
+ where: [cycle count variable] = cycle count for [subroutine
+ name] (see [filename].ext)
+
+------------------------------------------------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+; Function Code FOR idctrow
+----------------------------------------------------------------------------*/
+void idctrow(
+ int16 *blk, uint8 *pred, uint8 *dst, int width
+)
+{
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
+ int i = 8;
+ uint32 pred_word, dst_word;
+ int res, res2;
+
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ /* row (horizontal) IDCT
+ *
+ * 7 pi 1 dst[k] = sum c[l] * src[l] * cos( -- *
+ * ( k + - ) * l ) l=0 8 2
+ *
+ * where: c[0] = 128 c[1..7] = 128*sqrt(2) */
+
+ /* preset the offset, such that we can take advantage pre-offset addressing mode */
+ width -= 4;
+ dst -= width;
+ pred -= 12;
+ blk -= 8;
+
+ while (i--)
+ {
+ x1 = (int32)blk[12] << 8;
+ blk[12] = 0;
+ x2 = blk[14];
+ blk[14] = 0;
+ x3 = blk[10];
+ blk[10] = 0;
+ x4 = blk[9];
+ blk[9] = 0;
+ x5 = blk[15];
+ blk[15] = 0;
+ x6 = blk[13];
+ blk[13] = 0;
+ x7 = blk[11];
+ blk[11] = 0;
+ x0 = ((*(blk += 8)) << 8) + 8192;
+ blk[0] = 0; /* for proper rounding in the fourth stage */
+
+ /* first stage */
+ x8 = W7 * (x4 + x5) + 4;
+ x4 = (x8 + (W1 - W7) * x4) >> 3;
+ x5 = (x8 - (W1 + W7) * x5) >> 3;
+ x8 = W3 * (x6 + x7) + 4;
+ x6 = (x8 - (W3 - W5) * x6) >> 3;
+ x7 = (x8 - (W3 + W5) * x7) >> 3;
+
+ /* second stage */
+ x8 = x0 + x1;
+ x0 -= x1;
+ x1 = W6 * (x3 + x2) + 4;
+ x2 = (x1 - (W2 + W6) * x2) >> 3;
+ x3 = (x1 + (W2 - W6) * x3) >> 3;
+ x1 = x4 + x6;
+ x4 -= x6;
+ x6 = x5 + x7;
+ x5 -= x7;
+
+ /* third stage */
+ x7 = x8 + x3;
+ x8 -= x3;
+ x3 = x0 + x2;
+ x0 -= x2;
+ x2 = (181 * (x4 + x5) + 128) >> 8;
+ x4 = (181 * (x4 - x5) + 128) >> 8;
+
+ /* fourth stage */
+ pred_word = *((uint32*)(pred += 12)); /* read 4 bytes from pred */
+
+ res = (x7 + x1) >> 14;
+ ADD_AND_CLIP1(res);
+ res2 = (x3 + x2) >> 14;
+ ADD_AND_CLIP2(res2);
+ dst_word = (res2 << 8) | res;
+ res = (x0 + x4) >> 14;
+ ADD_AND_CLIP3(res);
+ dst_word |= (res << 16);
+ res = (x8 + x6) >> 14;
+ ADD_AND_CLIP4(res);
+ dst_word |= (res << 24);
+ *((uint32*)(dst += width)) = dst_word; /* save 4 bytes to dst */
+
+ pred_word = *((uint32*)(pred += 4)); /* read 4 bytes from pred */
+
+ res = (x8 - x6) >> 14;
+ ADD_AND_CLIP1(res);
+ res2 = (x0 - x4) >> 14;
+ ADD_AND_CLIP2(res2);
+ dst_word = (res2 << 8) | res;
+ res = (x3 - x2) >> 14;
+ ADD_AND_CLIP3(res);
+ dst_word |= (res << 16);
+ res = (x7 - x1) >> 14;
+ ADD_AND_CLIP4(res);
+ dst_word |= (res << 24);
+ *((uint32*)(dst += 4)) = dst_word; /* save 4 bytes to dst */
+ }
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return;
+}
+
+void idctrow_intra(
+ int16 *blk, PIXEL *comp, int width
+)
+{
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int32 x0, x1, x2, x3, x4, x5, x6, x7, x8, temp;
+ int i = 8;
+ int offset = width;
+ int32 word;
+
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ /* row (horizontal) IDCT
+ *
+ * 7 pi 1 dst[k] = sum c[l] * src[l] * cos( -- *
+ * ( k + - ) * l ) l=0 8 2
+ *
+ * where: c[0] = 128 c[1..7] = 128*sqrt(2) */
+ while (i--)
+ {
+ x1 = (int32)blk[4] << 8;
+ blk[4] = 0;
+ x2 = blk[6];
+ blk[6] = 0;
+ x3 = blk[2];
+ blk[2] = 0;
+ x4 = blk[1];
+ blk[1] = 0;
+ x5 = blk[7];
+ blk[7] = 0;
+ x6 = blk[5];
+ blk[5] = 0;
+ x7 = blk[3];
+ blk[3] = 0;
+#ifndef FAST_IDCT
+ /* shortcut */ /* covered by idctrow1 01/9/2001 */
+ if (!(x1 | x2 | x3 | x4 | x5 | x6 | x7))
+ {
+ blk[0] = blk[1] = blk[2] = blk[3] = blk[4] = blk[5] = blk[6] = blk[7] = (blk[0] + 32) >> 6;
+ return;
+ }
+#endif
+ x0 = ((int32)blk[0] << 8) + 8192;
+ blk[0] = 0; /* for proper rounding in the fourth stage */
+
+ /* first stage */
+ x8 = W7 * (x4 + x5) + 4;
+ x4 = (x8 + (W1 - W7) * x4) >> 3;
+ x5 = (x8 - (W1 + W7) * x5) >> 3;
+ x8 = W3 * (x6 + x7) + 4;
+ x6 = (x8 - (W3 - W5) * x6) >> 3;
+ x7 = (x8 - (W3 + W5) * x7) >> 3;
+
+ /* second stage */
+ x8 = x0 + x1;
+ x0 -= x1;
+ x1 = W6 * (x3 + x2) + 4;
+ x2 = (x1 - (W2 + W6) * x2) >> 3;
+ x3 = (x1 + (W2 - W6) * x3) >> 3;
+ x1 = x4 + x6;
+ x4 -= x6;
+ x6 = x5 + x7;
+ x5 -= x7;
+
+ /* third stage */
+ x7 = x8 + x3;
+ x8 -= x3;
+ x3 = x0 + x2;
+ x0 -= x2;
+ x2 = (181 * (x4 + x5) + 128) >> 8;
+ x4 = (181 * (x4 - x5) + 128) >> 8;
+
+ /* fourth stage */
+ word = ((x7 + x1) >> 14);
+ CLIP_RESULT(word)
+
+ temp = ((x3 + x2) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 8);
+
+ temp = ((x0 + x4) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 16);
+
+ temp = ((x8 + x6) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 24);
+ *((int32*)(comp)) = word;
+
+ word = ((x8 - x6) >> 14);
+ CLIP_RESULT(word)
+
+ temp = ((x0 - x4) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 8);
+
+ temp = ((x3 - x2) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 16);
+
+ temp = ((x7 - x1) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 24);
+ *((int32*)(comp + 4)) = word;
+ comp += offset;
+
+ blk += B_SIZE;
+ }
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return;
+}
+
+/*----------------------------------------------------------------------------
+; End Function: idctrow
+----------------------------------------------------------------------------*/
+
+
+/****************************************************************************/
+
+/*
+------------------------------------------------------------------------------
+ FUNCTION NAME: idctcol
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS FOR idctcol
+
+ Inputs:
+ [input_variable_name] = [description of the input to module, its type
+ definition, and length (when applicable)]
+
+ Local Stores/Buffers/Pointers Needed:
+ [local_store_name] = [description of the local store, its type
+ definition, and length (when applicable)]
+ [local_buffer_name] = [description of the local buffer, its type
+ definition, and length (when applicable)]
+ [local_ptr_name] = [description of the local pointer, its type
+ definition, and length (when applicable)]
+
+ Global Stores/Buffers/Pointers Needed:
+ [global_store_name] = [description of the global store, its type
+ definition, and length (when applicable)]
+ [global_buffer_name] = [description of the global buffer, its type
+ definition, and length (when applicable)]
+ [global_ptr_name] = [description of the global pointer, its type
+ definition, and length (when applicable)]
+
+ Outputs:
+ [return_variable_name] = [description of data/pointer returned
+ by module, its type definition, and length
+ (when applicable)]
+
+ Pointers and Buffers Modified:
+ [variable_bfr_ptr] points to the [describe where the
+ variable_bfr_ptr points to, its type definition, and length
+ (when applicable)]
+ [variable_bfr] contents are [describe the new contents of
+ variable_bfr]
+
+ Local Stores Modified:
+ [local_store_name] = [describe new contents, its type
+ definition, and length (when applicable)]
+
+ Global Stores Modified:
+ [global_store_name] = [describe new contents, its type
+ definition, and length (when applicable)]
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION FOR idctcol
+
+------------------------------------------------------------------------------
+ REQUIREMENTS FOR idctcol
+
+------------------------------------------------------------------------------
+ REFERENCES FOR idctcol
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE FOR idctcol
+
+------------------------------------------------------------------------------
+ RESOURCES USED FOR idctcol
+ When the code is written for a specific target processor the
+ the resources used should be documented below.
+
+ STACK USAGE: [stack count for this module] + [variable to represent
+ stack usage for each subroutine called]
+
+ where: [stack usage variable] = stack usage for [subroutine
+ name] (see [filename].ext)
+
+ DATA MEMORY USED: x words
+
+ PROGRAM MEMORY USED: x words
+
+ CLOCK CYCLES: [cycle count equation for this module] + [variable
+ used to represent cycle count for each subroutine
+ called]
+
+ where: [cycle count variable] = cycle count for [subroutine
+ name] (see [filename].ext)
+
+------------------------------------------------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+; Function Code FOR idctcol
+----------------------------------------------------------------------------*/
+void idctcol(
+ int16 *blk
+)
+{
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
+
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ /* column (vertical) IDCT
+ *
+ * 7 pi 1 dst[8*k] = sum c[l] * src[8*l] *
+ * cos( -- * ( k + - ) * l ) l=0 8 2
+ *
+ * where: c[0] = 1/1024 c[1..7] = (1/1024)*sqrt(2) */
+ x1 = (int32)blk[32] << 11;
+ x2 = blk[48];
+ x3 = blk[16];
+ x4 = blk[8];
+ x5 = blk[56];
+ x6 = blk[40];
+ x7 = blk[24];
+#ifndef FAST_IDCT
+ /* shortcut */ /* covered by idctcolumn1 01/9/2001 */
+ if (!(x1 | x2 | x3 | x4 | x5 | x6 | x7))
+ {
+ blk[0] = blk[8] = blk[16] = blk[24] = blk[32] = blk[40] = blk[48] = blk[56]
+ = blk[0] << 3;
+ return;
+ }
+#endif
+
+ x0 = ((int32)blk[0] << 11) + 128;
+
+ /* first stage */
+ x8 = W7 * (x4 + x5);
+ x4 = x8 + (W1 - W7) * x4;
+ x5 = x8 - (W1 + W7) * x5;
+ x8 = W3 * (x6 + x7);
+ x6 = x8 - (W3 - W5) * x6;
+ x7 = x8 - (W3 + W5) * x7;
+
+ /* second stage */
+ x8 = x0 + x1;
+ x0 -= x1;
+ x1 = W6 * (x3 + x2);
+ x2 = x1 - (W2 + W6) * x2;
+ x3 = x1 + (W2 - W6) * x3;
+ x1 = x4 + x6;
+ x4 -= x6;
+ x6 = x5 + x7;
+ x5 -= x7;
+
+ /* third stage */
+ x7 = x8 + x3;
+ x8 -= x3;
+ x3 = x0 + x2;
+ x0 -= x2;
+ x2 = (181 * (x4 + x5) + 128) >> 8;
+ x4 = (181 * (x4 - x5) + 128) >> 8;
+
+ /* fourth stage */
+ blk[0] = (x7 + x1) >> 8;
+ blk[8] = (x3 + x2) >> 8;
+ blk[16] = (x0 + x4) >> 8;
+ blk[24] = (x8 + x6) >> 8;
+ blk[32] = (x8 - x6) >> 8;
+ blk[40] = (x0 - x4) >> 8;
+ blk[48] = (x3 - x2) >> 8;
+ blk[56] = (x7 - x1) >> 8;
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return;
+}
+/*----------------------------------------------------------------------------
+; End Function: idctcol
+----------------------------------------------------------------------------*/
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/cal_dc_scaler.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/cal_dc_scaler.cpp
new file mode 100644
index 0000000..85889d3
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/cal_dc_scaler.cpp
@@ -0,0 +1,182 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+/*
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ [input_variable_name] = [description of the input to module, its type
+ definition, and length (when applicable)]
+
+ Local Stores/Buffers/Pointers Needed:
+ [local_store_name] = [description of the local store, its type
+ definition, and length (when applicable)]
+ [local_buffer_name] = [description of the local buffer, its type
+ definition, and length (when applicable)]
+ [local_ptr_name] = [description of the local pointer, its type
+ definition, and length (when applicable)]
+
+ Global Stores/Buffers/Pointers Needed:
+ [global_store_name] = [description of the global store, its type
+ definition, and length (when applicable)]
+ [global_buffer_name] = [description of the global buffer, its type
+ definition, and length (when applicable)]
+ [global_ptr_name] = [description of the global pointer, its type
+ definition, and length (when applicable)]
+
+ Outputs:
+ [return_variable_name] = [description of data/pointer returned
+ by module, its type definition, and length
+ (when applicable)]
+
+ Pointers and Buffers Modified:
+ [variable_bfr_ptr] points to the [describe where the
+ variable_bfr_ptr points to, its type definition, and length
+ (when applicable)]
+ [variable_bfr] contents are [describe the new contents of
+ variable_bfr]
+
+ Local Stores Modified:
+ [local_store_name] = [describe new contents, its type
+ definition, and length (when applicable)]
+
+ Global Stores Modified:
+ [global_store_name] = [describe new contents, its type
+ definition, and length (when applicable)]
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This module calculates the DC quantization scale according
+ to the incoming Q and type.
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ [List requirements to be satisfied by this module.]
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ [List all references used in designing this module.]
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+------------------------------------------------------------------------------
+ RESOURCES USED
+ When the code is written for a specific target processor the
+ the resources used should be documented below.
+
+ STACK USAGE: [stack count for this module] + [variable to represent
+ stack usage for each subroutine called]
+
+ where: [stack usage variable] = stack usage for [subroutine
+ name] (see [filename].ext)
+
+ DATA MEMORY USED: x words
+
+ PROGRAM MEMORY USED: x words
+
+ CLOCK CYCLES: [cycle count equation for this module] + [variable
+ used to represent cycle count for each subroutine
+ called]
+
+ where: [cycle count variable] = cycle count for [subroutine
+ name] (see [filename].ext)
+
+------------------------------------------------------------------------------
+*/
+
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "mp4dec_lib.h"
+#include "vlc_decode.h"
+#include "bitstream.h"
+#include "zigzag.h"
+
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here. Include conditional
+; compile variables also.
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL FUNCTION DEFINITIONS
+; Function Prototype declaration
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL STORE/BUFFER/POINTER DEFINITIONS
+; Variable declaration - defined here and used outside this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL FUNCTION REFERENCES
+; Declare functions defined elsewhere and referenced in this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; FUNCTION CODE
+----------------------------------------------------------------------------*/
+int cal_dc_scaler(
+ int QP,
+ int type)
+{
+
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int dc_scaler;
+
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ if (type == LUMINANCE_DC_TYPE)
+ {
+ if (QP > 0 && QP < 5) dc_scaler = 8;
+ else if (QP > 4 && QP < 9) dc_scaler = 2 * QP;
+ else if (QP > 8 && QP < 25) dc_scaler = QP + 8;
+ else dc_scaler = 2 * QP - 16;
+ }
+ else /* if (type == CHROMINANCE_DC_TYPE), there is no other types. */
+ {
+ if (QP > 0 && QP < 5) dc_scaler = 8;
+ else if (QP > 4 && QP < 25) dc_scaler = (QP + 13) >> 1;
+ else dc_scaler = QP - 6;
+ }
+
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return dc_scaler;
+}
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/chv_filter.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/chv_filter.cpp
new file mode 100644
index 0000000..6593b48
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/chv_filter.cpp
@@ -0,0 +1,654 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+/*
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ [input_variable_name] = [description of the input to module, its type
+ definition, and length (when applicable)]
+
+ Local Stores/Buffers/Pointers Needed:
+ [local_store_name] = [description of the local store, its type
+ definition, and length (when applicable)]
+ [local_buffer_name] = [description of the local buffer, its type
+ definition, and length (when applicable)]
+ [local_ptr_name] = [description of the local pointer, its type
+ definition, and length (when applicable)]
+
+ Global Stores/Buffers/Pointers Needed:
+ [global_store_name] = [description of the global store, its type
+ definition, and length (when applicable)]
+ [global_buffer_name] = [description of the global buffer, its type
+ definition, and length (when applicable)]
+ [global_ptr_name] = [description of the global pointer, its type
+ definition, and length (when applicable)]
+
+ Outputs:
+ [return_variable_name] = [description of data/pointer returned
+ by module, its type definition, and length
+ (when applicable)]
+
+ Pointers and Buffers Modified:
+ [variable_bfr_ptr] points to the [describe where the
+ variable_bfr_ptr points to, its type definition, and length
+ (when applicable)]
+ [variable_bfr] contents are [describe the new contents of
+ variable_bfr]
+
+ Local Stores Modified:
+ [local_store_name] = [describe new contents, its type
+ definition, and length (when applicable)]
+
+ Global Stores Modified:
+ [global_store_name] = [describe new contents, its type
+ definition, and length (when applicable)]
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ For fast Deblock filtering
+ Newer version (macroblock based processing)
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ [List requirements to be satisfied by this module.]
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ [List all references used in designing this module.]
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+------------------------------------------------------------------------------
+ RESOURCES USED
+ When the code is written for a specific target processor the
+ the resources used should be documented below.
+
+ STACK USAGE: [stack count for this module] + [variable to represent
+ stack usage for each subroutine called]
+
+ where: [stack usage variable] = stack usage for [subroutine
+ name] (see [filename].ext)
+
+ DATA MEMORY USED: x words
+
+ PROGRAM MEMORY USED: x words
+
+ CLOCK CYCLES: [cycle count equation for this module] + [variable
+ used to represent cycle count for each subroutine
+ called]
+
+ where: [cycle count variable] = cycle count for [subroutine
+ name] (see [filename].ext)
+
+------------------------------------------------------------------------------
+*/
+
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "mp4dec_lib.h"
+#include "post_proc.h"
+
+#define OSCL_DISABLE_WARNING_CONV_POSSIBLE_LOSS_OF_DATA
+
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+//#define FILTER_LEN_8
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here. Include conditional
+; compile variables also.
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL FUNCTION DEFINITIONS
+; Function Prototype declaration
+
+----------------------------------------------------------------------------
+; LOCAL STORE/BUFFER/POINTER DEFINITIONS
+; Variable declaration - defined here and used outside this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL FUNCTION REFERENCES
+; Declare functions defined elsewhere and referenced in this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+#ifdef PV_POSTPROC_ON
+
+/*************************************************************************
+ Function prototype : void CombinedHorzVertFilter( uint8 *rec,
+ int width,
+ int height,
+ int *QP_store,
+ int chr,
+ uint8 *pp_mod)
+ Parameters :
+ rec : pointer to the decoded frame buffer.
+ width : width of decoded frame.
+ height : height of decoded frame
+ QP_store: pointer to the array of QP corresponding to the decoded frame.
+ It had only one value for each MB.
+ chr : luma or color indication
+ == 0 luma
+ == 1 color
+ pp_mod : The semphore used for deblocking
+
+ Remark : The function do the deblocking on decoded frames.
+ First based on the semaphore info., it is divided into hard and soft filtering.
+ To differentiate real and fake edge, it then check the difference with QP to
+ decide whether to do the filtering or not.
+
+*************************************************************************/
+
+
+/*----------------------------------------------------------------------------
+; FUNCTION CODE
+----------------------------------------------------------------------------*/
+void CombinedHorzVertFilter(
+ uint8 *rec,
+ int width,
+ int height,
+ int16 *QP_store,
+ int chr,
+ uint8 *pp_mod)
+{
+
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int br, bc, mbr, mbc;
+ int QP = 1;
+ uint8 *ptr, *ptr_e;
+ int pp_w, pp_h;
+ int brwidth;
+
+ int jVal0, jVal1, jVal2;
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ pp_w = (width >> 3);
+ pp_h = (height >> 3);
+
+ for (mbr = 0; mbr < pp_h; mbr += 2) /* row of blocks */
+ {
+ brwidth = mbr * pp_w; /* number of blocks above current block row */
+ for (mbc = 0; mbc < pp_w; mbc += 2) /* col of blocks */
+ {
+ if (!chr)
+ QP = QP_store[(brwidth>>2) + (mbc>>1)]; /* QP is per MB based value */
+
+ /********* for each block **************/
+ /****************** Horiz. Filtering ********************/
+ for (br = mbr + 1; br < mbr + 3; br++) /* 2x2 blocks */
+ {
+ brwidth += pp_w; /* number of blocks above & left current block row */
+ /* the profile on ARM920T shows separate these two boundary check is faster than combine them */
+ if (br < pp_h) /* boundary : don't do it on the lowest row block */
+ for (bc = mbc; bc < mbc + 2; bc++)
+ {
+ /****** check boundary for deblocking ************/
+ if (bc < pp_w) /* boundary : don't do it on the most right col block */
+ {
+ ptr = rec + (brwidth << 6) + (bc << 3);
+ jVal0 = brwidth + bc;
+ if (chr) QP = QP_store[jVal0];
+
+ ptr_e = ptr + 8; /* pointer to where the loop ends */
+
+ if (((pp_mod[jVal0]&0x02)) && ((pp_mod[jVal0-pp_w]&0x02)))
+ {
+ /* Horiz Hard filter */
+ do
+ {
+ jVal0 = *(ptr - width); /* C */
+ jVal1 = *ptr; /* D */
+ jVal2 = jVal1 - jVal0;
+
+ if (((jVal2 > 0) && (jVal2 < (QP << 1)))
+ || ((jVal2 < 0) && (jVal2 > -(QP << 1)))) /* (D-C) compared with 2QP */
+ {
+ /* differentiate between real and fake edge */
+ jVal0 = ((jVal0 + jVal1) >> 1); /* (D+C)/2 */
+ *(ptr - width) = (uint8)(jVal0); /* C */
+ *ptr = (uint8)(jVal0); /* D */
+
+ jVal0 = *(ptr - (width << 1)); /* B */
+ jVal1 = *(ptr + width); /* E */
+ jVal2 = jVal1 - jVal0; /* E-B */
+
+ if (jVal2 > 0)
+ {
+ jVal0 += ((jVal2 + 3) >> 2);
+ jVal1 -= ((jVal2 + 3) >> 2);
+ *(ptr - (width << 1)) = (uint8)jVal0; /* store B */
+ *(ptr + width) = (uint8)jVal1; /* store E */
+ }
+ else if (jVal2)
+ {
+ jVal0 -= ((3 - jVal2) >> 2);
+ jVal1 += ((3 - jVal2) >> 2);
+ *(ptr - (width << 1)) = (uint8)jVal0; /* store B */
+ *(ptr + width) = (uint8)jVal1; /* store E */
+ }
+
+ jVal0 = *(ptr - (width << 1) - width); /* A */
+ jVal1 = *(ptr + (width << 1)); /* F */
+ jVal2 = jVal1 - jVal0; /* (F-A) */
+
+ if (jVal2 > 0)
+ {
+ jVal0 += ((jVal2 + 7) >> 3);
+ jVal1 -= ((jVal2 + 7) >> 3);
+ *(ptr - (width << 1) - width) = (uint8)(jVal0);
+ *(ptr + (width << 1)) = (uint8)(jVal1);
+ }
+ else if (jVal2)
+ {
+ jVal0 -= ((7 - jVal2) >> 3);
+ jVal1 += ((7 - jVal2) >> 3);
+ *(ptr - (width << 1) - width) = (uint8)(jVal0);
+ *(ptr + (width << 1)) = (uint8)(jVal1);
+ }
+ }/* a3_0 > 2QP */
+ }
+ while (++ptr < ptr_e);
+ }
+ else /* Horiz soft filter*/
+ {
+ do
+ {
+ jVal0 = *(ptr - width); /* B */
+ jVal1 = *ptr; /* C */
+ jVal2 = jVal1 - jVal0; /* C-B */
+
+ if (((jVal2 > 0) && (jVal2 < (QP)))
+ || ((jVal2 < 0) && (jVal2 > -(QP)))) /* (C-B) compared with QP */
+ {
+
+ jVal0 = ((jVal0 + jVal1) >> 1); /* (B+C)/2 cannot overflow; ceil() */
+ *(ptr - width) = (uint8)(jVal0); /* B = (B+C)/2 */
+ *ptr = (uint8)jVal0; /* C = (B+C)/2 */
+
+ jVal0 = *(ptr - (width << 1)); /* A */
+ jVal1 = *(ptr + width); /* D */
+ jVal2 = jVal1 - jVal0; /* D-A */
+
+
+ if (jVal2 > 0)
+ {
+ jVal1 -= ((jVal2 + 7) >> 3);
+ jVal0 += ((jVal2 + 7) >> 3);
+ *(ptr - (width << 1)) = (uint8)jVal0; /* A */
+ *(ptr + width) = (uint8)jVal1; /* D */
+ }
+ else if (jVal2)
+ {
+ jVal1 += ((7 - jVal2) >> 3);
+ jVal0 -= ((7 - jVal2) >> 3);
+ *(ptr - (width << 1)) = (uint8)jVal0; /* A */
+ *(ptr + width) = (uint8)jVal1; /* D */
+ }
+ }
+ }
+ while (++ptr < ptr_e);
+ } /* Soft filter*/
+ }/* boundary checking*/
+ }/*bc*/
+ }/*br*/
+ brwidth -= (pp_w << 1);
+ /****************** Vert. Filtering ********************/
+ for (br = mbr; br < mbr + 2; br++)
+ {
+ if (br < pp_h)
+ for (bc = mbc + 1; bc < mbc + 3; bc++)
+ {
+ /****** check boundary for deblocking ************/
+ if (bc < pp_w)
+ {
+ ptr = rec + (brwidth << 6) + (bc << 3);
+ jVal0 = brwidth + bc;
+ if (chr) QP = QP_store[jVal0];
+
+ ptr_e = ptr + (width << 3);
+
+ if (((pp_mod[jVal0-1]&0x01)) && ((pp_mod[jVal0]&0x01)))
+ {
+ /* Vert Hard filter */
+ do
+ {
+ jVal1 = *ptr; /* D */
+ jVal0 = *(ptr - 1); /* C */
+ jVal2 = jVal1 - jVal0; /* D-C */
+
+ if (((jVal2 > 0) && (jVal2 < (QP << 1)))
+ || ((jVal2 < 0) && (jVal2 > -(QP << 1))))
+ {
+ jVal1 = (jVal0 + jVal1) >> 1; /* (C+D)/2 */
+ *ptr = jVal1;
+ *(ptr - 1) = jVal1;
+
+ jVal1 = *(ptr + 1); /* E */
+ jVal0 = *(ptr - 2); /* B */
+ jVal2 = jVal1 - jVal0; /* E-B */
+
+ if (jVal2 > 0)
+ {
+ jVal1 -= ((jVal2 + 3) >> 2); /* E = E -(E-B)/4 */
+ jVal0 += ((jVal2 + 3) >> 2); /* B = B +(E-B)/4 */
+ *(ptr + 1) = jVal1;
+ *(ptr - 2) = jVal0;
+ }
+ else if (jVal2)
+ {
+ jVal1 += ((3 - jVal2) >> 2); /* E = E -(E-B)/4 */
+ jVal0 -= ((3 - jVal2) >> 2); /* B = B +(E-B)/4 */
+ *(ptr + 1) = jVal1;
+ *(ptr - 2) = jVal0;
+ }
+
+ jVal1 = *(ptr + 2); /* F */
+ jVal0 = *(ptr - 3); /* A */
+
+ jVal2 = jVal1 - jVal0; /* (F-A) */
+
+ if (jVal2 > 0)
+ {
+ jVal1 -= ((jVal2 + 7) >> 3); /* F -= (F-A)/8 */
+ jVal0 += ((jVal2 + 7) >> 3); /* A += (F-A)/8 */
+ *(ptr + 2) = jVal1;
+ *(ptr - 3) = jVal0;
+ }
+ else if (jVal2)
+ {
+ jVal1 -= ((jVal2 - 7) >> 3); /* F -= (F-A)/8 */
+ jVal0 += ((jVal2 - 7) >> 3); /* A += (F-A)/8 */
+ *(ptr + 2) = jVal1;
+ *(ptr - 3) = jVal0;
+ }
+ } /* end of ver hard filetering */
+ }
+ while ((ptr += width) < ptr_e);
+ }
+ else /* Vert soft filter*/
+ {
+ do
+ {
+ jVal1 = *ptr; /* C */
+ jVal0 = *(ptr - 1); /* B */
+ jVal2 = jVal1 - jVal0;
+
+ if (((jVal2 > 0) && (jVal2 < (QP)))
+ || ((jVal2 < 0) && (jVal2 > -(QP))))
+ {
+
+ jVal1 = (jVal0 + jVal1 + 1) >> 1;
+ *ptr = jVal1; /* C */
+ *(ptr - 1) = jVal1; /* B */
+
+ jVal1 = *(ptr + 1); /* D */
+ jVal0 = *(ptr - 2); /* A */
+ jVal2 = (jVal1 - jVal0); /* D- A */
+
+ if (jVal2 > 0)
+ {
+ jVal1 -= (((jVal2) + 7) >> 3); /* D -= (D-A)/8 */
+ jVal0 += (((jVal2) + 7) >> 3); /* A += (D-A)/8 */
+ *(ptr + 1) = jVal1;
+ *(ptr - 2) = jVal0;
+
+ }
+ else if (jVal2)
+ {
+ jVal1 += ((7 - (jVal2)) >> 3); /* D -= (D-A)/8 */
+ jVal0 -= ((7 - (jVal2)) >> 3); /* A += (D-A)/8 */
+ *(ptr + 1) = jVal1;
+ *(ptr - 2) = jVal0;
+ }
+ }
+ }
+ while ((ptr += width) < ptr_e);
+ } /* Soft filter*/
+ } /* boundary*/
+ } /*bc*/
+ brwidth += pp_w;
+ }/*br*/
+ brwidth -= (pp_w << 1);
+ }/*mbc*/
+ brwidth += (pp_w << 1);
+ }/*mbr*/
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return;
+}
+void CombinedHorzVertFilter_NoSoftDeblocking(
+ uint8 *rec,
+ int width,
+ int height,
+ int16 *QP_store,
+ int chr,
+ uint8 *pp_mod)
+{
+
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int br, bc, mbr, mbc;
+ int QP = 1;
+ uint8 *ptr, *ptr_e;
+ int pp_w, pp_h;
+ int brwidth;
+
+ int jVal0, jVal1, jVal2;
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ pp_w = (width >> 3);
+ pp_h = (height >> 3);
+
+ for (mbr = 0; mbr < pp_h; mbr += 2) /* row of blocks */
+ {
+ brwidth = mbr * pp_w; /* number of blocks above current block row */
+ for (mbc = 0; mbc < pp_w; mbc += 2) /* col of blocks */
+ {
+ if (!chr)
+ QP = QP_store[(brwidth>>2) + (mbc>>1)]; /* QP is per MB based value */
+
+ /********* for each block **************/
+ /****************** Horiz. Filtering ********************/
+ for (br = mbr + 1; br < mbr + 3; br++) /* 2x2 blocks */
+ {
+ brwidth += pp_w; /* number of blocks above & left current block row */
+ /* the profile on ARM920T shows separate these two boundary check is faster than combine them */
+ if (br < pp_h) /* boundary : don't do it on the lowest row block */
+ for (bc = mbc; bc < mbc + 2; bc++)
+ {
+ /****** check boundary for deblocking ************/
+ if (bc < pp_w) /* boundary : don't do it on the most right col block */
+ {
+ ptr = rec + (brwidth << 6) + (bc << 3);
+ jVal0 = brwidth + bc;
+ if (chr) QP = QP_store[jVal0];
+
+ ptr_e = ptr + 8; /* pointer to where the loop ends */
+
+ if (((pp_mod[jVal0]&0x02)) && ((pp_mod[jVal0-pp_w]&0x02)))
+ {
+ /* Horiz Hard filter */
+ do
+ {
+ jVal0 = *(ptr - width); /* C */
+ jVal1 = *ptr; /* D */
+ jVal2 = jVal1 - jVal0;
+
+ if (((jVal2 > 0) && (jVal2 < (QP << 1)))
+ || ((jVal2 < 0) && (jVal2 > -(QP << 1)))) /* (D-C) compared with 2QP */
+ {
+ /* differentiate between real and fake edge */
+ jVal0 = ((jVal0 + jVal1) >> 1); /* (D+C)/2 */
+ *(ptr - width) = (uint8)(jVal0); /* C */
+ *ptr = (uint8)(jVal0); /* D */
+
+ jVal0 = *(ptr - (width << 1)); /* B */
+ jVal1 = *(ptr + width); /* E */
+ jVal2 = jVal1 - jVal0; /* E-B */
+
+ if (jVal2 > 0)
+ {
+ jVal0 += ((jVal2 + 3) >> 2);
+ jVal1 -= ((jVal2 + 3) >> 2);
+ *(ptr - (width << 1)) = (uint8)jVal0; /* store B */
+ *(ptr + width) = (uint8)jVal1; /* store E */
+ }
+ else if (jVal2)
+ {
+ jVal0 -= ((3 - jVal2) >> 2);
+ jVal1 += ((3 - jVal2) >> 2);
+ *(ptr - (width << 1)) = (uint8)jVal0; /* store B */
+ *(ptr + width) = (uint8)jVal1; /* store E */
+ }
+
+ jVal0 = *(ptr - (width << 1) - width); /* A */
+ jVal1 = *(ptr + (width << 1)); /* F */
+ jVal2 = jVal1 - jVal0; /* (F-A) */
+
+ if (jVal2 > 0)
+ {
+ jVal0 += ((jVal2 + 7) >> 3);
+ jVal1 -= ((jVal2 + 7) >> 3);
+ *(ptr - (width << 1) - width) = (uint8)(jVal0);
+ *(ptr + (width << 1)) = (uint8)(jVal1);
+ }
+ else if (jVal2)
+ {
+ jVal0 -= ((7 - jVal2) >> 3);
+ jVal1 += ((7 - jVal2) >> 3);
+ *(ptr - (width << 1) - width) = (uint8)(jVal0);
+ *(ptr + (width << 1)) = (uint8)(jVal1);
+ }
+ }/* a3_0 > 2QP */
+ }
+ while (++ptr < ptr_e);
+ }
+
+ }/* boundary checking*/
+ }/*bc*/
+ }/*br*/
+ brwidth -= (pp_w << 1);
+ /****************** Vert. Filtering ********************/
+ for (br = mbr; br < mbr + 2; br++)
+ {
+ if (br < pp_h)
+ for (bc = mbc + 1; bc < mbc + 3; bc++)
+ {
+ /****** check boundary for deblocking ************/
+ if (bc < pp_w)
+ {
+ ptr = rec + (brwidth << 6) + (bc << 3);
+ jVal0 = brwidth + bc;
+ if (chr) QP = QP_store[jVal0];
+
+ ptr_e = ptr + (width << 3);
+
+ if (((pp_mod[jVal0-1]&0x01)) && ((pp_mod[jVal0]&0x01)))
+ {
+ /* Vert Hard filter */
+ do
+ {
+ jVal1 = *ptr; /* D */
+ jVal0 = *(ptr - 1); /* C */
+ jVal2 = jVal1 - jVal0; /* D-C */
+
+ if (((jVal2 > 0) && (jVal2 < (QP << 1)))
+ || ((jVal2 < 0) && (jVal2 > -(QP << 1))))
+ {
+ jVal1 = (jVal0 + jVal1) >> 1; /* (C+D)/2 */
+ *ptr = jVal1;
+ *(ptr - 1) = jVal1;
+
+ jVal1 = *(ptr + 1); /* E */
+ jVal0 = *(ptr - 2); /* B */
+ jVal2 = jVal1 - jVal0; /* E-B */
+
+ if (jVal2 > 0)
+ {
+ jVal1 -= ((jVal2 + 3) >> 2); /* E = E -(E-B)/4 */
+ jVal0 += ((jVal2 + 3) >> 2); /* B = B +(E-B)/4 */
+ *(ptr + 1) = jVal1;
+ *(ptr - 2) = jVal0;
+ }
+ else if (jVal2)
+ {
+ jVal1 += ((3 - jVal2) >> 2); /* E = E -(E-B)/4 */
+ jVal0 -= ((3 - jVal2) >> 2); /* B = B +(E-B)/4 */
+ *(ptr + 1) = jVal1;
+ *(ptr - 2) = jVal0;
+ }
+
+ jVal1 = *(ptr + 2); /* F */
+ jVal0 = *(ptr - 3); /* A */
+
+ jVal2 = jVal1 - jVal0; /* (F-A) */
+
+ if (jVal2 > 0)
+ {
+ jVal1 -= ((jVal2 + 7) >> 3); /* F -= (F-A)/8 */
+ jVal0 += ((jVal2 + 7) >> 3); /* A += (F-A)/8 */
+ *(ptr + 2) = jVal1;
+ *(ptr - 3) = jVal0;
+ }
+ else if (jVal2)
+ {
+ jVal1 -= ((jVal2 - 7) >> 3); /* F -= (F-A)/8 */
+ jVal0 += ((jVal2 - 7) >> 3); /* A += (F-A)/8 */
+ *(ptr + 2) = jVal1;
+ *(ptr - 3) = jVal0;
+ }
+ } /* end of ver hard filetering */
+ }
+ while ((ptr += width) < ptr_e);
+ }
+
+ } /* boundary*/
+ } /*bc*/
+ brwidth += pp_w;
+ }/*br*/
+ brwidth -= (pp_w << 1);
+ }/*mbc*/
+ brwidth += (pp_w << 1);
+ }/*mbr*/
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return;
+}
+#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/chvr_filter.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/chvr_filter.cpp
new file mode 100644
index 0000000..795cf71
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/chvr_filter.cpp
@@ -0,0 +1,565 @@
+/* ------------------------------------------------------------------
+ * 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 "mp4dec_lib.h"
+#include "post_proc.h"
+
+#ifdef PV_POSTPROC_ON
+
+void CombinedHorzVertRingFilter(
+ uint8 *rec,
+ int width,
+ int height,
+ int16 *QP_store,
+ int chr,
+ uint8 *pp_mod)
+{
+
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int index, counter;
+ int br, bc, incr, mbr, mbc;
+ int QP = 1;
+ int v[5];
+ uint8 *ptr, *ptr_c, *ptr_n;
+ int w1, w2, w3, w4;
+ int pp_w, pp_h, brwidth;
+ int sum, delta;
+ int a3_0, a3_1, a3_2, A3_0;
+ /* for Deringing Threshold approach (MPEG4)*/
+ int max_diff, thres, v0, h0, min_blk, max_blk;
+ int cnthflag;
+
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ /* Calculate the width and height of the area in blocks (divide by 8) */
+ pp_w = (width >> 3);
+ pp_h = (height >> 3);
+
+ /* Set up various values needed for updating pointers into rec */
+ w1 = width; /* Offset to next row in pixels */
+ w2 = width << 1; /* Offset to two rows in pixels */
+ w3 = w1 + w2; /* Offset to three rows in pixels */
+ w4 = w2 << 1; /* Offset to four rows in pixels */
+ incr = width - BLKSIZE; /* Offset to next row after processing block */
+
+ /* Work through the area hortizontally by two rows per step */
+ for (mbr = 0; mbr < pp_h; mbr += 2)
+ {
+ /* brwidth contains the block number of the leftmost block
+ * of the current row */
+ brwidth = mbr * pp_w;
+
+ /* Work through the area vertically by two columns per step */
+ for (mbc = 0; mbc < pp_w; mbc += 2)
+ {
+ /* if the data is luminance info, get the correct
+ * quantization paramenter. One parameter per macroblock */
+ if (!chr)
+ {
+ /* brwidth/4 is the macroblock number and mbc/2 is the macroblock col number*/
+ QP = QP_store[(brwidth>>2) + (mbc>>1)];
+ }
+
+ /****************** Horiz. Filtering ********************/
+ /* Process four blocks for the filtering */
+ /********************************************************/
+ /* Loop over two rows of blocks */
+ for (br = mbr + 1; br < mbr + 3; br++) /* br is the row counter in blocks */
+ {
+ /* Set brwidth to the first (leftmost) block number of the next row */
+ /* brwidth is used as an index when counting blocks */
+ brwidth += pp_w;
+
+ /* Loop over two columns of blocks in the row */
+ for (bc = mbc; bc < mbc + 2; bc++) /* bc is the column counter in blocks */
+ {
+ /****** check boundary for deblocking ************/
+ /* Execute if the row and column counters are within the area */
+ if (br < pp_h && bc < pp_w)
+ {
+ /* Set the ptr to the first pixel of the first block of the second row
+ * brwidth * 64 is the pixel row offset
+ * bc * 8 is the pixel column offset */
+ ptr = rec + (brwidth << 6) + (bc << 3);
+
+ /* Set the index to the current block of the second row counting in blocks */
+ index = brwidth + bc;
+
+ /* if the data is chrominance info, get the correct
+ * quantization paramenter. One parameter per block. */
+ if (chr)
+ {
+ QP = QP_store[index];
+ }
+
+ /* Execute hard horizontal filter if semaphore for horizontal deblocking
+ * is set for the current block and block immediately above it */
+ if (((pp_mod[index]&0x02) != 0) && ((pp_mod[index-pp_w]&0x02) != 0))
+ { /* Hard filter */
+
+ /* Set HorzHflag (bit 4) in the pp_mod location */
+ pp_mod[index-pp_w] |= 0x10; /* 4/26/00 reuse pp_mod for HorzHflag*/
+
+ /* Filter across the 8 pixels of the block */
+ for (index = BLKSIZE; index > 0; index--)
+ {
+ /* Difference between the current pixel and the pixel above it */
+ a3_0 = *ptr - *(ptr - w1);
+
+ /* if the magnitude of the difference is greater than the KThH threshold
+ * and within the quantization parameter, apply hard filter */
+ if ((a3_0 > KThH || a3_0 < -KThH) && a3_0<QP && a3_0> -QP)
+ {
+ ptr_c = ptr - w3; /* Points to pixel three rows above */
+ ptr_n = ptr + w1; /* Points to pixel one row below */
+ v[0] = (int)(*(ptr_c - w3));
+ v[1] = (int)(*(ptr_c - w2));
+ v[2] = (int)(*(ptr_c - w1));
+ v[3] = (int)(*ptr_c);
+ v[4] = (int)(*(ptr_c + w1));
+
+ sum = v[0]
+ + v[1]
+ + v[2]
+ + *ptr_c
+ + v[4]
+ + (*(ptr_c + w2))
+ + (*(ptr_c + w3)); /* Current pixel */
+
+ delta = (sum + *ptr_c + 4) >> 3; /* Average pixel values with rounding */
+ *(ptr_c) = (uint8) delta;
+
+ /* Move pointer down one row of pixels (points to pixel two rows
+ * above current pixel) */
+ ptr_c += w1;
+
+ for (counter = 0; counter < 5; counter++)
+ {
+ /* Subtract off highest pixel and add in pixel below */
+ sum = sum - v[counter] + *ptr_n;
+ /* Average the pixel values with rounding */
+ delta = (sum + *ptr_c + 4) >> 3;
+ *ptr_c = (uint8)(delta);
+
+ /* Increment pointers to next pixel row */
+ ptr_c += w1;
+ ptr_n += w1;
+ }
+ }
+ /* Increment pointer to next pixel */
+ ++ptr;
+ } /* index*/
+ }
+ else
+ { /* soft filter*/
+
+ /* Clear HorzHflag (bit 4) in the pp_mod location */
+ pp_mod[index-pp_w] &= 0xef; /* reset 1110,1111 */
+
+ for (index = BLKSIZE; index > 0; index--)
+ {
+ /* Difference between the current pixel and the pixel above it */
+ a3_0 = *(ptr) - *(ptr - w1);
+
+ /* if the magnitude of the difference is greater than the KTh threshold,
+ * apply soft filter */
+ if ((a3_0 > KTh || a3_0 < -KTh))
+ {
+
+ /* Sum of weighted differences */
+ a3_0 += ((*(ptr - w2) - *(ptr + w1)) << 1) + (a3_0 << 2);
+
+ /* Check if sum is less than the quantization parameter */
+ if (PV_ABS(a3_0) < (QP << 3))
+ {
+ a3_1 = *(ptr - w2) - *(ptr - w3);
+ a3_1 += ((*(ptr - w4) - *(ptr - w1)) << 1) + (a3_1 << 2);
+
+ a3_2 = *(ptr + w2) - *(ptr + w1);
+ a3_2 += ((*(ptr) - *(ptr + w3)) << 1) + (a3_2 << 2);
+
+ A3_0 = PV_ABS(a3_0) - PV_MIN(PV_ABS(a3_1), PV_ABS(a3_2));
+
+ if (A3_0 > 0)
+ {
+ A3_0 += A3_0 << 2;
+ A3_0 = (A3_0 + 32) >> 6;
+ if (a3_0 > 0)
+ {
+ A3_0 = -A3_0;
+ }
+
+ delta = (*(ptr - w1) - *(ptr)) >> 1;
+ if (delta >= 0)
+ {
+ if (delta >= A3_0)
+ {
+ delta = PV_MAX(A3_0, 0);
+ }
+ }
+ else
+ {
+ if (A3_0 > 0)
+ {
+ delta = 0;
+ }
+ else
+ {
+ delta = PV_MAX(A3_0, delta);
+ }
+ }
+
+ *(ptr - w1) = (uint8)(*(ptr - w1) - delta);
+ *(ptr) = (uint8)(*(ptr) + delta);
+ }
+ } /*threshold*/
+ }
+ /* Increment pointer to next pixel */
+ ++ptr;
+ } /*index*/
+ } /* Soft filter*/
+ }/* boundary checking*/
+ }/*bc*/
+ }/*br*/
+ brwidth -= (pp_w << 1);
+
+
+ /****************** Vert. Filtering *********************/
+ /* Process four blocks for the filtering */
+ /********************************************************/
+ /* Loop over two rows of blocks */
+ for (br = mbr; br < mbr + 2; br++) /* br is the row counter in blocks */
+ {
+ for (bc = mbc + 1; bc < mbc + 3; bc++) /* bc is the column counter in blocks */
+ {
+ /****** check boundary for deblocking ************/
+ /* Execute if the row and column counters are within the area */
+ if (br < pp_h && bc < pp_w)
+ {
+ /* Set the ptr to the first pixel of the first block of the second row
+ * brwidth * 64 is the pixel row offset
+ * bc * 8 is the pixel column offset */
+ ptr = rec + (brwidth << 6) + (bc << 3);
+
+ /* Set the index to the current block of the second row counting in blocks */
+ index = brwidth + bc;
+
+ /* if the data is chrominance info, get the correct
+ * quantization paramenter. One parameter per block. */
+ if (chr)
+ {
+ QP = QP_store[index];
+ }
+
+ /* Execute hard vertical filter if semaphore for vertical deblocking
+ * is set for the current block and block immediately left of it */
+ if (((pp_mod[index-1]&0x01) != 0) && ((pp_mod[index]&0x01) != 0))
+ { /* Hard filter */
+
+ /* Set VertHflag (bit 5) in the pp_mod location of previous block*/
+ pp_mod[index-1] |= 0x20; /* 4/26/00 reuse pp_mod for VertHflag*/
+
+ /* Filter across the 8 pixels of the block */
+ for (index = BLKSIZE; index > 0; index--)
+ {
+ /* Difference between the current pixel
+ * and the pixel to left of it */
+ a3_0 = *ptr - *(ptr - 1);
+
+ /* if the magnitude of the difference is greater than the KThH threshold
+ * and within the quantization parameter, apply hard filter */
+ if ((a3_0 > KThH || a3_0 < -KThH) && a3_0<QP && a3_0> -QP)
+ {
+ ptr_c = ptr - 3;
+ ptr_n = ptr + 1;
+ v[0] = (int)(*(ptr_c - 3));
+ v[1] = (int)(*(ptr_c - 2));
+ v[2] = (int)(*(ptr_c - 1));
+ v[3] = (int)(*ptr_c);
+ v[4] = (int)(*(ptr_c + 1));
+
+ sum = v[0]
+ + v[1]
+ + v[2]
+ + *ptr_c
+ + v[4]
+ + (*(ptr_c + 2))
+ + (*(ptr_c + 3));
+
+ delta = (sum + *ptr_c + 4) >> 3;
+ *(ptr_c) = (uint8) delta;
+
+ /* Move pointer down one pixel to the right */
+ ptr_c += 1;
+ for (counter = 0; counter < 5; counter++)
+ {
+ /* Subtract off highest pixel and add in pixel below */
+ sum = sum - v[counter] + *ptr_n;
+ /* Average the pixel values with rounding */
+ delta = (sum + *ptr_c + 4) >> 3;
+ *ptr_c = (uint8)(delta);
+
+ /* Increment pointers to next pixel */
+ ptr_c += 1;
+ ptr_n += 1;
+ }
+ }
+ /* Increment pointers to next pixel row */
+ ptr += w1;
+ } /* index*/
+ }
+ else
+ { /* soft filter*/
+
+ /* Clear VertHflag (bit 5) in the pp_mod location */
+ pp_mod[index-1] &= 0xdf; /* reset 1101,1111 */
+ for (index = BLKSIZE; index > 0; index--)
+ {
+ /* Difference between the current pixel and the pixel above it */
+ a3_0 = *(ptr) - *(ptr - 1);
+
+ /* if the magnitude of the difference is greater than the KTh threshold,
+ * apply soft filter */
+ if ((a3_0 > KTh || a3_0 < -KTh))
+ {
+
+ /* Sum of weighted differences */
+ a3_0 += ((*(ptr - 2) - *(ptr + 1)) << 1) + (a3_0 << 2);
+
+ /* Check if sum is less than the quantization parameter */
+ if (PV_ABS(a3_0) < (QP << 3))
+ {
+ a3_1 = *(ptr - 2) - *(ptr - 3);
+ a3_1 += ((*(ptr - 4) - *(ptr - 1)) << 1) + (a3_1 << 2);
+
+ a3_2 = *(ptr + 2) - *(ptr + 1);
+ a3_2 += ((*(ptr) - *(ptr + 3)) << 1) + (a3_2 << 2);
+
+ A3_0 = PV_ABS(a3_0) - PV_MIN(PV_ABS(a3_1), PV_ABS(a3_2));
+
+ if (A3_0 > 0)
+ {
+ A3_0 += A3_0 << 2;
+ A3_0 = (A3_0 + 32) >> 6;
+ if (a3_0 > 0)
+ {
+ A3_0 = -A3_0;
+ }
+
+ delta = (*(ptr - 1) - *(ptr)) >> 1;
+ if (delta >= 0)
+ {
+ if (delta >= A3_0)
+ {
+ delta = PV_MAX(A3_0, 0);
+ }
+ }
+ else
+ {
+ if (A3_0 > 0)
+ {
+ delta = 0;
+ }
+ else
+ {
+ delta = PV_MAX(A3_0, delta);
+ }
+ }
+
+ *(ptr - 1) = (uint8)(*(ptr - 1) - delta);
+ *(ptr) = (uint8)(*(ptr) + delta);
+ }
+ } /*threshold*/
+ }
+ ptr += w1;
+ } /*index*/
+ } /* Soft filter*/
+ } /* boundary*/
+ } /*bc*/
+ /* Increment pointer to next row of pixels */
+ brwidth += pp_w;
+ }/*br*/
+ brwidth -= (pp_w << 1);
+
+ /****************** Deringing ***************************/
+ /* Process four blocks for the filtering */
+ /********************************************************/
+ /* Loop over two rows of blocks */
+ for (br = mbr; br < mbr + 2; br++)
+ {
+ /* Loop over two columns of blocks in the row */
+ for (bc = mbc; bc < mbc + 2; bc++)
+ {
+ /* Execute if the row and column counters are within the area */
+ if (br < pp_h && bc < pp_w)
+ {
+ /* Set the index to the current block */
+ index = brwidth + bc;
+
+ /* Execute deringing if semaphore for deringing (bit-3 of pp_mod)
+ * is set for the current block */
+ if ((pp_mod[index]&0x04) != 0)
+ {
+ /* Don't process deringing if on an edge block */
+ if (br > 0 && bc > 0 && br < pp_h - 1 && bc < pp_w - 1)
+ {
+ /* cnthflag = weighted average of HorzHflag of current,
+ * one above, previous blocks*/
+ cnthflag = ((pp_mod[index] & 0x10) +
+ (pp_mod[index-pp_w] & 0x10) +
+ ((pp_mod[index-1] >> 1) & 0x10) +
+ ((pp_mod[index] >> 1) & 0x10)) >> 4; /* 4/26/00*/
+
+ /* Do the deringing if decision flags indicate it's necessary */
+ if (cnthflag < 3)
+ {
+ /* if the data is chrominance info, get the correct
+ * quantization paramenter. One parameter per block. */
+ if (chr)
+ {
+ QP = QP_store[index];
+ }
+
+ /* Set amount to change luminance if it needs to be changed
+ * based on quantization parameter */
+ max_diff = (QP >> 2) + 4;
+
+ /* Set pointer to first pixel of current block */
+ ptr = rec + (brwidth << 6) + (bc << 3);
+
+ /* Find minimum and maximum value of pixel block */
+ FindMaxMin(ptr, &min_blk, &max_blk, incr);
+
+ /* threshold determination */
+ thres = (max_blk + min_blk + 1) >> 1;
+
+ /* If pixel range is greater or equal than DERING_THR, smooth the region */
+ if ((max_blk - min_blk) >= DERING_THR) /*smooth 8x8 region*/
+#ifndef NoMMX
+ {
+ /* smooth all pixels in the block*/
+ DeringAdaptiveSmoothMMX(ptr, width, thres, max_diff);
+ }
+#else
+ {
+ /* Setup the starting point of the region to smooth */
+ v0 = (br << 3) - 1;
+ h0 = (bc << 3) - 1;
+
+ /*smooth 8x8 region*/
+ AdaptiveSmooth_NoMMX(rec, v0, h0, v0 + 1, h0 + 1, thres, width, max_diff);
+ }
+#endif
+ }/*cnthflag*/
+ } /*dering br==1 or bc==1 (boundary block)*/
+ else /* Process the boundary blocks */
+ {
+ /* Decide to perform deblocking based on the semaphore flags
+ * of the neighboring blocks in each case. A certain number of
+ * hard filtering flags have to be set in order to signal need
+ * for smoothing */
+ if (br > 0 && br < pp_h - 1)
+ {
+ if (bc > 0)
+ {
+ cnthflag = ((pp_mod[index-pp_w] & 0x10) +
+ (pp_mod[index] & 0x10) +
+ ((pp_mod[index-1] >> 1) & 0x10)) >> 4;
+ }
+ else
+ {
+ cnthflag = ((pp_mod[index] & 0x10) +
+ (pp_mod[index-pp_w] & 0x10) +
+ ((pp_mod[index] >> 1) & 0x10)) >> 4;
+ }
+ }
+ else if (bc > 0 && bc < pp_w - 1)
+ {
+ if (br > 0)
+ {
+ cnthflag = ((pp_mod[index-pp_w] & 0x10) +
+ ((pp_mod[index-1] >> 1) & 0x10) +
+ ((pp_mod[index] >> 1) & 0x10)) >> 4;
+ }
+ else
+ {
+ cnthflag = ((pp_mod[index] & 0x10) +
+ ((pp_mod[index-1] >> 1) & 0x10) +
+ ((pp_mod[index] >> 1) & 0x10)) >> 4;
+ }
+ }
+ else /* at the corner do default*/
+ {
+ cnthflag = 0;
+ }
+
+ /* Do the deringing if decision flags indicate it's necessary */
+ if (cnthflag < 2)
+ {
+
+ /* if the data is chrominance info, get the correct
+ * quantization paramenter. One parameter per block. */
+ if (chr)
+ {
+ QP = QP_store[index];
+ }
+
+ /* Set amount to change luminance if it needs to be changed
+ * based on quantization parameter */
+ max_diff = (QP >> 2) + 4;
+
+ /* Set pointer to first pixel of current block */
+ ptr = rec + (brwidth << 6) + (bc << 3);
+
+ /* Find minimum and maximum value of pixel block */
+ FindMaxMin(ptr, &min_blk, &max_blk, incr);
+
+ /* threshold determination */
+ thres = (max_blk + min_blk + 1) >> 1;
+
+ /* Setup the starting point of the region to smooth
+ * This is going to be a 4x4 region */
+ v0 = (br << 3) + 1;
+ h0 = (bc << 3) + 1;
+
+ /* If pixel range is greater or equal than DERING_THR, smooth the region */
+ if ((max_blk - min_blk) >= DERING_THR)
+ {
+ /* Smooth 4x4 region */
+ AdaptiveSmooth_NoMMX(rec, v0, h0, v0 - 3, h0 - 3, thres, width, max_diff);
+ }
+ }/*cnthflag*/
+ } /* br==0, bc==0*/
+ } /* dering*/
+ } /*boundary condition*/
+ }/*bc*/
+ brwidth += pp_w;
+ }/*br*/
+ brwidth -= (pp_w << 1);
+ }/*mbc*/
+ brwidth += (pp_w << 1);
+ }/*mbr*/
+
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return ;
+}
+#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/combined_decode.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/combined_decode.cpp
new file mode 100644
index 0000000..6499233
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/combined_decode.cpp
@@ -0,0 +1,840 @@
+/* ------------------------------------------------------------------
+ * 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 "mp4dec_lib.h" /* video decoder function prototypes */
+#include "vlc_decode.h"
+#include "bitstream.h"
+#include "scaling.h"
+#include "mbtype_mode.h"
+
+#define OSCL_DISABLE_WARNING_CONDITIONAL_IS_CONSTANT
+/* ======================================================================== */
+/* Function : DecodeFrameCombinedMode() */
+/* Purpose : Decode a frame of MPEG4 bitstream in combined mode. */
+/* In/out : */
+/* Return : */
+/* Modified : */
+/* */
+/* 03/30/2000 : Cleaned up and optimized the code. */
+/* 03/31/2000 : Added proper handling of MB stuffing. */
+/* 04/13/2000 : Rewrote this combined mode path completely */
+/* so that it handles "Combined Mode With Error */
+/* Resilience." Now the code resembles the */
+/* pseudo codes in MPEG-4 standard better. */
+/* 10/13/2000 : Add fast VLC+dequant */
+/* 04/13/2001 : fix MB_stuffing */
+/* 08/07/2001 : remove MBzero */
+/* ======================================================================== */
+PV_STATUS DecodeFrameCombinedMode(VideoDecData *video)
+{
+ PV_STATUS status;
+ int mbnum;
+ Vop *currVop = video->currVop;
+ BitstreamDecVideo *stream = video->bitstream;
+ int shortVideoHeader = video->shortVideoHeader;
+ int16 QP, *QPMB = video->QPMB;
+ uint8 *Mode = video->headerInfo.Mode;
+ int nTotalMB = video->nTotalMB;
+ int nMBPerRow = video->nMBPerRow;
+ int slice_counter;
+ uint32 tmpvar, long_zero_bits;
+ uint code;
+ int valid_stuffing;
+ int resync_marker_length;
+ int stuffing_length;
+
+ /* add this for error resilient, 05/18/2000 */
+ int32 startPacket;
+ int mb_start;
+ /* copy and pad to prev_Vop for INTER coding */
+ switch (currVop->predictionType)
+ {
+ case I_VOP :
+// oscl_memset(Mode, MODE_INTRA, sizeof(uint8)*nTotalMB);
+ resync_marker_length = 17;
+ stuffing_length = 9;
+ break;
+ case P_VOP :
+ oscl_memset(video->motX, 0, sizeof(MOT)*4*nTotalMB);
+ oscl_memset(video->motY, 0, sizeof(MOT)*4*nTotalMB);
+// oscl_memset(Mode, MODE_INTER, sizeof(uint8)*nTotalMB);
+ resync_marker_length = 16 + currVop->fcodeForward;
+ stuffing_length = 10;
+ break;
+ default :
+ mp4dec_log("DecodeFrameCombinedMode(): Vop type not supported.\n");
+ return PV_FAIL;
+ }
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ if (video->shortVideoHeader)
+ {
+ if (video->advanced_INTRA)
+ {
+ if (video->modified_quant)
+ {
+ video->vlcDecCoeffIntra = &VlcDecTCOEFShortHeader_AnnexIT;
+ video->vlcDecCoeffInter = &VlcDecTCOEFShortHeader_AnnexT;
+ }
+ else
+ {
+ video->vlcDecCoeffIntra = &VlcDecTCOEFShortHeader_AnnexI;
+ video->vlcDecCoeffInter = &VlcDecTCOEFShortHeader;
+ }
+ }
+ else
+ {
+ if (video->modified_quant)
+ {
+ video->vlcDecCoeffInter = video->vlcDecCoeffIntra = &VlcDecTCOEFShortHeader_AnnexT;
+ }
+ else
+ {
+ video->vlcDecCoeffInter = video->vlcDecCoeffIntra = &VlcDecTCOEFShortHeader;
+ }
+ }
+ }
+
+#endif
+
+ /** Initialize sliceNo ***/
+ mbnum = slice_counter = 0;
+// oscl_memset(video->sliceNo, 0, sizeof(uint8)*nTotalMB);
+ QP = video->currVop->quantizer;
+
+ do
+ {
+ /* This section is equivalent to motion_shape_texture() */
+ /* in the MPEG-4 standard. 04/13/2000 */
+ mb_start = mbnum;
+ video->usePrevQP = 0; /* 04/27/01 */
+ startPacket = getPointer(stream);
+
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ if (video->modified_quant)
+ {
+ video->QP_CHR = MQ_chroma_QP_table[QP];
+ }
+ else
+ {
+ video->QP_CHR = QP; /* ANNEX_T */
+ }
+#endif
+ /* remove any stuffing bits */
+ BitstreamShowBits16(stream, stuffing_length, &code);
+ while (code == 1)
+ {
+ PV_BitstreamFlushBits(stream, stuffing_length);
+ BitstreamShowBits16(stream, stuffing_length, &code);
+ }
+
+ do
+ {
+ /* we need video->mbnum in lower level functions */
+ video->mbnum = mbnum;
+ video->mbnum_row = PV_GET_ROW(mbnum, nMBPerRow);
+ video->mbnum_col = mbnum - video->mbnum_row * nMBPerRow;
+ /* assign slice number for each macroblocks */
+ video->sliceNo[mbnum] = (uint8) slice_counter;
+
+ /* decode COD, MCBPC, ACpred_flag, CPBY and DQUANT */
+ /* We have to discard stuffed MB header */
+ status = GetMBheader(video, &QP);
+
+ if (status != PV_SUCCESS)
+ {
+ VideoDecoderErrorDetected(video);
+ video->mbnum = mb_start;
+ movePointerTo(stream, (startPacket & -8));
+ break;
+ }
+
+ /* Store the QP value for later use in AC prediction */
+ QPMB[mbnum] = QP;
+
+ if (Mode[mbnum] != MODE_SKIPPED)
+ {
+ /* decode the DCT coeficients for the MB */
+ status = GetMBData(video);
+ if (status != PV_SUCCESS)
+ {
+ VideoDecoderErrorDetected(video);
+ video->mbnum = mb_start;
+ movePointerTo(stream, (startPacket & -8));
+ break;
+ }
+ }
+ else /* MODE_SKIPPED */
+ {
+ SkippedMBMotionComp(video); /* 08/04/05 */
+ }
+ // Motion compensation and put video->mblock->pred_block
+ mbnum++;
+
+ /* remove any stuffing bits */
+ BitstreamShowBits16(stream, stuffing_length, &code);
+ while (code == 1)
+ {
+ PV_BitstreamFlushBits(stream, stuffing_length);
+ BitstreamShowBits16(stream, stuffing_length, &code);
+ }
+
+ /* have we reached the end of the video packet or vop? */
+ if (shortVideoHeader)
+ {
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ if (!video->slice_structure)
+ {
+#endif
+ if (mbnum >= (int)(video->mbnum_row + 1)*video->nMBinGOB) /* 10/11/01 */
+ {
+ if (mbnum >= nTotalMB) return PV_SUCCESS;
+ status = BitstreamShowBits32(stream, GOB_RESYNC_MARKER_LENGTH, &tmpvar);
+
+ if (tmpvar == GOB_RESYNC_MARKER)
+ {
+ break;
+ }
+ else
+ {
+ status = PV_BitstreamShowBitsByteAlign(stream, GOB_RESYNC_MARKER_LENGTH, &tmpvar);
+ if (tmpvar == GOB_RESYNC_MARKER) break;
+ }
+ }
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ }
+ else
+ {
+
+ if (mbnum >= nTotalMB) /* in case no valid stuffing 06/23/01 */
+ {
+ valid_stuffing = validStuffing_h263(stream);
+ if (valid_stuffing == 0)
+ {
+ VideoDecoderErrorDetected(video);
+ ConcealPacket(video, mb_start, nTotalMB, slice_counter);
+ }
+ return PV_SUCCESS;
+ }
+ /* ANNEX_K */
+ PV_BitstreamShowBitsByteAlignNoForceStuffing(stream, 17, &tmpvar);
+ if (tmpvar == RESYNC_MARKER)
+ {
+ valid_stuffing = validStuffing_h263(stream);
+ if (valid_stuffing)
+ break; /* 06/21/01 */
+ }
+
+ }
+#endif
+ }
+ else
+ {
+ if (mbnum >= nTotalMB) /* in case no valid stuffing 06/23/01 */
+ {
+ /* 11/01/2002 if we are at the end of the frame and there is some garbage data
+ at the end of the frame (i.e. no next startcode) break if the stuffing is valid */
+ valid_stuffing = validStuffing(stream);
+ if (valid_stuffing == 0)
+ {
+ /* end 11/01/2002 */
+ VideoDecoderErrorDetected(video);
+ ConcealPacket(video, mb_start, nTotalMB, slice_counter);
+ }
+ PV_BitstreamByteAlign(stream);
+ return PV_SUCCESS;
+ }
+
+ status = PV_BitstreamShowBitsByteAlign(stream, 23, &tmpvar); /* this call is valid for f_code < 8 */
+ long_zero_bits = !tmpvar;
+
+ if ((tmpvar >> (23 - resync_marker_length)) == RESYNC_MARKER || long_zero_bits)
+ {
+ valid_stuffing = validStuffing(stream);
+ if (valid_stuffing)
+ break; /* 06/21/01 */
+ }
+
+ }
+ }
+ while (TRUE);
+
+ if (shortVideoHeader)
+ { /* We need to check newgob to refresh quantizer */
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ if (!video->slice_structure)
+ {
+#endif
+ while ((status = PV_GobHeader(video)) == PV_FAIL)
+ {
+ if ((status = quickSearchGOBHeader(stream)) != PV_SUCCESS)
+ {
+ break;
+ }
+ }
+
+ mbnum = currVop->gobNumber * video->nMBinGOB;
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ }
+ else
+ {
+ while ((status = PV_H263SliceHeader(video, &mbnum)) == PV_FAIL)
+ {
+ if ((status = quickSearchH263SliceHeader(stream)) != PV_SUCCESS)
+ {
+ break;
+ }
+ }
+ }
+
+#endif
+ }
+ else
+ {
+ while ((status = PV_ReadVideoPacketHeader(video, &mbnum)) == PV_FAIL)
+ {
+ if ((status = quickSearchVideoPacketHeader(stream, resync_marker_length)) != PV_SUCCESS)
+ {
+ break;
+ }
+ }
+ }
+
+ if (status == PV_END_OF_VOP)
+ {
+ mbnum = nTotalMB;
+ }
+
+ if (mbnum > video->mbnum + 1)
+ {
+ ConcealPacket(video, video->mbnum, mbnum, slice_counter);
+ }
+ QP = video->currVop->quantizer;
+ slice_counter++;
+ if (mbnum >= nTotalMB) break;
+
+ }
+ while (TRUE);
+ return PV_SUCCESS;
+}
+
+
+/* ============================================================================ */
+/* Function : GetMBHeader() */
+/* Purpose : Decode MB header, not_coded, mcbpc, ac_pred_flag, cbpy, dquant. */
+/* In/out : */
+/* Return : */
+/* Modified : */
+/* */
+/* 3/29/00 : Changed the returned value and optimized the code. */
+/* 4/01/01 : new ACDC prediction structure */
+/* ============================================================================ */
+PV_STATUS GetMBheader(VideoDecData *video, int16 *QP)
+{
+ BitstreamDecVideo *stream = video->bitstream;
+ int mbnum = video->mbnum;
+ uint8 *Mode = video->headerInfo.Mode;
+ int x_pos = video->mbnum_col;
+ typeDCStore *DC = video->predDC + mbnum;
+ typeDCACStore *DCAC_row = video->predDCAC_row + x_pos;
+ typeDCACStore *DCAC_col = video->predDCAC_col;
+ const static int16 DQ_tab[4] = { -1, -2, 1, 2};
+
+ int CBPY, CBPC;
+ int MBtype, VopType;
+ int MCBPC;
+ uint DQUANT;
+ int comp;
+ Bool mb_coded;
+
+ VopType = video->currVop->predictionType;
+ mb_coded = ((VopType == I_VOP) ? TRUE : !BitstreamRead1Bits_INLINE(stream));
+
+ if (!mb_coded)
+ {
+ /* skipped macroblock */
+ Mode[mbnum] = MODE_SKIPPED;
+ //oscl_memset(DCAC_row, 0, sizeof(typeDCACStore)); /* SKIPPED_ACDC */
+ //oscl_memset(DCAC_col, 0, sizeof(typeDCACStore));
+ ZERO_OUT_64BYTES(DCAC_row);
+ ZERO_OUT_64BYTES(DCAC_col); /* 08/12/05 */
+
+ for (comp = 0; comp < 6; comp++)
+ {
+ (*DC)[comp] = mid_gray;
+ }
+ }
+ else
+ {
+ /* coded macroblock */
+ if (VopType == I_VOP)
+ {
+ MCBPC = PV_VlcDecMCBPC_com_intra(stream);
+ }
+ else
+ {
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ if (!video->deblocking)
+ {
+ MCBPC = PV_VlcDecMCBPC_com_inter(stream);
+ }
+ else
+ {
+ MCBPC = PV_VlcDecMCBPC_com_inter_H263(stream);
+ }
+#else
+ MCBPC = PV_VlcDecMCBPC_com_inter(stream);
+#endif
+ }
+
+ if (VLC_ERROR_DETECTED(MCBPC))
+ {
+ return PV_FAIL;
+ }
+
+ Mode[mbnum] = (uint8)(MBtype = MBtype_mode[MCBPC & 7]);
+ CBPC = (MCBPC >> 4) & 3;
+
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ if (MBtype & INTRA_MASK)
+ {
+ if (!video->shortVideoHeader)
+ {
+ video->acPredFlag[mbnum] = (uint8) BitstreamRead1Bits(stream);
+ }
+ else
+ {
+ if (video->advanced_INTRA)
+ {
+ if (!BitstreamRead1Bits(stream))
+ {
+ video->acPredFlag[mbnum] = 0;
+ }
+ else
+ {
+ video->acPredFlag[mbnum] = 1;
+ if (BitstreamRead1Bits(stream))
+ {
+ video->mblock->direction = 0;
+ }
+ else
+ {
+ video->mblock->direction = 1;
+ }
+ }
+ }
+ else
+ {
+ video->acPredFlag[mbnum] = 0;
+ }
+ }
+ }
+#else
+ if ((MBtype & INTRA_MASK) && !video->shortVideoHeader)
+ {
+ video->acPredFlag[mbnum] = (uint8) BitstreamRead1Bits_INLINE(stream);
+ }
+ else
+ {
+ video->acPredFlag[mbnum] = 0;
+ }
+#endif
+ CBPY = PV_VlcDecCBPY(stream, MBtype & INTRA_MASK); /* INTRA || INTRA_Q */
+ if (CBPY < 0)
+ {
+ return PV_FAIL;
+ }
+
+ // GW 04/23/99
+ video->headerInfo.CBP[mbnum] = (uint8)(CBPY << 2 | (CBPC & 3));
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ if (MBtype & Q_MASK)
+ {
+ if (!video->modified_quant)
+ {
+ DQUANT = BitstreamReadBits16(stream, 2);
+ *QP += DQ_tab[DQUANT];
+
+ if (*QP < 1) *QP = 1;
+ else if (*QP > 31) *QP = 31;
+ video->QP_CHR = *QP; /* ANNEX_T */
+ }
+ else
+ {
+ if (BitstreamRead1Bits(stream))
+ {
+ if (BitstreamRead1Bits(stream))
+ {
+ *QP += DQ_tab_Annex_T_11[*QP];
+ }
+ else
+ {
+ *QP += DQ_tab_Annex_T_10[*QP];
+ }
+ if (*QP < 1) *QP = 1;
+ else if (*QP > 31) *QP = 31;
+ }
+ else
+ {
+ *QP = (int16)BitstreamReadBits16(stream, 5);
+ }
+ video->QP_CHR = MQ_chroma_QP_table[*QP];
+ }
+ }
+#else
+ if (MBtype & Q_MASK)
+ {
+ DQUANT = BitstreamReadBits16(stream, 2);
+ *QP += DQ_tab[DQUANT];
+
+ if (*QP < 1) *QP = 1;
+ else if (*QP > 31) *QP = 31;
+ }
+#endif
+ }
+ return PV_SUCCESS;
+}
+
+
+
+
+
+/***********************************************************CommentBegin******
+* 3/10/00 : initial modification to the
+* new PV-Decoder Lib format.
+* 4/2/2000 : Cleanup and error-handling modification. This
+* function has been divided into several sub-functions for
+* better coding style and maintainance reason. I also
+* greatly shrunk the code size here.
+* 9/18/2000 : VlcDecode+Dequant optimization *
+* 4/01/2001 : new ACDC prediction structure
+* 3/29/2002 : removed GetIntraMB and GetInterMB
+***********************************************************CommentEnd********/
+PV_STATUS GetMBData(VideoDecData *video)
+{
+ BitstreamDecVideo *stream = video->bitstream;
+ int mbnum = video->mbnum;
+ MacroBlock *mblock = video->mblock;
+ int16 *dataBlock;
+ PIXEL *c_comp;
+ uint mode = video->headerInfo.Mode[mbnum];
+ uint CBP = video->headerInfo.CBP[mbnum];
+ typeDCStore *DC = video->predDC + mbnum;
+ int intra_dc_vlc_thr = video->currVop->intraDCVlcThr;
+ int16 QP = video->QPMB[mbnum];
+ int16 QP_tmp = QP;
+ int width = video->width;
+ int comp;
+ int switched;
+ int ncoeffs[6] = {0, 0, 0, 0, 0, 0};
+ int *no_coeff = mblock->no_coeff;
+ int16 DC_coeff;
+ PV_STATUS status;
+
+#ifdef PV_POSTPROC_ON
+ /* post-processing */
+ uint8 *pp_mod[6];
+ int TotalMB = video->nTotalMB;
+ int MB_in_width = video->nMBPerRow;
+#endif
+ int y_pos = video->mbnum_row;
+ int x_pos = video->mbnum_col;
+ int32 offset = (int32)(y_pos << 4) * width + (x_pos << 4);
+
+ /* Decode each 8-by-8 blocks. comp 0 ~ 3 are luminance blocks, 4 ~ 5 */
+ /* are chrominance blocks. 04/03/2000. */
+#ifdef PV_POSTPROC_ON
+ if (video->postFilterType != PV_NO_POST_PROC)
+ {
+ /** post-processing ***/
+ pp_mod[0] = video->pstprcTypCur + (y_pos << 1) * (MB_in_width << 1) + (x_pos << 1);
+ pp_mod[1] = pp_mod[0] + 1;
+ pp_mod[2] = pp_mod[0] + (MB_in_width << 1);
+ pp_mod[3] = pp_mod[2] + 1;
+ pp_mod[4] = video->pstprcTypCur + (TotalMB << 2) + mbnum;
+ pp_mod[5] = pp_mod[4] + TotalMB;
+ }
+#endif
+
+ /* oscl_memset(mblock->block, 0, sizeof(typeMBStore)); Aug 9,2005 */
+
+ if (mode & INTRA_MASK) /* MODE_INTRA || MODE_INTRA_Q */
+ {
+ switched = 0;
+ if (intra_dc_vlc_thr)
+ {
+ if (video->usePrevQP)
+ QP_tmp = video->QPMB[mbnum-1]; /* running QP 04/26/01 */
+
+ switched = (intra_dc_vlc_thr == 7 || QP_tmp >= intra_dc_vlc_thr * 2 + 11);
+ }
+
+ mblock->DCScalarLum = cal_dc_scaler(QP, LUMINANCE_DC_TYPE); /* 3/01/01 */
+ mblock->DCScalarChr = cal_dc_scaler(QP, CHROMINANCE_DC_TYPE);
+
+ for (comp = 0; comp < 6; comp++)
+ {
+ dataBlock = mblock->block[comp]; /* 10/20/2000 */
+
+ if (video->shortVideoHeader)
+ {
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ if (!video->advanced_INTRA)
+ {
+#endif
+ DC_coeff = (int16) BitstreamReadBits16_INLINE(stream, 8);
+
+ if ((DC_coeff & 0x7f) == 0) /* 128 & 0 */
+ {
+ /* currently we will only signal FAIL for 128. We will ignore the 0 case */
+ if (DC_coeff == 128)
+ {
+ return PV_FAIL;
+ }
+ else
+ {
+ VideoDecoderErrorDetected(video);
+ }
+ }
+ if (DC_coeff == 255)
+ {
+ DC_coeff = 128;
+ }
+ dataBlock[0] = (int16) DC_coeff;
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ }
+#endif
+ ncoeffs[comp] = VlcDequantH263IntraBlock_SH(video, comp, mblock->bitmapcol[comp], &mblock->bitmaprow[comp]);
+
+ }
+ else
+ {
+ if (switched == 0)
+ {
+ status = PV_DecodePredictedIntraDC(comp, stream, &DC_coeff);
+ if (status != PV_SUCCESS) return PV_FAIL;
+
+ dataBlock[0] = (int16) DC_coeff;
+ }
+ ncoeffs[comp] = VlcDequantH263IntraBlock(video, comp,
+ switched, mblock->bitmapcol[comp], &mblock->bitmaprow[comp]);
+ }
+
+ if (VLC_ERROR_DETECTED(ncoeffs[comp]))
+ {
+ if (switched)
+ return PV_FAIL;
+ else
+ {
+ ncoeffs[comp] = 1;
+ oscl_memset((dataBlock + 1), 0, sizeof(int16)*63);
+ }
+ }
+ no_coeff[comp] = ncoeffs[comp];
+
+#ifdef PV_POSTPROC_ON
+ if (video->postFilterType != PV_NO_POST_PROC)
+ *pp_mod[comp] = (uint8) PostProcSemaphore(dataBlock);
+#endif
+ }
+ MBlockIDCT(video);
+ }
+ else /* INTER modes */
+ { /* moved it here Aug 15, 2005 */
+ /* decode the motion vector (if there are any) */
+ status = PV_GetMBvectors(video, mode);
+ if (status != PV_SUCCESS)
+ {
+ return status;
+ }
+
+
+ MBMotionComp(video, CBP);
+ c_comp = video->currVop->yChan + offset;
+
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ for (comp = 0; comp < 4; comp++)
+ {
+ (*DC)[comp] = mid_gray;
+ if (CBP & (1 << (5 - comp)))
+ {
+ ncoeffs[comp] = VlcDequantH263InterBlock(video, comp, mblock->bitmapcol[comp], &mblock->bitmaprow[comp]);
+ if (VLC_ERROR_DETECTED(ncoeffs[comp])) return PV_FAIL;
+
+ BlockIDCT(c_comp + (comp&2)*(width << 2) + 8*(comp&1), mblock->pred_block + (comp&2)*64 + 8*(comp&1), mblock->block[comp], width, ncoeffs[comp],
+ mblock->bitmapcol[comp], mblock->bitmaprow[comp]);
+
+#ifdef PV_POSTPROC_ON
+ /* for inter just test for ringing */
+ if (video->postFilterType != PV_NO_POST_PROC)
+ *pp_mod[comp] = (uint8)((ncoeffs[comp] > 3) ? 4 : 0);
+#endif
+ }
+ else
+ {
+ /* no IDCT for all zeros blocks 03/28/2002 */
+ /* BlockIDCT(); */
+#ifdef PV_POSTPROC_ON
+ if (video->postFilterType != PV_NO_POST_PROC)
+ *pp_mod[comp] = 0;
+#endif
+ }
+ }
+
+ video->QPMB[mbnum] = video->QP_CHR; /* ANNEX_T */
+
+
+
+ (*DC)[4] = mid_gray;
+ if (CBP & 2)
+ {
+ ncoeffs[4] = VlcDequantH263InterBlock(video, 4, mblock->bitmapcol[4], &mblock->bitmaprow[4]);
+ if (VLC_ERROR_DETECTED(ncoeffs[4])) return PV_FAIL;
+
+ BlockIDCT(video->currVop->uChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 256, mblock->block[4], width >> 1, ncoeffs[4],
+ mblock->bitmapcol[4], mblock->bitmaprow[4]);
+
+#ifdef PV_POSTPROC_ON
+ /* for inter just test for ringing */
+ if (video->postFilterType != PV_NO_POST_PROC)
+ *pp_mod[4] = (uint8)((ncoeffs[4] > 3) ? 4 : 0);
+#endif
+ }
+ else
+ {
+ /* no IDCT for all zeros blocks 03/28/2002 */
+ /* BlockIDCT(); */
+#ifdef PV_POSTPROC_ON
+ if (video->postFilterType != PV_NO_POST_PROC)
+ *pp_mod[4] = 0;
+#endif
+ }
+ (*DC)[5] = mid_gray;
+ if (CBP & 1)
+ {
+ ncoeffs[5] = VlcDequantH263InterBlock(video, 5, mblock->bitmapcol[5], &mblock->bitmaprow[5]);
+ if (VLC_ERROR_DETECTED(ncoeffs[5])) return PV_FAIL;
+
+ BlockIDCT(video->currVop->vChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 264, mblock->block[5], width >> 1, ncoeffs[5],
+ mblock->bitmapcol[5], mblock->bitmaprow[5]);
+
+#ifdef PV_POSTPROC_ON
+ /* for inter just test for ringing */
+ if (video->postFilterType != PV_NO_POST_PROC)
+ *pp_mod[5] = (uint8)((ncoeffs[5] > 3) ? 4 : 0);
+#endif
+ }
+ else
+ {
+ /* no IDCT for all zeros blocks 03/28/2002 */
+ /* BlockIDCT(); */
+#ifdef PV_POSTPROC_ON
+ if (video->postFilterType != PV_NO_POST_PROC)
+ *pp_mod[5] = 0;
+#endif
+ }
+ video->QPMB[mbnum] = QP; /* restore the QP values ANNEX_T*/
+#else
+ for (comp = 0; comp < 4; comp++)
+ {
+ (*DC)[comp] = mid_gray;
+ if (CBP & (1 << (5 - comp)))
+ {
+ ncoeffs[comp] = VlcDequantH263InterBlock(video, comp, mblock->bitmapcol[comp], &mblock->bitmaprow[comp]);
+ if (VLC_ERROR_DETECTED(ncoeffs[comp])) return PV_FAIL;
+
+ BlockIDCT(c_comp + (comp&2)*(width << 2) + 8*(comp&1), mblock->pred_block + (comp&2)*64 + 8*(comp&1), mblock->block[comp], width, ncoeffs[comp],
+ mblock->bitmapcol[comp], mblock->bitmaprow[comp]);
+
+#ifdef PV_POSTPROC_ON
+ /* for inter just test for ringing */
+ if (video->postFilterType != PV_NO_POST_PROC)
+ *pp_mod[comp] = (uint8)((ncoeffs[comp] > 3) ? 4 : 0);
+#endif
+ }
+ else
+ {
+ /* no IDCT for all zeros blocks 03/28/2002 */
+ /* BlockIDCT(); */
+#ifdef PV_POSTPROC_ON
+ if (video->postFilterType != PV_NO_POST_PROC)
+ *pp_mod[comp] = 0;
+#endif
+ }
+ }
+
+ (*DC)[4] = mid_gray;
+ if (CBP & 2)
+ {
+ ncoeffs[4] = VlcDequantH263InterBlock(video, 4, mblock->bitmapcol[4], &mblock->bitmaprow[4]);
+ if (VLC_ERROR_DETECTED(ncoeffs[4])) return PV_FAIL;
+
+ BlockIDCT(video->currVop->uChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 256, mblock->block[4], width >> 1, ncoeffs[4],
+ mblock->bitmapcol[4], mblock->bitmaprow[4]);
+
+#ifdef PV_POSTPROC_ON
+ /* for inter just test for ringing */
+ if (video->postFilterType != PV_NO_POST_PROC)
+ *pp_mod[4] = (uint8)((ncoeffs[4] > 3) ? 4 : 0);
+#endif
+ }
+ else
+ {
+ /* no IDCT for all zeros blocks 03/28/2002 */
+ /* BlockIDCT(); */
+#ifdef PV_POSTPROC_ON
+ if (video->postFilterType != PV_NO_POST_PROC)
+ *pp_mod[4] = 0;
+#endif
+ }
+ (*DC)[5] = mid_gray;
+ if (CBP & 1)
+ {
+ ncoeffs[5] = VlcDequantH263InterBlock(video, 5, mblock->bitmapcol[5], &mblock->bitmaprow[5]);
+ if (VLC_ERROR_DETECTED(ncoeffs[5])) return PV_FAIL;
+
+ BlockIDCT(video->currVop->vChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 264, mblock->block[5], width >> 1, ncoeffs[5],
+ mblock->bitmapcol[5], mblock->bitmaprow[5]);
+
+#ifdef PV_POSTPROC_ON
+ /* for inter just test for ringing */
+ if (video->postFilterType != PV_NO_POST_PROC)
+ *pp_mod[5] = (uint8)((ncoeffs[5] > 3) ? 4 : 0);
+#endif
+ }
+ else
+ {
+ /* no IDCT for all zeros blocks 03/28/2002 */
+ /* BlockIDCT(); */
+#ifdef PV_POSTPROC_ON
+ if (video->postFilterType != PV_NO_POST_PROC)
+ *pp_mod[5] = 0;
+#endif
+#endif // PV_ANNEX_IJKT_SUPPORT
+
+
+
+
+
+
+ }
+
+ video->usePrevQP = 1; /* should be set after decoding the first Coded 04/27/01 */
+ return PV_SUCCESS;
+}
+
+
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/conceal.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/conceal.cpp
new file mode 100644
index 0000000..e9ead01
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/conceal.cpp
@@ -0,0 +1,193 @@
+/* ------------------------------------------------------------------
+ * 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 "mp4dec_lib.h" /* video decoder function prototypes */
+#include "vlc_decode.h"
+#include "bitstream.h"
+#include "scaling.h"
+
+/* ====================================================================== /
+Function : ConcealTexture_I()
+Date : 06/12/2001
+Purpose : Conceal texture for I-partition
+In/out :
+Return :
+Modified :
+/ ====================================================================== */
+void ConcealTexture_I(VideoDecData *video, int32 startFirstPartition, int mb_start, int mb_stop, int slice_counter)
+{
+ int mbnum;
+ BitstreamDecVideo *stream = video->bitstream;
+ int16 QP;
+ int intra_dc_vlc_thr = video->currVop->intraDCVlcThr;
+
+ movePointerTo(stream, startFirstPartition);
+
+ video->usePrevQP = 0;
+ for (mbnum = mb_start; mbnum < mb_stop; mbnum++)
+ {
+ video->mbnum = mbnum;
+ video->mbnum_row = PV_GET_ROW(mbnum, video->nMBPerRow);
+ video->mbnum_col = mbnum - video->mbnum_row * video->nMBPerRow;
+ video->sliceNo[mbnum] = (uint8) slice_counter;
+ QP = video->QPMB[mbnum];
+ PV_VlcDecMCBPC_com_intra(stream);
+ GetMBheaderDataPart_DQUANT_DC(video, &QP);
+
+ if (intra_dc_vlc_thr)
+ {
+ if (video->usePrevQP)
+ QP = video->QPMB[mbnum-1];
+ if (intra_dc_vlc_thr == 7 || QP >= intra_dc_vlc_thr*2 + 11) /* if switched then conceal from previous frame */
+ {
+ ConcealPacket(video, mbnum, mb_stop, slice_counter);
+ video->mbnum = mb_stop - 1;
+ video->mbnum_row = PV_GET_ROW(video->mbnum, video->nMBPerRow);
+ video->mbnum_col = video->mbnum - video->mbnum_row * video->nMBPerRow;
+ break;
+ }
+ }
+
+ video->headerInfo.CBP[mbnum] = 0;
+ video->acPredFlag[mbnum] = 0;
+ GetMBData_DataPart(video);
+ video->usePrevQP = 1;
+ }
+ return;
+}
+
+/* ====================================================================== /
+Function : ConcealTexture_P()
+Date : 05/16/2000
+Purpose : Conceal texture for P-partition
+In/out :
+Return :
+/ ====================================================================== */
+
+void ConcealTexture_P(VideoDecData *video, int mb_start, int mb_stop, int slice_counter)
+{
+ int mbnum;
+
+ for (mbnum = mb_start; mbnum < mb_stop; mbnum++)
+ {
+ video->mbnum = mbnum;
+ video->mbnum_row = PV_GET_ROW(mbnum, video->nMBPerRow);
+ video->mbnum_col = mbnum - video->mbnum_row * video->nMBPerRow;
+ video->sliceNo[mbnum] = (uint8) slice_counter;
+ oscl_memset(video->mblock->block, 0, sizeof(typeMBStore));
+ /* to get rid of dark region caused by INTRA blocks */
+ /* 05/19/2000 */
+ if (video->headerInfo.Mode[mbnum] & INTER_MASK)
+ {
+ MBMotionComp(video, 0);
+ }
+ else
+ {
+ video->headerInfo.Mode[mbnum] = MODE_SKIPPED;
+ SkippedMBMotionComp(video);
+ }
+ }
+
+ return;
+}
+
+/***************************************************************
+Function: ConcealPacket
+Purpose : Conceal motion and texture of a packet by direct
+copying from previous frame.
+Returned: void
+Modified:
+*************************************************************/
+void ConcealPacket(VideoDecData *video,
+ int mb_start,
+ int mb_stop,
+ int slice_counter)
+{
+ int i;
+ for (i = mb_start; i < mb_stop; i++)
+ {
+ CopyVopMB(video->currVop, video->concealFrame, i, video->width, video->height);
+ video->sliceNo[i] = (uint8) slice_counter;
+ video->headerInfo.Mode[i] = MODE_SKIPPED;
+ }
+
+ return;
+}
+
+/****************************************************************************
+Function: CopyVopMB
+Purpose : Fill a macroblock with previous Vop.
+Returned : void
+Modified: 6/04/2001 rewrote the function
+ copies from concealFrame
+****************************************************************************/
+void CopyVopMB(Vop *curr, uint8 *prevFrame, int mbnum, int width_Y, int height)
+{
+ int width_C = width_Y >> 1;
+ int row = MB_SIZE;
+ uint8 *y1, *y2, *u1, *u2, *v1, *v2;
+ int xpos, ypos, MB_in_width;
+ int32 lumstart, chrstart, size;
+
+ MB_in_width = (width_Y + 15) >> 4;
+ ypos = PV_GET_ROW(mbnum, MB_in_width);
+ xpos = mbnum - ypos * MB_in_width;
+ lumstart = (ypos << 4) * (int32)width_Y + (xpos << 4);
+ chrstart = (ypos << 3) * (int32)width_C + (xpos << 3);
+
+ size = (int32)height * width_Y;
+
+ y1 = curr->yChan + lumstart;
+ u1 = curr->uChan + chrstart;
+ v1 = curr->vChan + chrstart;
+ y2 = prevFrame + lumstart;
+ u2 = prevFrame + size + chrstart;
+ v2 = prevFrame + size + (size >> 2) + chrstart;
+ while (row)
+ {
+ oscl_memcpy(y1, y2, MB_SIZE);
+ y1 += width_Y;
+ y2 += width_Y;
+ oscl_memcpy(y1, y2, MB_SIZE);
+ y1 += width_Y;
+ y2 += width_Y;
+ oscl_memcpy(y1, y2, MB_SIZE);
+ y1 += width_Y;
+ y2 += width_Y;
+ oscl_memcpy(y1, y2, MB_SIZE);
+ y1 += width_Y;
+ y2 += width_Y;
+
+ oscl_memcpy(u1, u2, B_SIZE);
+ u1 += width_C;
+ u2 += width_C;
+ oscl_memcpy(u1, u2, B_SIZE);
+ u1 += width_C;
+ u2 += width_C;
+
+ oscl_memcpy(v1, v2, B_SIZE);
+ v1 += width_C;
+ v2 += width_C;
+ oscl_memcpy(v1, v2, B_SIZE);
+ v1 += width_C;
+ v2 += width_C;
+
+ row -= 4;
+ }
+ return;
+} /* CopyVopMB */
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/datapart_decode.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/datapart_decode.cpp
new file mode 100644
index 0000000..00db04b
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/datapart_decode.cpp
@@ -0,0 +1,794 @@
+/* ------------------------------------------------------------------
+ * 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 "mp4dec_lib.h"
+#include "vlc_decode.h"
+#include "bitstream.h"
+#include "scaling.h"
+#include "mbtype_mode.h"
+#include "idct.h"
+
+#define OSCL_DISABLE_WARNING_CONDITIONAL_IS_CONSTANT
+/* ======================================================================== */
+/* Function : DecodeFrameDataPartMode() */
+/* Purpose : Decode a frame of MPEG4 bitstream in datapartitioning mode. */
+/* In/out : */
+/* Return : */
+/* Modified : */
+/* */
+/* 04/25/2000 : Rewrite the data partitioning path completely */
+/* according to the pseudo codes in MPEG-4 */
+/* standard. */
+/* Modified : 09/18/2000 add fast VlcDecode+Dequant */
+/* 04/17/2001 cleanup */
+/* ======================================================================== */
+PV_STATUS DecodeFrameDataPartMode(VideoDecData *video)
+{
+ PV_STATUS status;
+ Vop *currVop = video->currVop;
+ BitstreamDecVideo *stream = video->bitstream;
+
+ int nMBPerRow = video->nMBPerRow;
+
+ int vopType = currVop->predictionType;
+ int mbnum;
+ int nTotalMB = video->nTotalMB;
+ int slice_counter;
+ int resync_marker_length;
+
+ /* copy and pad to prev_Vop for INTER coding */
+ switch (vopType)
+ {
+ case I_VOP :
+// oscl_memset(Mode, MODE_INTRA, sizeof(uint8)*nTotalMB);
+ resync_marker_length = 17;
+ break;
+ case P_VOP :
+ oscl_memset(video->motX, 0, sizeof(MOT)*4*nTotalMB);
+ oscl_memset(video->motY, 0, sizeof(MOT)*4*nTotalMB);
+// oscl_memset(Mode, MODE_INTER, sizeof(uint8)*nTotalMB);
+ resync_marker_length = 16 + currVop->fcodeForward;
+ break;
+ default :
+ mp4dec_log("DecodeFrameDataPartMode(): Vop type not supported.\n");
+ return PV_FAIL;
+ }
+
+ /** Initialize sliceNo ***/
+ mbnum = slice_counter = 0;
+// oscl_memset(video->sliceNo, 0, sizeof(uint8)*nTotalMB);
+
+ do
+ {
+ /* This section is equivalent to motion_shape_texture() */
+ /* in the MPEG-4 standard. 04/13/2000 */
+ video->mbnum = mbnum;
+ video->mbnum_row = PV_GET_ROW(mbnum, nMBPerRow); /* This is needed if nbnum is read from the packet header */
+ video->mbnum_col = mbnum - video->mbnum_row * nMBPerRow;
+
+ switch (vopType)
+ {
+ case I_VOP :
+ status = DecodeDataPart_I_VideoPacket(video, slice_counter);
+ break;
+
+ case P_VOP :
+ status = DecodeDataPart_P_VideoPacket(video, slice_counter);
+ break;
+
+ default :
+ mp4dec_log("DecodeFrameDataPartMode(): Vop type not supported.\n");
+ return PV_FAIL;
+ }
+
+ while ((status = PV_ReadVideoPacketHeader(video, &mbnum)) == PV_FAIL)
+ {
+ if ((status = quickSearchVideoPacketHeader(stream, resync_marker_length)) != PV_SUCCESS)
+ {
+ break;
+ }
+ }
+
+ if (status == PV_END_OF_VOP)
+ {
+ mbnum = nTotalMB;
+ }
+
+ if (mbnum > video->mbnum + 1)
+ {
+ ConcealPacket(video, video->mbnum, mbnum, slice_counter);
+ }
+ slice_counter++;
+ if (mbnum >= nTotalMB)
+ {
+ break;
+ }
+
+
+ }
+ while (TRUE);
+
+ return PV_SUCCESS;
+}
+
+
+/* ======================================================================== */
+/* Function : DecodeDataPart_I_VideoPacket() */
+/* Date : 04/25/2000 */
+/* Purpose : Decode Data Partitioned Mode Video Packet in I-VOP */
+/* In/out : */
+/* Return : PV_SUCCESS if successed, PV_FAIL if failed. */
+/* Modified : 09/18/2000 add fast VlcDecode+Dequant */
+/* 04/01/2001 fixed MB_stuffing, removed unnecessary code */
+/* ======================================================================== */
+PV_STATUS DecodeDataPart_I_VideoPacket(VideoDecData *video, int slice_counter)
+{
+ PV_STATUS status;
+ uint8 *Mode = video->headerInfo.Mode;
+ BitstreamDecVideo *stream = video->bitstream;
+ int nTotalMB = video->nTotalMB;
+ int mbnum, mb_start, mb_end;
+ int16 QP, *QPMB = video->QPMB;
+ int MBtype, MCBPC, CBPY;
+ uint32 tmpvar;
+ uint code;
+ int nMBPerRow = video->nMBPerRow;
+ Bool valid_stuffing;
+ int32 startSecondPart, startFirstPart = getPointer(stream);
+
+ /* decode the first partition */
+ QP = video->currVop->quantizer;
+ mb_start = mbnum = video->mbnum;
+ video->usePrevQP = 0; /* 04/27/01 */
+
+
+ BitstreamShowBits16(stream, 9, &code);
+ while (code == 1)
+ {
+ PV_BitstreamFlushBits(stream, 9);
+ BitstreamShowBits16(stream, 9, &code);
+ }
+
+ do
+ {
+ /* decode COD, MCBPC, ACpred_flag, CPBY and DQUANT */
+ MCBPC = PV_VlcDecMCBPC_com_intra(stream);
+
+ if (!VLC_ERROR_DETECTED(MCBPC))
+ {
+ Mode[mbnum] = (uint8)(MBtype = MBtype_mode[MCBPC & 7]);
+ video->headerInfo.CBP[mbnum] = (uint8)((MCBPC >> 4) & 3);
+ status = GetMBheaderDataPart_DQUANT_DC(video, &QP);
+ video->usePrevQP = 1; /* set it after the first coded MB 04/27/01 */
+ }
+ else
+ {
+ /* Report the error to the application. 06/20/2000 */
+ VideoDecoderErrorDetected(video);
+ video->mbnum = mb_start;
+ movePointerTo(stream, startFirstPart);
+ return PV_FAIL;
+ }
+
+ video->sliceNo[mbnum] = (uint8) slice_counter;
+ QPMB[mbnum] = QP;
+ video->mbnum = ++mbnum;
+
+ BitstreamShowBits16(stream, 9, &code);
+ while (code == 1)
+ {
+ PV_BitstreamFlushBits(stream, 9);
+ BitstreamShowBits16(stream, 9, &code);
+ }
+ /* have we reached the end of the video packet or vop? */
+ status = BitstreamShowBits32(stream, DC_MARKER_LENGTH, &tmpvar);
+
+ }
+ while (tmpvar != DC_MARKER && video->mbnum < nTotalMB);
+
+ if (tmpvar == DC_MARKER)
+ {
+ PV_BitstreamFlushBits(stream, DC_MARKER_LENGTH);
+ }
+ else
+ {
+ status = quickSearchDCM(stream);
+ if (status == PV_SUCCESS)
+ {
+ /* only way you can end up being here is in the last packet,and there is stuffing at
+ the end of the first partition */
+ PV_BitstreamFlushBits(stream, DC_MARKER_LENGTH);
+ }
+ else
+ {
+ /* Report the error to the application. 06/20/2000 */
+ VideoDecoderErrorDetected(video);
+ movePointerTo(stream, startFirstPart);
+ video->mbnum = mb_start;
+ /* concealment will be taken care of in the upper layer */
+ return PV_FAIL;
+ }
+ }
+
+ /* decode the second partition */
+ startSecondPart = getPointer(stream);
+
+ mb_end = video->mbnum;
+
+ for (mbnum = mb_start; mbnum < mb_end; mbnum++)
+ {
+ MBtype = Mode[mbnum];
+ /* No skipped mode in I-packets 3/1/2001 */
+ video->mbnum = mbnum;
+
+ video->mbnum_row = PV_GET_ROW(mbnum, nMBPerRow); /* This is needed if nbnum is read from the packet header */
+ video->mbnum_col = mbnum - video->mbnum_row * nMBPerRow;
+ /* there is always acdcpred in DataPart mode 04/10/01 */
+ video->acPredFlag[mbnum] = (uint8) BitstreamRead1Bits(stream);
+
+ CBPY = PV_VlcDecCBPY(stream, MBtype & INTRA_MASK); /* MODE_INTRA || MODE_INTRA_Q */
+ if (CBPY < 0)
+ {
+ /* Report the error to the application. 06/20/2000 */
+ VideoDecoderErrorDetected(video);
+ movePointerTo(stream, startSecondPart); /* */
+ /* Conceal packet, 05/15/2000 */
+ ConcealTexture_I(video, startFirstPart, mb_start, mb_end, slice_counter);
+ return PV_FAIL;
+ }
+
+ video->headerInfo.CBP[mbnum] |= (uint8)(CBPY << 2);
+ }
+
+ video->usePrevQP = 0;
+
+ for (mbnum = mb_start; mbnum < mb_end; mbnum++)
+ {
+ video->mbnum = mbnum;
+
+ video->mbnum_row = PV_GET_ROW(mbnum , nMBPerRow); /* This is needed if nbnum is read from the packet header */
+ video->mbnum_col = mbnum - video->mbnum_row * nMBPerRow;
+ /* No skipped mode in I-packets 3/1/2001 */
+ /* decode the DCT coeficients for the MB */
+ status = GetMBData_DataPart(video);
+ if (status != PV_SUCCESS)
+ {
+ /* Report the error to the application. 06/20/2000 */
+ VideoDecoderErrorDetected(video);
+ movePointerTo(stream, startSecondPart); /* */
+ /* Conceal packet, 05/15/2000 */
+ ConcealTexture_I(video, startFirstPart, mb_start, mb_end, slice_counter);
+ return status;
+ }
+ video->usePrevQP = 1; /* 04/27/01 should be set after decoding first MB */
+ }
+
+ valid_stuffing = validStuffing(stream);
+ if (!valid_stuffing)
+ {
+ VideoDecoderErrorDetected(video);
+ movePointerTo(stream, startSecondPart);
+ ConcealTexture_I(video, startFirstPart, mb_start, mb_end, slice_counter);
+ return PV_FAIL;
+ }
+ return PV_SUCCESS;
+}
+
+
+/* ======================================================================== */
+/* Function : DecodeDataPart_P_VideoPacket() */
+/* Date : 04/25/2000 */
+/* Purpose : Decode Data Partitioned Mode Video Packet in P-VOP */
+/* In/out : */
+/* Return : PV_SUCCESS if successed, PV_FAIL if failed. */
+/* Modified : 09/18/2000, fast VlcDecode+Dequant */
+/* 04/13/2001, fixed MB_stuffing, new ACDC pred structure, */
+/* cleanup */
+/* 08/07/2001, remove MBzero */
+/* ======================================================================== */
+PV_STATUS DecodeDataPart_P_VideoPacket(VideoDecData *video, int slice_counter)
+{
+ PV_STATUS status;
+ uint8 *Mode = video->headerInfo.Mode;
+ BitstreamDecVideo *stream = video->bitstream;
+ int nTotalMB = video->nTotalMB;
+ int mbnum, mb_start, mb_end;
+ int16 QP, *QPMB = video->QPMB;
+ int MBtype, CBPY;
+ Bool valid_stuffing;
+ int intra_MB;
+ uint32 tmpvar;
+ uint code;
+ int32 startFirstPart, startSecondPart;
+ int nMBPerRow = video->nMBPerRow;
+ uint8 *pbyte;
+ /* decode the first partition */
+ startFirstPart = getPointer(stream);
+ mb_start = video->mbnum;
+ video->usePrevQP = 0; /* 04/27/01 */
+
+ BitstreamShowBits16(stream, 10, &code);
+ while (code == 1)
+ {
+ PV_BitstreamFlushBits(stream, 10);
+ BitstreamShowBits16(stream, 10, &code);
+ }
+
+ do
+ {
+ /* decode COD, MCBPC, ACpred_flag, CPBY and DQUANT */
+ /* We have to discard stuffed MB header */
+
+ status = GetMBheaderDataPart_P(video);
+
+ if (status != PV_SUCCESS)
+ {
+ /* Report the error to the application. 06/20/2000 */
+ VideoDecoderErrorDetected(video);
+ movePointerTo(stream, startFirstPart);
+ video->mbnum = mb_start;
+ return PV_FAIL;
+ }
+
+ /* we must update slice_counter before motion vector decoding. */
+ video->sliceNo[video->mbnum] = (uint8) slice_counter;
+
+ if (Mode[video->mbnum] & INTER_MASK) /* INTER || INTER_Q || INTER_4V */
+ {
+ /* decode the motion vector (if there are any) */
+ status = PV_GetMBvectors(video, Mode[video->mbnum]);
+ if (status != PV_SUCCESS)
+ {
+ /* Report the error to the application. 06/20/2000 */
+ VideoDecoderErrorDetected(video);
+ movePointerTo(stream, startFirstPart);
+ video->mbnum = mb_start;
+ return PV_FAIL;
+ }
+ }
+ video->mbnum++;
+
+ video->mbnum_row = PV_GET_ROW(video->mbnum, nMBPerRow); /* This is needed if mbnum is read from the packet header */
+ video->mbnum_col = video->mbnum - video->mbnum_row * nMBPerRow;
+
+ BitstreamShowBits16(stream, 10, &code);
+ while (code == 1)
+ {
+ PV_BitstreamFlushBits(stream, 10);
+ BitstreamShowBits16(stream, 10, &code);
+ }
+ /* have we reached the end of the video packet or vop? */
+ status = BitstreamShowBits32(stream, MOTION_MARKER_COMB_LENGTH, &tmpvar);
+ /* if (status != PV_SUCCESS && status != PV_END_OF_BUFFER) return status; */
+ }
+ while (tmpvar != MOTION_MARKER_COMB && video->mbnum < nTotalMB);
+
+ if (tmpvar == MOTION_MARKER_COMB)
+ {
+ PV_BitstreamFlushBits(stream, MOTION_MARKER_COMB_LENGTH);
+ }
+ else
+ {
+ status = quickSearchMotionMarker(stream);
+ if (status == PV_SUCCESS)
+ {
+ /* only way you can end up being here is in the last packet,and there is stuffing at
+ the end of the first partition */
+ PV_BitstreamFlushBits(stream, MOTION_MARKER_COMB_LENGTH);
+ }
+ else
+ {
+ /* Report the error to the application. 06/20/2000 */
+ VideoDecoderErrorDetected(video);
+ movePointerTo(stream, startFirstPart);
+ video->mbnum = mb_start;
+ /* concealment will be taken care of in the upper layer */
+ return PV_FAIL;
+ }
+ }
+
+ /* decode the second partition */
+ startSecondPart = getPointer(stream);
+ QP = video->currVop->quantizer;
+
+ mb_end = video->mbnum;
+
+ for (mbnum = mb_start; mbnum < mb_end; mbnum++)
+ {
+ MBtype = Mode[mbnum];
+
+ if (MBtype == MODE_SKIPPED)
+ {
+ QPMB[mbnum] = QP; /* 03/01/01 */
+ continue;
+ }
+ intra_MB = (MBtype & INTRA_MASK); /* (MBtype == MODE_INTRA || MBtype == MODE_INTRA_Q) */
+ video->mbnum = mbnum;
+ video->mbnum_row = PV_GET_ROW(mbnum, nMBPerRow); /* This is needed if nbnum is read from the packet header */
+ video->mbnum_col = mbnum - video->mbnum_row * nMBPerRow;
+
+ /* there is always acdcprediction in DataPart mode 04/10/01 */
+ if (intra_MB)
+ {
+ video->acPredFlag[mbnum] = (uint8) BitstreamRead1Bits_INLINE(stream);
+ }
+
+ CBPY = PV_VlcDecCBPY(stream, intra_MB);
+ if (CBPY < 0)
+ {
+ /* Report the error to the application. 06/20/2000 */
+ VideoDecoderErrorDetected(video);
+ /* Conceal second partition, 5/15/2000 */
+ movePointerTo(stream, startSecondPart);
+ ConcealTexture_P(video, mb_start, mb_end, slice_counter);
+ return PV_FAIL;
+ }
+
+ video->headerInfo.CBP[mbnum] |= (uint8)(CBPY << 2);
+ if (intra_MB || MBtype == MODE_INTER_Q) /* 04/26/01 */
+ {
+ status = GetMBheaderDataPart_DQUANT_DC(video, &QP);
+ if (status != PV_SUCCESS) return status;
+ }
+ video->usePrevQP = 1; /* 04/27/01 */
+ QPMB[mbnum] = QP;
+ }
+
+ video->usePrevQP = 0; /* 04/27/01 */
+
+ for (mbnum = mb_start; mbnum < mb_end; mbnum++)
+ {
+ video->mbnum = mbnum;
+ video->mbnum_row = PV_GET_ROW(mbnum, nMBPerRow); /* This is needed if nbnum is read from the packet header */
+ video->mbnum_col = mbnum - video->mbnum_row * nMBPerRow;
+
+
+ if (Mode[mbnum] != MODE_SKIPPED)
+ {
+ /* decode the DCT coeficients for the MB */
+ status = GetMBData_DataPart(video);
+ if (status != PV_SUCCESS)
+ {
+ /* Report the error to the application. 06/20/2000 */
+ VideoDecoderErrorDetected(video);
+
+ /* Conceal second partition, 5/15/2000 */
+ movePointerTo(stream, startSecondPart);
+ ConcealTexture_P(video, mb_start, mb_end, slice_counter);
+ return status;
+ }
+ video->usePrevQP = 1; /* 04/27/01 */
+ }
+ else
+ { // SKIPPED
+
+ /* Motion compensation and put it to video->mblock->pred_block */
+ SkippedMBMotionComp(video);
+
+ //oscl_memset(video->predDCAC_row + video->mbnum_col, 0, sizeof(typeDCACStore)); /* SKIPPED_ACDC */
+ //oscl_memset(video->predDCAC_col, 0, sizeof(typeDCACStore));
+ /* 08/08/2005 */
+ pbyte = (uint8*)(video->predDCAC_row + video->mbnum_col);
+ ZERO_OUT_64BYTES(pbyte);
+ pbyte = (uint8*)(video->predDCAC_col);
+ ZERO_OUT_64BYTES(pbyte);
+
+ }
+ }
+
+ valid_stuffing = validStuffing(stream); /* */
+ if (!valid_stuffing)
+ {
+ VideoDecoderErrorDetected(video);
+ movePointerTo(stream, startSecondPart); /* */
+ ConcealTexture_P(video, mb_start, mb_end, slice_counter);
+
+ return PV_FAIL;
+ }
+ return PV_SUCCESS;
+}
+
+
+/* ======================================================================== */
+/* Function : GetMBheaderDataPart_DQUANT_DC() */
+/* Date : 04/26/2000 */
+/* Purpose : Decode DQUANT and DC in Data Partitioned Mode for both */
+/* I-VOP and P-VOP. */
+/* In/out : */
+/* Return : PV_SUCCESS if successed, PV_FAIL if failed. */
+/* Modified : 02/13/2001 new ACDC prediction structure, */
+/* cleanup */
+/* ======================================================================== */
+PV_STATUS GetMBheaderDataPart_DQUANT_DC(VideoDecData *video, int16 *QP)
+{
+ PV_STATUS status = PV_SUCCESS;
+ BitstreamDecVideo *stream = video->bitstream;
+ int mbnum = video->mbnum;
+ int intra_dc_vlc_thr = video->currVop->intraDCVlcThr;
+ uint8 *Mode = video->headerInfo.Mode;
+ int MBtype = Mode[mbnum];
+ typeDCStore *DC = video->predDC + mbnum;
+ int comp;
+ Bool switched;
+ uint DQUANT;
+ int16 QP_tmp;
+
+ const static int DQ_tab[4] = { -1, -2, 1, 2};
+
+ if (MBtype & Q_MASK) /* INTRA_Q || INTER_Q */
+ {
+ DQUANT = BitstreamReadBits16(stream, 2);
+ *QP += DQ_tab[DQUANT];
+
+ if (*QP < 1) *QP = 1;
+ else if (*QP > 31) *QP = 31;
+ }
+ if (MBtype & INTRA_MASK) /* INTRA || INTRA_Q */ /* no switch, code DC separately */
+ {
+ QP_tmp = *QP; /* running QP 04/26/01*/
+ switched = 0;
+ if (intra_dc_vlc_thr) /* 04/27/01 */
+ {
+ if (video->usePrevQP)
+ QP_tmp = video->QPMB[mbnum-1];
+ switched = (intra_dc_vlc_thr == 7 || QP_tmp >= intra_dc_vlc_thr * 2 + 11);
+ }
+ if (!switched)
+ {
+ for (comp = 0; comp < 6; comp++)
+ {
+ status = PV_DecodePredictedIntraDC(comp, stream, (*DC + comp)); /* 03/01/01 */
+ if (status != PV_SUCCESS) return PV_FAIL;
+ }
+ }
+ else
+ {
+ for (comp = 0; comp < 6; comp++)
+ {
+ (*DC)[comp] = 0; /* 04/26/01 needed for switched case*/
+ }
+ }
+ }
+ return status;
+}
+
+
+/***********************************************************CommentBegin******
+* 04/25/2000 : Initial modification to the new PV Lib format.
+* 04/17/2001 : new ACDC pred structure
+***********************************************************CommentEnd********/
+PV_STATUS GetMBheaderDataPart_P(VideoDecData *video)
+{
+ BitstreamDecVideo *stream = video->bitstream;
+ int mbnum = video->mbnum;
+ uint8 *Mode = video->headerInfo.Mode;
+ typeDCStore *DC = video->predDC + mbnum;
+ uint no_dct_flag;
+ int comp;
+ int MCBPC;
+
+ no_dct_flag = BitstreamRead1Bits_INLINE(stream);
+
+ if (no_dct_flag)
+ {
+ /* skipped macroblock */
+ Mode[mbnum] = MODE_SKIPPED;
+
+ for (comp = 0; comp < 6; comp++)
+ {
+ (*DC)[comp] = mid_gray;
+ /* ACDC REMOVE AC coefs are set in DecodeDataPart_P */
+ }
+ }
+ else
+ {
+ /* coded macroblock */
+ MCBPC = PV_VlcDecMCBPC_com_inter(stream);
+
+ if (VLC_ERROR_DETECTED(MCBPC))
+ {
+ return PV_FAIL;
+ }
+
+ Mode[mbnum] = (uint8)MBtype_mode[MCBPC & 7];
+ video->headerInfo.CBP[mbnum] = (uint8)((MCBPC >> 4) & 3);
+ }
+
+ return PV_SUCCESS;
+}
+
+
+/***********************************************************CommentBegin******
+* 04/17/01 new ACDC pred structure, reorganized code, cleanup
+***********************************************************CommentEnd********/
+PV_STATUS GetMBData_DataPart(VideoDecData *video)
+{
+ int mbnum = video->mbnum;
+ int16 *dataBlock;
+ MacroBlock *mblock = video->mblock;
+ int QP = video->QPMB[mbnum];
+ int32 offset;
+ PIXEL *c_comp;
+ int width = video->width;
+ int intra_dc_vlc_thr = video->currVop->intraDCVlcThr;
+ uint CBP = video->headerInfo.CBP[mbnum];
+ uint8 mode = video->headerInfo.Mode[mbnum];
+ int x_pos = video->mbnum_col;
+ typeDCStore *DC = video->predDC + mbnum;
+ int ncoeffs[6], *no_coeff = mblock->no_coeff;
+ int comp;
+ Bool switched;
+ int QP_tmp = QP;
+
+ int y_pos = video->mbnum_row;
+#ifdef PV_POSTPROC_ON
+ uint8 *pp_mod[6];
+ int TotalMB = video->nTotalMB;
+ int MB_in_width = video->nMBPerRow;
+#endif
+
+
+
+ /*****
+ * Decoding of the 6 blocks (depending on transparent pattern)
+ *****/
+#ifdef PV_POSTPROC_ON
+ if (video->postFilterType != PV_NO_POST_PROC)
+ {
+ /** post-processing ***/
+ pp_mod[0] = video->pstprcTypCur + (y_pos << 1) * (MB_in_width << 1) + (x_pos << 1);
+ pp_mod[1] = pp_mod[0] + 1;
+ pp_mod[2] = pp_mod[0] + (MB_in_width << 1);
+ pp_mod[3] = pp_mod[2] + 1;
+ pp_mod[4] = video->pstprcTypCur + (TotalMB << 2) + mbnum;
+ pp_mod[5] = pp_mod[4] + TotalMB;
+ }
+#endif
+
+ /* oscl_memset(mblock->block, 0, sizeof(typeMBStore)); Aug 9,2005 */
+
+ if (mode & INTRA_MASK) /* MODE_INTRA || mode == MODE_INTRA_Q */
+ {
+ switched = 0;
+ if (intra_dc_vlc_thr)
+ {
+ if (video->usePrevQP)
+ QP_tmp = video->QPMB[mbnum-1]; /* running QP 04/26/01 */
+
+ switched = (intra_dc_vlc_thr == 7 || QP_tmp >= intra_dc_vlc_thr * 2 + 11);
+ }
+
+ mblock->DCScalarLum = cal_dc_scaler(QP, LUMINANCE_DC_TYPE); /* ACDC 03/01/01 */
+ mblock->DCScalarChr = cal_dc_scaler(QP, CHROMINANCE_DC_TYPE);
+
+ for (comp = 0; comp < 6; comp++)
+ {
+ dataBlock = mblock->block[comp]; /*, 10/20/2000 */
+
+ dataBlock[0] = (*DC)[comp];
+
+ ncoeffs[comp] = VlcDequantH263IntraBlock(video, comp,
+ switched, mblock->bitmapcol[comp], &mblock->bitmaprow[comp]);
+
+ if (VLC_ERROR_DETECTED(ncoeffs[comp])) /* */
+ {
+ if (switched)
+ return PV_FAIL;
+ else
+ {
+ ncoeffs[comp] = 1;
+ oscl_memset((dataBlock + 1), 0, sizeof(int16)*63);
+ }
+ }
+ no_coeff[comp] = ncoeffs[comp];
+ /* modified to new semaphore for post-proc */
+ // Future work:: can be combined in the dequant function
+ // @todo Deblocking Semaphore for INTRA block
+#ifdef PV_POSTPROC_ON
+ if (video->postFilterType != PV_NO_POST_PROC)
+ *pp_mod[comp] = (uint8) PostProcSemaphore(dataBlock);
+#endif
+ }
+ MBlockIDCT(video);
+ }
+ else /* MODE INTER*/
+ {
+
+
+
+
+ MBMotionComp(video, CBP);
+ offset = (int32)(y_pos << 4) * width + (x_pos << 4);
+ c_comp = video->currVop->yChan + offset;
+
+
+ for (comp = 0; comp < 4; comp++)
+ {
+ (*DC)[comp] = mid_gray;
+
+ if (CBP & (1 << (5 - comp)))
+ {
+ ncoeffs[comp] = VlcDequantH263InterBlock(video, comp,
+ mblock->bitmapcol[comp], &mblock->bitmaprow[comp]);
+ if (VLC_ERROR_DETECTED(ncoeffs[comp]))
+ return PV_FAIL;
+
+
+ BlockIDCT(c_comp + (comp&2)*(width << 2) + 8*(comp&1), mblock->pred_block + (comp&2)*64 + 8*(comp&1), mblock->block[comp], width, ncoeffs[comp],
+ mblock->bitmapcol[comp], mblock->bitmaprow[comp]);
+
+ }
+ else
+ {
+ ncoeffs[comp] = 0;
+ }
+
+ /* @todo Deblocking Semaphore for INTRA block, for inter just test for ringing */
+#ifdef PV_POSTPROC_ON
+ if (video->postFilterType != PV_NO_POST_PROC)
+ *pp_mod[comp] = (uint8)((ncoeffs[comp] > 3) ? 4 : 0);
+#endif
+ }
+
+ (*DC)[4] = mid_gray;
+ if (CBP & 2)
+ {
+ ncoeffs[4] = VlcDequantH263InterBlock(video, 4,
+ mblock->bitmapcol[4], &mblock->bitmaprow[4]);
+ if (VLC_ERROR_DETECTED(ncoeffs[4]))
+ return PV_FAIL;
+
+ BlockIDCT(video->currVop->uChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 256, mblock->block[4], width >> 1, ncoeffs[4],
+ mblock->bitmapcol[4], mblock->bitmaprow[4]);
+
+ }
+ else
+ {
+ ncoeffs[4] = 0;
+ }
+#ifdef PV_POSTPROC_ON
+ if (video->postFilterType != PV_NO_POST_PROC)
+ *pp_mod[4] = (uint8)((ncoeffs[4] > 3) ? 4 : 0);
+#endif
+ (*DC)[5] = mid_gray;
+ if (CBP & 1)
+ {
+ ncoeffs[5] = VlcDequantH263InterBlock(video, 5,
+ mblock->bitmapcol[5], &mblock->bitmaprow[5]);
+ if (VLC_ERROR_DETECTED(ncoeffs[5]))
+ return PV_FAIL;
+
+ BlockIDCT(video->currVop->vChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 264, mblock->block[5], width >> 1, ncoeffs[5],
+ mblock->bitmapcol[5], mblock->bitmaprow[5]);
+
+ }
+ else
+ {
+ ncoeffs[5] = 0;
+ }
+#ifdef PV_POSTPROC_ON
+ if (video->postFilterType != PV_NO_POST_PROC)
+ *pp_mod[5] = (uint8)((ncoeffs[5] > 3) ? 4 : 0);
+#endif
+
+
+
+
+ /* Motion compensation and put it to video->mblock->pred_block */
+ }
+ return PV_SUCCESS;
+}
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/dcac_prediction.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/dcac_prediction.cpp
new file mode 100644
index 0000000..2a8bf1e
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/dcac_prediction.cpp
@@ -0,0 +1,368 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "mp4dec_lib.h"
+#include "vlc_decode.h"
+#include "bitstream.h"
+#include "zigzag.h"
+#include "scaling.h"
+
+void doDCACPrediction(
+ VideoDecData *video,
+ int comp,
+ int16 *q_block,
+ int *direction
+)
+{
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int i;
+ int mbnum = video->mbnum;
+ int nMBPerRow = video->nMBPerRow;
+ int x_pos = video->mbnum_col;
+ int y_pos = video->mbnum_row;
+ int16 *AC_tmp;
+ int QP_tmp;
+ int16 *QP_store = video->QPMB + mbnum;
+ int QP = video->QPMB[mbnum];
+ int QP_half = QP >> 1;
+ int32 val;
+ int flag_0 = FALSE, flag_1 = FALSE;
+ uint8 *slice_nb = video->sliceNo;
+ typeDCStore *DC_store = video->predDC + mbnum;
+ typeDCACStore *DCAC_row = video->predDCAC_row + x_pos;
+ typeDCACStore *DCAC_col = video->predDCAC_col;
+
+ uint ACpred_flag = (uint) video->acPredFlag[mbnum];
+
+ int left_bnd, up_bnd;
+
+ static const int Xpos[6] = { -1, 0, -1, 0, -1, -1};
+ static const int Ypos[6] = { -1, -1, 0, 0, -1, -1};
+
+ static const int Xtab[6] = {1, 0, 3, 2, 4, 5};
+ static const int Ytab[6] = {2, 3, 0, 1, 4, 5};
+ static const int Ztab[6] = {3, 2, 1, 0, 4, 5};
+
+ /* I added these to speed up comparisons */
+ static const int Pos0[6] = { 1, 1, 0, 0, 1, 1};
+ static const int Pos1[6] = { 1, 0, 1, 0, 1, 1};
+
+ static const int B_Xtab[6] = {0, 1, 0, 1, 2, 3};
+ static const int B_Ytab[6] = {0, 0, 1, 1, 2, 3};
+
+// int *direction; /* 0: HORIZONTAL, 1: VERTICAL */
+ int block_A, block_B, block_C;
+ int DC_pred;
+ int y_offset, x_offset, x_tab, y_tab, z_tab; /* speedup coefficients */
+ int b_xtab, b_ytab;
+
+ if (!comp && x_pos && !(video->headerInfo.Mode[mbnum-1]&INTRA_MASK)) /* not intra */
+ {
+ oscl_memset(DCAC_col, 0, sizeof(typeDCACStore));
+ }
+ if (!comp && y_pos && !(video->headerInfo.Mode[mbnum-nMBPerRow]&INTRA_MASK)) /* not intra */
+ {
+ oscl_memset(DCAC_row, 0, sizeof(typeDCACStore));
+ }
+
+ y_offset = Ypos[comp] * nMBPerRow;
+ x_offset = Xpos[comp];
+ x_tab = Xtab[comp];
+ y_tab = Ytab[comp];
+ z_tab = Ztab[comp];
+
+ b_xtab = B_Xtab[comp];
+ b_ytab = B_Ytab[comp];
+
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ /* Find the direction of prediction and the DC prediction */
+
+ if (x_pos == 0 && y_pos == 0)
+ { /* top left corner */
+ block_A = (comp == 1 || comp == 3) ? flag_0 = TRUE, DC_store[0][x_tab] : mid_gray;
+ block_B = (comp == 3) ? DC_store[x_offset][z_tab] : mid_gray;
+ block_C = (comp == 2 || comp == 3) ? flag_1 = TRUE, DC_store[0][y_tab] : mid_gray;
+ }
+ else if (x_pos == 0)
+ { /* left edge */
+ up_bnd = Pos0[comp] && slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow];
+
+ block_A = (comp == 1 || comp == 3) ? flag_0 = TRUE, DC_store[0][x_tab] : mid_gray;
+ block_B = ((comp == 1 && up_bnd) || comp == 3) ? DC_store[y_offset+x_offset][z_tab] : mid_gray;
+ block_C = (comp == 2 || comp == 3 || up_bnd) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
+ }
+ else if (y_pos == 0)
+ { /* top row */
+ left_bnd = Pos1[comp] && slice_nb[mbnum] == slice_nb[mbnum-1];
+
+ block_A = (comp == 1 || comp == 3 || left_bnd) ? flag_0 = TRUE, DC_store[x_offset][x_tab] : mid_gray;
+ block_B = ((comp == 2 && left_bnd) || comp == 3) ? DC_store[y_offset + x_offset][z_tab] : mid_gray;
+ block_C = (comp == 2 || comp == 3) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
+ }
+ else
+ {
+ up_bnd = Pos0[comp] && slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow];
+ left_bnd = Pos1[comp] && slice_nb[mbnum] == slice_nb[mbnum-1];
+
+ block_A = (comp == 1 || comp == 3 || left_bnd) ? flag_0 = TRUE, DC_store[x_offset][x_tab] : mid_gray;
+ block_B = (((comp == 0 || comp == 4 || comp == 5) && slice_nb[mbnum] == slice_nb[mbnum-1-nMBPerRow]) ||
+ (comp == 1 && up_bnd) || (comp == 2 && left_bnd) || (comp == 3)) ? DC_store[y_offset+x_offset][z_tab] : mid_gray;
+ block_C = (comp == 2 || comp == 3 || up_bnd) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
+ }
+
+
+ if ((PV_ABS((block_A - block_B))) < (PV_ABS((block_B - block_C))))
+ {
+ DC_pred = block_C;
+ *direction = 1;
+ if (ACpred_flag == 1)
+ {
+ if (flag_1)
+ {
+ AC_tmp = DCAC_row[0][b_xtab];
+ QP_tmp = QP_store[y_offset];
+ if (QP_tmp == QP)
+ {
+ for (i = 1; i < 8; i++)
+ {
+ q_block[i] = *AC_tmp++;
+ }
+ }
+ else
+ {
+ for (i = 1; i < 8; i++)
+ {
+ val = (int32)(*AC_tmp++) * QP_tmp;
+ q_block[i] = (val < 0) ? (int16)((val - QP_half) / QP) : (int16)((val + QP_half) / QP);
+ /* Vertical, top ROW of block C */
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ DC_pred = block_A;
+ *direction = 0;
+ if (ACpred_flag == 1)
+ {
+ if (flag_0)
+ {
+ AC_tmp = DCAC_col[0][b_ytab];
+ QP_tmp = QP_store[x_offset];
+ if (QP_tmp == QP)
+ {
+ for (i = 1; i < 8; i++)
+ {
+ q_block[i<<3] = *AC_tmp++;
+ }
+ }
+ else
+ {
+ for (i = 1; i < 8; i++)
+ {
+ val = (int32)(*AC_tmp++) * QP_tmp;
+ q_block[i<<3] = (val < 0) ? (int16)((val - QP_half) / QP) : (int16)((val + QP_half) / QP);
+ /* Vertical, top ROW of block C */
+ }
+ }
+ }
+ }
+ }
+
+ /* Now predict the DC coefficient */
+ QP_tmp = (comp < 4) ? video->mblock->DCScalarLum : video->mblock->DCScalarChr;
+ q_block[0] += (int16)((DC_pred + (QP_tmp >> 1)) * scale[QP_tmp] >> 18);
+// q_block[0] += (DC_pred+(QP_tmp>>1))/QP_tmp;
+
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return;
+}
+#ifdef PV_ANNEX_IJKT_SUPPORT
+void doDCACPrediction_I(
+ VideoDecData *video,
+ int comp,
+ int16 *q_block
+)
+{
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int mbnum = video->mbnum;
+ int nMBPerRow = video->nMBPerRow;
+ int x_pos = video->mbnum_col;
+ int y_pos = video->mbnum_row;
+ int16 *AC_tmp;
+ int flag_0 = FALSE, flag_1 = FALSE;
+ uint8 *slice_nb = video->sliceNo;
+ typeDCStore *DC_store = video->predDC + mbnum;
+ typeDCACStore *DCAC_row = video->predDCAC_row + x_pos;
+ typeDCACStore *DCAC_col = video->predDCAC_col;
+ int left_bnd, up_bnd;
+ uint8 *mode = video->headerInfo.Mode;
+ uint ACpred_flag = (uint) video->acPredFlag[mbnum];
+
+
+
+ static const int Xpos[6] = { -1, 0, -1, 0, -1, -1};
+ static const int Ypos[6] = { -1, -1, 0, 0, -1, -1};
+
+ static const int Xtab[6] = {1, 0, 3, 2, 4, 5};
+ static const int Ytab[6] = {2, 3, 0, 1, 4, 5};
+
+ /* I added these to speed up comparisons */
+ static const int Pos0[6] = { 1, 1, 0, 0, 1, 1};
+ static const int Pos1[6] = { 1, 0, 1, 0, 1, 1};
+
+ static const int B_Xtab[6] = {0, 1, 0, 1, 2, 3};
+ static const int B_Ytab[6] = {0, 0, 1, 1, 2, 3};
+
+// int *direction; /* 0: HORIZONTAL, 1: VERTICAL */
+ int block_A, block_C;
+ int y_offset, x_offset, x_tab, y_tab; /* speedup coefficients */
+ int b_xtab, b_ytab;
+ y_offset = Ypos[comp] * nMBPerRow;
+ x_offset = Xpos[comp];
+ x_tab = Xtab[comp];
+ y_tab = Ytab[comp];
+
+ b_xtab = B_Xtab[comp];
+ b_ytab = B_Ytab[comp];
+
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ /* Find the direction of prediction and the DC prediction */
+
+ if (x_pos == 0 && y_pos == 0)
+ { /* top left corner */
+ block_A = (comp == 1 || comp == 3) ? flag_0 = TRUE, DC_store[0][x_tab] : mid_gray;
+ block_C = (comp == 2 || comp == 3) ? flag_1 = TRUE, DC_store[0][y_tab] : mid_gray;
+ }
+ else if (x_pos == 0)
+ { /* left edge */
+ up_bnd = (Pos0[comp] && slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow])
+ && (mode[mbnum-nMBPerRow] == MODE_INTRA || mode[mbnum-nMBPerRow] == MODE_INTRA_Q);;
+
+ block_A = (comp == 1 || comp == 3) ? flag_0 = TRUE, DC_store[0][x_tab] : mid_gray;
+ block_C = (comp == 2 || comp == 3 || up_bnd) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
+ }
+ else if (y_pos == 0)
+ { /* top row */
+ left_bnd = (Pos1[comp] && slice_nb[mbnum] == slice_nb[mbnum-1])
+ && (mode[mbnum-1] == MODE_INTRA || mode[mbnum-1] == MODE_INTRA_Q);
+
+ block_A = (comp == 1 || comp == 3 || left_bnd) ? flag_0 = TRUE, DC_store[x_offset][x_tab] : mid_gray;
+ block_C = (comp == 2 || comp == 3) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
+ }
+ else
+ {
+ up_bnd = (Pos0[comp] && slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow])
+ && (mode[mbnum-nMBPerRow] == MODE_INTRA || mode[mbnum-nMBPerRow] == MODE_INTRA_Q);
+ left_bnd = (Pos1[comp] && slice_nb[mbnum] == slice_nb[mbnum-1])
+ && (mode[mbnum-1] == MODE_INTRA || mode[mbnum-1] == MODE_INTRA_Q);
+
+ block_A = (comp == 1 || comp == 3 || left_bnd) ? flag_0 = TRUE, DC_store[x_offset][x_tab] : mid_gray;
+ block_C = (comp == 2 || comp == 3 || up_bnd) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
+ }
+
+ if (ACpred_flag == 0)
+ {
+ if (flag_0 == TRUE)
+ {
+ if (flag_1 == TRUE)
+ {
+ q_block[0] = (int16)((block_A + block_C) >> 1);
+ }
+ else
+ {
+ q_block[0] = (int16)block_A;
+ }
+ }
+ else
+ {
+ if (flag_1 == TRUE)
+ {
+ q_block[0] = (int16)block_C;
+ }
+ else
+ {
+ q_block[0] = mid_gray;
+ }
+ }
+
+ }
+ else
+ {
+ if (video->mblock->direction == 1)
+ {
+ if (flag_1 == TRUE)
+ {
+ q_block[0] = (int16)block_C;
+
+ AC_tmp = DCAC_row[0][b_xtab];
+ q_block[1] = AC_tmp[0];
+ q_block[2] = AC_tmp[1];
+ q_block[3] = AC_tmp[2];
+ q_block[4] = AC_tmp[3];
+ q_block[5] = AC_tmp[4];
+ q_block[6] = AC_tmp[5];
+ q_block[7] = AC_tmp[6];
+ }
+ else
+ {
+ q_block[0] = mid_gray;
+ }
+ }
+ else
+ {
+ if (flag_0 == TRUE)
+ {
+ q_block[0] = (int16)block_A;
+
+ AC_tmp = DCAC_col[0][b_ytab];
+ q_block[8] = AC_tmp[0];
+ q_block[16] = AC_tmp[1];
+ q_block[24] = AC_tmp[2];
+ q_block[32] = AC_tmp[3];
+ q_block[40] = AC_tmp[4];
+ q_block[48] = AC_tmp[5];
+ q_block[56] = AC_tmp[6];
+ }
+ else
+ {
+ q_block[0] = mid_gray;
+ }
+ }
+ }
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return;
+}
+#endif
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/dec_pred_intra_dc.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/dec_pred_intra_dc.cpp
new file mode 100644
index 0000000..c19c23a
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/dec_pred_intra_dc.cpp
@@ -0,0 +1,75 @@
+/* ------------------------------------------------------------------
+ * 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 "mp4dec_lib.h"
+#include "vlc_decode.h"
+#include "bitstream.h"
+#include "zigzag.h"
+
+PV_STATUS PV_DecodePredictedIntraDC(
+ int compnum,
+ BitstreamDecVideo *stream,
+ int16 *INTRADC_delta)
+{
+
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ PV_STATUS status = PV_SUCCESS;
+ uint DC_size;
+ uint code;
+ int first_bit;
+
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ /* read DC size 2 - 8 bits */
+ status = PV_VlcDecIntraDCPredSize(stream, compnum, &DC_size);
+
+ if (status == PV_SUCCESS)
+ {
+ if (DC_size == 0)
+ {
+ *INTRADC_delta = 0;
+ }
+ else
+ {
+ /* read delta DC 0 - 8 bits */
+ code = (int) BitstreamReadBits16_INLINE(stream, DC_size);
+
+ first_bit = code >> (DC_size - 1);
+
+ if (first_bit == 0)
+ {
+ /* negative delta INTRA DC */
+ *INTRADC_delta = code ^((1 << DC_size) - 1);
+ *INTRADC_delta = -(*INTRADC_delta);
+ }
+ else
+ { /* positive delta INTRA DC */
+ *INTRADC_delta = code;
+ }
+ if (DC_size > 8) BitstreamRead1Bits_INLINE(stream);
+ }
+ }
+
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return status;
+}
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/deringing_chroma.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/deringing_chroma.cpp
new file mode 100644
index 0000000..ce779b0
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/deringing_chroma.cpp
@@ -0,0 +1,215 @@
+/* ------------------------------------------------------------------
+ * 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 "mp4dec_lib.h"
+#include "post_proc.h"
+
+#ifdef PV_POSTPROC_ON
+
+void Deringing_Chroma(
+ uint8 *Rec_C,
+ int width,
+ int height,
+ int16 *QP_store,
+ int,
+ uint8 *pp_mod
+)
+{
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int thres;
+ int v_blk, h_blk;
+ int max_diff;
+ int v_pel, h_pel;
+ int max_blk, min_blk;
+ int v0, h0;
+ uint8 *ptr;
+ int sum, sum1, incr;
+ int32 addr_v;
+ int sign_v[10], sum_v[10];
+ int *ptr2, *ptr3;
+ uint8 pelu, pelc, pell;
+ incr = width - BLKSIZE;
+
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ /* chrominance */
+ /* Do the first line (7 pixels at a time => Don't use MMX)*/
+ for (h_blk = 0; h_blk < width; h_blk += BLKSIZE)
+ {
+ max_diff = (QP_store[h_blk>>3] >> 2) + 4;
+ ptr = &Rec_C[h_blk];
+ max_blk = min_blk = *ptr;
+ FindMaxMin(ptr, &min_blk, &max_blk, width);
+ h0 = ((h_blk - 1) >= 1) ? (h_blk - 1) : 1;
+
+ if (max_blk - min_blk >= 4)
+ {
+ thres = (max_blk + min_blk + 1) >> 1;
+
+
+ for (v_pel = 1; v_pel < BLKSIZE - 1; v_pel++)
+ {
+ addr_v = (int32)v_pel * width;
+ ptr = &Rec_C[addr_v + h0 - 1];
+ ptr2 = &sum_v[0];
+ ptr3 = &sign_v[0];
+
+ pelu = *(ptr - width);
+ pelc = *ptr;
+ pell = *(ptr + width);
+ ptr++;
+ *ptr2++ = pelu + (pelc << 1) + pell;
+ *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
+
+ pelu = *(ptr - width);
+ pelc = *ptr;
+ pell = *(ptr + width);
+ ptr++;
+ *ptr2++ = pelu + (pelc << 1) + pell;
+ *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
+
+ for (h_pel = h0; h_pel < h_blk + BLKSIZE - 1; h_pel++)
+ {
+ pelu = *(ptr - width);
+ pelc = *ptr;
+ pell = *(ptr + width);
+
+ *ptr2 = pelu + (pelc << 1) + pell;
+ *ptr3 = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
+
+ sum1 = *(ptr3 - 2) + *(ptr3 - 1) + *ptr3;
+ if (sum1 == 0 || sum1 == 9)
+ {
+ sum = (*(ptr2 - 2) + (*(ptr2 - 1) << 1) + *ptr2 + 8) >> 4;
+
+ ptr--;
+ if (PV_ABS(*ptr - sum) > max_diff)
+ {
+ if (sum > *ptr)
+ sum = *ptr + max_diff;
+ else
+ sum = *ptr - max_diff;
+ }
+ *ptr++ = (uint8) sum;
+ }
+ ptr++;
+ ptr2++;
+ ptr3++;
+ }
+ }
+ }
+ }
+
+ for (v_blk = BLKSIZE; v_blk < height; v_blk += BLKSIZE)
+ {
+ v0 = v_blk - 1;
+ /* Do the first block (pixels=7 => No MMX) */
+ max_diff = (QP_store[((((int32)v_blk*width)>>3))>>3] >> 2) + 4;
+ ptr = &Rec_C[(int32)v_blk * width];
+ max_blk = min_blk = *ptr;
+ FindMaxMin(ptr, &min_blk, &max_blk, incr);
+
+ if (max_blk - min_blk >= 4)
+ {
+ thres = (max_blk + min_blk + 1) >> 1;
+
+ for (v_pel = v0; v_pel < v_blk + BLKSIZE - 1; v_pel++)
+ {
+ addr_v = v_pel * width;
+ ptr = &Rec_C[addr_v];
+ ptr2 = &sum_v[0];
+ ptr3 = &sign_v[0];
+
+ pelu = *(ptr - width);
+ pelc = *ptr;
+ pell = *(ptr + width);
+ ptr++;
+ *ptr2++ = pelu + (pelc << 1) + pell;
+ *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
+
+ pelu = *(ptr - width);
+ pelc = *ptr;
+ pell = *(ptr + width);
+ ptr++;
+ *ptr2++ = pelu + (pelc << 1) + pell;
+ *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
+
+ for (h_pel = 1; h_pel < BLKSIZE - 1; h_pel++)
+ {
+ pelu = *(ptr - width);
+ pelc = *ptr;
+ pell = *(ptr + width);
+
+ *ptr2 = pelu + (pelc << 1) + pell;
+ *ptr3 = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
+
+ sum1 = *(ptr3 - 2) + *(ptr3 - 1) + *ptr3;
+ if (sum1 == 0 || sum1 == 9)
+ {
+ sum = (*(ptr2 - 2) + (*(ptr2 - 1) << 1) + *ptr2 + 8) >> 4;
+
+ ptr--;
+ if (PV_ABS(*ptr - sum) > max_diff)
+ {
+ if (sum > *ptr)
+ sum = *ptr + max_diff;
+ else
+ sum = *ptr - max_diff;
+ }
+ *ptr++ = (uint8) sum;
+ }
+ ptr++;
+ ptr2++;
+ ptr3++;
+ }
+ }
+ }
+
+
+ /* Do the rest in MMX */
+ for (h_blk = BLKSIZE; h_blk < width; h_blk += BLKSIZE)
+ {
+ if ((pp_mod[(v_blk/8)*(width/8)+h_blk/8]&0x4) != 0)
+ {
+ max_diff = (QP_store[((((int32)v_blk*width)>>3)+h_blk)>>3] >> 2) + 4;
+ ptr = &Rec_C[(int32)v_blk * width + h_blk];
+ max_blk = min_blk = *ptr;
+ FindMaxMin(ptr, &min_blk, &max_blk, incr);
+ h0 = h_blk - 1;
+
+ if (max_blk - min_blk >= 4)
+ {
+ thres = (max_blk + min_blk + 1) >> 1;
+#ifdef NoMMX
+ AdaptiveSmooth_NoMMX(Rec_C, v0, h0, v_blk, h_blk, thres, width, max_diff);
+#else
+ DeringAdaptiveSmoothMMX(&Rec_C[(int32)v0*width+h0], width, thres, max_diff);
+#endif
+ }
+ }
+ }
+ } /* macroblock level */
+
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return;
+}
+#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/deringing_luma.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/deringing_luma.cpp
new file mode 100644
index 0000000..b5574b4
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/deringing_luma.cpp
@@ -0,0 +1,231 @@
+/* ------------------------------------------------------------------
+ * 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 "mp4dec_lib.h"
+#include "post_proc.h"
+
+#ifdef PV_POSTPROC_ON
+
+void Deringing_Luma(
+ uint8 *Rec_Y,
+ int width,
+ int height,
+ int16 *QP_store,
+ int,
+ uint8 *pp_mod)
+{
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int thres[4], range[4], max_range_blk, max_thres_blk;
+ int MB_V, MB_H, BLK_V, BLK_H;
+ int v_blk, h_blk;
+ int max_diff;
+ int max_blk, min_blk;
+ int v0, h0;
+ uint8 *ptr;
+ int thr, blks, incr;
+ int mb_indx, blk_indx;
+
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ incr = width - BLKSIZE;
+
+ /* Dering the first line of macro blocks */
+ for (MB_H = 0; MB_H < width; MB_H += MBSIZE)
+ {
+ max_diff = (QP_store[(MB_H)>>4] >> 2) + 4;
+
+ /* threshold determination */
+ max_range_blk = max_thres_blk = 0;
+ blks = 0;
+
+ for (BLK_V = 0; BLK_V < MBSIZE; BLK_V += BLKSIZE)
+ {
+ for (BLK_H = 0; BLK_H < MBSIZE; BLK_H += BLKSIZE)
+ {
+ ptr = &Rec_Y[(int32)(BLK_V) * width + MB_H + BLK_H];
+ FindMaxMin(ptr, &min_blk, &max_blk, incr);
+
+ thres[blks] = (max_blk + min_blk + 1) >> 1;
+ range[blks] = max_blk - min_blk;
+
+ if (range[blks] >= max_range_blk)
+ {
+ max_range_blk = range[blks];
+ max_thres_blk = thres[blks];
+ }
+ blks++;
+ }
+ }
+
+ blks = 0;
+ for (v_blk = 0; v_blk < MBSIZE; v_blk += BLKSIZE)
+ {
+ v0 = ((v_blk - 1) >= 1) ? (v_blk - 1) : 1;
+ for (h_blk = MB_H; h_blk < MB_H + MBSIZE; h_blk += BLKSIZE)
+ {
+ h0 = ((h_blk - 1) >= 1) ? (h_blk - 1) : 1;
+
+ /* threshold rearrangement for flat region adjacent to non-flat region */
+ if (range[blks]<32 && max_range_blk >= 64)
+ thres[blks] = max_thres_blk;
+
+ /* threshold rearrangement for deblocking
+ (blockiness annoying at DC dominant region) */
+ if (max_range_blk >= 16)
+ {
+ /* adaptive smoothing */
+ thr = thres[blks];
+
+ AdaptiveSmooth_NoMMX(Rec_Y, v0, h0, v_blk, h_blk,
+ thr, width, max_diff);
+ }
+ blks++;
+ } /* block level (Luminance) */
+ }
+ } /* macroblock level */
+
+
+ /* Do the rest of the macro-block-lines */
+ for (MB_V = MBSIZE; MB_V < height; MB_V += MBSIZE)
+ {
+ /* First macro-block */
+ max_diff = (QP_store[((((int32)MB_V*width)>>4))>>4] >> 2) + 4;
+ /* threshold determination */
+ max_range_blk = max_thres_blk = 0;
+ blks = 0;
+ for (BLK_V = 0; BLK_V < MBSIZE; BLK_V += BLKSIZE)
+ {
+ for (BLK_H = 0; BLK_H < MBSIZE; BLK_H += BLKSIZE)
+ {
+ ptr = &Rec_Y[(int32)(MB_V + BLK_V) * width + BLK_H];
+ FindMaxMin(ptr, &min_blk, &max_blk, incr);
+ thres[blks] = (max_blk + min_blk + 1) >> 1;
+ range[blks] = max_blk - min_blk;
+
+ if (range[blks] >= max_range_blk)
+ {
+ max_range_blk = range[blks];
+ max_thres_blk = thres[blks];
+ }
+ blks++;
+ }
+ }
+
+ blks = 0;
+ for (v_blk = MB_V; v_blk < MB_V + MBSIZE; v_blk += BLKSIZE)
+ {
+ v0 = v_blk - 1;
+ for (h_blk = 0; h_blk < MBSIZE; h_blk += BLKSIZE)
+ {
+ h0 = ((h_blk - 1) >= 1) ? (h_blk - 1) : 1;
+
+ /* threshold rearrangement for flat region adjacent to non-flat region */
+ if (range[blks]<32 && max_range_blk >= 64)
+ thres[blks] = max_thres_blk;
+
+ /* threshold rearrangement for deblocking
+ (blockiness annoying at DC dominant region) */
+ if (max_range_blk >= 16)
+ {
+ /* adaptive smoothing */
+ thr = thres[blks];
+
+ AdaptiveSmooth_NoMMX(Rec_Y, v0, h0, v_blk, h_blk,
+ thr, width, max_diff);
+ }
+ blks++;
+ }
+ } /* block level (Luminance) */
+
+ /* Rest of the macro-blocks */
+ for (MB_H = MBSIZE; MB_H < width; MB_H += MBSIZE)
+ {
+ max_diff = (QP_store[((((int32)MB_V*width)>>4)+MB_H)>>4] >> 2) + 4;
+
+ /* threshold determination */
+ max_range_blk = max_thres_blk = 0;
+ blks = 0;
+
+ mb_indx = (MB_V / 8) * (width / 8) + MB_H / 8;
+ for (BLK_V = 0; BLK_V < MBSIZE; BLK_V += BLKSIZE)
+ {
+ for (BLK_H = 0; BLK_H < MBSIZE; BLK_H += BLKSIZE)
+ {
+ blk_indx = mb_indx + (BLK_V / 8) * width / 8 + BLK_H / 8;
+ /* Update based on pp_mod only */
+ if ((pp_mod[blk_indx]&0x4) != 0)
+ {
+ ptr = &Rec_Y[(int32)(MB_V + BLK_V) * width + MB_H + BLK_H];
+ FindMaxMin(ptr, &min_blk, &max_blk, incr);
+ thres[blks] = (max_blk + min_blk + 1) >> 1;
+ range[blks] = max_blk - min_blk;
+
+ if (range[blks] >= max_range_blk)
+ {
+ max_range_blk = range[blks];
+ max_thres_blk = thres[blks];
+ }
+ }
+ blks++;
+ }
+ }
+
+ blks = 0;
+ for (v_blk = MB_V; v_blk < MB_V + MBSIZE; v_blk += BLKSIZE)
+ {
+ v0 = v_blk - 1;
+ mb_indx = (v_blk / 8) * (width / 8);
+ for (h_blk = MB_H; h_blk < MB_H + MBSIZE; h_blk += BLKSIZE)
+ {
+ h0 = h_blk - 1;
+ blk_indx = mb_indx + h_blk / 8;
+ if ((pp_mod[blk_indx]&0x4) != 0)
+ {
+ /* threshold rearrangement for flat region adjacent to non-flat region */
+ if (range[blks]<32 && max_range_blk >= 64)
+ thres[blks] = max_thres_blk;
+
+ /* threshold rearrangement for deblocking
+ (blockiness annoying at DC dominant region) */
+ if (max_range_blk >= 16)
+ {
+ /* adaptive smoothing */
+ thr = thres[blks];
+#ifdef NoMMX
+ AdaptiveSmooth_NoMMX(Rec_Y, v0, h0, v_blk, h_blk,
+ thr, width, max_diff);
+#else
+ DeringAdaptiveSmoothMMX(&Rec_Y[v0*width+h0],
+ width, thr, max_diff);
+#endif
+ }
+ }
+ blks++;
+ }
+ } /* block level (Luminance) */
+ } /* macroblock level */
+ } /* macroblock level */
+
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return;
+}
+#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/find_min_max.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/find_min_max.cpp
new file mode 100644
index 0000000..a357ea6
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/find_min_max.cpp
@@ -0,0 +1,176 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+/*
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ input_ptr = pointer to the buffer containing values of type UChar
+ in a 2D block of data.
+ min_ptr = pointer to the minimum value of type Int to be found in a
+ square block of size BLKSIZE contained in 2D block of data.
+ max_ptr = pointer to the maximum value of type Int to be found in a
+ square block of size BLKSIZE contained in 2D block of data.
+ incr = value of type Int representing the width of 2D block of data.
+
+ Local Stores/Buffers/Pointers Needed:
+ None
+
+ Global Stores/Buffers/Pointers Needed:
+ None
+
+ Outputs:
+ None
+
+ Pointers and Buffers Modified:
+ min_ptr points to the found minimum value in the square block of
+ size BLKSIZE contained in 2D block of data.
+
+ max_ptr points to the found maximum value in the square block of
+ size BLKSIZE contained in 2D block of data.
+
+ Local Stores Modified:
+ None
+
+ Global Stores Modified:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function finds the maximum and the minimum values in a square block of
+ data of size BLKSIZE * BLKSIZE. The data is contained in the buffer which
+ represents a 2D block of data that is larger than BLKSIZE * BLKSIZE.
+ This is illustrated below.
+
+ mem loc x + 00h -> o o o o o o o o o o o o o o o o
+ mem loc x + 10h -> o o o o o X X X X X X X X o o o
+ mem loc x + 20h -> o o o o o X X X X X X X X o o o
+ mem loc x + 30h -> o o o o o X X X X X X X X o o o
+ mem loc x + 40h -> o o o o o X X X X X X X X o o o
+ mem loc x + 50h -> o o o o o X X X X X X X X o o o
+ mem loc x + 60h -> o o o o o X X X X X X X X o o o
+ mem loc x + 70h -> o o o o o X X X X X X X X o o o
+ mem loc x + 80h -> o o o o o X X X X X X X X o o o
+ mem loc x + 90h -> o o o o o o o o o o o o o o o o
+ mem loc x + A0h -> o o o o o o o o o o o o o o o o
+ mem loc x + B0h -> o o o o o o o o o o o o o o o o
+
+For illustration purposes, the diagram assumes that BLKSIZE is equal to 8
+but this is not a requirement. In this diagram, the buffer starts at
+location x but the input pointer, input_ptr, passed into this function
+would be the first row of data to be searched which is at x + 15h. The
+value of incr passed onto this function represents the amount the input_ptr
+needs to be incremented to point to the next row of data.
+
+This function compares each value in a row to the current maximum and
+minimum. After each row, input_ptr is incremented to point to the next row.
+This is repeated until all rows have been processed. When the search is
+complete the location pointed to by min_ptr contains the minimum value
+found and the location pointed to by max_ptr contains the maximum value found.
+
+------------------------------------------------------------------------------
+*/
+
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "mp4dec_lib.h"
+#include "post_proc.h"
+
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here. Include conditional
+; compile variables also.
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL FUNCTION DEFINITIONS
+; Function Prototype declaration
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL STORE/BUFFER/POINTER DEFINITIONS
+; Variable declaration - defined here and used outside this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL FUNCTION REFERENCES
+; Declare functions defined elsewhere and referenced in this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+
+#ifdef PV_POSTPROC_ON
+/*----------------------------------------------------------------------------
+; FUNCTION CODE
+----------------------------------------------------------------------------*/
+void FindMaxMin(
+ uint8 *input_ptr,
+ int *min_ptr,
+ int *max_ptr,
+ int incr)
+{
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ register uint i, j;
+ register int min, max;
+
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ max = min = *input_ptr;
+ /* incr = incr - BLKSIZE; */ /* 09/06/2001, already passed in as width - BLKSIZE */
+
+ for (i = BLKSIZE; i > 0; i--)
+ {
+ for (j = BLKSIZE; j > 0; j--)
+ {
+ if (*input_ptr > max)
+ {
+ max = *input_ptr;
+ }
+ else if (*input_ptr < min)
+ {
+ min = *input_ptr;
+ }
+ input_ptr += 1;
+ }
+
+ /* set pointer to the beginning of the next row*/
+ input_ptr += incr;
+ }
+
+ *max_ptr = max;
+ *min_ptr = min;
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return;
+}
+#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp
new file mode 100644
index 0000000..e23f23d
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp
@@ -0,0 +1,1190 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+/*
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ xpos = x half-pixel of (x,y) coordinates within a VOP; motion
+ compensated coordinates; native type
+ ypos = y half-pixel of (x,y) coordinates within a VOP; motion
+ compensated coordinates; native type
+ comp = pointer to 8-bit compensated prediction values within a VOP;
+ computed by this module (i/o); full-pel resolution
+ c_prev = pointer to previous 8-bit prediction values within a VOP;
+ values range from (0-255); full-pel resolution
+ sh_d = pointer to residual values used to compensate the predicted
+ value; values range from (-512 to 511); full-pel resolution
+ width = width of the VOP in pixels (x axis); full-pel resolution
+ rnd1 = rounding value for case when one dimension uses half-pel
+ resolution
+ rnd2 = rounding value for case when two dimensions uses half-pel
+ resolution
+ CBP = flag indicating whether residual is all zeros
+ (0 -> all zeros, 1 -> not all zeros)
+ outside_flag = flag indicating whether motion vector is outside the
+ VOP (0 -> inside, 1 -> outside)
+
+ Outputs:
+ returns 1
+
+ Local Stores/Buffers/Pointers Needed:
+ None
+
+ Global Stores/Buffers/Pointers Needed:
+ None
+
+ Pointers and Buffers Modified:
+ comp = buffer contains newly computed compensated prediction values
+
+ Local Stores Modified:
+ None
+
+ Global Stores Modified:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ Compute pixel values for a block in the current VOP. The prediction
+ values are generated by averaging pixel values in the previous VOP; the
+ block position in the previous frame is computed from the current block's
+ motion vector. The computed pixel values are then computed by adding the
+ prediction values to the block residual values.
+
+
+------------------------------------------------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "mp4dec_lib.h"
+#include "motion_comp.h"
+
+#define OSCL_DISABLE_WARNING_CONV_POSSIBLE_LOSS_OF_DATA
+
+int GetPredAdvancedBy0x0(
+ uint8 *prev, /* i */
+ uint8 *pred_block, /* i */
+ int width, /* i */
+ int pred_width_rnd /* i */
+)
+{
+ uint i; /* loop variable */
+ int offset, offset2;
+ uint32 pred_word, word1, word2;
+ int tmp;
+
+ /* initialize offset to adjust pixel counter */
+ /* the next row; full-pel resolution */
+ offset = width - B_SIZE; /* offset for prev */
+ offset2 = (pred_width_rnd >> 1) - 4; /* offset for pred_block */
+
+ tmp = (uint32)prev & 0x3;
+ pred_block -= offset2; /* preset */
+
+ if (tmp == 0) /* word-aligned */
+ {
+ for (i = B_SIZE; i > 0; i--)
+ {
+ *((uint32*)(pred_block += offset2)) = *((uint32*)prev);
+ *((uint32*)(pred_block += 4)) = *((uint32*)(prev + 4));
+ prev += width;
+ }
+ return 1;
+ }
+ else if (tmp == 1) /* first position */
+ {
+ prev--; /* word-aligned */
+
+ for (i = B_SIZE; i > 0; i--)
+ {
+ word1 = *((uint32*)prev); /* read 4 bytes, b4 b3 b2 b1 */
+ word2 = *((uint32*)(prev += 4)); /* read 4 bytes, b8 b7 b6 b5 */
+ word1 >>= 8; /* 0 b4 b3 b2 */
+ pred_word = word1 | (word2 << 24); /* b5 b4 b3 b2 */
+ *((uint32*)(pred_block += offset2)) = pred_word;
+
+ word1 = *((uint32*)(prev += 4)); /* b12 b11 b10 b9 */
+ word2 >>= 8; /* 0 b8 b7 b6 */
+ pred_word = word2 | (word1 << 24); /* b9 b8 b7 b6 */
+ *((uint32*)(pred_block += 4)) = pred_word;
+
+ prev += offset;
+ }
+
+ return 1;
+ }
+ else if (tmp == 2) /* second position */
+ {
+ prev -= 2; /* word1-aligned */
+
+ for (i = B_SIZE; i > 0; i--)
+ {
+ word1 = *((uint32*)prev); /* read 4 bytes, b4 b3 b2 b1 */
+ word2 = *((uint32*)(prev += 4)); /* read 4 bytes, b8 b7 b6 b5 */
+ word1 >>= 16; /* 0 0 b4 b3 */
+ pred_word = word1 | (word2 << 16); /* b6 b5 b4 b3 */
+ *((uint32*)(pred_block += offset2)) = pred_word;
+
+ word1 = *((uint32*)(prev += 4)); /* b12 b11 b10 b9 */
+ word2 >>= 16; /* 0 0 b8 b7 */
+ pred_word = word2 | (word1 << 16); /* b10 b9 b8 b7 */
+ *((uint32*)(pred_block += 4)) = pred_word;
+
+
+ prev += offset;
+ }
+
+ return 1;
+ }
+ else /* third position */
+ {
+ prev -= 3; /* word1-aligned */
+
+ for (i = B_SIZE; i > 0; i--)
+ {
+ word1 = *((uint32*)prev); /* read 4 bytes, b4 b3 b2 b1 */
+ word2 = *((uint32*)(prev += 4)); /* read 4 bytes, b8 b7 b6 b5 */
+ word1 >>= 24; /* 0 0 0 b4 */
+ pred_word = word1 | (word2 << 8); /* b7 b6 b5 b4 */
+ *((uint32*)(pred_block += offset2)) = pred_word;
+
+ word1 = *((uint32*)(prev += 4)); /* b12 b11 b10 b9 */
+ word2 >>= 24; /* 0 0 0 b8 */
+ pred_word = word2 | (word1 << 8); /* b11 b10 b9 b8 */
+ *((uint32*)(pred_block += 4)) = pred_word;
+
+ prev += offset;
+ }
+
+ return 1;
+ }
+}
+
+/**************************************************************************/
+int GetPredAdvancedBy0x1(
+ uint8 *prev, /* i */
+ uint8 *pred_block, /* i */
+ int width, /* i */
+ int pred_width_rnd /* i */
+)
+{
+ uint i; /* loop variable */
+ int offset, offset2;
+ uint32 word1, word2, word3, word12;
+ int tmp;
+ int rnd1;
+ uint32 mask;
+
+ /* initialize offset to adjust pixel counter */
+ /* the next row; full-pel resolution */
+ offset = width - B_SIZE; /* offset for prev */
+ offset2 = (pred_width_rnd >> 1) - 4; /* offset of pred_block */
+
+ rnd1 = pred_width_rnd & 1;
+
+ /* Branch based on pixel location (half-pel or full-pel) for x and y */
+ pred_block -= offset2; /* preset */
+
+ tmp = (uint32)prev & 3;
+ mask = 254;
+ mask |= (mask << 8);
+ mask |= (mask << 16); /* 0xFEFEFEFE */
+
+ if (tmp == 0) /* word-aligned */
+ {
+ if (rnd1 == 1)
+ {
+ for (i = B_SIZE; i > 0; i--)
+ {
+ word1 = *((uint32*)prev); /* b4 b3 b2 b1 */
+ word2 = *((uint32*)(prev += 4)); /* b8 b7 b6 b5 */
+ word12 = (word1 >> 8); /* 0 b4 b3 b2 */
+ word12 |= (word2 << 24); /* b5 b4 b3 b2 */
+ word3 = word1 | word12; // rnd1 = 1; otherwise word3 = word1&word12
+ word1 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 &= mask;
+ word1 >>= 1;
+ word1 = word1 + (word12 >> 1);
+ word1 += word3;
+ *((uint32*)(pred_block += offset2)) = word1; /* write 4 pixels */
+
+ word1 = *((uint32*)(prev += 4)); /* b12 b11 b10 b9 */
+ word12 = (word2 >> 8); /* 0 b8 b7 b6 */
+ word12 |= (word1 << 24); /* b9 b8 b7 b6 */
+ word3 = word2 | word12;
+ word2 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 &= mask;
+ word2 >>= 1;
+ word2 = word2 + (word12 >> 1);
+ word2 += word3;
+ *((uint32*)(pred_block += 4)) = word2; /* write 4 pixels */
+
+ prev += offset;
+ }
+ return 1;
+ }
+ else /* rnd1 == 0 */
+ {
+ for (i = B_SIZE; i > 0; i--)
+ {
+ word1 = *((uint32*)prev); /* b4 b3 b2 b1 */
+
+ word2 = *((uint32*)(prev += 4)); /* b8 b7 b6 b5 */
+ word12 = (word1 >> 8); /* 0 b4 b3 b2 */
+ word12 |= (word2 << 24); /* b5 b4 b3 b2 */
+ word3 = word1 & word12; // rnd1 = 1; otherwise word3 = word1&word12
+ word1 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 &= mask;
+ word1 >>= 1;
+ word1 = word1 + (word12 >> 1);
+ word1 += word3;
+ *((uint32*)(pred_block += offset2)) = word1; /* write 4 pixels */
+
+ word1 = *((uint32*)(prev += 4)); /* b12 b11 b10 b9 */
+ word12 = (word2 >> 8); /* 0 b8 b7 b6 */
+ word12 |= (word1 << 24); /* b9 b8 b7 b6 */
+ word3 = word2 & word12;
+ word2 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 &= mask;
+ word2 >>= 1;
+ word2 = word2 + (word12 >> 1);
+ word2 += word3;
+ *((uint32*)(pred_block += 4)) = word2; /* write 4 pixels */
+
+ prev += offset;
+ }
+ return 1;
+ } /* rnd1 */
+ }
+ else if (tmp == 1)
+ {
+ prev--; /* word-aligned */
+ if (rnd1 == 1)
+ {
+ for (i = B_SIZE; i > 0; i--)
+ {
+ word1 = *((uint32*)prev); /* b3 b2 b1 b0 */
+ word2 = *((uint32*)(prev += 4)); /* b7 b6 b5 b4 */
+ word12 = (word1 >> 8); /* 0 b3 b2 b1 */
+ word1 >>= 16; /* 0 0 b3 b2 */
+ word12 |= (word2 << 24); /* b4 b3 b2 b1 */
+ word1 |= (word2 << 16); /* b5 b4 b3 b2 */
+ word3 = word1 | word12; // rnd1 = 1; otherwise word3 = word1&word12
+ word1 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 &= mask;
+ word1 >>= 1;
+ word1 = word1 + (word12 >> 1);
+ word1 += word3;
+ *((uint32*)(pred_block += offset2)) = word1; /* write 4 pixels */
+
+ word1 = *((uint32*)(prev += 4)); /* b11 b10 b9 b8 */
+ word12 = (word2 >> 8); /* 0 b7 b6 b5 */
+ word2 >>= 16; /* 0 0 b7 b6 */
+ word12 |= (word1 << 24); /* b8 b7 b6 b5 */
+ word2 |= (word1 << 16); /* b9 b8 b7 b6 */
+ word3 = word2 | word12; // rnd1 = 1; otherwise word3 = word2&word12
+ word2 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 &= mask;
+ word2 >>= 1;
+ word2 = word2 + (word12 >> 1);
+ word2 += word3;
+ *((uint32*)(pred_block += 4)) = word2; /* write 4 pixels */
+
+ prev += offset;
+ }
+ return 1;
+ }
+ else /* rnd1 = 0 */
+ {
+ for (i = B_SIZE; i > 0; i--)
+ {
+ word1 = *((uint32*)prev); /* b3 b2 b1 b0 */
+
+ word2 = *((uint32*)(prev += 4)); /* b7 b6 b5 b4 */
+ word12 = (word1 >> 8); /* 0 b3 b2 b1 */
+ word1 >>= 16; /* 0 0 b3 b2 */
+ word12 |= (word2 << 24); /* b4 b3 b2 b1 */
+ word1 |= (word2 << 16); /* b5 b4 b3 b2 */
+ word3 = word1 & word12;
+ word1 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 &= mask;
+ word1 >>= 1;
+ word1 = word1 + (word12 >> 1);
+ word1 += word3;
+ *((uint32*)(pred_block += offset2)) = word1; /* write 4 pixels */
+
+ word1 = *((uint32*)(prev += 4)); /* b11 b10 b9 b8 */
+ word12 = (word2 >> 8); /* 0 b7 b6 b5 */
+ word2 >>= 16; /* 0 0 b7 b6 */
+ word12 |= (word1 << 24); /* b8 b7 b6 b5 */
+ word2 |= (word1 << 16); /* b9 b8 b7 b6 */
+ word3 = word2 & word12;
+ word2 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 &= mask;
+ word2 >>= 1;
+ word2 = word2 + (word12 >> 1);
+ word2 += word3;
+ *((uint32*)(pred_block += 4)) = word2; /* write 4 pixels */
+
+ prev += offset;
+ }
+ return 1;
+ } /* rnd1 */
+ }
+ else if (tmp == 2)
+ {
+ prev -= 2; /* word-aligned */
+ if (rnd1 == 1)
+ {
+ for (i = B_SIZE; i > 0; i--)
+ {
+ word1 = *((uint32*)prev); /* b2 b1 b0 bN1 */
+ word2 = *((uint32*)(prev += 4)); /* b6 b5 b4 b3 */
+ word12 = (word1 >> 16); /* 0 0 b2 b1 */
+ word1 >>= 24; /* 0 0 0 b2 */
+ word12 |= (word2 << 16); /* b4 b3 b2 b1 */
+ word1 |= (word2 << 8); /* b5 b4 b3 b2 */
+ word3 = word1 | word12; // rnd1 = 1; otherwise word3 = word1&word12
+ word1 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 &= mask;
+ word1 >>= 1;
+ word1 = word1 + (word12 >> 1);
+ word1 += word3;
+ *((uint32*)(pred_block += offset2)) = word1; /* write 4 pixels */
+
+ word1 = *((uint32*)(prev += 4)); /* b10 b9 b8 b7 */
+ word12 = (word2 >> 16); /* 0 0 b6 b5 */
+ word2 >>= 24; /* 0 0 0 b6 */
+ word12 |= (word1 << 16); /* b8 b7 b6 b5 */
+ word2 |= (word1 << 8); /* b9 b8 b7 b6 */
+ word3 = word2 | word12; // rnd1 = 1; otherwise word3 = word1&word12
+ word2 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 &= mask;
+ word2 >>= 1;
+ word2 = word2 + (word12 >> 1);
+ word2 += word3;
+ *((uint32*)(pred_block += 4)) = word2; /* write 4 pixels */
+ prev += offset;
+ }
+ return 1;
+ }
+ else /* rnd1 == 0 */
+ {
+ for (i = B_SIZE; i > 0; i--)
+ {
+ word1 = *((uint32*)prev); /* b2 b1 b0 bN1 */
+ word2 = *((uint32*)(prev += 4)); /* b6 b5 b4 b3 */
+ word12 = (word1 >> 16); /* 0 0 b2 b1 */
+ word1 >>= 24; /* 0 0 0 b2 */
+ word12 |= (word2 << 16); /* b4 b3 b2 b1 */
+ word1 |= (word2 << 8); /* b5 b4 b3 b2 */
+ word3 = word1 & word12; // rnd1 = 1; otherwise word3 = word1&word12
+ word1 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 &= mask;
+ word1 >>= 1;
+ word1 = word1 + (word12 >> 1);
+ word1 += word3;
+ *((uint32*)(pred_block += offset2)) = word1; /* write 4 pixels */
+
+ word1 = *((uint32*)(prev += 4)); /* b10 b9 b8 b7 */
+ word12 = (word2 >> 16); /* 0 0 b6 b5 */
+ word2 >>= 24; /* 0 0 0 b6 */
+ word12 |= (word1 << 16); /* b8 b7 b6 b5 */
+ word2 |= (word1 << 8); /* b9 b8 b7 b6 */
+ word3 = word2 & word12; // rnd1 = 1; otherwise word3 = word1&word12
+ word2 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 &= mask;
+ word2 >>= 1;
+ word2 = word2 + (word12 >> 1);
+ word2 += word3;
+ *((uint32*)(pred_block += 4)) = word2; /* write 4 pixels */
+ prev += offset;
+ }
+ return 1;
+ }
+ }
+ else /* tmp = 3 */
+ {
+ prev -= 3; /* word-aligned */
+ if (rnd1 == 1)
+ {
+ for (i = B_SIZE; i > 0; i--)
+ {
+ word1 = *((uint32*)prev); /* b1 b0 bN1 bN2 */
+ word2 = *((uint32*)(prev += 4)); /* b5 b4 b3 b2 */
+ word12 = (word1 >> 24); /* 0 0 0 b1 */
+ word12 |= (word2 << 8); /* b4 b3 b2 b1 */
+ word1 = word2;
+ word3 = word1 | word12; // rnd1 = 1; otherwise word3 = word1&word12
+ word1 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 &= mask;
+ word1 >>= 1;
+ word1 = word1 + (word12 >> 1);
+ word1 += word3;
+ *((uint32*)(pred_block += offset2)) = word1; /* write 4 pixels */
+
+ word1 = *((uint32*)(prev += 4)); /* b9 b8 b7 b6 */
+ word12 = (word2 >> 24); /* 0 0 0 b5 */
+ word12 |= (word1 << 8); /* b8 b7 b6 b5 */
+ word2 = word1; /* b9 b8 b7 b6 */
+ word3 = word2 | word12; // rnd1 = 1; otherwise word3 = word1&word12
+ word2 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 &= mask;
+ word2 >>= 1;
+ word2 = word2 + (word12 >> 1);
+ word2 += word3;
+ *((uint32*)(pred_block += 4)) = word2; /* write 4 pixels */
+ prev += offset;
+ }
+ return 1;
+ }
+ else
+ {
+ for (i = B_SIZE; i > 0; i--)
+ {
+ word1 = *((uint32*)prev); /* b1 b0 bN1 bN2 */
+ word2 = *((uint32*)(prev += 4)); /* b5 b4 b3 b2 */
+ word12 = (word1 >> 24); /* 0 0 0 b1 */
+ word12 |= (word2 << 8); /* b4 b3 b2 b1 */
+ word1 = word2;
+ word3 = word1 & word12; // rnd1 = 1; otherwise word3 = word1&word12
+ word1 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 &= mask;
+ word1 >>= 1;
+ word1 = word1 + (word12 >> 1);
+ word1 += word3;
+ *((uint32*)(pred_block += offset2)) = word1; /* write 4 pixels */
+
+ word1 = *((uint32*)(prev += 4)); /* b9 b8 b7 b6 */
+ word12 = (word2 >> 24); /* 0 0 0 b5 */
+ word12 |= (word1 << 8); /* b8 b7 b6 b5 */
+ word2 = word1; /* b9 b8 b7 b6 */
+ word3 = word2 & word12; // rnd1 = 1; otherwise word3 = word1&word12
+ word2 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 &= mask;
+ word2 >>= 1;
+ word2 = word2 + (word12 >> 1);
+ word2 += word3;
+ *((uint32*)(pred_block += 4)) = word2; /* write 4 pixels */
+ prev += offset;
+ }
+ return 1;
+ }
+ }
+}
+
+/**************************************************************************/
+int GetPredAdvancedBy1x0(
+ uint8 *prev, /* i */
+ uint8 *pred_block, /* i */
+ int width, /* i */
+ int pred_width_rnd /* i */
+)
+{
+ uint i; /* loop variable */
+ int offset, offset2;
+ uint32 word1, word2, word3, word12, word22;
+ int tmp;
+ int rnd1;
+ uint32 mask;
+
+ /* initialize offset to adjust pixel counter */
+ /* the next row; full-pel resolution */
+ offset = width - B_SIZE; /* offset for prev */
+ offset2 = (pred_width_rnd >> 1) - 4; /* offset for pred_block */
+
+ rnd1 = pred_width_rnd & 1;
+
+ /* Branch based on pixel location (half-pel or full-pel) for x and y */
+ pred_block -= offset2; /* preset */
+
+ tmp = (uint32)prev & 3;
+ mask = 254;
+ mask |= (mask << 8);
+ mask |= (mask << 16); /* 0xFEFEFEFE */
+
+ if (tmp == 0) /* word-aligned */
+ {
+ prev -= 4;
+ if (rnd1 == 1)
+ {
+ for (i = B_SIZE; i > 0; i--)
+ {
+ word1 = *((uint32*)(prev += 4));
+ word2 = *((uint32*)(prev + width));
+ word3 = word1 | word2; // rnd1 = 1; otherwise word3 = word1&word2
+ word1 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word2 &= mask;
+ word1 >>= 1;
+ word1 = word1 + (word2 >> 1);
+ word1 += word3;
+ *((uint32*)(pred_block += offset2)) = word1;
+ word1 = *((uint32*)(prev += 4));
+ word2 = *((uint32*)(prev + width));
+ word3 = word1 | word2; // rnd1 = 1; otherwise word3 = word1&word2
+ word1 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word2 &= mask;
+ word1 >>= 1;
+ word1 = word1 + (word2 >> 1);
+ word1 += word3;
+ *((uint32*)(pred_block += 4)) = word1;
+
+ prev += offset;
+ }
+ return 1;
+ }
+ else /* rnd1 = 0 */
+ {
+ for (i = B_SIZE; i > 0; i--)
+ {
+ word1 = *((uint32*)(prev += 4));
+ word2 = *((uint32*)(prev + width));
+ word3 = word1 & word2; /* rnd1 = 0; */
+ word1 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word2 &= mask;
+ word1 >>= 1;
+ word1 = word1 + (word2 >> 1);
+ word1 += word3;
+ *((uint32*)(pred_block += offset2)) = word1;
+ word1 = *((uint32*)(prev += 4));
+ word2 = *((uint32*)(prev + width));
+ word3 = word1 & word2; /* rnd1 = 0; */
+ word1 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word2 &= mask;
+ word1 >>= 1;
+ word1 = word1 + (word2 >> 1);
+ word1 += word3;
+ *((uint32*)(pred_block += 4)) = word1;
+
+ prev += offset;
+ }
+ return 1;
+ }
+ }
+ else if (tmp == 1)
+ {
+ prev--; /* word-aligned */
+ if (rnd1 == 1)
+ {
+ for (i = B_SIZE; i > 0; i--)
+ {
+ word12 = *((uint32*)prev); /* read b4 b3 b2 b1 */
+ word22 = *((uint32*)(prev + width));
+
+ word1 = *((uint32*)(prev += 4)); /* read b8 b7 b6 b5 */
+ word2 = *((uint32*)(prev + width));
+ word12 >>= 8; /* 0 b4 b3 b2 */
+ word22 >>= 8;
+ word12 = word12 | (word1 << 24); /* b5 b4 b3 b2 */
+ word22 = word22 | (word2 << 24);
+ word3 = word12 | word22;
+ word12 &= mask;
+ word22 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 >>= 1;
+ word12 = word12 + (word22 >> 1);
+ word12 += word3;
+ *((uint32*)(pred_block += offset2)) = word12;
+
+ word12 = *((uint32*)(prev += 4)); /* read b12 b11 b10 b9 */
+ word22 = *((uint32*)(prev + width));
+ word1 >>= 8; /* 0 b8 b7 b6 */
+ word2 >>= 8;
+ word1 = word1 | (word12 << 24); /* b9 b8 b7 b6 */
+ word2 = word2 | (word22 << 24);
+ word3 = word1 | word2;
+ word1 &= mask;
+ word2 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word1 >>= 1;
+ word1 = word1 + (word2 >> 1);
+ word1 += word3;
+ *((uint32*)(pred_block += 4)) = word1;
+ prev += offset;
+ }
+ return 1;
+ }
+ else /* rnd1 = 0 */
+ {
+ for (i = B_SIZE; i > 0; i--)
+ {
+ word12 = *((uint32*)prev); /* read b4 b3 b2 b1 */
+ word22 = *((uint32*)(prev + width));
+
+ word1 = *((uint32*)(prev += 4)); /* read b8 b7 b6 b5 */
+ word2 = *((uint32*)(prev + width));
+ word12 >>= 8; /* 0 b4 b3 b2 */
+ word22 >>= 8;
+ word12 = word12 | (word1 << 24); /* b5 b4 b3 b2 */
+ word22 = word22 | (word2 << 24);
+ word3 = word12 & word22;
+ word12 &= mask;
+ word22 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 >>= 1;
+ word12 = word12 + (word22 >> 1);
+ word12 += word3;
+ *((uint32*)(pred_block += offset2)) = word12;
+
+ word12 = *((uint32*)(prev += 4)); /* read b12 b11 b10 b9 */
+ word22 = *((uint32*)(prev + width));
+ word1 >>= 8; /* 0 b8 b7 b6 */
+ word2 >>= 8;
+ word1 = word1 | (word12 << 24); /* b9 b8 b7 b6 */
+ word2 = word2 | (word22 << 24);
+ word3 = word1 & word2;
+ word1 &= mask;
+ word2 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word1 >>= 1;
+ word1 = word1 + (word2 >> 1);
+ word1 += word3;
+ *((uint32*)(pred_block += 4)) = word1;
+ prev += offset;
+ }
+ return 1;
+ }
+ }
+ else if (tmp == 2)
+ {
+ prev -= 2; /* word-aligned */
+ if (rnd1 == 1)
+ {
+ for (i = B_SIZE; i > 0; i--)
+ {
+ word12 = *((uint32*)prev); /* read b4 b3 b2 b1 */
+ word22 = *((uint32*)(prev + width));
+
+ word1 = *((uint32*)(prev += 4)); /* read b8 b7 b6 b5 */
+ word2 = *((uint32*)(prev + width));
+ word12 >>= 16; /* 0 0 b4 b3 */
+ word22 >>= 16;
+ word12 = word12 | (word1 << 16); /* b6 b5 b4 b3 */
+ word22 = word22 | (word2 << 16);
+ word3 = word12 | word22;
+ word12 &= mask;
+ word22 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 >>= 1;
+ word12 = word12 + (word22 >> 1);
+ word12 += word3;
+ *((uint32*)(pred_block += offset2)) = word12;
+
+ word12 = *((uint32*)(prev += 4)); /* read b12 b11 b10 b9 */
+ word22 = *((uint32*)(prev + width));
+ word1 >>= 16; /* 0 0 b8 b7 */
+ word2 >>= 16;
+ word1 = word1 | (word12 << 16); /* b10 b9 b8 b7 */
+ word2 = word2 | (word22 << 16);
+ word3 = word1 | word2;
+ word1 &= mask;
+ word2 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word1 >>= 1;
+ word1 = word1 + (word2 >> 1);
+ word1 += word3;
+ *((uint32*)(pred_block += 4)) = word1;
+ prev += offset;
+ }
+ return 1;
+ }
+ else /* rnd1 = 0 */
+ {
+ for (i = B_SIZE; i > 0; i--)
+ {
+ word12 = *((uint32*)prev); /* read b4 b3 b2 b1 */
+ word22 = *((uint32*)(prev + width));
+
+ word1 = *((uint32*)(prev += 4)); /* read b8 b7 b6 b5 */
+ word2 = *((uint32*)(prev + width));
+ word12 >>= 16; /* 0 0 b4 b3 */
+ word22 >>= 16;
+ word12 = word12 | (word1 << 16); /* b6 b5 b4 b3 */
+ word22 = word22 | (word2 << 16);
+ word3 = word12 & word22;
+ word12 &= mask;
+ word22 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 >>= 1;
+ word12 = word12 + (word22 >> 1);
+ word12 += word3;
+ *((uint32*)(pred_block += offset2)) = word12;
+
+ word12 = *((uint32*)(prev += 4)); /* read b12 b11 b10 b9 */
+ word22 = *((uint32*)(prev + width));
+ word1 >>= 16; /* 0 0 b8 b7 */
+ word2 >>= 16;
+ word1 = word1 | (word12 << 16); /* b10 b9 b8 b7 */
+ word2 = word2 | (word22 << 16);
+ word3 = word1 & word2;
+ word1 &= mask;
+ word2 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word1 >>= 1;
+ word1 = word1 + (word2 >> 1);
+ word1 += word3;
+ *((uint32*)(pred_block += 4)) = word1;
+ prev += offset;
+ }
+
+ return 1;
+ }
+ }
+ else /* tmp == 3 */
+ {
+ prev -= 3; /* word-aligned */
+ if (rnd1 == 1)
+ {
+ for (i = B_SIZE; i > 0; i--)
+ {
+ word12 = *((uint32*)prev); /* read b4 b3 b2 b1 */
+ word22 = *((uint32*)(prev + width));
+
+ word1 = *((uint32*)(prev += 4)); /* read b8 b7 b6 b5 */
+ word2 = *((uint32*)(prev + width));
+ word12 >>= 24; /* 0 0 0 b4 */
+ word22 >>= 24;
+ word12 = word12 | (word1 << 8); /* b7 b6 b5 b4 */
+ word22 = word22 | (word2 << 8);
+ word3 = word12 | word22;
+ word12 &= mask;
+ word22 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 >>= 1;
+ word12 = word12 + (word22 >> 1);
+ word12 += word3;
+ *((uint32*)(pred_block += offset2)) = word12;
+
+ word12 = *((uint32*)(prev += 4)); /* read b12 b11 b10 b9 */
+ word22 = *((uint32*)(prev + width));
+ word1 >>= 24; /* 0 0 0 b8 */
+ word2 >>= 24;
+ word1 = word1 | (word12 << 8); /* b11 b10 b9 b8 */
+ word2 = word2 | (word22 << 8);
+ word3 = word1 | word2;
+ word1 &= mask;
+ word2 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word1 >>= 1;
+ word1 = word1 + (word2 >> 1);
+ word1 += word3;
+ *((uint32*)(pred_block += 4)) = word1;
+ prev += offset;
+ }
+ return 1;
+ }
+ else /* rnd1 = 0 */
+ {
+ for (i = B_SIZE; i > 0; i--)
+ {
+ word12 = *((uint32*)prev); /* read b4 b3 b2 b1 */
+ word22 = *((uint32*)(prev + width));
+
+ word1 = *((uint32*)(prev += 4)); /* read b8 b7 b6 b5 */
+ word2 = *((uint32*)(prev + width));
+ word12 >>= 24; /* 0 0 0 b4 */
+ word22 >>= 24;
+ word12 = word12 | (word1 << 8); /* b7 b6 b5 b4 */
+ word22 = word22 | (word2 << 8);
+ word3 = word12 & word22;
+ word12 &= mask;
+ word22 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word12 >>= 1;
+ word12 = word12 + (word22 >> 1);
+ word12 += word3;
+ *((uint32*)(pred_block += offset2)) = word12;
+
+ word12 = *((uint32*)(prev += 4)); /* read b12 b11 b10 b9 */
+ word22 = *((uint32*)(prev + width));
+ word1 >>= 24; /* 0 0 0 b8 */
+ word2 >>= 24;
+ word1 = word1 | (word12 << 8); /* b11 b10 b9 b8 */
+ word2 = word2 | (word22 << 8);
+ word3 = word1 & word2;
+ word1 &= mask;
+ word2 &= mask;
+ word3 &= (~mask); /* 0x1010101, check last bit */
+ word1 >>= 1;
+ word1 = word1 + (word2 >> 1);
+ word1 += word3;
+ *((uint32*)(pred_block += 4)) = word1;
+ prev += offset;
+ }
+ return 1;
+ } /* rnd */
+ } /* tmp */
+}
+
+/**********************************************************************************/
+int GetPredAdvancedBy1x1(
+ uint8 *prev, /* i */
+ uint8 *pred_block, /* i */
+ int width, /* i */
+ int pred_width_rnd /* i */
+)
+{
+ uint i; /* loop variable */
+ int offset, offset2;
+ uint32 x1, x2, x1m, x2m, y1, y2, y1m, y2m; /* new way */
+ int tmp;
+ int rnd1, rnd2;
+ uint32 mask;
+
+ /* initialize offset to adjust pixel counter */
+ /* the next row; full-pel resolution */
+ offset = width - B_SIZE; /* offset for prev */
+ offset2 = (pred_width_rnd >> 1) - 8; /* offset for pred_block */
+
+ rnd1 = pred_width_rnd & 1;
+
+ rnd2 = rnd1 + 1;
+ rnd2 |= (rnd2 << 8);
+ rnd2 |= (rnd2 << 16);
+
+ mask = 0x3F;
+ mask |= (mask << 8);
+ mask |= (mask << 16); /* 0x3f3f3f3f */
+
+ tmp = (uint32)prev & 3;
+
+ pred_block -= 4; /* preset */
+
+ if (tmp == 0) /* word-aligned */
+ {
+ for (i = B_SIZE; i > 0; i--)
+ {
+ x1 = *((uint32*)prev); /* load a3 a2 a1 a0 */
+ x2 = *((uint32*)(prev + width)); /* load b3 b2 b1 b0, another line */
+ y1 = *((uint32*)(prev += 4)); /* a7 a6 a5 a4 */
+ y2 = *((uint32*)(prev + width)); /* b7 b6 b5 b4 */
+
+ x1m = (x1 >> 2) & mask; /* zero out last 2 bits */
+ x2m = (x2 >> 2) & mask;
+ x1 = x1 ^(x1m << 2);
+ x2 = x2 ^(x2m << 2);
+ x1m += x2m;
+ x1 += x2;
+
+ /* x2m, x2 free */
+ y1m = (y1 >> 2) & mask; /* zero out last 2 bits */
+ y2m = (y2 >> 2) & mask;
+ y1 = y1 ^(y1m << 2);
+ y2 = y2 ^(y2m << 2);
+ y1m += y2m;
+ y1 += y2;
+
+ /* y2m, y2 free */
+ /* x2m, x2 free */
+ x2 = *((uint32*)(prev += 4)); /* a11 a10 a9 a8 */
+ y2 = *((uint32*)(prev + width)); /* b11 b10 b9 b8 */
+ x2m = (x2 >> 2) & mask;
+ y2m = (y2 >> 2) & mask;
+ x2 = x2 ^(x2m << 2);
+ y2 = y2 ^(y2m << 2);
+ x2m += y2m;
+ x2 += y2;
+ /* y2m, y2 free */
+
+ /* now operate on x1m, x1, y1m, y1, x2m, x2 */
+ /* x1m = a3+b3, a2+b2, a1+b1, a0+b0 */
+ /* y1m = a7+b7, a6+b6, a5+b5, a4+b4 */
+ /* x2m = a11+b11, a10+b10, a9+b9, a8+b8 */
+ /* x1, y1, x2 */
+
+ y2m = x1m >> 8;
+ y2 = x1 >> 8;
+ y2m |= (y1m << 24); /* a4+b4, a3+b3, a2+b2, a1+b1 */
+ y2 |= (y1 << 24);
+ x1m += y2m; /* a3+b3+a4+b4, ....., a0+b0+a1+b1 */
+ x1 += y2;
+ x1 += rnd2;
+ x1 &= (mask << 2);
+ x1m += (x1 >> 2);
+ *((uint32*)(pred_block += 4)) = x1m; /* save x1m */
+
+ y2m = y1m >> 8;
+ y2 = y1 >> 8;
+ y2m |= (x2m << 24); /* a8+b8, a7+b7, a6+b6, a5+b5 */
+ y2 |= (x2 << 24);
+ y1m += y2m; /* a7+b7+a8+b8, ....., a4+b4+a5+b5 */
+ y1 += y2;
+ y1 += rnd2;
+ y1 &= (mask << 2);
+ y1m += (y1 >> 2);
+ *((uint32*)(pred_block += 4)) = y1m; /* save y1m */
+
+ pred_block += offset2;
+ prev += offset;
+ }
+
+ return 1;
+ }
+ else if (tmp == 1)
+ {
+ prev--; /* to word-aligned */
+ for (i = B_SIZE; i > 0; i--)
+ {
+ x1 = *((uint32*)prev); /* load a3 a2 a1 a0 */
+ x2 = *((uint32*)(prev + width)); /* load b3 b2 b1 b0, another line */
+ y1 = *((uint32*)(prev += 4)); /* a7 a6 a5 a4 */
+ y2 = *((uint32*)(prev + width)); /* b7 b6 b5 b4 */
+
+ x1m = (x1 >> 2) & mask; /* zero out last 2 bits */
+ x2m = (x2 >> 2) & mask;
+ x1 = x1 ^(x1m << 2);
+ x2 = x2 ^(x2m << 2);
+ x1m += x2m;
+ x1 += x2;
+
+ /* x2m, x2 free */
+ y1m = (y1 >> 2) & mask; /* zero out last 2 bits */
+ y2m = (y2 >> 2) & mask;
+ y1 = y1 ^(y1m << 2);
+ y2 = y2 ^(y2m << 2);
+ y1m += y2m;
+ y1 += y2;
+
+ /* y2m, y2 free */
+ /* x2m, x2 free */
+ x2 = *((uint32*)(prev += 4)); /* a11 a10 a9 a8 */
+ y2 = *((uint32*)(prev + width)); /* b11 b10 b9 b8 */
+ x2m = (x2 >> 2) & mask;
+ y2m = (y2 >> 2) & mask;
+ x2 = x2 ^(x2m << 2);
+ y2 = y2 ^(y2m << 2);
+ x2m += y2m;
+ x2 += y2;
+ /* y2m, y2 free */
+
+ /* now operate on x1m, x1, y1m, y1, x2m, x2 */
+ /* x1m = a3+b3, a2+b2, a1+b1, a0+b0 */
+ /* y1m = a7+b7, a6+b6, a5+b5, a4+b4 */
+ /* x2m = a11+b11, a10+b10, a9+b9, a8+b8 */
+ /* x1, y1, x2 */
+
+ x1m >>= 8 ;
+ x1 >>= 8;
+ x1m |= (y1m << 24); /* a4+b4, a3+b3, a2+b2, a1+b1 */
+ x1 |= (y1 << 24);
+ y2m = (y1m << 16);
+ y2 = (y1 << 16);
+ y2m |= (x1m >> 8); /* a5+b5, a4+b4, a3+b3, a2+b2 */
+ y2 |= (x1 >> 8);
+ x1 += rnd2;
+ x1m += y2m; /* a4+b4+a5+b5, ....., a1+b1+a2+b2 */
+ x1 += y2;
+ x1 &= (mask << 2);
+ x1m += (x1 >> 2);
+ *((uint32*)(pred_block += 4)) = x1m; /* save x1m */
+
+ y1m >>= 8;
+ y1 >>= 8;
+ y1m |= (x2m << 24); /* a8+b8, a7+b7, a6+b6, a5+b5 */
+ y1 |= (x2 << 24);
+ y2m = (x2m << 16);
+ y2 = (x2 << 16);
+ y2m |= (y1m >> 8); /* a9+b9, a8+b8, a7+b7, a6+b6,*/
+ y2 |= (y1 >> 8);
+ y1 += rnd2;
+ y1m += y2m; /* a8+b8+a9+b9, ....., a5+b5+a6+b6 */
+ y1 += y2;
+ y1 &= (mask << 2);
+ y1m += (y1 >> 2);
+ *((uint32*)(pred_block += 4)) = y1m; /* save y1m */
+
+ pred_block += offset2;
+ prev += offset;
+ }
+ return 1;
+ }
+ else if (tmp == 2)
+ {
+ prev -= 2; /* to word-aligned */
+ for (i = B_SIZE; i > 0; i--)
+ {
+ x1 = *((uint32*)prev); /* load a3 a2 a1 a0 */
+ x2 = *((uint32*)(prev + width)); /* load b3 b2 b1 b0, another line */
+ y1 = *((uint32*)(prev += 4)); /* a7 a6 a5 a4 */
+ y2 = *((uint32*)(prev + width)); /* b7 b6 b5 b4 */
+
+ x1m = (x1 >> 2) & mask; /* zero out last 2 bits */
+ x2m = (x2 >> 2) & mask;
+ x1 = x1 ^(x1m << 2);
+ x2 = x2 ^(x2m << 2);
+ x1m += x2m;
+ x1 += x2;
+
+ /* x2m, x2 free */
+ y1m = (y1 >> 2) & mask; /* zero out last 2 bits */
+ y2m = (y2 >> 2) & mask;
+ y1 = y1 ^(y1m << 2);
+ y2 = y2 ^(y2m << 2);
+ y1m += y2m;
+ y1 += y2;
+
+ /* y2m, y2 free */
+ /* x2m, x2 free */
+ x2 = *((uint32*)(prev += 4)); /* a11 a10 a9 a8 */
+ y2 = *((uint32*)(prev + width)); /* b11 b10 b9 b8 */
+ x2m = (x2 >> 2) & mask;
+ y2m = (y2 >> 2) & mask;
+ x2 = x2 ^(x2m << 2);
+ y2 = y2 ^(y2m << 2);
+ x2m += y2m;
+ x2 += y2;
+ /* y2m, y2 free */
+
+ /* now operate on x1m, x1, y1m, y1, x2m, x2 */
+ /* x1m = a3+b3, a2+b2, a1+b1, a0+b0 */
+ /* y1m = a7+b7, a6+b6, a5+b5, a4+b4 */
+ /* x2m = a11+b11, a10+b10, a9+b9, a8+b8 */
+ /* x1, y1, x2 */
+
+ x1m >>= 16 ;
+ x1 >>= 16;
+ x1m |= (y1m << 16); /* a5+b5, a4+b4, a3+b3, a2+b2 */
+ x1 |= (y1 << 16);
+ y2m = (y1m << 8);
+ y2 = (y1 << 8);
+ y2m |= (x1m >> 8); /* a6+b6, a5+b5, a4+b4, a3+b3 */
+ y2 |= (x1 >> 8);
+ x1 += rnd2;
+ x1m += y2m; /* a5+b5+a6+b6, ....., a2+b2+a3+b3 */
+ x1 += y2;
+ x1 &= (mask << 2);
+ x1m += (x1 >> 2);
+ *((uint32*)(pred_block += 4)) = x1m; /* save x1m */
+
+ y1m >>= 16;
+ y1 >>= 16;
+ y1m |= (x2m << 16); /* a9+b9, a8+b8, a7+b7, a6+b6 */
+ y1 |= (x2 << 16);
+ y2m = (x2m << 8);
+ y2 = (x2 << 8);
+ y2m |= (y1m >> 8); /* a10+b10, a9+b9, a8+b8, a7+b7,*/
+ y2 |= (y1 >> 8);
+ y1 += rnd2;
+ y1m += y2m; /* a9+b9+a10+b10, ....., a6+b6+a7+b7 */
+ y1 += y2;
+ y1 &= (mask << 2);
+ y1m += (y1 >> 2);
+ *((uint32*)(pred_block += 4)) = y1m; /* save y1m */
+
+ pred_block += offset2;
+ prev += offset;
+ }
+ return 1;
+ }
+ else /* tmp == 3 */
+ {
+ prev -= 3; /* to word-aligned */
+ for (i = B_SIZE; i > 0; i--)
+ {
+ x1 = *((uint32*)prev); /* load a3 a2 a1 a0 */
+ x2 = *((uint32*)(prev + width)); /* load b3 b2 b1 b0, another line */
+ y1 = *((uint32*)(prev += 4)); /* a7 a6 a5 a4 */
+ y2 = *((uint32*)(prev + width)); /* b7 b6 b5 b4 */
+
+ x1m = (x1 >> 2) & mask; /* zero out last 2 bits */
+ x2m = (x2 >> 2) & mask;
+ x1 = x1 ^(x1m << 2);
+ x2 = x2 ^(x2m << 2);
+ x1m += x2m;
+ x1 += x2;
+
+ /* x2m, x2 free */
+ y1m = (y1 >> 2) & mask; /* zero out last 2 bits */
+ y2m = (y2 >> 2) & mask;
+ y1 = y1 ^(y1m << 2);
+ y2 = y2 ^(y2m << 2);
+ y1m += y2m;
+ y1 += y2;
+
+ /* y2m, y2 free */
+ /* x2m, x2 free */
+ x2 = *((uint32*)(prev += 4)); /* a11 a10 a9 a8 */
+ y2 = *((uint32*)(prev + width)); /* b11 b10 b9 b8 */
+ x2m = (x2 >> 2) & mask;
+ y2m = (y2 >> 2) & mask;
+ x2 = x2 ^(x2m << 2);
+ y2 = y2 ^(y2m << 2);
+ x2m += y2m;
+ x2 += y2;
+ /* y2m, y2 free */
+
+ /* now operate on x1m, x1, y1m, y1, x2m, x2 */
+ /* x1m = a3+b3, a2+b2, a1+b1, a0+b0 */
+ /* y1m = a7+b7, a6+b6, a5+b5, a4+b4 */
+ /* x2m = a11+b11, a10+b10, a9+b9, a8+b8 */
+ /* x1, y1, x2 */
+
+ x1m >>= 24 ;
+ x1 >>= 24;
+ x1m |= (y1m << 8); /* a6+b6, a5+b5, a4+b4, a3+b3 */
+ x1 |= (y1 << 8);
+
+ x1m += y1m; /* a6+b6+a7+b7, ....., a3+b3+a4+b4 */
+ x1 += y1;
+ x1 += rnd2;
+ x1 &= (mask << 2);
+ x1m += (x1 >> 2);
+ *((uint32*)(pred_block += 4)) = x1m; /* save x1m */
+
+ y1m >>= 24;
+ y1 >>= 24;
+ y1m |= (x2m << 8); /* a10+b10, a9+b9, a8+b8, a7+b7 */
+ y1 |= (x2 << 8);
+ y1m += x2m; /* a10+b10+a11+b11, ....., a7+b7+a8+b8 */
+ y1 += x2;
+ y1 += rnd2;
+ y1 &= (mask << 2);
+ y1m += (y1 >> 2);
+ *((uint32*)(pred_block += 4)) = y1m; /* save y1m */
+
+ pred_block += offset2;
+ prev += offset;
+ }
+ return 1;
+ }
+}
+
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/get_pred_outside.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/get_pred_outside.cpp
new file mode 100644
index 0000000..9cd9022
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/get_pred_outside.cpp
@@ -0,0 +1,514 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+/*
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ xpos = x half-pixel of (x,y) coordinates within a VOP; motion
+ compensated coordinates; native data type
+ ypos = y half-pixel of (x,y) coordinates within a VOP; motion
+ compensated coordinates; native data type
+ comp = pointer to 8-bit compensated prediction values within a VOP;
+ computed by this module (i/o); full-pel resolution; 8-bit data
+ c_prev = pointer to previous 8-bit prediction values within a VOP;
+ values range from (0-255); full-pel resolution; 8-bit data
+ sh_d = pointer to residual values used to compensate the predicted
+ value; values range from (-512 to 511); full-pel resolution;
+ native data type
+ width = width of the VOP in pixels (x axis); full-pel resolution;
+ native data type
+ height = height of the VOP in pixels (y axis); full-pel resolution;
+ native data type
+ rnd1 = rounding value for case when one dimension uses half-pel
+ resolution; native data type
+ rnd2 = rounding value for case when two dimensions uses half-pel
+ resolution; native data type
+
+ Outputs:
+ returns 1
+
+ Local Stores/Buffers/Pointers Needed:
+ None
+
+ Global Stores/Buffers/Pointers Needed:
+ None
+
+ Pointers and Buffers Modified:
+ comp = buffer contains newly computed compensated prediction values
+
+ Local Stores Modified:
+ None
+
+ Global Stores Modified:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ Summary:
+
+ This function performs motion compensated prediction for the case where
+ the motion vector points to a block outside the VOP. The function interpolates
+ the pixels that are outside the VOP using the boundary pixels for the block.
+ Once the values are interpolated, the pixel values are computed for a block
+ in the current VOP. The prediction values are generated by averaging pixel
+ values in the previous VOP; the block position in the previous frame is
+ computed from the current block's motion vector. The computed pixel values
+ are calculated by adding the prediction values to the block residual values.
+
+ Details:
+
+ First, this functions determines which VOP boundary(ies) the motion vector
+ is outside, i.e., left, right, top, bottom. xpos is compared to the left and
+ right boundaries; ypos is compared to the top and bottom boundaries. The number
+ of block pixels inside the the boundary in the x and y directions are stored
+ in endx and endy, respectively. If the entire block is inside the x or y
+ boundary, the respectively end is set to 0.
+
+ After the boundaries are tested, any pixels lying outside a boundary are
+ interpolated from the boundary pixels. For example, if the block is outside the
+ bottom boundary, boundary pixels alone the bottom of the VOP as used to
+ interpolated those pixels lying outside the bottom boundary. The interpolation
+ used is a simple column-wise or row-wise copy of the boundary pixels (inside the
+ block) depending on which boundary the block is outside. In our example, each
+ boundary pixel would be copied column-wise to the pixel beneath it. If the
+ block was outside right boundary, the boundary pixels would be copied row-wise
+ to the pixel to the right of it. If the block was outside both an x and y
+ boundary, the boundary pixels would be copied row-wise for the portion of the
+ block outside the x boundary, and column-wise for the portion of the block
+ outside the y boundary. And so on.
+
+ Once the pixel interpolation is complete, the motion compensated output values
+ (comp[]) are calculed from the motion compensated prediction (pred[])values and
+ the residual values (sh_d[]) of the current frame. The prediction values are
+ generated by averaging pixel values in the previous VOP; the block position in
+ the previous frame is computed from the current block's motion vector. The
+ computed pixel values are calculated by adding the prediction values to the
+ block residual values.
+
+*/
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "mp4dec_lib.h"
+#include "motion_comp.h"
+
+#define PAD_CORNER { temp = *prev; \
+ temp |= (temp<<8); \
+ temp |= (temp<<16); \
+ *((uint32*)ptr) = temp; \
+ *((uint32*)(ptr+4)) = temp; \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp; \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp; \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp; \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp; \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp; \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp; \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp; }
+
+#define PAD_ROW { temp = *((uint32*)prev); \
+ temp2 = *((uint32*)(prev+4)); \
+ *((uint32*)ptr) = temp;\
+ *((uint32*)(ptr+4)) = temp2; \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp2;\
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp2;\
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp2;\
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp2;\
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp2;\
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp2;\
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp2;}
+
+#define PAD_EXTRA_4x8 { temp = *((uint32*)(prev+8)); \
+ *((uint32*)ptr) = temp; \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+=16)) = temp; }
+
+#define PAD_COL { temp = *prev; \
+ temp|=(temp<<8); temp|=(temp<<16); \
+ *((uint32*)ptr) = temp; \
+ *((uint32*)(ptr+4)) = temp; \
+ temp = *(prev+=16); \
+ temp|=(temp<<8); temp|=(temp<<16); \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp; \
+ temp = *(prev+=16); \
+ temp|=(temp<<8); temp|=(temp<<16); \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp; \
+ temp = *(prev+=16); \
+ temp|=(temp<<8); temp|=(temp<<16); \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp; \
+ temp = *(prev+=16); \
+ temp|=(temp<<8); temp|=(temp<<16); \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp; \
+ temp = *(prev+=16); \
+ temp|=(temp<<8); temp|=(temp<<16); \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp; \
+ temp = *(prev+=16); \
+ temp|=(temp<<8); temp|=(temp<<16); \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp; \
+ temp = *(prev+=16); \
+ temp|=(temp<<8); temp|=(temp<<16); \
+ *((uint32*)(ptr+=16)) = temp; \
+ *((uint32*)(ptr+4)) = temp;}
+
+/* copy 8x8 block */
+#define COPY_BLOCK { *((uint32*)ptr) = *((uint32*)prev); \
+ *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
+ *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
+ *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
+ *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
+ *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
+ *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
+ *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
+ *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
+ *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
+ *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
+ *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
+ *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
+ *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
+ *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
+ *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); }
+
+#define COPY_12x8 { *((uint32*)ptr) = *((uint32*)prev); \
+ *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
+ *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \
+ *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
+ *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
+ *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \
+ *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
+ *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
+ *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \
+ *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
+ *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
+ *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \
+ *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
+ *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
+ *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \
+ *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
+ *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
+ *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \
+ *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
+ *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
+ *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \
+ *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
+ *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
+ *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); }
+
+/*----------------------------------------------------------------------------
+; FUNCTION CODE
+----------------------------------------------------------------------------*/
+int GetPredOutside(
+ int xpos, /* i */
+ int ypos, /* i */
+ uint8 *c_prev, /* i */
+ uint8 *pred_block, /* i */
+ int width, /* i */
+ int height, /* i */
+ int rnd1, /* i */
+ int pred_width
+)
+{
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ uint8 *prev; /* pointers to adjacent pixels in the */
+ uint8 pred[256]; /* storage for padded pixel values, 16x16 */
+ uint8 *ptr;
+ int xoffset;
+ uint32 temp, temp2;
+
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ /* saturate xpos and ypos */
+ if (xpos < -16) xpos = -16;
+ if (xpos > ((width - 1) << 1)) xpos = (width - 1) << 1;
+ if (ypos < -16) ypos = -16;
+ if (ypos > ((height - 1) << 1)) ypos = (height - 1) << 1;
+
+ if (xpos < 0)
+ {
+ if (ypos < 0) /* pad top left of frame */
+ {
+ /* copy the block */
+ ptr = pred + (8 << 4) + 8;
+ prev = c_prev;
+ COPY_BLOCK
+
+ /* pad the corner */
+ ptr = pred;
+ prev = pred + (8 << 4) + 8;
+ PAD_CORNER
+
+ /* pad top */
+ ptr = pred + 8;
+ prev = pred + (8 << 4) + 8;
+ PAD_ROW
+
+ /* pad left */
+ ptr = pred + (8 << 4);
+ prev = pred + (8 << 4) + 8;
+ PAD_COL
+
+
+ ptr = pred + (((ypos >> 1) + 8) << 4) + (xpos >> 1) + 8;
+
+ GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1);
+
+ return 1;
+ }
+ else if ((ypos >> 1) < (height - B_SIZE)) /* pad left of frame */
+ {
+ /* copy block */
+ ptr = pred + 8;
+ prev = c_prev + (ypos >> 1) * width;
+ COPY_BLOCK
+ /* copy extra line */
+ *((uint32*)(ptr += 16)) = *((uint32*)(prev += width));
+ *((uint32*)(ptr + 4)) = *((uint32*)(prev + 4));
+
+ /* pad left */
+ ptr = pred;
+ prev = pred + 8;
+ PAD_COL
+ /* pad extra line */
+ temp = *(prev += 16);
+ temp |= (temp << 8);
+ temp |= (temp << 16);
+ *((uint32*)(ptr += 16)) = temp;
+ *((uint32*)(ptr + 4)) = temp;
+
+ ptr = pred + 8 + (xpos >> 1);
+
+ GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1);
+
+ return 1;
+ }
+ else /* pad bottom left of frame */
+ {
+ /* copy the block */
+ ptr = pred + 8; /* point to the center */
+ prev = c_prev + width * (height - 8);
+ COPY_BLOCK
+
+ /* pad the corner */
+ ptr = pred + (8 << 4);
+ prev = ptr - 8;
+ PAD_CORNER
+
+ /* pad bottom */
+ ptr = pred + (8 << 4) + 8;
+ prev = ptr - 16;
+ PAD_ROW
+
+ /* pad left */
+ ptr = pred ;
+ prev = ptr + 8;
+ PAD_COL
+
+ ptr = pred + 8 + (((ypos >> 1) - (height - 8)) << 4) + (xpos >> 1);
+
+ GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1);
+
+ return 1;
+ }
+ }
+ else if ((xpos >> 1) < (width - B_SIZE))
+ {
+ if (ypos < 0) /* pad top of frame */
+ {
+ xoffset = xpos >> 1;
+ xoffset = xoffset & 0x3; /* word align ptr */
+
+ /* copy block */
+ ptr = pred + (8 << 4);
+ prev = c_prev + (xpos >> 1) - xoffset;
+
+ if (xoffset || (xpos&1)) /* copy extra 4x8 */
+ {
+ COPY_12x8
+ }
+ else
+ {
+ COPY_BLOCK
+ }
+
+ /* pad top */
+ ptr = pred;
+ prev = pred + (8 << 4);
+ PAD_ROW
+ if (xoffset || (xpos&1)) /* pad extra 4x8 */
+ {
+ ptr = pred + 8;
+ PAD_EXTRA_4x8
+ }
+
+ ptr = pred + (((ypos >> 1) + 8) << 4) + xoffset;
+
+ GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1);
+
+ return 1;
+ }
+ else /* pad bottom of frame */
+ {
+ xoffset = xpos >> 1;
+ xoffset = xoffset & 0x3; /* word align ptr */
+ /* copy block */
+ ptr = pred ;
+ prev = c_prev + width * (height - 8) + (xpos >> 1) - xoffset;
+ if (xoffset || (xpos&1))
+ {
+ COPY_12x8
+ }
+ else
+ {
+ COPY_BLOCK
+ }
+
+ /* pad bottom */
+ ptr = pred + (8 << 4);
+ prev = ptr - 16;
+ PAD_ROW
+ if (xoffset || (xpos&1))
+ {
+ ptr = pred + (8 << 4) + 8;
+ PAD_EXTRA_4x8
+ }
+
+ ptr = pred + (((ypos >> 1) - (height - 8)) << 4) + xoffset;
+
+ GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1);
+
+ return 1;
+ }
+ }
+ else
+ {
+ if (ypos < 0) /* pad top right of frame */
+ {
+ /* copy block */
+ ptr = pred + (8 << 4);
+ prev = c_prev + width - 8;
+ COPY_BLOCK
+
+ /* pad top-right */
+ ptr = pred + 8;
+ prev = pred + (8 << 4) + 7;
+ PAD_CORNER
+
+ /* pad top */
+ ptr = pred ;
+ prev = pred + (8 << 4);
+ PAD_ROW;
+
+ /* pad right */
+ ptr = pred + (8 << 4) + 8;
+ prev = ptr - 1;
+ PAD_COL;
+
+ ptr = pred + ((8 + (ypos >> 1)) << 4) + (8 - (width - (xpos >> 1)));
+
+ GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1);
+
+ return 1;
+ }
+ else if ((ypos >> 1) < (height - B_SIZE)) /* pad right of frame */
+ {
+ /* copy block */
+ ptr = pred;
+ prev = c_prev + (ypos >> 1) * width + width - 8;
+ COPY_BLOCK
+ /* copy extra line */
+ *((uint32*)(ptr += 16)) = *((uint32*)(prev += width));
+ *((uint32*)(ptr + 4)) = *((uint32*)(prev + 4));
+
+ /* pad right */
+ ptr = pred + 8;
+ prev = ptr - 1;
+ PAD_COL;
+ /* pad extra line */
+ temp = *(prev += 16);
+ temp |= (temp << 8);
+ temp |= (temp << 16);
+ *((uint32*)(ptr += 16)) = temp;
+ *((uint32*)(ptr + 4)) = temp;
+
+
+ ptr = pred + 8 - (width - (xpos >> 1));
+
+ GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1);
+
+ return 1;
+
+ }
+ else /* pad bottom right of frame */
+ {
+ /* copy block */
+ ptr = pred;
+ prev = c_prev + width * (height - 8) + width - 8;
+ COPY_BLOCK
+
+ /* pad bottom-right */
+ ptr = pred + (8 << 4) + 8;
+ prev = ptr - 17;
+ PAD_CORNER
+
+ /* pad right */
+ ptr = pred + 8;
+ prev = ptr - 1;
+ PAD_COL
+
+ /* pad bottom */
+ ptr = pred + (8 << 4);
+ prev = ptr - 16;
+ PAD_ROW
+
+ ptr = pred + 8 - (width - (xpos >> 1)) + ((8 - (height - (ypos >> 1))) << 4);
+
+ GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1);
+
+ return 1;
+ }
+ }
+}
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/idct.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/idct.cpp
new file mode 100644
index 0000000..2e932a4
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/idct.cpp
@@ -0,0 +1,579 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+/*
+------------------------------------------------------------------------------
+ MODULE DESCRIPTION
+
+ This file contains the functions that transform an 8r8 image block from
+ dequantized DCT coefficients to spatial domain pirel values by calculating
+ inverse discrete cosine transform (IDCT).
+
+------------------------------------------------------------------------------
+*/
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "mp4dec_lib.h"
+#include "idct.h"
+#include "motion_comp.h"
+#ifndef FAST_IDCT
+
+/*
+------------------------------------------------------------------------------
+ FUNCTION NAME: idct
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS FOR idct
+
+ Inputs:
+ blk = pointer to the buffer containing the dequantized DCT
+ coefficients of type int for an 8r8 image block;
+ values range from (-2048, 2047) which defined as standard.
+
+ Local Stores/Buffers/Pointers Needed:
+ None
+
+ Global Stores/Buffers/Pointers Needed:
+ None
+
+ Outputs:
+ None
+
+ Pointers and Buffers Modified:
+ blk points to the found IDCT values for an 8r8 image block.
+
+ Local Stores Modified:
+ None
+
+ Global Stores Modified:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION FOR idct
+
+ This function transforms an 8r8 image block from dequantized DCT coefficients
+ (F(u,v)) to spatial domain pirel values (f(r,y)) by performing the two
+ dimensional inverse discrete cosine transform (IDCT).
+
+ _7_ _7_ C(u) C(v)
+ f(r,y) = \ \ F(u,v)---- ----cos[(2r+1)*u*pi/16]cos[(2y+1)*v*pi/16]
+ /__ /__ 2 2
+ u=0 v=0
+
+ where C(i) = 1/sqrt(2) if i=0
+ C(i) = 1 otherwise
+
+ 2-D IDCT can be separated as horizontal(row-wise) and vertical(column-wise)
+ 1-D IDCTs. Therefore, 2-D IDCT values are found by the following two steps:
+ 1. Find horizontal 1-D IDCT values for each row from 8r8 dequantized DCT
+ coefficients by row IDCT operation.
+
+ _7_ C(u)
+ g(r,v) = \ F(u,v) ---- cos[(2r+1)*u*pi/16]
+ /__ 2
+ u=0
+
+ 2. Find vertical 1-D IDCT values for each column from the results of 1
+ by column IDCT operation.
+
+ _7_ C(v)
+ f(r,y) = \ g(r,v) ---- cos[(2y+1)*v*pi/16]
+ /__ 2
+ v=0
+
+------------------------------------------------------------------------------
+ REQUIREMENTS FOR idct
+
+ None
+
+------------------------------------------------------------------------------
+*/
+/* REFERENCES FOR idct */
+/* idct.c, inverse fast discrete cosine transform
+ inverse two dimensional DCT, Chen-Wang algorithm
+ (cf. IEEE ASSP-32, pp. 803-816, Aug. 1984)
+ 32-bit integer arithmetic (8 bit coefficients)
+ 11 mults, 29 adds per DCT
+ sE, 18.8.91
+
+ coefficients ertended to 12 bit for IEEE1180-1990
+ compliance sE, 2.1.94
+*/
+
+
+/*----------------------------------------------------------------------------
+; Function Code FOR idct
+----------------------------------------------------------------------------*/
+void idct_intra(
+ int *blk, uint8 *comp, int width
+)
+{
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int i;
+ int32 tmpBLK[64];
+ int32 *tmpBLK32 = &tmpBLK[0];
+ int32 r0, r1, r2, r3, r4, r5, r6, r7, r8; /* butterfly nodes */
+ int32 a;
+ int offset = width - 8;
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ /* two dimensional inverse discrete cosine transform */
+
+
+ /* column (vertical) IDCT */
+ for (i = B_SIZE - 1; i >= 0; i--)
+ {
+ /* initialize butterfly nodes at first stage */
+
+ r1 = blk[B_SIZE * 4 + i] << 11;
+ /* since row IDCT results have net left shift by 3 */
+ /* this left shift by 8 gives net left shift by 11 */
+ /* in order to maintain the same scale as that of */
+ /* coefficients Wi */
+
+ r2 = blk[B_SIZE * 6 + i];
+ r3 = blk[B_SIZE * 2 + i];
+ r4 = blk[B_SIZE * 1 + i];
+ r5 = blk[B_SIZE * 7 + i];
+ r6 = blk[B_SIZE * 5 + i];
+ r7 = blk[B_SIZE * 3 + i];
+
+ if (!(r1 | r2 | r3 | r4 | r5 | r6 | r7))
+ {
+ /* shortcut */
+ /* execute if values of g(r,1) to g(r,7) in a column*/
+ /* are all zeros */
+
+ /* make output of IDCT >>3 or scaled by 1/8 and */
+ /* with the proper rounding */
+ a = (blk[B_SIZE * 0 + i]) << 3;
+ tmpBLK32[B_SIZE * 0 + i] = a;
+ tmpBLK32[B_SIZE * 1 + i] = a;
+ tmpBLK32[B_SIZE * 2 + i] = a;
+ tmpBLK32[B_SIZE * 3 + i] = a;
+ tmpBLK32[B_SIZE * 4 + i] = a;
+ tmpBLK32[B_SIZE * 5 + i] = a;
+ tmpBLK32[B_SIZE * 6 + i] = a;
+ tmpBLK32[B_SIZE * 7 + i] = a;
+ }
+ else
+ {
+ r0 = (blk[8 * 0 + i] << 11) + 128;
+
+ /* first stage */
+
+ r8 = W7 * (r4 + r5);
+ r4 = (r8 + (W1 - W7) * r4);
+ /* Multiplication with Wi increases the net left */
+ /* shift from 11 to 14,we have to shift back by 3*/
+ r5 = (r8 - (W1 + W7) * r5);
+ r8 = W3 * (r6 + r7);
+ r6 = (r8 - (W3 - W5) * r6);
+ r7 = (r8 - (W3 + W5) * r7);
+
+ /* second stage */
+ r8 = r0 + r1;
+ r0 -= r1;
+
+ r1 = W6 * (r3 + r2);
+ r2 = (r1 - (W2 + W6) * r2);
+ r3 = (r1 + (W2 - W6) * r3);
+
+ r1 = r4 + r6;
+ r4 -= r6;
+ r6 = r5 + r7;
+ r5 -= r7;
+
+ /* third stage */
+ r7 = r8 + r3;
+ r8 -= r3;
+ r3 = r0 + r2;
+ r0 -= r2;
+ r2 = (181 * (r4 + r5) + 128) >> 8; /* rounding */
+ r4 = (181 * (r4 - r5) + 128) >> 8;
+
+ /* fourth stage */
+ /* net shift of IDCT is >>3 after the following */
+ /* shift operation, it makes output of 2-D IDCT */
+ /* scaled by 1/8, that is scaled twice by */
+ /* 1/(2*sqrt(2)) for row IDCT and column IDCT. */
+ /* see detail analysis in design doc. */
+ tmpBLK32[0 + i] = (r7 + r1) >> 8;
+ tmpBLK32[(1<<3) + i] = (r3 + r2) >> 8;
+ tmpBLK32[(2<<3) + i] = (r0 + r4) >> 8;
+ tmpBLK32[(3<<3) + i] = (r8 + r6) >> 8;
+ tmpBLK32[(4<<3) + i] = (r8 - r6) >> 8;
+ tmpBLK32[(5<<3) + i] = (r0 - r4) >> 8;
+ tmpBLK32[(6<<3) + i] = (r3 - r2) >> 8;
+ tmpBLK32[(7<<3) + i] = (r7 - r1) >> 8;
+ }
+ }
+ /* row (horizontal) IDCT */
+ for (i = 0 ; i < B_SIZE; i++)
+ {
+ /* initialize butterfly nodes at the first stage */
+
+ r1 = ((int32)tmpBLK32[4+(i<<3)]) << 8;
+ /* r1 left shift by 11 is to maintain the same */
+ /* scale as that of coefficients (W1,...W7) */
+ /* since blk[4] won't multiply with Wi. */
+ /* see detail diagram in design document. */
+
+ r2 = tmpBLK32[6+(i<<3)];
+ r3 = tmpBLK32[2+(i<<3)];
+ r4 = tmpBLK32[1+(i<<3)];
+ r5 = tmpBLK32[7+(i<<3)];
+ r6 = tmpBLK32[5+(i<<3)];
+ r7 = tmpBLK32[3+(i<<3)];
+
+ if (!(r1 | r2 | r3 | r4 | r5 | r6 | r7))
+ {
+ /* shortcut */
+ /* execute if values of F(1,v) to F(7,v) in a row*/
+ /* are all zeros */
+
+ /* output of row IDCT scaled by 8 */
+ a = (((int32)tmpBLK32[0+(i<<3)] + 32) >> 6);
+ CLIP_RESULT(a)
+ *comp++ = a;
+ *comp++ = a;
+ *comp++ = a;
+ *comp++ = a;
+ *comp++ = a;
+ *comp++ = a;
+ *comp++ = a;
+ *comp++ = a;
+
+ comp += offset;
+ }
+
+ else
+ {
+ /* for proper rounding in the fourth stage */
+ r0 = (((int32)tmpBLK32[0+(i<<3)]) << 8) + 8192;
+
+ /* first stage */
+
+ r8 = W7 * (r4 + r5) + 4;
+ r4 = (r8 + (W1 - W7) * r4) >> 3;
+ r5 = (r8 - (W1 + W7) * r5) >> 3;
+
+ r8 = W3 * (r6 + r7) + 4;
+ r6 = (r8 - (W3 - W5) * r6) >> 3;
+ r7 = (r8 - (W3 + W5) * r7) >> 3;
+
+ /* second stage */
+ r8 = r0 + r1;
+ r0 -= r1;
+
+ r1 = W6 * (r3 + r2) + 4;
+ r2 = (r1 - (W2 + W6) * r2) >> 3;
+ r3 = (r1 + (W2 - W6) * r3) >> 3;
+
+ r1 = r4 + r6;
+ r4 -= r6;
+ r6 = r5 + r7;
+ r5 -= r7;
+
+ /* third stage */
+ r7 = r8 + r3;
+ r8 -= r3;
+ r3 = r0 + r2;
+ r0 -= r2;
+ r2 = (181 * (r4 + r5) + 128) >> 8; /* rounding */
+ r4 = (181 * (r4 - r5) + 128) >> 8;
+
+ /* fourth stage */
+ /* net shift of this function is <<3 after the */
+ /* following shift operation, it makes output of */
+ /* row IDCT scaled by 8 to retain 3 bits precision*/
+ a = ((r7 + r1) >> 14);
+ CLIP_RESULT(a)
+ *comp++ = a;
+ a = ((r3 + r2) >> 14);
+ CLIP_RESULT(a)
+ *comp++ = a;
+ a = ((r0 + r4) >> 14);
+ CLIP_RESULT(a)
+ *comp++ = a;
+ a = ((r8 + r6) >> 14);
+ CLIP_RESULT(a)
+ *comp++ = a;
+ a = ((r8 - r6) >> 14);
+ CLIP_RESULT(a)
+ *comp++ = a;
+ a = ((r0 - r4) >> 14);
+ CLIP_RESULT(a)
+ *comp++ = a;
+ a = ((r3 - r2) >> 14);
+ CLIP_RESULT(a)
+ *comp++ = a;
+ a = ((r7 - r1) >> 14);
+ CLIP_RESULT(a)
+ *comp++ = a;
+
+ comp += offset;
+ }
+ }
+
+
+
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return;
+}
+
+void idct(
+ int *blk, uint8 *pred, uint8 *dst, int width)
+{
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int i;
+ int32 tmpBLK[64];
+ int32 *tmpBLK32 = &tmpBLK[0];
+ int32 r0, r1, r2, r3, r4, r5, r6, r7, r8; /* butterfly nodes */
+ int32 a;
+ int res;
+
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ /* two dimensional inverse discrete cosine transform */
+
+
+ /* column (vertical) IDCT */
+ for (i = B_SIZE - 1; i >= 0; i--)
+ {
+ /* initialize butterfly nodes at first stage */
+
+ r1 = blk[B_SIZE * 4 + i] << 11;
+ /* since row IDCT results have net left shift by 3 */
+ /* this left shift by 8 gives net left shift by 11 */
+ /* in order to maintain the same scale as that of */
+ /* coefficients Wi */
+
+ r2 = blk[B_SIZE * 6 + i];
+ r3 = blk[B_SIZE * 2 + i];
+ r4 = blk[B_SIZE * 1 + i];
+ r5 = blk[B_SIZE * 7 + i];
+ r6 = blk[B_SIZE * 5 + i];
+ r7 = blk[B_SIZE * 3 + i];
+
+ if (!(r1 | r2 | r3 | r4 | r5 | r6 | r7))
+ {
+ /* shortcut */
+ /* execute if values of g(r,1) to g(r,7) in a column*/
+ /* are all zeros */
+
+ /* make output of IDCT >>3 or scaled by 1/8 and */
+ /* with the proper rounding */
+ a = (blk[B_SIZE * 0 + i]) << 3;
+ tmpBLK32[B_SIZE * 0 + i] = a;
+ tmpBLK32[B_SIZE * 1 + i] = a;
+ tmpBLK32[B_SIZE * 2 + i] = a;
+ tmpBLK32[B_SIZE * 3 + i] = a;
+ tmpBLK32[B_SIZE * 4 + i] = a;
+ tmpBLK32[B_SIZE * 5 + i] = a;
+ tmpBLK32[B_SIZE * 6 + i] = a;
+ tmpBLK32[B_SIZE * 7 + i] = a;
+ }
+ else
+ {
+ r0 = (blk[8 * 0 + i] << 11) + 128;
+
+ /* first stage */
+
+ r8 = W7 * (r4 + r5);
+ r4 = (r8 + (W1 - W7) * r4);
+ /* Multiplication with Wi increases the net left */
+ /* shift from 11 to 14,we have to shift back by 3*/
+ r5 = (r8 - (W1 + W7) * r5);
+ r8 = W3 * (r6 + r7);
+ r6 = (r8 - (W3 - W5) * r6);
+ r7 = (r8 - (W3 + W5) * r7);
+
+ /* second stage */
+ r8 = r0 + r1;
+ r0 -= r1;
+
+ r1 = W6 * (r3 + r2);
+ r2 = (r1 - (W2 + W6) * r2);
+ r3 = (r1 + (W2 - W6) * r3);
+
+ r1 = r4 + r6;
+ r4 -= r6;
+ r6 = r5 + r7;
+ r5 -= r7;
+
+ /* third stage */
+ r7 = r8 + r3;
+ r8 -= r3;
+ r3 = r0 + r2;
+ r0 -= r2;
+ r2 = (181 * (r4 + r5) + 128) >> 8; /* rounding */
+ r4 = (181 * (r4 - r5) + 128) >> 8;
+
+ /* fourth stage */
+ /* net shift of IDCT is >>3 after the following */
+ /* shift operation, it makes output of 2-D IDCT */
+ /* scaled by 1/8, that is scaled twice by */
+ /* 1/(2*sqrt(2)) for row IDCT and column IDCT. */
+ /* see detail analysis in design doc. */
+ tmpBLK32[0 + i] = (r7 + r1) >> 8;
+ tmpBLK32[(1<<3) + i] = (r3 + r2) >> 8;
+ tmpBLK32[(2<<3) + i] = (r0 + r4) >> 8;
+ tmpBLK32[(3<<3) + i] = (r8 + r6) >> 8;
+ tmpBLK32[(4<<3) + i] = (r8 - r6) >> 8;
+ tmpBLK32[(5<<3) + i] = (r0 - r4) >> 8;
+ tmpBLK32[(6<<3) + i] = (r3 - r2) >> 8;
+ tmpBLK32[(7<<3) + i] = (r7 - r1) >> 8;
+ }
+ }
+ /* row (horizontal) IDCT */
+ for (i = B_SIZE - 1; i >= 0; i--)
+ {
+ /* initialize butterfly nodes at the first stage */
+
+ r1 = ((int32)tmpBLK32[4+(i<<3)]) << 8;
+ /* r1 left shift by 11 is to maintain the same */
+ /* scale as that of coefficients (W1,...W7) */
+ /* since blk[4] won't multiply with Wi. */
+ /* see detail diagram in design document. */
+
+ r2 = tmpBLK32[6+(i<<3)];
+ r3 = tmpBLK32[2+(i<<3)];
+ r4 = tmpBLK32[1+(i<<3)];
+ r5 = tmpBLK32[7+(i<<3)];
+ r6 = tmpBLK32[5+(i<<3)];
+ r7 = tmpBLK32[3+(i<<3)];
+
+ if (!(r1 | r2 | r3 | r4 | r5 | r6 | r7))
+ {
+ /* shortcut */
+ /* execute if values of F(1,v) to F(7,v) in a row*/
+ /* are all zeros */
+
+ /* output of row IDCT scaled by 8 */
+ a = (tmpBLK32[0+(i<<3)] + 32) >> 6;
+ blk[0+(i<<3)] = a;
+ blk[1+(i<<3)] = a;
+ blk[2+(i<<3)] = a;
+ blk[3+(i<<3)] = a;
+ blk[4+(i<<3)] = a;
+ blk[5+(i<<3)] = a;
+ blk[6+(i<<3)] = a;
+ blk[7+(i<<3)] = a;
+
+ }
+
+ else
+ {
+ /* for proper rounding in the fourth stage */
+ r0 = (((int32)tmpBLK32[0+(i<<3)]) << 8) + 8192;
+
+ /* first stage */
+
+ r8 = W7 * (r4 + r5) + 4;
+ r4 = (r8 + (W1 - W7) * r4) >> 3;
+ r5 = (r8 - (W1 + W7) * r5) >> 3;
+
+ r8 = W3 * (r6 + r7) + 4;
+ r6 = (r8 - (W3 - W5) * r6) >> 3;
+ r7 = (r8 - (W3 + W5) * r7) >> 3;
+
+ /* second stage */
+ r8 = r0 + r1;
+ r0 -= r1;
+
+ r1 = W6 * (r3 + r2) + 4;
+ r2 = (r1 - (W2 + W6) * r2) >> 3;
+ r3 = (r1 + (W2 - W6) * r3) >> 3;
+
+ r1 = r4 + r6;
+ r4 -= r6;
+ r6 = r5 + r7;
+ r5 -= r7;
+
+ /* third stage */
+ r7 = r8 + r3;
+ r8 -= r3;
+ r3 = r0 + r2;
+ r0 -= r2;
+ r2 = (181 * (r4 + r5) + 128) >> 8; /* rounding */
+ r4 = (181 * (r4 - r5) + 128) >> 8;
+
+ /* fourth stage */
+ /* net shift of this function is <<3 after the */
+ /* following shift operation, it makes output of */
+ /* row IDCT scaled by 8 to retain 3 bits precision*/
+ blk[0+(i<<3)] = (r7 + r1) >> 14;
+ blk[1+(i<<3)] = (r3 + r2) >> 14;
+ blk[2+(i<<3)] = (r0 + r4) >> 14;
+ blk[3+(i<<3)] = (r8 + r6) >> 14;
+ blk[4+(i<<3)] = (r8 - r6) >> 14;
+ blk[5+(i<<3)] = (r0 - r4) >> 14;
+ blk[6+(i<<3)] = (r3 - r2) >> 14;
+ blk[7+(i<<3)] = (r7 - r1) >> 14;
+ }
+ /* add with prediction , 08/03/05 */
+ res = (*pred++ + block[0+(i<<3)]);
+ CLIP_RESULT(res);
+ *dst++ = res;
+ res = (*pred++ + block[1+(i<<3)]);
+ CLIP_RESULT(res);
+ *dst++ = res;
+ res = (*pred++ + block[2+(i<<3)]);
+ CLIP_RESULT(res);
+ *dst++ = res;
+ res = (*pred++ + block[3+(i<<3)]);
+ CLIP_RESULT(res);
+ *dst++ = res;
+ res = (*pred++ + block[4+(i<<3)]);
+ CLIP_RESULT(res);
+ *dst++ = res;
+ res = (*pred++ + block[5+(i<<3)]);
+ CLIP_RESULT(res);
+ *dst++ = res;
+ res = (*pred++ + block[6+(i<<3)]);
+ CLIP_RESULT(res);
+ *dst++ = res;
+ res = (*pred++ + block[7+(i<<3)]);
+ CLIP_RESULT(res);
+ *dst++ = res;
+
+ pred += 8;
+ dst += (width - 8);
+ }
+
+
+
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return;
+}
+
+#endif
+/*----------------------------------------------------------------------------
+; End Function: idct
+----------------------------------------------------------------------------*/
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/idct.h b/media/libstagefright/codecs/m4v_h263/dec/src/idct.h
new file mode 100644
index 0000000..8edb654
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/idct.h
@@ -0,0 +1,118 @@
+/* ------------------------------------------------------------------
+ * 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 idct_h
+#define idct_h
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "mp4dec_lib.h"
+
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here.
+----------------------------------------------------------------------------*/
+#define INTEGER_IDCT
+
+#ifdef FAST_IDCT
+#ifndef INTEGER_IDCT
+#define INTEGER_IDCT
+#endif
+#endif
+
+#ifdef FAST_IDCT
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+ void idctrow0(int16 *blk, uint8 *pred, uint8 *dst, int width);
+ void idctrow1(int16 *blk, uint8 *pred, uint8 *dst, int width);
+ void idctrow2(int16 *blk, uint8 *pred, uint8 *dst, int width);
+ void idctrow3(int16 *blk, uint8 *pred, uint8 *dst, int width);
+ void idctrow4(int16 *blk, uint8 *pred, uint8 *dst, int width);
+ void idctcol0(int16 *blk);
+ void idctcol1(int16 *blk);
+ void idctcol2(int16 *blk);
+ void idctcol3(int16 *blk);
+ void idctcol4(int16 *blk);
+
+ void idctrow0_intra(int16 *blk, PIXEL *comp, int width);
+ void idctrow1_intra(int16 *blk, PIXEL *comp, int width);
+ void idctrow2_intra(int16 *blk, PIXEL *comp, int width);
+ void idctrow3_intra(int16 *blk, PIXEL *comp, int width);
+ void idctrow4_intra(int16 *blk, PIXEL *comp, int width);
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+/* this code assumes ">>" to be a two's-complement arithmetic */
+/* right shift: (-2)>>1 == -1 , (-3)>>1 == -2 */
+
+/* a positive real constant is converted to an integer scaled by 2048 */
+/* or equivalent to left shift by 11 */
+
+#define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */
+#define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */
+#define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */
+#define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */
+#define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */
+#define W7 565 /* 2048*sqrt(2)*cos(7*pi/16) */
+#define W1mW7 2276
+#define W1pW7 3406
+#define W5mW3 -799
+#define mW3mW5 -4017
+#define mW2mW6 -3784
+#define W2mW6 1568
+
+/* left shift by 11 is to maintain the accuracy of the decimal point */
+/* for the transform coefficients (W1,...W7) */
+
+/*----------------------------------------------------------------------------
+; EXTERNAL VARIABLES REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; SIMPLE TYPEDEF'S
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; ENUMERATED TYPEDEF'S
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; STRUCTURES TYPEDEF'S
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; GLOBAL FUNCTION DEFINITIONS
+; Function Prototype declaration
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; END
+----------------------------------------------------------------------------*/
+#endif
+
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/idct_vca.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/idct_vca.cpp
new file mode 100644
index 0000000..f35ce4f
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/idct_vca.cpp
@@ -0,0 +1,660 @@
+/* ------------------------------------------------------------------
+ * 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 "mp4def.h"
+#include "idct.h"
+#include "motion_comp.h"
+
+#ifdef FAST_IDCT
+
+/****************************************************************
+* vca_idct.c : created 6/1/99 for several options
+* of hard-coded reduced idct function (using nz_coefs)
+******************************************************************/
+
+/*****************************************************/
+//pretested version
+void idctrow0(int16 *, uint8 *, uint8 *, int)
+{
+ return ;
+}
+void idctcol0(int16 *)
+{
+ return ;
+}
+
+void idctrow1(int16 *blk, uint8 *pred, uint8 *dst, int width)
+{
+ /* shortcut */
+ int tmp;
+ int i = 8;
+ uint32 pred_word, dst_word;
+ int res, res2;
+
+ /* preset the offset, such that we can take advantage pre-offset addressing mode */
+ width -= 4;
+ dst -= width;
+ pred -= 12;
+ blk -= 8;
+
+ while (i--)
+ {
+ tmp = (*(blk += 8) + 32) >> 6;
+ *blk = 0;
+
+ pred_word = *((uint32*)(pred += 12)); /* read 4 bytes from pred */
+ res = tmp + (pred_word & 0xFF);
+ CLIP_RESULT(res);
+ res2 = tmp + ((pred_word >> 8) & 0xFF);
+ CLIP_RESULT(res2);
+ dst_word = (res2 << 8) | res;
+ res = tmp + ((pred_word >> 16) & 0xFF);
+ CLIP_RESULT(res);
+ dst_word |= (res << 16);
+ res = tmp + ((pred_word >> 24) & 0xFF);
+ CLIP_RESULT(res);
+ dst_word |= (res << 24);
+ *((uint32*)(dst += width)) = dst_word; /* save 4 bytes to dst */
+
+ pred_word = *((uint32*)(pred += 4)); /* read 4 bytes from pred */
+ res = tmp + (pred_word & 0xFF);
+ CLIP_RESULT(res);
+ res2 = tmp + ((pred_word >> 8) & 0xFF);
+ CLIP_RESULT(res2);
+ dst_word = (res2 << 8) | res;
+ res = tmp + ((pred_word >> 16) & 0xFF);
+ CLIP_RESULT(res);
+ dst_word |= (res << 16);
+ res = tmp + ((pred_word >> 24) & 0xFF);
+ CLIP_RESULT(res);
+ dst_word |= (res << 24);
+ *((uint32*)(dst += 4)) = dst_word; /* save 4 bytes to dst */
+ }
+ return;
+}
+
+void idctcol1(int16 *blk)
+{ /* shortcut */
+ blk[0] = blk[8] = blk[16] = blk[24] = blk[32] = blk[40] = blk[48] = blk[56] =
+ blk[0] << 3;
+ return;
+}
+
+void idctrow2(int16 *blk, uint8 *pred, uint8 *dst, int width)
+{
+ int32 x0, x1, x2, x4, x5;
+ int i = 8;
+ uint32 pred_word, dst_word;
+ int res, res2;
+
+ /* preset the offset, such that we can take advantage pre-offset addressing mode */
+ width -= 4;
+ dst -= width;
+ pred -= 12;
+ blk -= 8;
+
+ while (i--)
+ {
+ /* shortcut */
+ x4 = blk[9];
+ blk[9] = 0;
+ x0 = ((*(blk += 8)) << 8) + 8192;
+ *blk = 0; /* for proper rounding in the fourth stage */
+
+ /* first stage */
+ x5 = (W7 * x4 + 4) >> 3;
+ x4 = (W1 * x4 + 4) >> 3;
+
+ /* third stage */
+ x2 = (181 * (x4 + x5) + 128) >> 8;
+ x1 = (181 * (x4 - x5) + 128) >> 8;
+
+ /* fourth stage */
+ pred_word = *((uint32*)(pred += 12)); /* read 4 bytes from pred */
+ res = (x0 + x4) >> 14;
+ ADD_AND_CLIP1(res);
+ res2 = (x0 + x2) >> 14;
+ ADD_AND_CLIP2(res2);
+ dst_word = (res2 << 8) | res;
+ res = (x0 + x1) >> 14;
+ ADD_AND_CLIP3(res);
+ dst_word |= (res << 16);
+ res = (x0 + x5) >> 14;
+ ADD_AND_CLIP4(res);
+ dst_word |= (res << 24);
+ *((uint32*)(dst += width)) = dst_word; /* save 4 bytes to dst */
+
+ pred_word = *((uint32*)(pred += 4)); /* read 4 bytes from pred */
+ res = (x0 - x5) >> 14;
+ ADD_AND_CLIP1(res);
+ res2 = (x0 - x1) >> 14;
+ ADD_AND_CLIP2(res2);
+ dst_word = (res2 << 8) | res;
+ res = (x0 - x2) >> 14;
+ ADD_AND_CLIP3(res);
+ dst_word |= (res << 16);
+ res = (x0 - x4) >> 14;
+ ADD_AND_CLIP4(res);
+ dst_word |= (res << 24);
+ *((uint32*)(dst += 4)) = dst_word; /* save 4 bytes to dst */
+ }
+ return ;
+}
+
+void idctcol2(int16 *blk)
+{
+ int32 x0, x1, x3, x5, x7;//, x8;
+
+ x1 = blk[8];
+ x0 = ((int32)blk[0] << 11) + 128;
+ /* both upper and lower*/
+
+ x7 = W7 * x1;
+ x1 = W1 * x1;
+
+ x3 = x7;
+ x5 = (181 * (x1 - x7) + 128) >> 8;
+ x7 = (181 * (x1 + x7) + 128) >> 8;
+
+ blk[0] = (x0 + x1) >> 8;
+ blk[8] = (x0 + x7) >> 8;
+ blk[16] = (x0 + x5) >> 8;
+ blk[24] = (x0 + x3) >> 8;
+ blk[56] = (x0 - x1) >> 8;
+ blk[48] = (x0 - x7) >> 8;
+ blk[40] = (x0 - x5) >> 8;
+ blk[32] = (x0 - x3) >> 8;
+
+ return ;
+}
+
+void idctrow3(int16 *blk, uint8 *pred, uint8 *dst, int width)
+{
+ int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
+ int i = 8;
+ uint32 pred_word, dst_word;
+ int res, res2;
+
+ /* preset the offset, such that we can take advantage pre-offset addressing mode */
+ width -= 4;
+ dst -= width;
+ pred -= 12;
+ blk -= 8;
+
+ while (i--)
+ {
+ x2 = blk[10];
+ blk[10] = 0;
+ x1 = blk[9];
+ blk[9] = 0;
+ x0 = ((*(blk += 8)) << 8) + 8192;
+ *blk = 0; /* for proper rounding in the fourth stage */
+ /* both upper and lower*/
+ /* both x2orx6 and x0orx4 */
+
+ x4 = x0;
+ x6 = (W6 * x2 + 4) >> 3;
+ x2 = (W2 * x2 + 4) >> 3;
+ x8 = x0 - x2;
+ x0 += x2;
+ x2 = x8;
+ x8 = x4 - x6;
+ x4 += x6;
+ x6 = x8;
+
+ x7 = (W7 * x1 + 4) >> 3;
+ x1 = (W1 * x1 + 4) >> 3;
+ x3 = x7;
+ x5 = (181 * (x1 - x7) + 128) >> 8;
+ x7 = (181 * (x1 + x7) + 128) >> 8;
+
+ pred_word = *((uint32*)(pred += 12)); /* read 4 bytes from pred */
+ res = (x0 + x1) >> 14;
+ ADD_AND_CLIP1(res);
+ res2 = (x4 + x7) >> 14;
+ ADD_AND_CLIP2(res2);
+ dst_word = (res2 << 8) | res;
+ res = (x6 + x5) >> 14;
+ ADD_AND_CLIP3(res);
+ dst_word |= (res << 16);
+ res = (x2 + x3) >> 14;
+ ADD_AND_CLIP4(res);
+ dst_word |= (res << 24);
+ *((uint32*)(dst += width)) = dst_word; /* save 4 bytes to dst */
+
+ pred_word = *((uint32*)(pred += 4)); /* read 4 bytes from pred */
+ res = (x2 - x3) >> 14;
+ ADD_AND_CLIP1(res);
+ res2 = (x6 - x5) >> 14;
+ ADD_AND_CLIP2(res2);
+ dst_word = (res2 << 8) | res;
+ res = (x4 - x7) >> 14;
+ ADD_AND_CLIP3(res);
+ dst_word |= (res << 16);
+ res = (x0 - x1) >> 14;
+ ADD_AND_CLIP4(res);
+ dst_word |= (res << 24);
+ *((uint32*)(dst += 4)) = dst_word; /* save 4 bytes to dst */
+ }
+
+ return ;
+}
+
+void idctcol3(int16 *blk)
+{
+ int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
+
+ x2 = blk[16];
+ x1 = blk[8];
+ x0 = ((int32)blk[0] << 11) + 128;
+
+ x4 = x0;
+ x6 = W6 * x2;
+ x2 = W2 * x2;
+ x8 = x0 - x2;
+ x0 += x2;
+ x2 = x8;
+ x8 = x4 - x6;
+ x4 += x6;
+ x6 = x8;
+
+ x7 = W7 * x1;
+ x1 = W1 * x1;
+ x3 = x7;
+ x5 = (181 * (x1 - x7) + 128) >> 8;
+ x7 = (181 * (x1 + x7) + 128) >> 8;
+
+ blk[0] = (x0 + x1) >> 8;
+ blk[8] = (x4 + x7) >> 8;
+ blk[16] = (x6 + x5) >> 8;
+ blk[24] = (x2 + x3) >> 8;
+ blk[56] = (x0 - x1) >> 8;
+ blk[48] = (x4 - x7) >> 8;
+ blk[40] = (x6 - x5) >> 8;
+ blk[32] = (x2 - x3) >> 8;
+
+ return;
+}
+
+
+void idctrow4(int16 *blk, uint8 *pred, uint8 *dst, int width)
+{
+ int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
+ int i = 8;
+ uint32 pred_word, dst_word;
+ int res, res2;
+
+ /* preset the offset, such that we can take advantage pre-offset addressing mode */
+ width -= 4;
+ dst -= width;
+ pred -= 12;
+ blk -= 8;
+
+ while (i--)
+ {
+ x2 = blk[10];
+ blk[10] = 0;
+ x1 = blk[9];
+ blk[9] = 0;
+ x3 = blk[11];
+ blk[11] = 0;
+ x0 = ((*(blk += 8)) << 8) + 8192;
+ *blk = 0; /* for proper rounding in the fourth stage */
+
+ x4 = x0;
+ x6 = (W6 * x2 + 4) >> 3;
+ x2 = (W2 * x2 + 4) >> 3;
+ x8 = x0 - x2;
+ x0 += x2;
+ x2 = x8;
+ x8 = x4 - x6;
+ x4 += x6;
+ x6 = x8;
+
+ x7 = (W7 * x1 + 4) >> 3;
+ x1 = (W1 * x1 + 4) >> 3;
+ x5 = (W3 * x3 + 4) >> 3;
+ x3 = (- W5 * x3 + 4) >> 3;
+ x8 = x1 - x5;
+ x1 += x5;
+ x5 = x8;
+ x8 = x7 - x3;
+ x3 += x7;
+ x7 = (181 * (x5 + x8) + 128) >> 8;
+ x5 = (181 * (x5 - x8) + 128) >> 8;
+
+ pred_word = *((uint32*)(pred += 12)); /* read 4 bytes from pred */
+ res = (x0 + x1) >> 14;
+ ADD_AND_CLIP1(res);
+ res2 = (x4 + x7) >> 14;
+ ADD_AND_CLIP2(res2);
+ dst_word = (res2 << 8) | res;
+ res = (x6 + x5) >> 14;
+ ADD_AND_CLIP3(res);
+ dst_word |= (res << 16);
+ res = (x2 + x3) >> 14;
+ ADD_AND_CLIP4(res);
+ dst_word |= (res << 24);
+ *((uint32*)(dst += width)) = dst_word; /* save 4 bytes to dst */
+
+ pred_word = *((uint32*)(pred += 4)); /* read 4 bytes from pred */
+ res = (x2 - x3) >> 14;
+ ADD_AND_CLIP1(res);
+ res2 = (x6 - x5) >> 14;
+ ADD_AND_CLIP2(res2);
+ dst_word = (res2 << 8) | res;
+ res = (x4 - x7) >> 14;
+ ADD_AND_CLIP3(res);
+ dst_word |= (res << 16);
+ res = (x0 - x1) >> 14;
+ ADD_AND_CLIP4(res);
+ dst_word |= (res << 24);
+ *((uint32*)(dst += 4)) = dst_word; /* save 4 bytes to dst */
+ }
+ return ;
+}
+
+void idctcol4(int16 *blk)
+{
+ int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
+ x2 = blk[16];
+ x1 = blk[8];
+ x3 = blk[24];
+ x0 = ((int32)blk[0] << 11) + 128;
+
+ x4 = x0;
+ x6 = W6 * x2;
+ x2 = W2 * x2;
+ x8 = x0 - x2;
+ x0 += x2;
+ x2 = x8;
+ x8 = x4 - x6;
+ x4 += x6;
+ x6 = x8;
+
+ x7 = W7 * x1;
+ x1 = W1 * x1;
+ x5 = W3 * x3;
+ x3 = -W5 * x3;
+ x8 = x1 - x5;
+ x1 += x5;
+ x5 = x8;
+ x8 = x7 - x3;
+ x3 += x7;
+ x7 = (181 * (x5 + x8) + 128) >> 8;
+ x5 = (181 * (x5 - x8) + 128) >> 8;
+
+
+ blk[0] = (x0 + x1) >> 8;
+ blk[8] = (x4 + x7) >> 8;
+ blk[16] = (x6 + x5) >> 8;
+ blk[24] = (x2 + x3) >> 8;
+ blk[56] = (x0 - x1) >> 8;
+ blk[48] = (x4 - x7) >> 8;
+ blk[40] = (x6 - x5) >> 8;
+ blk[32] = (x2 - x3) >> 8;
+
+ return ;
+}
+
+void idctrow0_intra(int16 *, PIXEL *, int)
+{
+ return ;
+}
+
+void idctrow1_intra(int16 *blk, PIXEL *comp, int width)
+{
+ /* shortcut */
+ int32 tmp;
+ int i = 8;
+ int offset = width;
+ uint32 word;
+
+ comp -= offset;
+ while (i--)
+ {
+ tmp = ((blk[0] + 32) >> 6);
+ blk[0] = 0;
+ CLIP_RESULT(tmp)
+
+ word = (tmp << 8) | tmp;
+ word = (word << 16) | word;
+
+ *((uint32*)(comp += offset)) = word;
+ *((uint32*)(comp + 4)) = word;
+
+
+
+
+ blk += B_SIZE;
+ }
+ return;
+}
+
+void idctrow2_intra(int16 *blk, PIXEL *comp, int width)
+{
+ int32 x0, x1, x2, x4, x5, temp;
+ int i = 8;
+ int offset = width;
+ int32 word;
+
+ comp -= offset;
+ while (i--)
+ {
+ /* shortcut */
+ x4 = blk[1];
+ blk[1] = 0;
+ x0 = ((int32)blk[0] << 8) + 8192;
+ blk[0] = 0; /* for proper rounding in the fourth stage */
+
+ /* first stage */
+ x5 = (W7 * x4 + 4) >> 3;
+ x4 = (W1 * x4 + 4) >> 3;
+
+ /* third stage */
+ x2 = (181 * (x4 + x5) + 128) >> 8;
+ x1 = (181 * (x4 - x5) + 128) >> 8;
+
+ /* fourth stage */
+ word = ((x0 + x4) >> 14);
+ CLIP_RESULT(word)
+
+ temp = ((x0 + x2) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 8);
+ temp = ((x0 + x1) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 16);
+ temp = ((x0 + x5) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 24);
+ *((int32*)(comp += offset)) = word;
+
+ word = ((x0 - x5) >> 14);
+ CLIP_RESULT(word)
+ temp = ((x0 - x1) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 8);
+ temp = ((x0 - x2) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 16);
+ temp = ((x0 - x4) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 24);
+ *((int32*)(comp + 4)) = word;
+
+ blk += B_SIZE;
+ }
+ return ;
+}
+
+void idctrow3_intra(int16 *blk, PIXEL *comp, int width)
+{
+ int32 x0, x1, x2, x3, x4, x5, x6, x7, x8, temp;
+ int i = 8;
+ int offset = width;
+ int32 word;
+
+ comp -= offset;
+
+ while (i--)
+ {
+ x2 = blk[2];
+ blk[2] = 0;
+ x1 = blk[1];
+ blk[1] = 0;
+ x0 = ((int32)blk[0] << 8) + 8192;
+ blk[0] = 0;/* for proper rounding in the fourth stage */
+ /* both upper and lower*/
+ /* both x2orx6 and x0orx4 */
+
+ x4 = x0;
+ x6 = (W6 * x2 + 4) >> 3;
+ x2 = (W2 * x2 + 4) >> 3;
+ x8 = x0 - x2;
+ x0 += x2;
+ x2 = x8;
+ x8 = x4 - x6;
+ x4 += x6;
+ x6 = x8;
+
+ x7 = (W7 * x1 + 4) >> 3;
+ x1 = (W1 * x1 + 4) >> 3;
+ x3 = x7;
+ x5 = (181 * (x1 - x7) + 128) >> 8;
+ x7 = (181 * (x1 + x7) + 128) >> 8;
+
+ word = ((x0 + x1) >> 14);
+ CLIP_RESULT(word)
+ temp = ((x4 + x7) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 8);
+
+
+ temp = ((x6 + x5) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 16);
+
+ temp = ((x2 + x3) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 24);
+ *((int32*)(comp += offset)) = word;
+
+ word = ((x2 - x3) >> 14);
+ CLIP_RESULT(word)
+
+ temp = ((x6 - x5) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 8);
+
+ temp = ((x4 - x7) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 16);
+
+ temp = ((x0 - x1) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 24);
+ *((int32*)(comp + 4)) = word;
+
+ blk += B_SIZE;
+ }
+ return ;
+}
+
+void idctrow4_intra(int16 *blk, PIXEL *comp, int width)
+{
+ int32 x0, x1, x2, x3, x4, x5, x6, x7, x8, temp;
+ int i = 8;
+ int offset = width;
+ int32 word;
+
+ comp -= offset;
+
+ while (i--)
+ {
+ x2 = blk[2];
+ blk[2] = 0;
+ x1 = blk[1];
+ blk[1] = 0;
+ x3 = blk[3];
+ blk[3] = 0;
+ x0 = ((int32)blk[0] << 8) + 8192;
+ blk[0] = 0;/* for proper rounding in the fourth stage */
+
+ x4 = x0;
+ x6 = (W6 * x2 + 4) >> 3;
+ x2 = (W2 * x2 + 4) >> 3;
+ x8 = x0 - x2;
+ x0 += x2;
+ x2 = x8;
+ x8 = x4 - x6;
+ x4 += x6;
+ x6 = x8;
+
+ x7 = (W7 * x1 + 4) >> 3;
+ x1 = (W1 * x1 + 4) >> 3;
+ x5 = (W3 * x3 + 4) >> 3;
+ x3 = (- W5 * x3 + 4) >> 3;
+ x8 = x1 - x5;
+ x1 += x5;
+ x5 = x8;
+ x8 = x7 - x3;
+ x3 += x7;
+ x7 = (181 * (x5 + x8) + 128) >> 8;
+ x5 = (181 * (x5 - x8) + 128) >> 8;
+
+ word = ((x0 + x1) >> 14);
+ CLIP_RESULT(word)
+
+ temp = ((x4 + x7) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 8);
+
+
+ temp = ((x6 + x5) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 16);
+
+ temp = ((x2 + x3) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 24);
+ *((int32*)(comp += offset)) = word;
+
+ word = ((x2 - x3) >> 14);
+ CLIP_RESULT(word)
+
+ temp = ((x6 - x5) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 8);
+
+ temp = ((x4 - x7) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 16);
+
+ temp = ((x0 - x1) >> 14);
+ CLIP_RESULT(temp)
+ word = word | (temp << 24);
+ *((int32*)(comp + 4)) = word;
+
+ blk += B_SIZE;
+ }
+
+ return ;
+}
+
+#endif
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/max_level.h b/media/libstagefright/codecs/m4v_h263/dec/src/max_level.h
new file mode 100644
index 0000000..2d59c73
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/max_level.h
@@ -0,0 +1,149 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+/*
+* ------------------------------------------------------------------- *
+* MPEG-4 Simple Profile Video Decoder *
+* ------------------------------------------------------------------- *
+*
+* This software module was originally developed by
+*
+* Michael Wollborn (TUH / ACTS-MoMuSyS)
+*
+* in the course of development of the MPEG-4 Video (ISO/IEC 14496-2) standard.
+* This software module is an implementation of a part of one or more MPEG-4
+* Video (ISO/IEC 14496-2) tools as specified by the MPEG-4 Video (ISO/IEC
+* 14496-2) standard.
+*
+* ISO/IEC gives users of the MPEG-4 Video (ISO/IEC 14496-2) standard free
+* license to this software module or modifications thereof for use in hardware
+* or software products claiming conformance to the MPEG-4 Video (ISO/IEC
+* 14496-2) standard.
+*
+* Those intending to use this software module in hardware or software products
+* are advised that its use may infringe existing patents. The original
+* developer of this software module and his/her company, the subsequent
+* editors and their companies, and ISO/IEC have no liability for use of this
+* software module or modifications thereof in an implementation. Copyright is
+* not released for non MPEG-4 Video (ISO/IEC 14496-2) Standard conforming
+* products.
+*
+* ACTS-MoMuSys partners retain full right to use the code for his/her own
+* purpose, assign or donate the code to a third party and to inhibit third
+* parties from using the code for non MPEG-4 Video (ISO/IEC 14496-2) Standard
+* conforming products. This copyright notice must be included in all copies or
+* derivative works.
+*
+* Copyright (c) 1997
+*
+*****************************************************************************
+
+This is a header file for "vlc_decode.c". The table data actually resides
+in "vlc_tab.c".
+
+
+------------------------------------------------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+; CONTINUE ONLY IF NOT ALREADY DEFINED
+----------------------------------------------------------------------------*/
+
+#ifndef max_level_H
+#define max_level_H
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "mp4def.h"
+
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here.
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL VARIABLES REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ extern const int intra_max_level[2][NCOEFF_BLOCK];
+
+ extern const int inter_max_level[2][NCOEFF_BLOCK];
+
+ extern const int intra_max_run0[28];
+
+
+ extern const int intra_max_run1[9];
+
+ extern const int inter_max_run0[13];
+
+
+ extern const int inter_max_run1[4];
+
+
+ /*----------------------------------------------------------------------------
+ ; SIMPLE TYPEDEF'S
+ ----------------------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------------------
+ ; ENUMERATED TYPEDEF'S
+ ----------------------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------------------
+ ; STRUCTURES TYPEDEF'S
+ ----------------------------------------------------------------------------*/
+
+
+ /*----------------------------------------------------------------------------
+ ; GLOBAL FUNCTION DEFINITIONS
+ ; Function Prototype declaration
+ ----------------------------------------------------------------------------*/
+
+
+ /*----------------------------------------------------------------------------
+ ; END
+ ----------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/mb_motion_comp.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/mb_motion_comp.cpp
new file mode 100644
index 0000000..fbc7be1a
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/mb_motion_comp.cpp
@@ -0,0 +1,623 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+/*
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ video = pointer to structure of type VideoDecData
+
+ Local Stores/Buffers/Pointers Needed:
+ roundtab16 = rounding table
+
+ Global Stores/Buffers/Pointers Needed:
+ None
+
+ Outputs:
+ None
+
+ Pointers and Buffers Modified:
+ video->currVop->yChan contents are the newly calculated luminance
+ data
+ video->currVop->uChan contents are the newly calculated chrominance
+ b data
+ video->currVop->vChan contents are the newly calculated chrominance
+ r data
+ video->pstprcTypCur contents are the updated semaphore propagation
+ values
+
+ Local Stores Modified:
+ None
+
+ Global Stores Modified:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function performs high level motion compensation on the luminance and
+ chrominance data. It sets up all the parameters required by the functions
+ that perform luminance and chrominance prediction and it initializes the
+ pointer to the post processing semaphores of a given block. It also checks
+ the motion compensation mode in order to determine which luminance or
+ chrominance prediction functions to call and determines how the post
+ processing semaphores are updated.
+
+*/
+
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "mp4dec_lib.h"
+#include "motion_comp.h"
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here. Include conditional
+; compile variables also.
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; LOCAL FUNCTION DEFINITIONS
+; Function Prototype declaration
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; LOCAL STORE/BUFFER/POINTER DEFINITIONS
+; Variable declaration - defined here and used outside this module
+----------------------------------------------------------------------------*/
+/* 09/29/2000 bring this from mp4def.h */
+// const static int roundtab4[] = {0,1,1,1};
+// const static int roundtab8[] = {0,0,1,1,1,1,1,2};
+/*** 10/30 for TPS */
+// const static int roundtab12[] = {0,0,0,1,1,1,1,1,1,1,2,2};
+/* 10/30 for TPS ***/
+const static int roundtab16[] = {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2};
+
+
+/*----------------------------------------------------------------------------
+; EXTERNAL FUNCTION REFERENCES
+; Declare functions defined elsewhere and referenced in this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; FUNCTION CODE
+----------------------------------------------------------------------------*/
+
+/** modified 3 August 2005 to do prediction and put the results in
+video->mblock->pred_block, no adding with residue */
+
+void MBMotionComp(
+ VideoDecData *video,
+ int CBP
+)
+{
+
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ /* Previous Video Object Plane */
+ Vop *prev = video->prevVop;
+
+ /* Current Macroblock (MB) in the VOP */
+ int mbnum = video->mbnum;
+
+ /* Number of MB per data row */
+ int MB_in_width = video->nMBPerRow;
+ int ypos, xpos;
+ PIXEL *c_comp, *c_prev;
+ PIXEL *cu_comp, *cu_prev;
+ PIXEL *cv_comp, *cv_prev;
+ int height, width, pred_width;
+ int imv, mvwidth;
+ int32 offset;
+ uint8 mode;
+ uint8 *pred_block, *pred;
+
+ /* Motion vector (dx,dy) in half-pel resolution */
+ int dx, dy;
+
+ MOT px[4], py[4];
+ int xpred, ypred;
+ int xsum;
+ int round1;
+#ifdef PV_POSTPROC_ON // 2/14/2001
+ /* Total number of pixels in the VOL */
+ int32 size = (int32) video->nTotalMB << 8;
+ uint8 *pp_dec_y, *pp_dec_u;
+ int ll[4];
+ int tmp = 0;
+ uint8 msk_deblock = 0;
+#endif
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ /* Set rounding type */
+ /* change from array to single 09/29/2000 */
+ round1 = (int)(1 - video->currVop->roundingType);
+
+ /* width of luminance data in pixels (y axis) */
+ width = video->width;
+
+ /* heigth of luminance data in pixels (x axis) */
+ height = video->height;
+
+ /* number of blocks per row */
+ mvwidth = MB_in_width << 1;
+
+ /* starting y position in current MB; origin of MB */
+ ypos = video->mbnum_row << 4 ;
+ /* starting x position in current MB; origin of MB */
+ xpos = video->mbnum_col << 4 ;
+
+ /* offset to (x,y) position in current luminance MB */
+ /* in pixel resolution */
+ /* ypos*width -> row, +x -> column */
+ offset = (int32)ypos * width + xpos;
+
+ /* get mode for current MB */
+ mode = video->headerInfo.Mode[mbnum];
+
+ /* block index */
+ /* imv = (xpos/8) + ((ypos/8) * mvwidth) */
+ imv = (offset >> 6) - (xpos >> 6) + (xpos >> 3);
+ if (mode & INTER_1VMASK)
+ {
+ dx = px[0] = px[1] = px[2] = px[3] = video->motX[imv];
+ dy = py[0] = py[1] = py[2] = py[3] = video->motY[imv];
+ if ((dx & 3) == 0)
+ {
+ dx = dx >> 1;
+ }
+ else
+ {
+ /* x component of MV is or'ed for rounding (?) */
+ dx = (dx >> 1) | 1;
+ }
+
+ /* y component of motion vector; divide by 2 for to */
+ /* convert to full-pel resolution. */
+ if ((dy & 3) == 0)
+ {
+ dy = dy >> 1;
+ }
+ else
+ {
+ /* y component of MV is or'ed for rounding (?) */
+ dy = (dy >> 1) | 1;
+ }
+ }
+ else
+ {
+ px[0] = video->motX[imv];
+ px[1] = video->motX[imv+1];
+ px[2] = video->motX[imv+mvwidth];
+ px[3] = video->motX[imv+mvwidth+1];
+ xsum = px[0] + px[1] + px[2] + px[3];
+ dx = PV_SIGN(xsum) * (roundtab16[(PV_ABS(xsum)) & 0xF] +
+ (((PV_ABS(xsum)) >> 4) << 1));
+ py[0] = video->motY[imv];
+ py[1] = video->motY[imv+1];
+ py[2] = video->motY[imv+mvwidth];
+ py[3] = video->motY[imv+mvwidth+1];
+ xsum = py[0] + py[1] + py[2] + py[3];
+ dy = PV_SIGN(xsum) * (roundtab16[(PV_ABS(xsum)) & 0xF] +
+ (((PV_ABS(xsum)) >> 4) << 1));
+ }
+
+ /* Pointer to previous luminance frame */
+ c_prev = prev->yChan;
+
+ pred_block = video->mblock->pred_block;
+
+ /* some blocks have no residue or INTER4V */
+ /*if (mode == MODE_INTER4V) 05/08/15 */
+ /* Motion Compensation for an 8x8 block within a MB */
+ /* (4 MV per MB) */
+
+
+
+ /* Call function that performs luminance prediction */
+ /* luminance_pred_mode_inter4v(xpos, ypos, px, py, c_prev,
+ video->mblock->pred_block, width, height,
+ round1, mvwidth, &xsum, &ysum);*/
+ c_comp = video->currVop->yChan + offset;
+
+
+ xpred = (int)((xpos << 1) + px[0]);
+ ypred = (int)((ypos << 1) + py[0]);
+
+ if ((CBP >> 5)&1)
+ {
+ pred = pred_block;
+ pred_width = 16;
+ }
+ else
+ {
+ pred = c_comp;
+ pred_width = width;
+ }
+
+ /* check whether the MV points outside the frame */
+ if (xpred >= 0 && xpred <= ((width << 1) - (2*B_SIZE)) &&
+ ypred >= 0 && ypred <= ((height << 1) - (2*B_SIZE)))
+ { /*****************************/
+ /* (x,y) is inside the frame */
+ /*****************************/
+ ;
+ GetPredAdvBTable[ypred&1][xpred&1](c_prev + (xpred >> 1) + ((ypred >> 1)*width),
+ pred, width, (pred_width << 1) | round1);
+ }
+ else
+ { /******************************/
+ /* (x,y) is outside the frame */
+ /******************************/
+ GetPredOutside(xpred, ypred, c_prev,
+ pred, width, height, round1, pred_width);
+ }
+
+
+ /* Compute prediction values over current luminance MB */
+ /* (blocks 1); add motion vector prior to input; */
+ /* add 8 to x_pos to advance to next block */
+ xpred = (int)(((xpos + B_SIZE) << 1) + px[1]);
+ ypred = (int)((ypos << 1) + py[1]);
+
+ if ((CBP >> 4)&1)
+ {
+ pred = pred_block + 8;
+ pred_width = 16;
+ }
+ else
+ {
+ pred = c_comp + 8;
+ pred_width = width;
+ }
+
+ /* check whether the MV points outside the frame */
+ if (xpred >= 0 && xpred <= ((width << 1) - (2*B_SIZE)) &&
+ ypred >= 0 && ypred <= ((height << 1) - (2*B_SIZE)))
+ { /*****************************/
+ /* (x,y) is inside the frame */
+ /*****************************/
+ GetPredAdvBTable[ypred&1][xpred&1](c_prev + (xpred >> 1) + ((ypred >> 1)*width),
+ pred, width, (pred_width << 1) | round1);
+ }
+ else
+ { /******************************/
+ /* (x,y) is outside the frame */
+ /******************************/
+ GetPredOutside(xpred, ypred, c_prev,
+ pred, width, height, round1, pred_width);
+ }
+
+
+
+ /* Compute prediction values over current luminance MB */
+ /* (blocks 2); add motion vector prior to input */
+ /* add 8 to y_pos to advance to block on next row */
+ xpred = (int)((xpos << 1) + px[2]);
+ ypred = (int)(((ypos + B_SIZE) << 1) + py[2]);
+
+ if ((CBP >> 3)&1)
+ {
+ pred = pred_block + 128;
+ pred_width = 16;
+ }
+ else
+ {
+ pred = c_comp + (width << 3);
+ pred_width = width;
+ }
+
+ /* check whether the MV points outside the frame */
+ if (xpred >= 0 && xpred <= ((width << 1) - (2*B_SIZE)) &&
+ ypred >= 0 && ypred <= ((height << 1) - (2*B_SIZE)))
+ { /*****************************/
+ /* (x,y) is inside the frame */
+ /*****************************/
+ GetPredAdvBTable[ypred&1][xpred&1](c_prev + (xpred >> 1) + ((ypred >> 1)*width),
+ pred, width, (pred_width << 1) | round1);
+ }
+ else
+ { /******************************/
+ /* (x,y) is outside the frame */
+ /******************************/
+ GetPredOutside(xpred, ypred, c_prev,
+ pred, width, height, round1, pred_width);
+ }
+
+
+
+ /* Compute prediction values over current luminance MB */
+ /* (blocks 3); add motion vector prior to input; */
+ /* add 8 to x_pos and y_pos to advance to next block */
+ /* on next row */
+ xpred = (int)(((xpos + B_SIZE) << 1) + px[3]);
+ ypred = (int)(((ypos + B_SIZE) << 1) + py[3]);
+
+ if ((CBP >> 2)&1)
+ {
+ pred = pred_block + 136;
+ pred_width = 16;
+ }
+ else
+ {
+ pred = c_comp + (width << 3) + 8;
+ pred_width = width;
+ }
+
+ /* check whether the MV points outside the frame */
+ if (xpred >= 0 && xpred <= ((width << 1) - (2*B_SIZE)) &&
+ ypred >= 0 && ypred <= ((height << 1) - (2*B_SIZE)))
+ { /*****************************/
+ /* (x,y) is inside the frame */
+ /*****************************/
+ GetPredAdvBTable[ypred&1][xpred&1](c_prev + (xpred >> 1) + ((ypred >> 1)*width),
+ pred, width, (pred_width << 1) | round1);
+ }
+ else
+ { /******************************/
+ /* (x,y) is outside the frame */
+ /******************************/
+ GetPredOutside(xpred, ypred, c_prev,
+ pred, width, height, round1, pred_width);
+ }
+ /* Call function to set de-blocking and de-ringing */
+ /* semaphores for luminance */
+
+#ifdef PV_POSTPROC_ON
+ if (video->postFilterType != PV_NO_POST_PROC)
+ {
+ if (mode&INTER_1VMASK)
+ {
+ pp_dec_y = video->pstprcTypCur + imv;
+ ll[0] = 1;
+ ll[1] = mvwidth - 1;
+ ll[2] = 1;
+ ll[3] = -mvwidth - 1;
+ msk_deblock = pp_semaphore_luma(xpred, ypred, pp_dec_y,
+ video->pstprcTypPrv, ll, &tmp, px[0], py[0], mvwidth,
+ width, height);
+
+ pp_dec_u = video->pstprcTypCur + (size >> 6) +
+ ((imv + (xpos >> 3)) >> 2);
+
+ pp_semaphore_chroma_inter(xpred, ypred, pp_dec_u,
+ video->pstprcTypPrv, dx, dy, mvwidth, height, size,
+ tmp, msk_deblock);
+ }
+ else
+ {
+ /* Post-processing mode (MBM_INTER8) */
+ /* deblocking and deringing) */
+ pp_dec_y = video->pstprcTypCur + imv;
+ *pp_dec_y = 4;
+ *(pp_dec_y + 1) = 4;
+ *(pp_dec_y + mvwidth) = 4;
+ *(pp_dec_y + mvwidth + 1) = 4;
+ pp_dec_u = video->pstprcTypCur + (size >> 6) +
+ ((imv + (xpos >> 3)) >> 2);
+ *pp_dec_u = 4;
+ pp_dec_u[size>>8] = 4;
+ }
+ }
+#endif
+
+
+ /* xpred and ypred calculation for Chrominance is */
+ /* in full-pel resolution. */
+
+ /* Chrominance */
+ /* width of chrominance data in pixels (y axis) */
+ width >>= 1;
+
+ /* heigth of chrominance data in pixels (x axis) */
+ height >>= 1;
+
+ /* Pointer to previous chrominance b frame */
+ cu_prev = prev->uChan;
+
+ /* Pointer to previous chrominance r frame */
+ cv_prev = prev->vChan;
+
+ /* x position in prediction data offset by motion vector */
+ /* xpred calculation for Chrominance is in full-pel */
+ /* resolution. */
+ xpred = xpos + dx;
+
+ /* y position in prediction data offset by motion vector */
+ /* ypred calculation for Chrominance is in full-pel */
+ /* resolution. */
+ ypred = ypos + dy;
+
+ cu_comp = video->currVop->uChan + (offset >> 2) + (xpos >> 2);
+ cv_comp = video->currVop->vChan + (offset >> 2) + (xpos >> 2);
+
+ /* Call function that performs chrominance prediction */
+ /* chrominance_pred(xpred, ypred, cu_prev, cv_prev,
+ pred_block, width_uv, height_uv,
+ round1);*/
+ if (xpred >= 0 && xpred <= ((width << 1) - (2*B_SIZE)) && ypred >= 0 &&
+ ypred <= ((height << 1) - (2*B_SIZE)))
+ {
+ /*****************************/
+ /* (x,y) is inside the frame */
+ /*****************************/
+ if ((CBP >> 1)&1)
+ {
+ pred = pred_block + 256;
+ pred_width = 16;
+ }
+ else
+ {
+ pred = cu_comp;
+ pred_width = width;
+ }
+
+ /* Compute prediction for Chrominance b (block[4]) */
+ GetPredAdvBTable[ypred&1][xpred&1](cu_prev + (xpred >> 1) + ((ypred >> 1)*width),
+ pred, width, (pred_width << 1) | round1);
+
+ if (CBP&1)
+ {
+ pred = pred_block + 264;
+ pred_width = 16;
+ }
+ else
+ {
+ pred = cv_comp;
+ pred_width = width;
+ }
+ /* Compute prediction for Chrominance r (block[5]) */
+ GetPredAdvBTable[ypred&1][xpred&1](cv_prev + (xpred >> 1) + ((ypred >> 1)*width),
+ pred, width, (pred_width << 1) | round1);
+
+ return ;
+ }
+ else
+ {
+ /******************************/
+ /* (x,y) is outside the frame */
+ /******************************/
+ if ((CBP >> 1)&1)
+ {
+ pred = pred_block + 256;
+ pred_width = 16;
+ }
+ else
+ {
+ pred = cu_comp;
+ pred_width = width;
+ }
+
+ /* Compute prediction for Chrominance b (block[4]) */
+ GetPredOutside(xpred, ypred, cu_prev,
+ pred, width, height, round1, pred_width);
+
+ if (CBP&1)
+ {
+ pred = pred_block + 264;
+ pred_width = 16;
+ }
+ else
+ {
+ pred = cv_comp;
+ pred_width = width;
+ }
+
+ /* Compute prediction for Chrominance r (block[5]) */
+ GetPredOutside(xpred, ypred, cv_prev,
+ pred, width, height, round1, pred_width);
+
+ return ;
+ }
+
+}
+
+/*** special function for skipped macroblock, Aug 15, 2005 */
+void SkippedMBMotionComp(
+ VideoDecData *video
+)
+{
+ Vop *prev = video->prevVop;
+ Vop *comp;
+ int ypos, xpos;
+ PIXEL *c_comp, *c_prev;
+ PIXEL *cu_comp, *cu_prev;
+ PIXEL *cv_comp, *cv_prev;
+ int width, width_uv;
+ int32 offset;
+#ifdef PV_POSTPROC_ON // 2/14/2001
+ int imv;
+ int32 size = (int32) video->nTotalMB << 8;
+ uint8 *pp_dec_y, *pp_dec_u;
+ uint8 *pp_prev1;
+ int mvwidth = video->nMBPerRow << 1;
+#endif
+
+ width = video->width;
+ width_uv = width >> 1;
+ ypos = video->mbnum_row << 4 ;
+ xpos = video->mbnum_col << 4 ;
+ offset = (int32)ypos * width + xpos;
+
+
+ /* zero motion compensation for previous frame */
+ /*mby*width + mbx;*/
+ c_prev = prev->yChan + offset;
+ /*by*width_uv + bx;*/
+ cu_prev = prev->uChan + (offset >> 2) + (xpos >> 2);
+ /*by*width_uv + bx;*/
+ cv_prev = prev->vChan + (offset >> 2) + (xpos >> 2);
+
+ comp = video->currVop;
+
+ c_comp = comp->yChan + offset;
+ cu_comp = comp->uChan + (offset >> 2) + (xpos >> 2);
+ cv_comp = comp->vChan + (offset >> 2) + (xpos >> 2);
+
+
+ /* Copy previous reconstructed frame into the current frame */
+ PutSKIPPED_MB(c_comp, c_prev, width);
+ PutSKIPPED_B(cu_comp, cu_prev, width_uv);
+ PutSKIPPED_B(cv_comp, cv_prev, width_uv);
+
+ /* 10/24/2000 post_processing semaphore generation */
+#ifdef PV_POSTPROC_ON // 2/14/2001
+ if (video->postFilterType != PV_NO_POST_PROC)
+ {
+ imv = (offset >> 6) - (xpos >> 6) + (xpos >> 3);
+ /* Post-processing mode (copy previous MB) */
+ pp_prev1 = video->pstprcTypPrv + imv;
+ pp_dec_y = video->pstprcTypCur + imv;
+ *pp_dec_y = *pp_prev1;
+ *(pp_dec_y + 1) = *(pp_prev1 + 1);
+ *(pp_dec_y + mvwidth) = *(pp_prev1 + mvwidth);
+ *(pp_dec_y + mvwidth + 1) = *(pp_prev1 + mvwidth + 1);
+
+ /* chrominance */
+ /*4*MB_in_width*MB_in_height*/
+ pp_prev1 = video->pstprcTypPrv + (size >> 6) +
+ ((imv + (xpos >> 3)) >> 2);
+ pp_dec_u = video->pstprcTypCur + (size >> 6) +
+ ((imv + (xpos >> 3)) >> 2);
+ *pp_dec_u = *pp_prev1;
+ pp_dec_u[size>>8] = pp_prev1[size>>8];
+ }
+#endif
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+
+ return;
+}
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/mb_utils.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/mb_utils.cpp
new file mode 100644
index 0000000..25a31b7
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/mb_utils.cpp
@@ -0,0 +1,133 @@
+/* ------------------------------------------------------------------
+ * 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 "mp4dec_lib.h"
+
+/* ====================================================================== /
+ Function : PutSKIPPED_MB()
+ Date : 04/03/2000
+/ ====================================================================== */
+
+void PutSKIPPED_MB(uint8 *comp, uint8 *prev, int width)
+{
+ int32 *temp0, *temp1;
+ int row;
+ row = MB_SIZE;
+
+
+ while (row)
+ {
+ temp0 = (int32 *)prev;
+ temp1 = (int32 *)comp;
+
+ temp1[0] = temp0[0];
+ temp1[1] = temp0[1];
+ temp1[2] = temp0[2];
+ temp1[3] = temp0[3];
+
+ comp += width;
+ prev += width;
+
+ temp0 = (int32 *)prev;
+ temp1 = (int32 *)comp;
+
+ temp1[0] = temp0[0];
+ temp1[1] = temp0[1];
+ temp1[2] = temp0[2];
+ temp1[3] = temp0[3];
+
+ comp += width;
+ prev += width;
+
+ temp0 = (int32 *)prev;
+ temp1 = (int32 *)comp;
+ temp1[0] = temp0[0];
+ temp1[1] = temp0[1];
+ temp1[2] = temp0[2];
+ temp1[3] = temp0[3];
+
+
+ comp += width;
+ prev += width;
+
+ temp0 = (int32 *)prev;
+ temp1 = (int32 *)comp;
+ temp1[0] = temp0[0];
+ temp1[1] = temp0[1];
+ temp1[2] = temp0[2];
+ temp1[3] = temp0[3];
+
+ comp += width;
+ prev += width;
+ row -= 4;
+ }
+}
+
+
+/* ====================================================================== /
+ Function : PutSKIPPED_B()
+ Date : 04/03/2000
+/ ====================================================================== */
+
+void PutSKIPPED_B(uint8 *comp, uint8 *prev, int width)
+{
+ int32 *temp0, *temp1;
+ int row;
+
+ row = B_SIZE;
+ while (row)
+ {
+ temp0 = (int32 *)prev;
+ temp1 = (int32 *)comp;
+
+ temp1[0] = temp0[0];
+ temp1[1] = temp0[1];
+
+ comp += width;
+ prev += width;
+
+ temp0 = (int32 *)prev;
+ temp1 = (int32 *)comp;
+
+ temp1[0] = temp0[0];
+ temp1[1] = temp0[1];
+
+ comp += width;
+ prev += width;
+
+ temp0 = (int32 *)prev;
+ temp1 = (int32 *)comp;
+
+ temp1[0] = temp0[0];
+ temp1[1] = temp0[1];
+
+ comp += width;
+ prev += width;
+
+ temp0 = (int32 *)prev;
+ temp1 = (int32 *)comp;
+
+ temp1[0] = temp0[0];
+ temp1[1] = temp0[1];
+
+ comp += width;
+ prev += width;
+ row -= 4;
+ }
+}
+
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/mbtype_mode.h b/media/libstagefright/codecs/m4v_h263/dec/src/mbtype_mode.h
new file mode 100644
index 0000000..c45bb5f
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/mbtype_mode.h
@@ -0,0 +1,37 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+const static int MBtype_mode[] =
+{
+ MODE_INTER,
+ MODE_INTER_Q,
+ MODE_INTER4V,
+ MODE_INTRA,
+ MODE_INTRA_Q,
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ MODE_INTER4V_Q,
+#endif
+ MODE_SKIPPED
+};
+#ifdef PV_ANNEX_IJKT_SUPPORT
+const static int16 DQ_tab_Annex_T_10[32] = {0, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3};
+const static int16 DQ_tab_Annex_T_11[32] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, -5};
+const static int16 MQ_chroma_QP_table[32] = {0, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13,
+ 14, 14, 14, 14, 14, 15, 15, 15, 15, 15
+ };
+#endif
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/motion_comp.h b/media/libstagefright/codecs/m4v_h263/dec/src/motion_comp.h
new file mode 100644
index 0000000..0c12f20
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/motion_comp.h
@@ -0,0 +1,108 @@
+/* ------------------------------------------------------------------
+ * 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 motion_comp_h
+#define motion_comp_h
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "mp4dec_lib.h"
+
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here.
+----------------------------------------------------------------------------*/
+/* CBP Mask defines used in chrominance prediction */
+#define CBP_MASK_CHROMA_BLK4 0x2
+#define CBP_MASK_CHROMA_BLK5 0x1
+
+/* CBP Mask defines used in luminance prediction (MODE_INTER4V) */
+#define CBP_MASK_BLK0_MODE_INTER4V 0x20
+#define CBP_MASK_BLK1_MODE_INTER4V 0x10
+#define CBP_MASK_BLK2_MODE_INTER4V 0x08
+#define CBP_MASK_BLK3_MODE_INTER4V 0x04
+
+/* CBP Mask defines used in luminance prediction (MODE_INTER or MODE_INTER_Q) */
+#define CBP_MASK_MB_MODE_INTER 0x3c
+
+/*----------------------------------------------------------------------------
+; EXTERNAL VARIABLES REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define CLIP_RESULT(x) if(x & -256){x = 0xFF & (~(x>>31));}
+#define ADD_AND_CLIP1(x) x += (pred_word&0xFF); CLIP_RESULT(x);
+#define ADD_AND_CLIP2(x) x += ((pred_word>>8)&0xFF); CLIP_RESULT(x);
+#define ADD_AND_CLIP3(x) x += ((pred_word>>16)&0xFF); CLIP_RESULT(x);
+#define ADD_AND_CLIP4(x) x += ((pred_word>>24)&0xFF); CLIP_RESULT(x);
+
+#define ADD_AND_CLIP(x,y) { x9 = ~(x>>8); \
+ if(x9!=-1){ \
+ x9 = ((uint32)x9)>>24; \
+ y = x9|(y<<8); \
+ } \
+ else \
+ { \
+ y = x|(y<<8); \
+ } \
+ }
+
+
+ static int (*const GetPredAdvBTable[2][2])(uint8*, uint8*, int, int) =
+ {
+ {&GetPredAdvancedBy0x0, &GetPredAdvancedBy0x1},
+ {&GetPredAdvancedBy1x0, &GetPredAdvancedBy1x1}
+ };
+
+ /*----------------------------------------------------------------------------
+ ; SIMPLE TYPEDEF'S
+ ----------------------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------------------
+ ; ENUMERATED TYPEDEF'S
+ ----------------------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------------------
+ ; STRUCTURES TYPEDEF'S
+ ----------------------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------------------
+ ; GLOBAL FUNCTION DEFINITIONS
+ ; Function Prototype declaration
+ ----------------------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------------------
+ ; END
+ ----------------------------------------------------------------------------*/
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/mp4dec_lib.h b/media/libstagefright/codecs/m4v_h263/dec/src/mp4dec_lib.h
new file mode 100644
index 0000000..9cd4edc
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/mp4dec_lib.h
@@ -0,0 +1,334 @@
+/* ------------------------------------------------------------------
+ * 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 _MP4DECLIB_H_
+#define _MP4DECLIB_H_
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "mp4def.h" /* typedef */
+#include "mp4lib_int.h" /* main video structure */
+
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here.
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL VARIABLES REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; SIMPLE TYPEDEF'S
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; ENUMERATED TYPEDEF'S
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; STRUCTURES TYPEDEF'S
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; GLOBAL FUNCTION DEFINITIONS
+; Function Prototype declaration
+----------------------------------------------------------------------------*/
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ /* defined in pvdec_api.c, these function are not supposed to be */
+ /* exposed to programmers outside PacketVideo. 08/15/2000. */
+ uint VideoDecoderErrorDetected(VideoDecData *video);
+
+#ifdef ENABLE_LOG
+ void m4vdec_dprintf(char *format, ...);
+#define mp4dec_log(message) m4vdec_dprintf(message)
+#else
+#define mp4dec_log(message)
+#endif
+
+ /*--------------------------------------------------------------------------*/
+ /* defined in frame_buffer.c */
+ PV_STATUS FillFrameBufferNew(BitstreamDecVideo *stream);
+ PV_STATUS FillFrameBuffer(BitstreamDecVideo *stream, int short_header);
+
+ /*--------------------------------------------------------------------------*/
+ /* defined in dc_ac_pred.c */
+ int cal_dc_scaler(int QP, int type);
+ PV_STATUS PV_DecodePredictedIntraDC(int compnum, BitstreamDecVideo *stream,
+ int16 *IntraDC_delta);
+
+ void doDCACPrediction(VideoDecData *video, int comp, int16 *q_block,
+ int *direction);
+
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ void doDCACPrediction_I(VideoDecData *video, int comp, int16 *q_block);
+#endif
+ /*--------------------------------------------------------------------------*/
+ /* defined in block_idct.c */
+ void MBlockIDCTAdd(VideoDecData *video, int nz_coefs[]);
+
+ void BlockIDCT(uint8 *dst, uint8 *pred, int16 *blk, int width, int nzcoefs,
+ uint8 *bitmapcol, uint8 bitmaprow);
+
+ void MBlockIDCT(VideoDecData *video);
+ void BlockIDCT_intra(MacroBlock *mblock, PIXEL *c_comp, int comp, int width_offset);
+ /*--------------------------------------------------------------------------*/
+ /* defined in combined_decode.c */
+ PV_STATUS DecodeFrameCombinedMode(VideoDecData *video);
+ PV_STATUS GetMBheader(VideoDecData *video, int16 *QP);
+ PV_STATUS GetMBData(VideoDecData *video);
+
+ /*--------------------------------------------------------------------------*/
+ /* defined in datapart_decode.c */
+ PV_STATUS DecodeFrameDataPartMode(VideoDecData *video);
+ PV_STATUS GetMBheaderDataPart_DQUANT_DC(VideoDecData *video, int16 *QP);
+ PV_STATUS GetMBheaderDataPart_P(VideoDecData *video);
+ PV_STATUS DecodeDataPart_I_VideoPacket(VideoDecData *video, int slice_counter);
+ PV_STATUS DecodeDataPart_P_VideoPacket(VideoDecData *video, int slice_counter);
+ PV_STATUS GetMBData_DataPart(VideoDecData *video);
+
+ /*--------------------------------------------------------------------------*/
+ /* defined in packet_util.c */
+ PV_STATUS PV_ReadVideoPacketHeader(VideoDecData *video, int *next_MB);
+ PV_STATUS RecoverPacketError(BitstreamDecVideo *stream, int marker_length, int32 *nextVop);
+ PV_STATUS RecoverGOBError(BitstreamDecVideo *stream, int marker_length, int32 *vopPos);
+ PV_STATUS PV_GobHeader(VideoDecData *video);
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ PV_STATUS PV_H263SliceHeader(VideoDecData *videoInt, int *next_MB);
+#endif
+ /*--------------------------------------------------------------------------*/
+ /* defined in motion_comp.c */
+ void MBMotionComp(VideoDecData *video, int CBP);
+ void SkippedMBMotionComp(VideoDecData *video);
+
+ /*--------------------------------------------------------------------------*/
+ /* defined in chrominance_pred.c */
+ void chrominance_pred(
+ int xpred, /* i */
+ int ypred, /* i */
+ uint8 *cu_prev, /* i */
+ uint8 *cv_prev, /* i */
+ uint8 *pred_block, /* i */
+ int width_uv, /* i */
+ int height_uv, /* i */
+ int round1
+ );
+
+ /*--------------------------------------------------------------------------*/
+ /* defined in luminance_pred_mode_inter.c */
+ void luminance_pred_mode_inter(
+ int xpred, /* i */
+ int ypred, /* i */
+ uint8 *c_prev, /* i */
+ uint8 *pred_block, /* i */
+ int width, /* i */
+ int height, /* i */
+ int round1
+ );
+
+ /*--------------------------------------------------------------------------*/
+ /* defined in luminance_pred_mode_inter4v.c */
+ void luminance_pred_mode_inter4v(
+ int xpos, /* i */
+ int ypos, /* i */
+ MOT *px, /* i */
+ MOT *py, /* i */
+ uint8 *c_prev, /* i */
+ uint8 *pred_block, /* i */
+ int width, /* i */
+ int height, /* i */
+ int round1, /* i */
+ int mvwidth, /* i */
+ int *xsum_ptr, /* i/o */
+ int *ysum_ptr /* i/o */
+ );
+
+ /*--------------------------------------------------------------------------*/
+ /* defined in pp_semaphore_chroma_inter.c */
+#ifdef PV_POSTPROC_ON
+ void pp_semaphore_chroma_inter(
+ int xpred, /* i */
+ int ypred, /* i */
+ uint8 *pp_dec_u, /* i/o */
+ uint8 *pstprcTypPrv, /* i */
+ int dx, /* i */
+ int dy, /* i */
+ int mvwidth, /* i */
+ int height, /* i */
+ int32 size, /* i */
+ int mv_loc, /* i */
+ uint8 msk_deblock /* i */
+ );
+
+ /*--------------------------------------------------------------------------*/
+ /* defined in pp_semaphore_luma.c */
+ uint8 pp_semaphore_luma(
+ int xpred, /* i */
+ int ypred, /* i */
+ uint8 *pp_dec_y, /* i/o */
+ uint8 *pstprcTypPrv, /* i */
+ int *ll, /* i */
+ int *mv_loc, /* i/o */
+ int dx, /* i */
+ int dy, /* i */
+ int mvwidth, /* i */
+ int width, /* i */
+ int height /* i */
+ );
+#endif
+ /*--------------------------------------------------------------------------*/
+ /* defined in get_pred_adv_mb_add.c */
+ int GetPredAdvancedMB(
+ int xpos,
+ int ypos,
+ uint8 *c_prev,
+ uint8 *pred_block,
+ int width,
+ int rnd1
+ );
+
+ /*--------------------------------------------------------------------------*/
+ /* defined in get_pred_adv_b_add.c */
+ int GetPredAdvancedBy0x0(
+ uint8 *c_prev, /* i */
+ uint8 *pred_block, /* i */
+ int width, /* i */
+ int pred_width_rnd /* i */
+ );
+
+ int GetPredAdvancedBy0x1(
+ uint8 *c_prev, /* i */
+ uint8 *pred_block, /* i */
+ int width, /* i */
+ int pred_width_rnd /* i */
+ );
+
+ int GetPredAdvancedBy1x0(
+ uint8 *c_prev, /* i */
+ uint8 *pred_block, /* i */
+ int width, /* i */
+ int pred_width_rnd /* i */
+ );
+
+ int GetPredAdvancedBy1x1(
+ uint8 *c_prev, /* i */
+ uint8 *pred_block, /* i */
+ int width, /* i */
+ int pred_width_rnd /* i */
+ );
+
+ /*--------------------------------------------------------------------------*/
+ /* defined in get_pred_outside.c */
+ int GetPredOutside(
+ int xpos,
+ int ypos,
+ uint8 *c_prev,
+ uint8 *pred_block,
+ int width,
+ int height,
+ int rnd1,
+ int pred_width
+ );
+
+ /*--------------------------------------------------------------------------*/
+ /* defined in find_pmvsErrRes.c */
+ void mv_prediction(VideoDecData *video, int block, MOT *mvx, MOT *mvy);
+
+ /*--------------------------------------------------------------------------*/
+
+ /*--------------------------------------------------------------------------*/
+ /* defined in mb_utils.c */
+ void Copy_MB_into_Vop(uint8 *comp, int yChan[][NCOEFF_BLOCK], int width);
+ void Copy_B_into_Vop(uint8 *comp, int cChan[], int width);
+ void PutSKIPPED_MB(uint8 *comp, uint8 *c_prev, int width);
+ void PutSKIPPED_B(uint8 *comp, uint8 *c_prev, int width);
+
+ /*--------------------------------------------------------------------------*/
+ /* defined in vop.c */
+ PV_STATUS DecodeGOVHeader(BitstreamDecVideo *stream, uint32 *time_base);
+ PV_STATUS DecodeVOLHeader(VideoDecData *video, int layer);
+ PV_STATUS DecodeVOPHeader(VideoDecData *video, Vop *currVop, Bool use_ext_tiemstamp);
+ PV_STATUS DecodeShortHeader(VideoDecData *video, Vop *currVop);
+ PV_STATUS PV_DecodeVop(VideoDecData *video);
+ uint32 CalcVopDisplayTime(Vol *currVol, Vop *currVop, int shortVideoHeader);
+
+ /*--------------------------------------------------------------------------*/
+ /* defined in post_proc.c */
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ void H263_Deblock(uint8 *rec, int width, int height, int16 *QP_store, uint8 *mode, int chr, int T);
+#endif
+ int PostProcSemaphore(int16 *q_block);
+ void PostFilter(VideoDecData *video, int filer_type, uint8 *output);
+ void FindMaxMin(uint8 *ptr, int *min, int *max, int incr);
+ void DeringAdaptiveSmoothMMX(uint8 *img, int incr, int thres, int mxdf);
+ void AdaptiveSmooth_NoMMX(uint8 *Rec_Y, int v0, int h0, int v_blk, int h_blk,
+ int thr, int width, int max_diff);
+ void Deringing_Luma(uint8 *Rec_Y, int width, int height, int16 *QP_store,
+ int Combined, uint8 *pp_mod);
+ void Deringing_Chroma(uint8 *Rec_C, int width, int height, int16 *QP_store,
+ int Combined, uint8 *pp_mod);
+ void CombinedHorzVertFilter(uint8 *rec, int width, int height, int16 *QP_store,
+ int chr, uint8 *pp_mod);
+ void CombinedHorzVertFilter_NoSoftDeblocking(uint8 *rec, int width, int height, int16 *QP_store,
+ int chr, uint8 *pp_mod);
+ void CombinedHorzVertRingFilter(uint8 *rec, int width, int height,
+ int16 *QP_store, int chr, uint8 *pp_mod);
+
+ /*--------------------------------------------------------------------------*/
+ /* defined in conceal.c */
+ void ConcealTexture_I(VideoDecData *video, int32 startFirstPartition, int mb_start, int mb_stop,
+ int slice_counter);
+ void ConcealTexture_P(VideoDecData *video, int mb_start, int mb_stop,
+ int slice_counter);
+ void ConcealPacket(VideoDecData *video, int mb_start, int mb_stop,
+ int slice_counter);
+ void CopyVopMB(Vop *curr, uint8 *prev, int mbnum, int width, int height);
+
+ /* define in vlc_dequant.c , 09/18/2000*/
+#ifdef PV_SUPPORT_MAIN_PROFILE
+ int VlcDequantMpegIntraBlock(void *video, int comp, int switched,
+ uint8 *bitmapcol, uint8 *bitmaprow);
+ int VlcDequantMpegInterBlock(void *video, int comp,
+ uint8 *bitmapcol, uint8 *bitmaprow);
+#endif
+ int VlcDequantH263IntraBlock(VideoDecData *video, int comp, int switched,
+ uint8 *bitmapcol, uint8 *bitmaprow);
+ int VlcDequantH263IntraBlock_SH(VideoDecData *video, int comp,
+ uint8 *bitmapcol, uint8 *bitmaprow);
+ int VlcDequantH263InterBlock(VideoDecData *video, int comp,
+ uint8 *bitmapcol, uint8 *bitmaprow);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+/*----------------------------------------------------------------------------
+; END
+----------------------------------------------------------------------------*/
+#endif
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/mp4def.h b/media/libstagefright/codecs/m4v_h263/dec/src/mp4def.h
new file mode 100644
index 0000000..3388d89
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/mp4def.h
@@ -0,0 +1,167 @@
+/* ------------------------------------------------------------------
+ * 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 _PVDECDEF_H_
+#define _PVDECDEF_H_
+
+#include "mp4dec_api.h"
+
+typedef enum
+{
+ PV_SUCCESS,
+ PV_FAIL,
+ PV_MB_STUFFING, /* hit Macroblock_Stuffing */
+ PV_END_OF_VOP, /* hit End_of_Video_Object_Plane */
+ PV_END_OF_MB /* hit End_of_Macroblock */
+#ifdef PV_TOLERATE_VOL_ERRORS
+ , PV_BAD_VOLHEADER
+#endif
+} PV_STATUS;
+
+typedef uint8 PIXEL;
+typedef int16 MOT; /* : "int" type runs faster on RISC machine */
+
+#define TRUE 1
+#define FALSE 0
+
+#define PV_ABS(x) (((x)<0)? -(x) : (x))
+#define PV_SIGN(x) (((x)<0)? -1 : 1)
+#define PV_SIGN0(a) (((a)<0)? -1 : (((a)>0) ? 1 : 0))
+#define PV_MAX(a,b) ((a)>(b)? (a):(b))
+#define PV_MIN(a,b) ((a)<(b)? (a):(b))
+#define PV_MEDIAN(A,B,C) ((A) > (B) ? ((A) < (C) ? (A) : (B) > (C) ? (B) : (C)): (B) < (C) ? (B) : (C) > (A) ? (C) : (A))
+/* You don't want to use ((x>UB)?UB:(x<LB)?LB:x) for the clipping */
+/* because it will use one extra comparison if the compiler is */
+/* not well-optimized. 04/19/2000. */
+#define CLIP_THE_RANGE(x,LB,UB) if (x<LB) x = LB; else if (x>UB) x = UB
+
+#define MODE_INTRA 0x08 //01000
+#define MODE_INTRA_Q 0x09 //01001
+#define MODE_SKIPPED 0x10 //10000
+#define MODE_INTER4V 0x14 //10100
+#define MODE_INTER 0x16 //10110
+#define MODE_INTER_Q 0x17 //10111
+#define MODE_INTER4V_Q 0x15 //10101
+#define INTER_1VMASK 0x2
+#define Q_MASK 0x1
+#define INTRA_MASK 0x8
+#define INTER_MASK 0x4
+
+
+#define I_VOP 0
+#define P_VOP 1
+#define B_VOP 2
+
+#define LUMINANCE_DC_TYPE 1
+#define CHROMINANCE_DC_TYPE 2
+
+#define START_CODE_LENGTH 32
+
+/* 11/30/98 */
+#define NoMarkerFound -1
+#define FoundRM 1 /* Resync Marker */
+#define FoundVSC 2 /* VOP_START_CODE. */
+#define FoundGSC 3 /* GROUP_START_CODE */
+#define FoundEOB 4 /* EOB_CODE */
+
+/* PacketVideo "absolution timestamp" object. 06/13/2000 */
+#define PVTS_START_CODE 0x01C4
+#define PVTS_START_CODE_LENGTH 32
+
+/* session layer and vop layer start codes */
+
+#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 /* lengtho of VO header: VO_START_CODE + VO_ID */
+
+#define SOL_START_CODE 0x01BE
+#define SOL_START_CODE_LENGTH 32
+
+#define VOL_START_CODE 0x12
+#define VOL_START_CODE_LENGTH 28
+
+#define VOP_START_CODE 0x1B6
+#define VOP_START_CODE_LENGTH 32
+
+#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 START_CODE_PREFIX 0x01
+#define START_CODE_PREFIX_LENGTH 24
+
+#define SHORT_VIDEO_START_MARKER 0x20
+#define SHORT_VIDEO_START_MARKER_LENGTH 22
+#define SHORT_VIDEO_END_MARKER 0x3F
+#define GOB_RESYNC_MARKER 0x01
+#define GOB_RESYNC_MARKER_LENGTH 17
+
+/* motion and resync markers used in error resilient mode */
+
+#define DC_MARKER 438273
+#define DC_MARKER_LENGTH 19
+
+#define MOTION_MARKER_COMB 126977
+#define MOTION_MARKER_COMB_LENGTH 17
+
+#define MOTION_MARKER_SEP 81921
+#define MOTION_MARKER_SEP_LENGTH 17
+
+#define RESYNC_MARKER 1
+#define RESYNC_MARKER_LENGTH 17
+
+#define SPRITE_NOT_USED 0
+#define STATIC_SPRITE 1
+#define ONLINE_SPRITE 2
+#define GMC_SPRITE 3
+
+/* macroblock and block size */
+#define MB_SIZE 16
+#define NCOEFF_MB (MB_SIZE*MB_SIZE)
+#define B_SIZE 8
+#define NCOEFF_BLOCK (B_SIZE*B_SIZE)
+#define NCOEFF_Y NCOEFF_MB
+#define NCOEFF_U NCOEFF_BLOCK
+#define NCOEFF_V NCOEFF_BLOCK
+#define BLK_PER_MB 4 /* Number of blocks per MB */
+
+/* VLC decoding related definitions */
+#define VLC_ERROR (-1)
+#define VLC_ESCAPE 7167
+
+
+/* macro utility */
+#define ZERO_OUT_64BYTES(x) { *((uint32*)x) = *(((uint32*)(x))+1) = \
+ *(((uint32*)(x))+2) = *(((uint32*)(x))+3) = \
+ *(((uint32*)(x))+4) = *(((uint32*)(x))+5) = \
+ *(((uint32*)(x))+6) = *(((uint32*)(x))+7) = \
+ *(((uint32*)(x))+8) = *(((uint32*)(x))+9) = \
+ *(((uint32*)(x))+10) = *(((uint32*)(x))+11) = \
+ *(((uint32*)(x))+12) = *(((uint32*)(x))+13) = \
+ *(((uint32*)(x))+14) = *(((uint32*)(x))+15) = 0; }
+
+
+
+#endif /* _PVDECDEF_H_ */
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/mp4lib_int.h b/media/libstagefright/codecs/m4v_h263/dec/src/mp4lib_int.h
new file mode 100644
index 0000000..d6754a7
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/mp4lib_int.h
@@ -0,0 +1,296 @@
+/* ------------------------------------------------------------------
+ * 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 _MP4LIB_INT_H_
+#define _MP4LIB_INT_H_
+
+#include "mp4def.h"
+#include "mp4dec_api.h" // extra structure
+
+#undef ENABLE_LOG
+#define BITRATE_AVERAGE_WINDOW 4
+#define FRAMERATE_SCALE ((BITRATE_AVERAGE_WINDOW-1)*10000L)
+#define FAST_IDCT /* , for fast Variable complexity IDCT */
+//#define PV_DEC_EXTERNAL_IDCT /* for separate IDCT (i.e. no direct access to output frame) */
+#define PV_ANNEX_IJKT_SUPPORT
+#define mid_gray 1024
+
+typedef struct tagBitstream
+{
+ /* function that reteive data from outside the library. 04/11/2000 */
+ /* In frame-based decoding mode, this shall be NULL. 08/29/2000 */
+ uint32 curr_word;
+ uint32 next_word;
+ uint8 *bitstreamBuffer; /* pointer to buffer memory */
+ int32 read_point; /* starting point in the buffer to be read to cache */
+ int incnt; /* bit left in cached */
+ int incnt_next;
+ uint32 bitcnt; /* total bit read so-far (from inbfr)*/
+ int32 data_end_pos; /*should be added , 06/07/2000 */
+ int searched_frame_boundary;
+} BitstreamDecVideo, *LPBitstreamDecVideo;
+
+/* complexity estimation parameters */
+typedef struct tagComplexity_Est
+{
+ uint8 text_1; /* texture_complexity_estimation_set_1 */
+ uint8 text_2; /* texture_complexity_estimation_set_2 */
+ uint8 mc; /* motion_compensation_complexity */
+} Complexity_Est;
+
+
+typedef struct tagVop
+{
+ PIXEL *yChan; /* The Y component */
+ PIXEL *uChan; /* The U component */
+ PIXEL *vChan; /* The V component */
+
+ uint32 timeStamp; /* Vop TimeStamp in msec */
+
+ /* Actual syntax elements for VOP (standard) */
+ int predictionType; /* VOP prediction type */
+ uint timeInc; /* VOP time increment (relative to last mtb) */
+ int vopCoded;
+ int roundingType;
+ int intraDCVlcThr;
+ int16 quantizer; /* VOP quantizer */
+ int fcodeForward; /* VOP dynamic range of motion vectors */
+ int fcodeBackward; /* VOP dynamic range of motion vectors */
+ int refSelectCode; /* enhancement layer reference select code */
+
+ /* H.263 parameters */
+ int gobNumber;
+ int gobFrameID;
+ int temporalRef; /* temporal reference, roll over at 256 */
+ int ETR;
+} Vop;
+
+typedef struct tagVol
+{
+ int volID; /* VOL identifier (for tracking) */
+ uint timeIncrementResolution;/* VOL time increment */
+ int nbitsTimeIncRes; /* number of bits for time increment */
+ uint timeInc_offset; /* timeInc offset for multiple VOP in a packet */
+ uint32 moduloTimeBase; /* internal decoder clock */
+ int fixedVopRate;
+ BitstreamDecVideo *bitstream; /* library bitstream buffer (input buffer) */
+
+ int complexity_estDisable; /* VOL disable complexity estimation */
+ int complexity_estMethod; /* VOL complexity estimation method */
+ Complexity_Est complexity; /* complexity estimation flags */
+
+ /* Error Resilience Flags */
+ int errorResDisable; /* VOL disable error resilence mode */
+ /* (Use Resynch markers) */
+ int useReverseVLC; /* VOL reversible VLCs */
+ int dataPartitioning; /* VOL data partitioning */
+
+ /* Bit depth */
+ uint bitsPerPixel;
+// int mid_gray; /* 2^(bits_per_pixel+2) */
+
+ /* Quantization related parameters */
+ int quantPrecision; /* Quantizer precision */
+ uint quantType; /* MPEG-4 or H.263 Quantization Type */
+ /* Added loaded quant mat, 05/22/2000 */
+ int loadIntraQuantMat; /* Load intra quantization matrix */
+ int loadNonIntraQuantMat; /* Load nonintra quantization matrix */
+ int iqmat[64]; /* Intra quant.matrix */
+ int niqmat[64]; /* Non-intra quant.matrix */
+
+ /* Parameters used for scalability */
+ int scalability; /* VOL scalability (flag) */
+ int scalType; /* temporal = 0, spatial = 1, both = 2 */
+
+ int refVolID; /* VOL id of reference VOL */
+ int refSampDir; /* VOL resol. of ref. VOL */
+ int horSamp_n; /* VOL hor. resampling of ref. VOL given by */
+ int horSamp_m; /* sampfac = hor_samp_n/hor_samp_m */
+ int verSamp_n; /* VOL ver. resampling of ref. VOL given by */
+ int verSamp_m; /* sampfac = ver_samp_n/ver_samp_m */
+ int enhancementType; /* VOL type of enhancement layer */
+ /* profile and level */
+ int32 profile_level_id; /* 8-bit profile and level */ // 6/17/04
+
+} Vol;
+
+
+typedef int16 typeMBStore[6][NCOEFF_BLOCK];
+
+typedef struct tagMacroBlock
+{
+ typeMBStore block; /* blocks */ /* ACDC */
+ uint8 pred_block[384]; /* prediction block, Aug 3,2005 */
+ uint8 bitmapcol[6][8];
+ uint8 bitmaprow[6];
+ int no_coeff[6];
+ int DCScalarLum; /* Luminance DC Scalar */
+ int DCScalarChr; /* Chrominance DC Scalar */
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ int direction;
+#endif
+} MacroBlock;
+
+typedef struct tagHeaderInfoDecVideo
+{
+ uint8 *Mode; /* Modes INTRA/INTER/etc. */
+ uint8 *CBP; /* MCBPC/CBPY stuff */
+} HeaderInfoDecVideo;
+
+
+/************************************************************/
+/* VLC structures */
+/************************************************************/
+typedef struct tagTcoef
+{
+ uint last;
+ uint run;
+ int level;
+ uint sign;
+} Tcoef, *LPTcoef;
+
+
+
+typedef struct tagVLCtab
+{
+ int32 val;
+ int32 len;
+} VLCtab, *LPVLCtab;
+
+typedef struct tagVLCshorttab
+{
+ int16 val;
+ int16 len;
+} VLCshorttab, *LPVLCshorttab ; /* for space saving, Antoine Nguyen*/
+
+typedef struct tagVLCtab2
+{
+ uint8 run;
+ uint8 level;
+ uint8 last;
+ uint8 len;
+} VLCtab2, *LPVLCtab2; /* 10/24/2000 */
+
+/* This type is designed for fast access of DC/AC */
+/* prediction data. If the compiler is smart */
+/* enough, it will use shifting for indexing. */
+/* 04/14/2000. */
+
+typedef int16 typeDCStore[6]; /* ACDC */
+typedef int16 typeDCACStore[4][8];
+
+
+
+/* Global structure that can be passed around */
+typedef struct tagVideoDecData
+{
+ BitstreamDecVideo *bitstream; /* library bitstream buffer (input buffer) */
+ /* Data For Layers (Scalability) */
+ Vol **vol; /* Data stored for each VOL */
+
+ /* Data used for reconstructing frames */
+ Vop *currVop; /* Current VOP (frame) */
+ Vop *prevVop; /* Previous VOP (frame) */
+ /* Data used to facilitate multiple layer decoding. 05/04/2000 */
+ Vop *prevEnhcVop; /* New change to rid of memcpy(). 04/24/2001 */
+ Vop **vopHeader; /* one for each layer. 08/29/2000 */
+
+ /* I/O structures */
+ MacroBlock *mblock; /* Macroblock data structure */
+ uint8 *acPredFlag; /* */
+
+ /* scratch memory used in data partitioned mode */
+ typeDCStore *predDC; /* The DC coeffs for each MB */
+ typeDCACStore *predDCAC_row;
+ typeDCACStore *predDCAC_col;
+
+ int usePrevQP; /* running QP decision switch */
+ uint8 *sliceNo; /* Slice indicator for each MB */
+ /* changed this to a 1D */
+ /* array for optimization */
+ MOT *motX; /* Motion vector in X direction */
+ MOT *motY; /* Motion vector in Y direction */
+ HeaderInfoDecVideo headerInfo; /* MB Header information */
+ int16 *QPMB; /* Quantizer value for each MB */
+
+ uint8 *pstprcTypCur; /* Postprocessing type for current frame */
+ uint8 *pstprcTypPrv; /* Postprocessing type for previous frame */
+ /* scratch memory used in all modes */
+ int mbnum; /* Macroblock number */
+ uint mbnum_row;
+ int mbnum_col;
+ /* I added these variables since they are used a lot. 04/13/2000 */
+ int nMBPerRow, nMBPerCol; /* number of MBs in each row & column */
+ int nTotalMB;
+ /* for short video header */
+ int nMBinGOB; /* number of MBs in GOB, 05/22/00 */
+ int nGOBinVop; /* number of GOB in Vop 05/22/00 */
+ /* VOL Dimensions */
+ int width; /* Width */
+ int height; /* Height */
+ int displayWidth; /* Handle image whose size is not a multiple of 16. */
+ int displayHeight; /* This is the actual size. 08/09/2000 */
+ int32 size;
+ /* Miscellaneous data points to be passed */
+ int frame_idx; /* Current frame ID */
+ int frameRate; /* Output frame Rate (over 10 seconds) */
+ int32 duration;
+ uint32 currTimestamp;
+ int currLayer; /* Current frame layer */
+ int shortVideoHeader; /* shortVideoHeader mode */
+ int intra_acdcPredDisable; /* VOL disable INTRA DC prediction */
+ int numberOfLayers; /* Number of Layers */
+ /* Frame to be used for concealment 07/07/2001 */
+ uint8 *concealFrame;
+ int vop_coding_type;
+ /* framerate and bitrate statistics counters. 08/23/2000 */
+ int32 nBitsPerVop[BITRATE_AVERAGE_WINDOW];
+ uint32 prevTimestamp[BITRATE_AVERAGE_WINDOW];
+ int nBitsForMBID; /* how many bits required for MB number? */
+ /* total data memory used by the docder library. 08/23/2000 */
+ int32 memoryUsage;
+
+ /* flag to turn on/off error concealment or soft decoding */
+ int errorConcealment;
+
+ /* Application controls */
+ VideoDecControls *videoDecControls;
+ int postFilterType; /* Postfilter mode 04/25/00 */
+
+
+
+ PV_STATUS(*vlcDecCoeffIntra)(BitstreamDecVideo *stream, Tcoef *pTcoef/*, int intra_luma*/);
+ PV_STATUS(*vlcDecCoeffInter)(BitstreamDecVideo *stream, Tcoef *pTcoef);
+ int initialized;
+
+ /* Annex IJKT */
+ int deblocking;
+ int slice_structure;
+ int modified_quant;
+ int advanced_INTRA;
+ int16 QP_CHR; /* ANNEX_T */
+} VideoDecData;
+
+/* for fast VLC+Dequant 10/12/2000*/
+typedef int (*VlcDequantBlockFuncP)(void *video, int comp, int switched,
+ uint8 *bitmaprow, uint8 *bitmapcol);
+
+//////////////////////////////////////////////////////////////
+// Decoder structures //
+//////////////////////////////////////////////////////////////
+#endif /* _MP4LIB_INT_H_ */
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/packet_util.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/packet_util.cpp
new file mode 100644
index 0000000..48414d7
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/packet_util.cpp
@@ -0,0 +1,252 @@
+/* ------------------------------------------------------------------
+ * 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 "mp4dec_lib.h"
+#include "vlc_decode.h"
+#include "bitstream.h"
+
+
+/***********************************************************CommentBegin******
+* 04/13/2000 : initial modification to the new PV-Decoder
+* Lib format.
+* 04/16/2001 : Removed PV_END_OF_BUFFER case, error resilience
+***********************************************************CommentEnd********/
+PV_STATUS PV_ReadVideoPacketHeader(VideoDecData *video, int *next_MB)
+{
+ PV_STATUS status;
+ Vol *currVol = video->vol[video->currLayer];
+ Vop *currVop = video->currVop;
+ BitstreamDecVideo *stream = video->bitstream;
+ int fcode_forward;
+ int resync_marker_length;
+ int nbits = video->nBitsForMBID;
+ uint32 tmpvar32;
+ uint tmpvar16;
+ int16 quantizer;
+ int nTotalMB = video->nTotalMB;
+
+ fcode_forward = currVop->fcodeForward;
+ resync_marker_length = 17;
+
+ if (currVop->predictionType != I_VOP) resync_marker_length = 16 + fcode_forward;
+
+ status = PV_BitstreamShowBitsByteAlign(stream, resync_marker_length, &tmpvar32);
+ /* if (status != PV_SUCCESS && status != PV_END_OF_BUFFER) return status; */
+ if (tmpvar32 == RESYNC_MARKER)
+ {
+// DecNextStartCode(stream);
+ PV_BitstreamByteAlign(stream);
+ BitstreamReadBits32(stream, resync_marker_length);
+
+ *next_MB = (int) BitstreamReadBits16(stream, nbits);
+// if (*next_MB <= video->mbnum) /* needs more investigation */
+// *next_MB = video->mbnum+1;
+
+ if (*next_MB >= nTotalMB) /* fix 04/05/01 */
+ {
+ *next_MB = video->mbnum + 1;
+ if (*next_MB >= nTotalMB) /* this check is needed */
+ *next_MB = nTotalMB - 1;
+ }
+ quantizer = (int16) BitstreamReadBits16(stream, currVol->quantPrecision);
+ if (quantizer == 0) return PV_FAIL; /* 04/03/01 */
+
+ currVop->quantizer = quantizer;
+
+ /* if we have HEC, read some redundant VOP header information */
+ /* this part needs improvement 04/05/01 */
+ if (BitstreamRead1Bits(stream))
+ {
+ int time_base = -1;
+
+ /* modulo_time_base (? bits) */
+ do
+ {
+ time_base++;
+ tmpvar16 = BitstreamRead1Bits(stream);
+ }
+ while (tmpvar16 == 1);
+
+ /* marker bit */
+ BitstreamRead1Bits(stream);
+
+ /* vop_time_increment (1-15 bits) */
+ BitstreamReadBits16(stream, currVol->nbitsTimeIncRes);
+
+ /* marker bit */
+ BitstreamRead1Bits(stream);
+
+ /* vop_prediction_type (2 bits) */
+ BitstreamReadBits16(stream, 2);
+
+ /* Added intra_dc_vlc_thr reading */
+ BitstreamReadBits16(stream, 3);
+
+ /* fcodes */
+ if (currVop->predictionType != I_VOP)
+ {
+ fcode_forward = (int) BitstreamReadBits16(stream, 3);
+
+ if (currVop->predictionType == B_VOP)
+ {
+ BitstreamReadBits16(stream, 3);
+ }
+ }
+
+ }
+ }
+ else
+ {
+ PV_BitstreamByteAlign(stream); /* */
+ status = BitstreamCheckEndBuffer(stream); /* return end_of_VOP 03/30/01 */
+ if (status != PV_SUCCESS)
+ {
+ return status;
+ }
+ status = BitstreamShowBits32HC(stream, &tmpvar32); /* 07/07/01 */
+ /* -16 = 0xFFFFFFF0*/
+ if ((tmpvar32 & 0xFFFFFFF0) == VISUAL_OBJECT_SEQUENCE_START_CODE) /* start code mask 00 00 01 */
+
+ {
+ /* we don't have to check for legl stuffing here. 05/08/2000 */
+ return PV_END_OF_VOP;
+ }
+ else
+ {
+ return PV_FAIL;
+ }
+ }
+
+ return PV_SUCCESS;
+}
+
+
+
+/***********************************************************CommentBegin******
+* 3/10/00 : initial modification to the
+* new PV-Decoder Lib format.
+* 04/17/01 : remove PV_END_OF_BUFFER, error checking
+***********************************************************CommentEnd********/
+PV_STATUS PV_GobHeader(VideoDecData *video)
+{
+ uint32 tmpvar;
+ Vop *currVop = video->currVop;
+ BitstreamDecVideo *stream = video->bitstream;
+ int quantPrecision = 5;
+ int16 quantizer;
+
+ BitstreamShowBits32(stream, GOB_RESYNC_MARKER_LENGTH, &tmpvar);
+
+ if (tmpvar != GOB_RESYNC_MARKER)
+ {
+ PV_BitstreamShowBitsByteAlign(stream, GOB_RESYNC_MARKER_LENGTH, &tmpvar);
+
+ if (tmpvar != GOB_RESYNC_MARKER)
+ {
+ return PV_FAIL;
+ }
+ else
+ PV_BitstreamByteAlign(stream); /* if bytealigned GOBHEADER search is performed */
+ /* then no more noforcestuffing */
+ }
+
+ /* we've got a GOB header info here */
+ BitstreamShowBits32(stream, GOB_RESYNC_MARKER_LENGTH + 5, &tmpvar);
+ tmpvar &= 0x1F;
+
+ if (tmpvar == 0)
+ {
+ return PV_END_OF_VOP;
+ }
+
+ if (tmpvar == 31)
+ {
+ PV_BitstreamFlushBits(stream, GOB_RESYNC_MARKER_LENGTH + 5);
+ BitstreamByteAlignNoForceStuffing(stream);
+ return PV_END_OF_VOP;
+ }
+
+ PV_BitstreamFlushBits(stream, GOB_RESYNC_MARKER_LENGTH + 5);
+ currVop->gobNumber = (int) tmpvar;
+ if (currVop->gobNumber >= video->nGOBinVop) return PV_FAIL;
+ currVop->gobFrameID = (int) BitstreamReadBits16(stream, 2);
+ quantizer = (int16) BitstreamReadBits16(stream, quantPrecision);
+ if (quantizer == 0) return PV_FAIL; /* 04/03/01 */
+
+ currVop->quantizer = quantizer;
+ return PV_SUCCESS;
+}
+#ifdef PV_ANNEX_IJKT_SUPPORT
+PV_STATUS PV_H263SliceHeader(VideoDecData *video, int *next_MB)
+{
+ PV_STATUS status;
+ uint32 tmpvar;
+ Vop *currVop = video->currVop;
+ BitstreamDecVideo *stream = video->bitstream;
+ int nTotalMB = video->nTotalMB;
+ int16 quantizer;
+
+ PV_BitstreamShowBitsByteAlignNoForceStuffing(stream, 17, &tmpvar);
+ if (tmpvar == RESYNC_MARKER)
+ {
+ BitstreamByteAlignNoForceStuffing(stream);
+ PV_BitstreamFlushBits(stream, 17);
+ if (!BitstreamRead1Bits(stream))
+ {
+ return PV_FAIL;
+ }
+ *next_MB = BitstreamReadBits16(stream, video->nBitsForMBID);
+ if (*next_MB >= nTotalMB) /* fix 04/05/01 */
+ {
+ *next_MB = video->mbnum + 1;
+ if (*next_MB >= nTotalMB) /* this check is needed */
+ *next_MB = nTotalMB - 1;
+ }
+ /* we will not parse sebp2 for large pictures 3GPP */
+ quantizer = (int16) BitstreamReadBits16(stream, 5);
+ if (quantizer == 0) return PV_FAIL;
+
+ currVop->quantizer = quantizer;
+ if (!BitstreamRead1Bits(stream))
+ {
+ return PV_FAIL;
+ }
+ currVop->gobFrameID = (int) BitstreamReadBits16(stream, 2);
+ }
+ else
+ {
+ status = BitstreamCheckEndBuffer(stream); /* return end_of_VOP 03/30/01 */
+ if (status != PV_SUCCESS)
+ {
+ return status;
+ }
+ PV_BitstreamShowBitsByteAlign(stream, SHORT_VIDEO_START_MARKER_LENGTH, &tmpvar);
+
+ if (tmpvar == SHORT_VIDEO_START_MARKER)
+ {
+ /* we don't have to check for legal stuffing here. 05/08/2000 */
+ return PV_END_OF_VOP;
+ }
+ else
+ {
+ return PV_FAIL;
+ }
+ }
+ return PV_SUCCESS;
+}
+#endif
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/post_filter.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/post_filter.cpp
new file mode 100644
index 0000000..b36050c
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/post_filter.cpp
@@ -0,0 +1,585 @@
+/* ------------------------------------------------------------------
+ * 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 "mp4dec_lib.h"
+
+#ifdef PV_ANNEX_IJKT_SUPPORT
+#include "motion_comp.h"
+#include "mbtype_mode.h"
+const static int STRENGTH_tab[] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12};
+#endif
+
+#ifdef PV_POSTPROC_ON
+/*----------------------------------------------------------------------------
+; FUNCTION CODE
+----------------------------------------------------------------------------*/
+void PostFilter(
+ VideoDecData *video,
+ int filter_type,
+ uint8 *output)
+{
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ uint8 *pp_mod;
+ int16 *QP_store;
+ int combined_with_deblock_filter;
+ int nTotalMB = video->nTotalMB;
+ int width, height;
+ int32 size;
+ int softDeblocking;
+ uint8 *decodedFrame = video->videoDecControls->outputFrame;
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ width = video->width;
+ height = video->height;
+ size = (int32)width * height;
+
+ oscl_memcpy(output, decodedFrame, size);
+ oscl_memcpy(output + size, decodedFrame + size, (size >> 2));
+ oscl_memcpy(output + size + (size >> 2), decodedFrame + size + (size >> 2), (size >> 2));
+
+ if (filter_type == 0)
+ return;
+
+ /* The softDecoding cutoff corresponds to ~93000 bps for QCIF 15fps clip */
+ if (PVGetDecBitrate(video->videoDecControls) > (100*video->frameRate*(size >> 12))) // MC_sofDeblock
+ softDeblocking = FALSE;
+ else
+ softDeblocking = TRUE;
+
+ combined_with_deblock_filter = filter_type & PV_DEBLOCK;
+ QP_store = video->QPMB;
+
+ /* Luma */
+ pp_mod = video->pstprcTypCur;
+
+ if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING))
+ {
+ CombinedHorzVertRingFilter(output, width, height, QP_store, 0, pp_mod);
+ }
+ else
+ {
+ if (filter_type & PV_DEBLOCK)
+ {
+ if (softDeblocking)
+ {
+ CombinedHorzVertFilter(output, width, height,
+ QP_store, 0, pp_mod);
+ }
+ else
+ {
+ CombinedHorzVertFilter_NoSoftDeblocking(output, width, height,
+ QP_store, 0, pp_mod);
+ }
+ }
+ if (filter_type & PV_DERING)
+ {
+ Deringing_Luma(output, width, height, QP_store,
+ combined_with_deblock_filter, pp_mod);
+
+ }
+ }
+
+ /* Chroma */
+
+ pp_mod += (nTotalMB << 2);
+ output += size;
+
+ if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING))
+ {
+ CombinedHorzVertRingFilter(output, (int)(width >> 1), (int)(height >> 1), QP_store, (int) 1, pp_mod);
+ }
+ else
+ {
+ if (filter_type & PV_DEBLOCK)
+ {
+ if (softDeblocking)
+ {
+ CombinedHorzVertFilter(output, (int)(width >> 1),
+ (int)(height >> 1), QP_store, (int) 1, pp_mod);
+ }
+ else
+ {
+ CombinedHorzVertFilter_NoSoftDeblocking(output, (int)(width >> 1),
+ (int)(height >> 1), QP_store, (int) 1, pp_mod);
+ }
+ }
+ if (filter_type & PV_DERING)
+ {
+ Deringing_Chroma(output, (int)(width >> 1),
+ (int)(height >> 1), QP_store,
+ combined_with_deblock_filter, pp_mod);
+ }
+ }
+
+ pp_mod += nTotalMB;
+ output += (size >> 2);
+
+ if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING))
+ {
+ CombinedHorzVertRingFilter(output, (int)(width >> 1), (int)(height >> 1), QP_store, (int) 1, pp_mod);
+ }
+ else
+ {
+ if (filter_type & PV_DEBLOCK)
+ {
+ if (softDeblocking)
+ {
+ CombinedHorzVertFilter(output, (int)(width >> 1),
+ (int)(height >> 1), QP_store, (int) 1, pp_mod);
+ }
+ else
+ {
+ CombinedHorzVertFilter_NoSoftDeblocking(output, (int)(width >> 1),
+ (int)(height >> 1), QP_store, (int) 1, pp_mod);
+ }
+ }
+ if (filter_type & PV_DERING)
+ {
+ Deringing_Chroma(output, (int)(width >> 1),
+ (int)(height >> 1), QP_store,
+ combined_with_deblock_filter, pp_mod);
+ }
+ }
+
+ /* swap current pp_mod to prev_frame pp_mod */
+ pp_mod = video->pstprcTypCur;
+ video->pstprcTypCur = video->pstprcTypPrv;
+ video->pstprcTypPrv = pp_mod;
+
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return;
+}
+#endif
+
+
+#ifdef PV_ANNEX_IJKT_SUPPORT
+void H263_Deblock(uint8 *rec,
+ int width,
+ int height,
+ int16 *QP_store,
+ uint8 *mode,
+ int chr, int annex_T)
+{
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int i, j, k;
+ uint8 *rec_y;
+ int tmpvar;
+ int mbnum, strength, A_D, d1_2, d1, d2, A, B, C, D, b_size;
+ int d, offset, nMBPerRow, nMBPerCol, width2 = (width << 1);
+ /* MAKE SURE I-VOP INTRA MACROBLOCKS ARE SET TO NON-SKIPPED MODE*/
+ mbnum = 0;
+
+ if (chr)
+ {
+ nMBPerRow = width >> 3;
+ nMBPerCol = height >> 3;
+ b_size = 8;
+ }
+ else
+ {
+ nMBPerRow = width >> 4;
+ nMBPerCol = height >> 4;
+ b_size = 16;
+ }
+
+
+ /********************************* VERTICAL FILTERING ****************************/
+ /* vertical filtering of mid sections no need to check neighboring QP's etc */
+ if (!chr)
+ {
+ rec_y = rec + (width << 3);
+ for (i = 0; i < (height >> 4); i++)
+ {
+ for (j = 0; j < (width >> 4); j++)
+ {
+ if (mode[mbnum] != MODE_SKIPPED)
+ {
+ k = 16;
+ strength = STRENGTH_tab[QP_store[mbnum]];
+ while (k--)
+ {
+ A = *(rec_y - width2);
+ D = *(rec_y + width);
+ A_D = A - D;
+ C = *rec_y;
+ B = *(rec_y - width);
+ d = (((C - B) << 2) + A_D);
+
+ if (d < 0)
+ {
+ d1 = -(-d >> 3);
+ if (d1 < -(strength << 1))
+ {
+ d1 = 0;
+ }
+ else if (d1 < -strength)
+ {
+ d1 = -d1 - (strength << 1);
+ }
+ d1_2 = -d1 >> 1;
+ }
+ else
+ {
+ d1 = d >> 3;
+ if (d1 > (strength << 1))
+ {
+ d1 = 0;
+ }
+ else if (d1 > strength)
+ {
+ d1 = (strength << 1) - d1;
+ }
+ d1_2 = d1 >> 1;
+ }
+
+ if (A_D < 0)
+ {
+ d2 = -(-A_D >> 2);
+ if (d2 < -d1_2)
+ {
+ d2 = -d1_2;
+ }
+ }
+ else
+ {
+ d2 = A_D >> 2;
+ if (d2 > d1_2)
+ {
+ d2 = d1_2;
+ }
+ }
+
+ *(rec_y - width2) = A - d2;
+ tmpvar = B + d1;
+ CLIP_RESULT(tmpvar)
+ *(rec_y - width) = tmpvar;
+ tmpvar = C - d1;
+ CLIP_RESULT(tmpvar)
+ *rec_y = tmpvar;
+ *(rec_y + width) = D + d2;
+ rec_y++;
+ }
+ }
+ else
+ {
+ rec_y += b_size;
+ }
+ mbnum++;
+ }
+ rec_y += (15 * width);
+
+ }
+ }
+
+ /* VERTICAL boundary blocks */
+
+
+ rec_y = rec + width * b_size;
+
+ mbnum = nMBPerRow;
+ for (i = 0; i < nMBPerCol - 1; i++)
+ {
+ for (j = 0; j < nMBPerRow; j++)
+ {
+ if (mode[mbnum] != MODE_SKIPPED || mode[mbnum - nMBPerRow] != MODE_SKIPPED)
+ {
+ k = b_size;
+ if (mode[mbnum] != MODE_SKIPPED)
+ {
+ strength = STRENGTH_tab[(annex_T ? MQ_chroma_QP_table[QP_store[mbnum]] : QP_store[mbnum])];
+ }
+ else
+ {
+ strength = STRENGTH_tab[(annex_T ? MQ_chroma_QP_table[QP_store[mbnum - nMBPerRow]] : QP_store[mbnum - nMBPerRow])];
+ }
+
+ while (k--)
+ {
+ A = *(rec_y - width2);
+ D = *(rec_y + width);
+ A_D = A - D;
+ C = *rec_y;
+ B = *(rec_y - width);
+ d = (((C - B) << 2) + A_D);
+
+ if (d < 0)
+ {
+ d1 = -(-d >> 3);
+ if (d1 < -(strength << 1))
+ {
+ d1 = 0;
+ }
+ else if (d1 < -strength)
+ {
+ d1 = -d1 - (strength << 1);
+ }
+ d1_2 = -d1 >> 1;
+ }
+ else
+ {
+ d1 = d >> 3;
+ if (d1 > (strength << 1))
+ {
+ d1 = 0;
+ }
+ else if (d1 > strength)
+ {
+ d1 = (strength << 1) - d1;
+ }
+ d1_2 = d1 >> 1;
+ }
+
+ if (A_D < 0)
+ {
+ d2 = -(-A_D >> 2);
+ if (d2 < -d1_2)
+ {
+ d2 = -d1_2;
+ }
+ }
+ else
+ {
+ d2 = A_D >> 2;
+ if (d2 > d1_2)
+ {
+ d2 = d1_2;
+ }
+ }
+
+ *(rec_y - width2) = A - d2;
+ tmpvar = B + d1;
+ CLIP_RESULT(tmpvar)
+ *(rec_y - width) = tmpvar;
+ tmpvar = C - d1;
+ CLIP_RESULT(tmpvar)
+ *rec_y = tmpvar;
+ *(rec_y + width) = D + d2;
+ rec_y++;
+ }
+ }
+ else
+ {
+ rec_y += b_size;
+ }
+ mbnum++;
+ }
+ rec_y += ((b_size - 1) * width);
+
+ }
+
+
+ /***************************HORIZONTAL FILTERING ********************************************/
+ mbnum = 0;
+ /* HORIZONTAL INNER */
+ if (!chr)
+ {
+ rec_y = rec + 8;
+ offset = width * b_size - b_size;
+
+ for (i = 0; i < nMBPerCol; i++)
+ {
+ for (j = 0; j < nMBPerRow; j++)
+ {
+ if (mode[mbnum] != MODE_SKIPPED)
+ {
+ k = 16;
+ strength = STRENGTH_tab[QP_store[mbnum]];
+ while (k--)
+ {
+ A = *(rec_y - 2);
+ D = *(rec_y + 1);
+ A_D = A - D;
+ C = *rec_y;
+ B = *(rec_y - 1);
+ d = (((C - B) << 2) + A_D);
+
+ if (d < 0)
+ {
+ d1 = -(-d >> 3);
+ if (d1 < -(strength << 1))
+ {
+ d1 = 0;
+ }
+ else if (d1 < -strength)
+ {
+ d1 = -d1 - (strength << 1);
+ }
+ d1_2 = -d1 >> 1;
+ }
+ else
+ {
+ d1 = d >> 3;
+ if (d1 > (strength << 1))
+ {
+ d1 = 0;
+ }
+ else if (d1 > strength)
+ {
+ d1 = (strength << 1) - d1;
+ }
+ d1_2 = d1 >> 1;
+ }
+
+ if (A_D < 0)
+ {
+ d2 = -(-A_D >> 2);
+ if (d2 < -d1_2)
+ {
+ d2 = -d1_2;
+ }
+ }
+ else
+ {
+ d2 = A_D >> 2;
+ if (d2 > d1_2)
+ {
+ d2 = d1_2;
+ }
+ }
+
+ *(rec_y - 2) = A - d2;
+ tmpvar = B + d1;
+ CLIP_RESULT(tmpvar)
+ *(rec_y - 1) = tmpvar;
+ tmpvar = C - d1;
+ CLIP_RESULT(tmpvar)
+ *rec_y = tmpvar;
+ *(rec_y + 1) = D + d2;
+ rec_y += width;
+ }
+ rec_y -= offset;
+ }
+ else
+ {
+ rec_y += b_size;
+ }
+ mbnum++;
+ }
+ rec_y += (15 * width);
+
+ }
+ }
+
+
+
+ /* HORIZONTAL EDGE */
+ rec_y = rec + b_size;
+ offset = width * b_size - b_size;
+ mbnum = 1;
+ for (i = 0; i < nMBPerCol; i++)
+ {
+ for (j = 0; j < nMBPerRow - 1; j++)
+ {
+ if (mode[mbnum] != MODE_SKIPPED || mode[mbnum-1] != MODE_SKIPPED)
+ {
+ k = b_size;
+ if (mode[mbnum] != MODE_SKIPPED)
+ {
+ strength = STRENGTH_tab[(annex_T ? MQ_chroma_QP_table[QP_store[mbnum]] : QP_store[mbnum])];
+ }
+ else
+ {
+ strength = STRENGTH_tab[(annex_T ? MQ_chroma_QP_table[QP_store[mbnum - 1]] : QP_store[mbnum - 1])];
+ }
+
+ while (k--)
+ {
+ A = *(rec_y - 2);
+ D = *(rec_y + 1);
+ A_D = A - D;
+ C = *rec_y;
+ B = *(rec_y - 1);
+ d = (((C - B) << 2) + A_D);
+
+ if (d < 0)
+ {
+ d1 = -(-d >> 3);
+ if (d1 < -(strength << 1))
+ {
+ d1 = 0;
+ }
+ else if (d1 < -strength)
+ {
+ d1 = -d1 - (strength << 1);
+ }
+ d1_2 = -d1 >> 1;
+ }
+ else
+ {
+ d1 = d >> 3;
+ if (d1 > (strength << 1))
+ {
+ d1 = 0;
+ }
+ else if (d1 > strength)
+ {
+ d1 = (strength << 1) - d1;
+ }
+ d1_2 = d1 >> 1;
+ }
+
+ if (A_D < 0)
+ {
+ d2 = -(-A_D >> 2);
+ if (d2 < -d1_2)
+ {
+ d2 = -d1_2;
+ }
+ }
+ else
+ {
+ d2 = A_D >> 2;
+ if (d2 > d1_2)
+ {
+ d2 = d1_2;
+ }
+ }
+
+ *(rec_y - 2) = A - d2;
+ tmpvar = B + d1;
+ CLIP_RESULT(tmpvar)
+ *(rec_y - 1) = tmpvar;
+ tmpvar = C - d1;
+ CLIP_RESULT(tmpvar)
+ *rec_y = tmpvar;
+ *(rec_y + 1) = D + d2;
+ rec_y += width;
+ }
+ rec_y -= offset;
+ }
+ else
+ {
+ rec_y += b_size;
+ }
+ mbnum++;
+ }
+ rec_y += ((width * (b_size - 1)) + b_size);
+ mbnum++;
+ }
+
+ return;
+}
+#endif
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/post_proc.h b/media/libstagefright/codecs/m4v_h263/dec/src/post_proc.h
new file mode 100644
index 0000000..091fdaf
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/post_proc.h
@@ -0,0 +1,75 @@
+/* ------------------------------------------------------------------
+ * 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 post_proc_H
+#define post_proc_H
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "mp4dec_lib.h"
+
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here.
+----------------------------------------------------------------------------*/
+#define UPDATE_PV_MAXPV_MIN(p,max,min) if ((p) > max) max=(p); else if ((p) < min) min = (p);
+
+#define INDEX(x,thr) (((x)>=thr)?1:0)
+#define BLKSIZE 8
+#define MBSIZE 16
+#define DERING_THR 16
+
+/* version for fast Deblock filtering*/
+#define KTh 4 /*threshold for soft filtering*/
+#define KThH 4 /*threshold for hard filtering */
+
+#define NoMMX
+
+/*----------------------------------------------------------------------------
+; EXTERNAL VARIABLES REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; SIMPLE TYPEDEF'S
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; ENUMERATED TYPEDEF'S
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; STRUCTURES TYPEDEF'S
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; GLOBAL FUNCTION DEFINITIONS
+; Function Prototype declaration
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; END
+----------------------------------------------------------------------------*/
+#endif
+
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/post_proc_semaphore.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/post_proc_semaphore.cpp
new file mode 100644
index 0000000..3abc6be
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/post_proc_semaphore.cpp
@@ -0,0 +1,247 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+/*
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ q_block = pointer to buffer of inverse quantized DCT coefficients of type
+ int for intra-VOP mode or buffer of residual data of type int
+ for inter-VOP mode
+
+ Local Stores/Buffers/Pointers Needed:
+ None
+
+ Global Stores/Buffers/Pointers Needed:
+ None
+
+ Outputs:
+ postmode = post processing semaphore with the vertical deblocking,
+ horizontal deblocking, and deringing bits set up accordingly
+
+ Pointers and Buffers Modified:
+ None
+
+ Local Stores Modified:
+ None
+
+ Global Stores Modified:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function sets up the postmode semaphore based on the contents of the
+ buffer pointed to by q_block. The function starts out with the assumption
+ that all entries of q_block, except for the first entry (q_block[0]), are
+ zero. This case can induce horizontal and vertical blocking artifacts,
+ therefore, both horizontal and vertical deblocking bits are enabled.
+
+ The following conditions are tested when setting up the horizontal/vertical
+ deblocking and deringing bits:
+ 1. When only the elements of the top row of the B_SIZE x B_SIZE block
+ (q_block[n], n = 0,..., B_SIZE-1) are non-zero, vertical blocking artifacts
+ may result, therefore, only the vertical deblocking bit is enabled.
+ Otherwise, the vertical deblocking bit is disabled.
+ 2. When only the elements of the far left column of the B_SIZE x B_SIZE block
+ (q_block[n*B_SIZE], n = 0, ..., B_SIZE-1) are non-zero, horizontal blocking
+ artifacts may result, therefore, only the horizontal deblocking bit is
+ enabled. Otherwise, the horizontal deblocking bit is disabled.
+ 3. If any non-zero elements exist in positions other than q_block[0],
+ q_block[1], or q_block[B_SIZE], the deringing bit is enabled. Otherwise,
+ it is disabled.
+
+ The 3 least significant bits of postmode defines vertical or horizontal
+ deblocking and deringing.
+
+ The valid values are shown below:
+ -------------------------------------------------------
+ | Type | Enabled | Disabled |
+ -------------------------------------------------------
+ | Vertical Deblocking (Bit #0) | 1 | 0 |
+ -------------------------------------------------------
+ | Horizontal Deblocking (Bit #1) | 1 | 0 |
+ -------------------------------------------------------
+ | Deringing (Bit #2) | 1 | 0 |
+ -------------------------------------------------------
+
+*/
+
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "mp4dec_lib.h"
+#include "mp4def.h"
+#include "post_proc.h"
+
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here. Include conditional
+; compile variables also.
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL FUNCTION DEFINITIONS
+; Function Prototype declaration
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL STORE/BUFFER/POINTER DEFINITIONS
+; Variable declaration - defined here and used outside this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL FUNCTION REFERENCES
+; Declare functions defined elsewhere and referenced in this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+#ifdef PV_POSTPROC_ON
+/*----------------------------------------------------------------------------
+; FUNCTION CODE
+----------------------------------------------------------------------------*/
+int PostProcSemaphore(
+ int16 *q_block)
+{
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int i, j;
+
+ /* Set default value to vertical and horizontal deblocking enabled */
+ /* Initial assumption is that only q_block[0] element is non-zero, */
+ /* therefore, vertical and horizontal deblocking bits are set to 1 */
+ int postmode = 0x3;
+
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ /* Vertical deblocking bit is enabled when only the entire top row of */
+ /* the B_SIZE x B_SIZE block, i.e., q_block[n], n = 0,..., B_SIZE-1, */
+ /* are non-zero. Since initial assumption is that all elements, except */
+ /* q_block[0], is zero, we need to check the remaining elements in the */
+ /* top row to determine if all or some are non-zero. */
+ if (q_block[1] != 0)
+ {
+ /* At this point, q_block[0] and q_block[1] are non-zero, while */
+ /* q_block[n], n = 2,..., B_SIZE-1, are zero. Therefore, we */
+ /* need to disable vertical deblocking */
+ postmode &= 0xE;
+ }
+
+ for (i = 2; i < B_SIZE; i++)
+ {
+ if (q_block[i])
+ {
+ /* Check if q_block[n], n = 2,..., B_SIZE-1, are non-zero.*/
+ /* If any of them turn out to be non-zero, we need to */
+ /* disable vertical deblocking. */
+ postmode &= 0xE;
+
+ /* Deringing is enabled if any nonzero elements exist in */
+ /* positions other than q_block[0], q_block[1] or */
+ /* q_block[B_SIZE]. */
+ postmode |= 0x4;
+
+ break;
+ }
+ }
+
+ /* Horizontal deblocking bit is enabled when only the entire far */
+ /* left column, i.e., q_block[n*B_SIZE], n = 0, ..., B_SIZE-1, */
+ /* are non-zero. Since initial assumption is that all elements, */
+ /* except q_block[0], is zero, we need to check the remaining */
+ /* elements in the far left column to determine if all or some */
+ /* are non-zero. */
+ if (q_block[B_SIZE])
+ {
+ /* At this point, only q_block[0] and q_block[B_SIZE] are non-zero, */
+ /* while q_block[n*B_SIZE], n = 2, 3,..., B_SIZE-1, are zero. */
+ /* Therefore, we need to disable horizontal deblocking. */
+ postmode &= 0xD;
+ }
+
+ for (i = 16; i < NCOEFF_BLOCK; i += B_SIZE)
+ {
+ if (q_block[i])
+ {
+ /* Check if q_block[n], n = 2*B_SIZE,...,(B_SIZE-1)*B_SIZE, */
+ /* are non-zero. If any of them turn out to be non-zero, */
+ /* we need to disable horizontal deblocking. */
+ postmode &= 0xD;
+
+ /* Deringing is enabled if any nonzero elements exist in */
+ /* positions other than q_block[0], q_block[1] or */
+ /* q_block[B_SIZE]. */
+ postmode |= 0x4;
+
+ break;
+ }
+ }
+
+ /* At this point, only the first row and far left column elements */
+ /* have been tested. If deringing bit is still not set at this */
+ /* point, check the rest of q_block to determine if the elements */
+ /* are non-zero. If all elements, besides q_block[0], q_block[1], */
+ /* or q_block[B_SIZE] are non-zero, deringing bit must be set */
+ if ((postmode & 0x4) == 0)
+ {
+ for (i = 1; i < B_SIZE; i++)
+ {
+ for (j = 1; j < B_SIZE; j++)
+ {
+ if (q_block[(i<<3)+j])
+ {
+ /* At this point, q_block[0] and another q_block */
+ /* element are non-zero, therefore, we need to */
+ /* disable vertical and horizontal deblocking */
+ postmode &= 0xC;
+
+ /* Deringing is enabled if any nonzero elements exist in */
+ /* positions other than q_block[0], q_block[1] or */
+ /* q_block[B_SIZE]. */
+ postmode |= 0x4;
+
+ /* Set outer FOR loop count to B_SIZE to get out of */
+ /* outer FOR loop */
+ i = B_SIZE;
+
+ /* Get out of inner FOR loop */
+ break;
+ }
+ }
+ }
+ }
+
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return (postmode);
+}
+
+#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/pp_semaphore_chroma_inter.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/pp_semaphore_chroma_inter.cpp
new file mode 100644
index 0000000..7c20222
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/pp_semaphore_chroma_inter.cpp
@@ -0,0 +1,262 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+/*
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ xpred = x-axis coordinate of the block used for prediction (int)
+ ypred = y-axis coordinate of the block used for prediction (int)
+ pp_dec_u = pointer to the post processing semaphore for chrominance
+ (uint8)
+ pstprcTypPrv = pointer the previous frame's post processing type
+ (uint8)
+ dx = horizontal component of the motion vector (int)
+ dy = vertical component of the motion vector (int)
+ mvwidth = number of blocks per row in the luminance VOP (int)
+ height = luminance VOP height in pixels (int)
+ size = total number of pixel in the current luminance VOP (int)
+ mv_loc = flag indicating location of the motion compensated
+ (x,y) position with respect to the luminance MB (int);
+ 0 -> inside MB, 1 -> outside MB
+ msk_deblock = flag indicating whether to perform deblocking
+ (msk_deblock = 0) or not (msk_deblock = 1) (uint8)
+
+ Local Stores/Buffers/Pointers Needed:
+ None
+
+ Global Stores/Buffers/Pointers Needed:
+ None
+
+ Outputs:
+ None
+
+ Pointers and Buffers Modified:
+ pp_dec_u contents are the updated semaphore propagation data
+
+ Local Stores Modified:
+ None
+
+ Global Stores Modified:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This functions performs post processing semaphore propagation processing
+ after chrominance prediction in interframe processing mode.
+
+*/
+
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "mp4dec_api.h"
+#include "mp4def.h"
+
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here. Include conditional
+; compile variables also.
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL FUNCTION DEFINITIONS
+; Function Prototype declaration
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL STORE/BUFFER/POINTER DEFINITIONS
+; Variable declaration - defined here and used outside this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL FUNCTION REFERENCES
+; Declare functions defined elsewhere and referenced in this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+#ifdef PV_POSTPROC_ON
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+ /*----------------------------------------------------------------------------
+ ; FUNCTION CODE
+ ----------------------------------------------------------------------------*/
+ void pp_semaphore_chroma_inter(
+ int xpred, /* i */
+ int ypred, /* i */
+ uint8 *pp_dec_u, /* i/o */
+ uint8 *pstprcTypPrv, /* i */
+ int dx, /* i */
+ int dy, /* i */
+ int mvwidth, /* i */
+ int height, /* i */
+ int32 size, /* i */
+ int mv_loc, /* i */
+ uint8 msk_deblock /* i */
+ )
+ {
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int mmvy, mmvx, nmvy, nmvx;
+ uint8 *pp_prev1, *pp_prev2, *pp_prev3, *pp_prev4;
+
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+
+ /* 09/28/2000, modify semaphore propagation to */
+ /* accommodate smart indexing */
+ mmvx = xpred >> 4; /* block x coor */
+ nmvx = mmvx;
+
+ mmvy = ypred >> 4; /* block y coor */
+ nmvy = mmvy;
+
+ /* Check if MV is outside the frame */
+ if (mv_loc == 1)
+ {
+ /* Perform boundary check */
+ if (nmvx < 0)
+ {
+ nmvx = 0;
+ }
+ else if (nmvx > mvwidth - 1)
+ {
+ nmvx = mvwidth - 1;
+ }
+
+ if (nmvy < 0)
+ {
+ nmvy = 0;
+ }
+ else if (nmvy > (height >> 4) - 1)
+ {
+ nmvy = (height >> 4) - 1;
+ }
+ }
+
+ /* Calculate pointer to first chrominance b semaphores in */
+ /* pstprcTypPrv, i.e., first chrominance b semaphore is in */
+ /* (pstprcTypPrv + (size>>6)). */
+ /* Since total number of chrominance blocks per row in a VOP */
+ /* is half of the total number of luminance blocks per row in a */
+ /* VOP, we use (mvwidth >> 1) when calculating the row offset. */
+ pp_prev1 = pstprcTypPrv + (size >> 6) + nmvx + nmvy * (mvwidth >> 1) ;
+
+ /* Check if MV is a multiple of 16 */
+ /* 1/5/01, make sure it doesn't go out of bound */
+ if (((dy&0xF) != 0) && (mmvy + 1 < (height >> 4) - 1))
+ { /* dy is not a multiple of 16 */
+
+ /* pp_prev3 is the block below pp_prev1 block */
+ pp_prev3 = pp_prev1 + (mvwidth >> 1);
+ }
+ else
+ { /* dy is a multiple of 16 */
+ pp_prev3 = pp_prev1;
+ }
+
+ /* 1/5/01, make sure it doesn't go out of bound */
+ if (((dx&0xF) != 0) && (mmvx + 1 < (mvwidth >> 1) - 1))
+ { /* dx is not a multiple of 16 */
+
+ /* pp_prev2 is the block to the right of pp_prev1 block */
+ pp_prev2 = pp_prev1 + 1;
+
+ /* pp_prev4 is the block to the right of the block */
+ /* below pp_prev1 block */
+ pp_prev4 = pp_prev3 + 1;
+ }
+ else
+ { /* dx is a multiple of 16 */
+
+ pp_prev2 = pp_prev1;
+ pp_prev4 = pp_prev3;
+ }
+
+ /* Advance offset to location of first Chrominance R semaphore in */
+ /* pstprcTypPrv. Since the number of pixels in a Chrominance VOP */
+ /* is (number of pixels in Luminance VOP/4), and there are 64 */
+ /* pixels in an 8x8 Chrominance block, the offset can be */
+ /* calculated as: */
+ /* mv_loc = (number of pixels in Luminance VOP/(4*64)) */
+ /* = size/256 = size>>8 */
+ mv_loc = (size >> 8);
+
+ /* 11/3/00, change the propagation for deblocking */
+ if (msk_deblock == 0)
+ {
+
+ /* Deblocking semaphore propagation for Chrominance */
+ /* b semaphores */
+ *(pp_dec_u) = 0;
+
+ /* Advance offset to point to Chrominance r semaphores */
+ pp_dec_u += mv_loc;
+
+ /* Deblocking semaphore propagation for Chrominance */
+ /* r semaphores */
+ *(pp_dec_u) = 0;
+ }
+ else
+ {
+ /* Deringing semaphore propagation for Chrominance B block */
+ if ((*(pp_dec_u)&4) == 0)
+ {
+ *(pp_dec_u) |= ((*(pp_prev1) | *(pp_prev2) |
+ *(pp_prev3) | *(pp_prev4)) & 0x4);
+ }
+
+ /* Advance offset to point to Chrominance r semaphores */
+ pp_dec_u += mv_loc;
+ pp_prev1 += mv_loc;
+ pp_prev2 += mv_loc;
+ pp_prev3 += mv_loc;
+ pp_prev4 += mv_loc;
+
+ /* Deringing semaphore propagation for Chrominance R */
+ if ((*(pp_dec_u)&4) == 0)
+ {
+ *(pp_dec_u) |= ((*(pp_prev1) | *(pp_prev2) |
+ *(pp_prev3) | *(pp_prev4)) & 0x4);
+ }
+ }
+
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return;
+ }
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/pp_semaphore_luma.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/pp_semaphore_luma.cpp
new file mode 100644
index 0000000..b3a1ebd
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/pp_semaphore_luma.cpp
@@ -0,0 +1,378 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+/*
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ xpred = x-axis coordinate of the MB used for prediction (int)
+ ypred = y-axis coordinate of the MB used for prediction (int)
+ pp_dec_y = pointer to the post processing semaphore for current
+ luminance frame (uint8)
+ pstprcTypPrv = pointer the previous frame's post processing type
+ (uint8)
+ ll = pointer to the buffer (int)
+ mv_loc = flag indicating location of the motion compensated
+ (x,y) position with respect to the luminance MB (int);
+ 0 -> inside MB, 1 -> outside MB
+ dx = horizontal component of the motion vector (int)
+ dy = vertical component of the motion vector (int)
+ mvwidth = number of blocks per row (int)
+ width = luminance VOP width in pixels (int)
+ height = luminance VOP height in pixels (int)
+
+ Local Stores/Buffers/Pointers Needed:
+ None
+
+ Global Stores/Buffers/Pointers Needed:
+ None
+
+ Outputs:
+ msk_deblock = flag that indicates whether deblocking is to be
+ performed (msk_deblock = 0) or not (msk_deblock =
+ 1) (uint8)
+
+ Pointers and Buffers Modified:
+ pp_dec_y contents are the updated semapohore propagation data
+
+ Local Stores Modified:
+ None
+
+ Global Stores Modified:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This functions performs post processing semaphore propagation processing
+ after luminance prediction.
+
+*/
+
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "mp4dec_api.h"
+#include "mp4def.h"
+
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here. Include conditional
+; compile variables also.
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL FUNCTION DEFINITIONS
+; Function Prototype declaration
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL STORE/BUFFER/POINTER DEFINITIONS
+; Variable declaration - defined here and used outside this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL FUNCTION REFERENCES
+; Declare functions defined elsewhere and referenced in this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+#ifdef PV_POSTPROC_ON
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+ /*----------------------------------------------------------------------------
+ ; FUNCTION CODE
+ ----------------------------------------------------------------------------*/
+ uint8 pp_semaphore_luma(
+ int xpred, /* i */
+ int ypred, /* i */
+ uint8 *pp_dec_y, /* i/o */
+ uint8 *pstprcTypPrv, /* i */
+ int *ll, /* i */
+ int *mv_loc, /* i/o */
+ int dx, /* i */
+ int dy, /* i */
+ int mvwidth, /* i */
+ int width, /* i */
+ int height /* i */
+ )
+ {
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int kk, mmvy, mmvx, nmvx, nmvy;
+ uint8 *pp_prev1, *pp_prev2, *pp_prev3, *pp_prev4;
+ uint8 msk_deblock = 0; /* 11/3/00 */
+
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ /* Interframe Processing - 1 MV per MB */
+
+ /* check whether the MV points outside the frame */
+ if (xpred >= 0 && xpred <= ((width << 1) - (2*MB_SIZE)) && ypred >= 0 &&
+ ypred <= ((height << 1) - (2*MB_SIZE)))
+ { /*****************************/
+ /* (x,y) is inside the frame */
+ /*****************************/
+
+ /* 10/24/2000 post_processing semaphore */
+ /* generation */
+
+ /* 10/23/2000 no boundary checking*/
+ *mv_loc = 0;
+
+ /* Calculate block x coordinate. Divide by 16 is for */
+ /* converting half-pixel resolution to block */
+ mmvx = xpred >> 4;
+
+ /* Calculate block y coordinate. Divide by 16 is for */
+ /* converting half-pixel resolution to block */
+ mmvy = ypred >> 4;
+
+ /* Find post processing semaphore location for block */
+ /* used for prediction, i.e., */
+ /* pp_prev1 = &pstprcTypPrv[mmvy*mvwidth][mmvx] */
+ pp_prev1 = pstprcTypPrv + mmvx + mmvy * mvwidth;
+
+ /* Check if MV is a multiple of 16 */
+ if ((dx&0xF) != 0)
+ { /* dx is not a multiple of 16 */
+
+ /* pp_prev2 is the block to the right of */
+ /* pp_prev1 block */
+ pp_prev2 = pp_prev1 + 1;
+
+ if ((dy&0xF) != 0)
+ { /* dy is not a multiple of 16 */
+
+ /* pp_prev3 is the block below */
+ /* pp_prev1 block */
+ pp_prev3 = pp_prev1 + mvwidth;
+ }
+ else
+ { /* dy is a multiple of 16 */
+
+ pp_prev3 = pp_prev1;
+ }
+
+ /* pp_prev4 is the block to the right of */
+ /* pp_prev3 block. */
+ pp_prev4 = pp_prev3 + 1;
+ }
+ else
+ { /* dx is a multiple of 16 */
+
+ pp_prev2 = pp_prev1;
+
+ if ((dy&0xF) != 0)
+ { /* dy is not a multiple of 16 */
+
+ /* pp_prev3 is the block below */
+ /* pp_prev1 block. */
+ pp_prev3 = pp_prev1 + mvwidth;
+ }
+ else
+ { /* dy is a multiple of 16 */
+
+ pp_prev3 = pp_prev1;
+ msk_deblock = 0x3;
+ }
+
+ pp_prev4 = pp_prev3;
+ }
+
+ /* Perform post processing semaphore propagation for each */
+ /* of the 4 blocks in a MB. */
+ for (kk = 0; kk < 4; kk++)
+ {
+ /* Deringing semaphore propagation */
+ if ((*(pp_dec_y) & 4) == 0)
+ {
+ *(pp_dec_y) |= ((*(pp_prev1) | *(pp_prev2) |
+ *(pp_prev3) | *(pp_prev4)) & 0x4);
+ }
+ /* Deblocking semaphore propagation */
+ /* 11/3/00, change the propagation for deblocking */
+ if (msk_deblock == 0)
+ {
+ *(pp_dec_y) = 0;
+ }
+
+ pp_dec_y += ll[kk];
+ pp_prev1 += ll[kk];
+ pp_prev2 += ll[kk];
+ pp_prev3 += ll[kk];
+ pp_prev4 += ll[kk];
+ }
+
+ }
+ else
+ { /******************************/
+ /* (x,y) is outside the frame */
+ /******************************/
+
+ /* 10/24/2000 post_processing semaphore */
+ /* generation */
+
+ /* 10/23/2000 boundary checking*/
+ *mv_loc = 1;
+
+ /* Perform post processing semaphore propagation for each */
+ /* of the 4 blocks in a MB. */
+ for (kk = 0; kk < 4; kk++)
+ {
+ /* Calculate block x coordinate and round (?). */
+ /* Divide by 16 is for converting half-pixel */
+ /* resolution to block. */
+ mmvx = (xpred + ((kk & 1) << 3)) >> 4;
+ nmvx = mmvx;
+
+ /* Calculate block y coordinate and round (?). */
+ /* Divide by 16 is for converting half-pixel */
+ /* resolution to block. */
+ mmvy = (ypred + ((kk & 2) << 2)) >> 4;
+ nmvy = mmvy;
+
+ /* Perform boundary checking */
+ if (nmvx < 0)
+ {
+ nmvx = 0;
+ }
+ else if (nmvx > mvwidth - 1)
+ {
+ nmvx = mvwidth - 1;
+ }
+
+ if (nmvy < 0)
+ {
+ nmvy = 0;
+ }
+ else if (nmvy > (height >> 3) - 1)
+ {
+ nmvy = (height >> 3) - 1;
+ }
+
+ /* Find post processing semaphore location for block */
+ /* used for prediction, i.e., */
+ /* pp_prev1 = &pstprcTypPrv[nmvy*mvwidth][nmvx] */
+ pp_prev1 = pstprcTypPrv + nmvx + nmvy * mvwidth;
+
+ /* Check if x component of MV is a multiple of 16 */
+ /* and check if block x coordinate is out of bounds */
+ if (((dx&0xF) != 0) && (mmvx + 1 < mvwidth - 1))
+ { /* dx is not a multiple of 16 and the block */
+ /* x coordinate is within the bounds */
+
+ /* pp_prev2 is the block to the right of */
+ /* pp_prev1 block */
+ pp_prev2 = pp_prev1 + 1;
+
+ /* Check if y component of MV is a multiple */
+ /* of 16 and check if block y coordinate is */
+ /* out of bounds */
+ if (((dy&0xF) != 0) && (mmvy + 1 < (height >> 3) - 1))
+ { /* dy is not a multiple of 16 and */
+ /* the block y coordinate is */
+ /* within the bounds */
+
+ /* pp_prev3 is the block below */
+ /* pp_prev1 block */
+ pp_prev3 = pp_prev1 + mvwidth;
+
+ /* all prediction are from different blocks */
+ msk_deblock = 0x3;
+ }
+ else
+ { /* dy is a multiple of 16 or the block */
+ /* y coordinate is out of bounds */
+
+ pp_prev3 = pp_prev1;
+ }
+
+ /* pp_prev4 is the block to the right of */
+ /* pp_prev3 block. */
+ pp_prev4 = pp_prev3 + 1;
+ }
+ else
+ { /* dx is a multiple of 16 or the block x */
+ /* coordinate is out of bounds */
+
+ pp_prev2 = pp_prev1;
+
+ /* Check if y component of MV is a multiple */
+ /* of 16 and check if block y coordinate is */
+ /* out of bounds */
+ if (((dy&0xF) != 0) && (mmvy + 1 < (height >> 3) - 1))
+ { /* dy is not a multiple of 16 and */
+ /* the block y coordinate is */
+ /* within the bounds */
+
+ /* pp_prev3 is the block below */
+ /* pp_prev1 block. */
+ pp_prev3 = pp_prev1 + mvwidth;
+ }
+ else
+ { /* dy is a multiple of 16 or the block */
+ /* y coordinate is out of bounds */
+
+ pp_prev3 = pp_prev1;
+ }
+
+ pp_prev4 = pp_prev3;
+ }
+
+ /* Deringing semaphore propagation */
+ if ((*(pp_dec_y)&4) == 0)
+ {
+ *(pp_dec_y) |= ((*(pp_prev1) |
+ *(pp_prev2) | *(pp_prev3) |
+ *(pp_prev4)) & 0x4);
+ }
+ /* Deblocking semaphore propagation */
+ /* 11/3/00, change the propaga= */
+ /* tion for deblocking */
+ if (msk_deblock == 0)
+ {
+ *(pp_dec_y) = 0;
+ }
+
+ pp_dec_y += ll[kk];
+ }
+ }
+
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return (msk_deblock);
+ }
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
new file mode 100644
index 0000000..0c354d9
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
@@ -0,0 +1,1696 @@
+/* ------------------------------------------------------------------
+ * 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 "mp4dec_lib.h"
+#include "vlc_decode.h"
+#include "bitstream.h"
+
+#define OSCL_DISABLE_WARNING_CONDITIONAL_IS_CONSTANT
+
+#ifdef DEC_INTERNAL_MEMORY_OPT
+#define QCIF_MBS 99
+#define QCIF_BS (4*QCIF_MBS)
+#define QCIF_MB_ROWS 11
+extern uint8 IMEM_sliceNo[QCIF_MBS];
+extern uint8 IMEM_acPredFlag[QCIF_MBS];
+extern uint8 IMEM_headerInfo_Mode[QCIF_MBS];
+extern uint8 IMEM_headerInfo_CBP[QCIF_MBS];
+extern int IMEM_headerInfo_QPMB[QCIF_MBS];
+extern MacroBlock IMEM_mblock;
+extern MOT IMEM_motX[QCIF_BS];
+extern MOT IMEM_motY[QCIF_BS];
+extern BitstreamDecVideo IMEM_BitstreamDecVideo[4];
+extern typeDCStore IMEM_predDC[QCIF_MBS];
+extern typeDCACStore IMEM_predDCAC_col[QCIF_MB_ROWS+1];
+
+extern VideoDecData IMEM_VideoDecData[1];
+extern Vop IMEM_currVop[1];
+extern Vop IMEM_prevVop[1];
+extern PIXEL IMEM_currVop_yChan[QCIF_MBS*128*3];
+extern PIXEL IMEM_prevVop_yChan[QCIF_MBS*128*3];
+extern uint8 IMEM_pstprcTypCur[6*QCIF_MBS];
+extern uint8 IMEM_pstprcTypPrv[6*QCIF_MBS];
+
+
+extern Vop IMEM_vopHEADER[2];
+extern Vol IMEM_VOL[2];
+extern Vop IMEM_vopHeader[2][1];
+extern Vol IMEM_vol[2][1];
+
+#endif
+
+/* ======================================================================== */
+/* Function : PVInitVideoDecoder() */
+/* Date : 04/11/2000, 08/29/2000 */
+/* Purpose : Initialization of the MPEG-4 video decoder library. */
+/* The return type is Bool instead of PV_STATUS because */
+/* we don't want to expose PV_STATUS to (outside) programmers */
+/* that use our decoder library SDK. */
+/* In/out : */
+/* Return : PV_TRUE if successed, PV_FALSE if failed. */
+/* Modified : */
+/* ======================================================================== */
+OSCL_EXPORT_REF Bool PVInitVideoDecoder(VideoDecControls *decCtrl, uint8 *volbuf[],
+ int32 *volbuf_size, int nLayers, int width, int height, MP4DecodingMode mode)
+{
+ VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
+ Bool status = PV_TRUE;
+ int idx;
+ BitstreamDecVideo *stream;
+
+
+ oscl_memset(decCtrl, 0, sizeof(VideoDecControls)); /* fix a size bug. 03/28/2001 */
+ decCtrl->nLayers = nLayers;
+ for (idx = 0; idx < nLayers; idx++)
+ {
+ decCtrl->volbuf[idx] = volbuf[idx];
+ decCtrl->volbuf_size[idx] = volbuf_size[idx];
+ }
+
+ /* memory allocation & initialization */
+#ifdef DEC_INTERNAL_MEMORY_OPT
+ video = IMEM_VideoDecData;
+#else
+ video = (VideoDecData *) oscl_malloc(sizeof(VideoDecData));
+#endif
+ if (video != NULL)
+ {
+ oscl_memset(video, 0, sizeof(VideoDecData));
+ video->memoryUsage = sizeof(VideoDecData);
+ video->numberOfLayers = nLayers;
+#ifdef DEC_INTERNAL_MEMORY_OPT
+ video->vol = (Vol **) IMEM_VOL;
+#else
+ video->vol = (Vol **) oscl_malloc(nLayers * sizeof(Vol *));
+#endif
+ if (video->vol == NULL) status = PV_FALSE;
+ video->memoryUsage += nLayers * sizeof(Vol *);
+
+
+ /* we need to setup this pointer for the application to */
+ /* pass it around. */
+ decCtrl->videoDecoderData = (void *) video;
+ video->videoDecControls = decCtrl; /* yes. we have a cyclic */
+ /* references here :) */
+
+ /* Allocating Vop space, this has to change when we add */
+ /* spatial scalability to the decoder */
+#ifdef DEC_INTERNAL_MEMORY_OPT
+ video->currVop = IMEM_currVop;
+ if (video->currVop == NULL) status = PV_FALSE;
+ else oscl_memset(video->currVop, 0, sizeof(Vop));
+ video->prevVop = IMEM_prevVop;
+ if (video->prevVop == NULL) status = PV_FALSE;
+ else oscl_memset(video->prevVop, 0, sizeof(Vop));
+ video->memoryUsage += (sizeof(Vop) * 2);
+ video->vopHeader = (Vop **) IMEM_vopHEADER;
+#else
+
+ video->currVop = (Vop *) oscl_malloc(sizeof(Vop));
+ if (video->currVop == NULL) status = PV_FALSE;
+ else oscl_memset(video->currVop, 0, sizeof(Vop));
+ video->prevVop = (Vop *) oscl_malloc(sizeof(Vop));
+ if (video->prevVop == NULL) status = PV_FALSE;
+ else oscl_memset(video->prevVop, 0, sizeof(Vop));
+ video->memoryUsage += (sizeof(Vop) * 2);
+
+ video->vopHeader = (Vop **) oscl_malloc(sizeof(Vop *) * nLayers);
+#endif
+ if (video->vopHeader == NULL) status = PV_FALSE;
+ else oscl_memset(video->vopHeader, 0, sizeof(Vop *)*nLayers);
+ video->memoryUsage += (sizeof(Vop *) * nLayers);
+
+ video->initialized = PV_FALSE;
+ /* Decode the header to get all information to allocate data */
+ if (status == PV_TRUE)
+ {
+ /* initialize decoded frame counter. 04/24/2001 */
+ video->frame_idx = -1;
+
+
+ for (idx = 0; idx < nLayers; idx++)
+ {
+
+#ifdef DEC_INTERNAL_MEMORY_OPT
+ video->vopHeader[idx] = IMEM_vopHeader[idx];
+#else
+ video->vopHeader[idx] = (Vop *) oscl_malloc(sizeof(Vop));
+#endif
+ if (video->vopHeader[idx] == NULL)
+ {
+ status = PV_FALSE;
+ break;
+ }
+ else
+ {
+ oscl_memset(video->vopHeader[idx], 0, sizeof(Vop));
+ video->vopHeader[idx]->timeStamp = 0;
+ video->memoryUsage += (sizeof(Vop));
+ }
+#ifdef DEC_INTERNAL_MEMORY_OPT
+ video->vol[idx] = IMEM_vol[idx];
+ video->memoryUsage += sizeof(Vol);
+ oscl_memset(video->vol[idx], 0, sizeof(Vol));
+ if (video->vol[idx] == NULL) status = PV_FALSE;
+ stream = IMEM_BitstreamDecVideo;
+#else
+ video->vol[idx] = (Vol *) oscl_malloc(sizeof(Vol));
+ if (video->vol[idx] == NULL)
+ {
+ status = PV_FALSE;
+ break;
+ }
+ else
+ {
+ video->memoryUsage += sizeof(Vol);
+ oscl_memset(video->vol[idx], 0, sizeof(Vol));
+ }
+
+ stream = (BitstreamDecVideo *) oscl_malloc(sizeof(BitstreamDecVideo));
+#endif
+ video->memoryUsage += sizeof(BitstreamDecVideo);
+ if (stream == NULL)
+ {
+ status = PV_FALSE;
+ break;
+ }
+ else
+ {
+ int32 buffer_size;
+ if ((buffer_size = BitstreamOpen(stream, idx)) < 0)
+ {
+ mp4dec_log("InitVideoDecoder(): Can't allocate bitstream buffer.\n");
+ status = PV_FALSE;
+ break;
+ }
+ video->memoryUsage += buffer_size;
+ video->vol[idx]->bitstream = stream;
+ video->vol[idx]->volID = idx;
+ video->vol[idx]->timeInc_offset = 0; /* 11/12/01 */
+ video->vlcDecCoeffIntra = &VlcDecTCOEFShortHeader;
+ video->vlcDecCoeffInter = &VlcDecTCOEFShortHeader;
+ if (mode == MPEG4_MODE)
+ {
+ /* Set up VOL header bitstream for frame-based decoding. 08/30/2000 */
+ BitstreamReset(stream, decCtrl->volbuf[idx], decCtrl->volbuf_size[idx]);
+
+ switch (DecodeVOLHeader(video, idx))
+ {
+ case PV_SUCCESS :
+ if (status == PV_TRUE)
+ status = PV_TRUE; /* we want to make sure that if first layer is bad, second layer is good return PV_FAIL */
+ else
+ status = PV_FALSE;
+ break;
+#ifdef PV_TOLERATE_VOL_ERRORS
+ case PV_BAD_VOLHEADER:
+ status = PV_TRUE;
+ break;
+#endif
+ default :
+ status = PV_FALSE;
+ break;
+ }
+
+ }
+ else
+ {
+ video->shortVideoHeader = PV_TRUE;
+ }
+
+ if (video->shortVideoHeader == PV_TRUE)
+ {
+ mode = H263_MODE;
+ /* Set max width and height. In H.263 mode, we use */
+ /* volbuf_size[0] to pass in width and volbuf_size[1] */
+ /* to pass in height. 04/23/2001 */
+ video->prevVop->temporalRef = 0; /* 11/12/01 */
+ /* Compute some convenience variables: 04/23/2001 */
+ video->vol[idx]->quantType = 0;
+ video->vol[idx]->quantPrecision = 5;
+ video->vol[idx]->errorResDisable = 1;
+ video->vol[idx]->dataPartitioning = 0;
+ video->vol[idx]->useReverseVLC = 0;
+ video->intra_acdcPredDisable = 1;
+ video->vol[idx]->scalability = 0;
+ video->size = (int32)width * height;
+
+ video->displayWidth = video->width = width;
+ video->displayHeight = video->height = height;
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ video->modified_quant = 0;
+ video->advanced_INTRA = 0;
+ video->deblocking = 0;
+ video->slice_structure = 0;
+#endif
+ }
+
+ }
+ }
+
+ }
+ if (status != PV_FALSE)
+ {
+ status = PVAllocVideoData(decCtrl, width, height, nLayers);
+ video->initialized = PV_TRUE;
+ }
+ }
+ else
+ {
+ status = PV_FALSE;
+ }
+
+ if (status == PV_FALSE) PVCleanUpVideoDecoder(decCtrl);
+
+ return status;
+}
+
+Bool PVAllocVideoData(VideoDecControls *decCtrl, int width, int height, int nLayers)
+{
+ VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
+ Bool status = PV_TRUE;
+ int nTotalMB;
+ int nMBPerRow;
+ int32 size;
+
+ if (video->shortVideoHeader == PV_TRUE)
+ {
+ video->displayWidth = video->width = width;
+ video->displayHeight = video->height = height;
+
+ video->nMBPerRow =
+ video->nMBinGOB = video->width / MB_SIZE;
+ video->nMBPerCol =
+ video->nGOBinVop = video->height / MB_SIZE;
+ video->nTotalMB =
+ video->nMBPerRow * video->nMBPerCol;
+ }
+
+ size = (int32)sizeof(PIXEL) * video->width * video->height;
+#ifdef PV_MEMORY_POOL
+ decCtrl->size = size;
+#else
+#ifdef DEC_INTERNAL_MEMORY_OPT
+ video->currVop->yChan = IMEM_currVop_yChan; /* Allocate memory for all VOP OKA 3/2/1*/
+ if (video->currVop->yChan == NULL) status = PV_FALSE;
+ video->currVop->uChan = video->currVop->yChan + size;
+ video->currVop->vChan = video->currVop->uChan + (size >> 2);
+
+ video->prevVop->yChan = IMEM_prevVop_yChan; /* Allocate memory for all VOP OKA 3/2/1*/
+ if (video->prevVop->yChan == NULL) status = PV_FALSE;
+ video->prevVop->uChan = video->prevVop->yChan + size;
+ video->prevVop->vChan = video->prevVop->uChan + (size >> 2);
+#else
+ video->currVop->yChan = (PIXEL *) oscl_malloc(size * 3 / 2); /* Allocate memory for all VOP OKA 3/2/1*/
+ if (video->currVop->yChan == NULL) status = PV_FALSE;
+
+ video->currVop->uChan = video->currVop->yChan + size;
+ video->currVop->vChan = video->currVop->uChan + (size >> 2);
+ video->prevVop->yChan = (PIXEL *) oscl_malloc(size * 3 / 2); /* Allocate memory for all VOP OKA 3/2/1*/
+ if (video->prevVop->yChan == NULL) status = PV_FALSE;
+
+ video->prevVop->uChan = video->prevVop->yChan + size;
+ video->prevVop->vChan = video->prevVop->uChan + (size >> 2);
+#endif
+ video->memoryUsage += (size * 3);
+#endif // MEMORY_POOL
+ /* Note that baseVop, enhcVop is only used to hold enhancement */
+ /* layer header information. 05/04/2000 */
+ if (nLayers > 1)
+ {
+ video->prevEnhcVop = (Vop *) oscl_malloc(sizeof(Vop));
+ video->memoryUsage += (sizeof(Vop));
+ if (video->prevEnhcVop == NULL)
+ {
+ status = PV_FALSE;
+ }
+ else
+ {
+ oscl_memset(video->prevEnhcVop, 0, sizeof(Vop));
+#ifndef PV_MEMORY_POOL
+ video->prevEnhcVop->yChan = (PIXEL *) oscl_malloc(size * 3 / 2); /* Allocate memory for all VOP OKA 3/2/1*/
+ if (video->prevEnhcVop->yChan == NULL) status = PV_FALSE;
+ video->prevEnhcVop->uChan = video->prevEnhcVop->yChan + size;
+ video->prevEnhcVop->vChan = video->prevEnhcVop->uChan + (size >> 2);
+ video->memoryUsage += (3 * size / 2);
+#endif
+ }
+ }
+
+ /* Allocating space for slices, AC prediction flag, and */
+ /* AC/DC prediction storage */
+ nTotalMB = video->nTotalMB;
+ nMBPerRow = video->nMBPerRow;
+
+#ifdef DEC_INTERNAL_MEMORY_OPT
+ video->sliceNo = (uint8 *)(IMEM_sliceNo);
+ if (video->sliceNo == NULL) status = PV_FALSE;
+ video->memoryUsage += nTotalMB;
+ video->acPredFlag = (uint8 *)(IMEM_acPredFlag);
+ if (video->acPredFlag == NULL) status = PV_FALSE;
+ video->memoryUsage += (nTotalMB);
+ video->predDC = (typeDCStore *)(IMEM_predDC);
+ if (video->predDC == NULL) status = PV_FALSE;
+ video->memoryUsage += (nTotalMB * sizeof(typeDCStore));
+ video->predDCAC_col = (typeDCACStore *)(IMEM_predDCAC_col);
+ if (video->predDCAC_col == NULL) status = PV_FALSE;
+ video->memoryUsage += ((nMBPerRow + 1) * sizeof(typeDCACStore));
+ video->predDCAC_row = video->predDCAC_col + 1;
+ video->headerInfo.Mode = (uint8 *)(IMEM_headerInfo_Mode);
+ if (video->headerInfo.Mode == NULL) status = PV_FALSE;
+ video->memoryUsage += nTotalMB;
+ video->headerInfo.CBP = (uint8 *)(IMEM_headerInfo_CBP);
+ if (video->headerInfo.CBP == NULL) status = PV_FALSE;
+ video->memoryUsage += nTotalMB;
+ video->QPMB = (int *)(IMEM_headerInfo_QPMB);
+ if (video->QPMB == NULL) status = PV_FALSE;
+ video->memoryUsage += (nTotalMB * sizeof(int));
+ video->mblock = &IMEM_mblock;
+ if (video->mblock == NULL) status = PV_FALSE;
+ oscl_memset(video->mblock->block, 0, sizeof(int16)*6*NCOEFF_BLOCK); // Aug 23,2005
+
+ video->memoryUsage += sizeof(MacroBlock);
+ video->motX = (MOT *)(IMEM_motX);
+ if (video->motX == NULL) status = PV_FALSE;
+ video->motY = (MOT *)(IMEM_motY);
+ if (video->motY == NULL) status = PV_FALSE;
+ video->memoryUsage += (sizeof(MOT) * 8 * nTotalMB);
+#else
+ video->sliceNo = (uint8 *) oscl_malloc(nTotalMB);
+ if (video->sliceNo == NULL) status = PV_FALSE;
+ video->memoryUsage += nTotalMB;
+
+ video->acPredFlag = (uint8 *) oscl_malloc(nTotalMB * sizeof(uint8));
+ if (video->acPredFlag == NULL) status = PV_FALSE;
+ video->memoryUsage += (nTotalMB);
+
+ video->predDC = (typeDCStore *) oscl_malloc(nTotalMB * sizeof(typeDCStore));
+ if (video->predDC == NULL) status = PV_FALSE;
+ video->memoryUsage += (nTotalMB * sizeof(typeDCStore));
+
+ video->predDCAC_col = (typeDCACStore *) oscl_malloc((nMBPerRow + 1) * sizeof(typeDCACStore));
+ if (video->predDCAC_col == NULL) status = PV_FALSE;
+ video->memoryUsage += ((nMBPerRow + 1) * sizeof(typeDCACStore));
+
+ /* element zero will be used for storing vertical (col) AC coefficients */
+ /* the rest will be used for storing horizontal (row) AC coefficients */
+ video->predDCAC_row = video->predDCAC_col + 1; /* ACDC */
+
+ /* Allocating HeaderInfo structure & Quantizer array */
+ video->headerInfo.Mode = (uint8 *) oscl_malloc(nTotalMB);
+ if (video->headerInfo.Mode == NULL) status = PV_FALSE;
+ video->memoryUsage += nTotalMB;
+ video->headerInfo.CBP = (uint8 *) oscl_malloc(nTotalMB);
+ if (video->headerInfo.CBP == NULL) status = PV_FALSE;
+ video->memoryUsage += nTotalMB;
+ video->QPMB = (int16 *) oscl_malloc(nTotalMB * sizeof(int16));
+ if (video->QPMB == NULL) status = PV_FALSE;
+ video->memoryUsage += (nTotalMB * sizeof(int));
+
+ /* Allocating macroblock space */
+ video->mblock = (MacroBlock *) oscl_malloc(sizeof(MacroBlock));
+ if (video->mblock == NULL)
+ {
+ status = PV_FALSE;
+ }
+ else
+ {
+ oscl_memset(video->mblock->block, 0, sizeof(int16)*6*NCOEFF_BLOCK); // Aug 23,2005
+
+ video->memoryUsage += sizeof(MacroBlock);
+ }
+ /* Allocating motion vector space */
+ video->motX = (MOT *) oscl_malloc(sizeof(MOT) * 4 * nTotalMB);
+ if (video->motX == NULL) status = PV_FALSE;
+ video->motY = (MOT *) oscl_malloc(sizeof(MOT) * 4 * nTotalMB);
+ if (video->motY == NULL) status = PV_FALSE;
+ video->memoryUsage += (sizeof(MOT) * 8 * nTotalMB);
+#endif
+
+#ifdef PV_POSTPROC_ON
+ /* Allocating space for post-processing Mode */
+#ifdef DEC_INTERNAL_MEMORY_OPT
+ video->pstprcTypCur = IMEM_pstprcTypCur;
+ video->memoryUsage += (nTotalMB * 6);
+ if (video->pstprcTypCur == NULL)
+ {
+ status = PV_FALSE;
+ }
+ else
+ {
+ oscl_memset(video->pstprcTypCur, 0, 4*nTotalMB + 2*nTotalMB);
+ }
+
+ video->pstprcTypPrv = IMEM_pstprcTypPrv;
+ video->memoryUsage += (nTotalMB * 6);
+ if (video->pstprcTypPrv == NULL)
+ {
+ status = PV_FALSE;
+ }
+ else
+ {
+ oscl_memset(video->pstprcTypPrv, 0, nTotalMB*6);
+ }
+
+#else
+ video->pstprcTypCur = (uint8 *) oscl_malloc(nTotalMB * 6);
+ video->memoryUsage += (nTotalMB * 6);
+ if (video->pstprcTypCur == NULL)
+ {
+ status = PV_FALSE;
+ }
+ else
+ {
+ oscl_memset(video->pstprcTypCur, 0, 4*nTotalMB + 2*nTotalMB);
+ }
+
+ video->pstprcTypPrv = (uint8 *) oscl_malloc(nTotalMB * 6);
+ video->memoryUsage += (nTotalMB * 6);
+ if (video->pstprcTypPrv == NULL)
+ {
+ status = PV_FALSE;
+ }
+ else
+ {
+ oscl_memset(video->pstprcTypPrv, 0, nTotalMB*6);
+ }
+
+#endif
+
+#endif
+
+ /* initialize the decoder library */
+ video->prevVop->predictionType = I_VOP;
+ video->prevVop->timeStamp = 0;
+#ifndef PV_MEMORY_POOL
+ oscl_memset(video->prevVop->yChan, 16, sizeof(uint8)*size); /* 10/31/01 */
+ oscl_memset(video->prevVop->uChan, 128, sizeof(uint8)*size / 2);
+
+ oscl_memset(video->currVop->yChan, 0, sizeof(uint8)*size*3 / 2);
+ if (nLayers > 1)
+ {
+ oscl_memset(video->prevEnhcVop->yChan, 0, sizeof(uint8)*size*3 / 2);
+ video->prevEnhcVop->timeStamp = 0;
+ }
+ video->concealFrame = video->prevVop->yChan; /* 07/07/2001 */
+ decCtrl->outputFrame = video->prevVop->yChan; /* 06/19/2002 */
+#endif
+
+ /* always start from base layer */
+ video->currLayer = 0;
+ return status;
+}
+
+/* ======================================================================== */
+/* Function : PVResetVideoDecoder() */
+/* Date : 01/14/2002 */
+/* Purpose : Reset video timestamps */
+/* In/out : */
+/* Return : PV_TRUE if successed, PV_FALSE if failed. */
+/* Modified : */
+/* ======================================================================== */
+Bool PVResetVideoDecoder(VideoDecControls *decCtrl)
+{
+ VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
+ int idx;
+
+ for (idx = 0; idx < decCtrl->nLayers; idx++)
+ {
+ video->vopHeader[idx]->timeStamp = 0;
+ }
+ video->prevVop->timeStamp = 0;
+ if (decCtrl->nLayers > 1)
+ video->prevEnhcVop->timeStamp = 0;
+
+ oscl_memset(video->mblock->block, 0, sizeof(int16)*6*NCOEFF_BLOCK); // Aug 23,2005
+
+ return PV_TRUE;
+}
+
+
+/* ======================================================================== */
+/* Function : PVCleanUpVideoDecoder() */
+/* Date : 04/11/2000, 08/29/2000 */
+/* Purpose : Cleanup of the MPEG-4 video decoder library. */
+/* In/out : */
+/* Return : PV_TRUE if successed, PV_FALSE if failed. */
+/* Modified : */
+/* ======================================================================== */
+OSCL_EXPORT_REF Bool PVCleanUpVideoDecoder(VideoDecControls *decCtrl)
+{
+ int idx;
+ VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
+#ifdef DEC_INTERNAL_MEMORY_OPT
+ if (video)
+ {
+#ifdef PV_POSTPROC_ON
+ video->pstprcTypCur = NULL;
+ video->pstprcTypPrv = NULL;
+#endif
+
+ video->acPredFlag = NULL;
+ video->sliceNo = NULL;
+ video->motX = NULL;
+ video->motY = NULL;
+ video->mblock = NULL;
+ video->QPMB = NULL;
+ video->predDC = NULL;
+ video->predDCAC_row = NULL;
+ video->predDCAC_col = NULL;
+ video->headerInfo.Mode = NULL;
+ video->headerInfo.CBP = NULL;
+ if (video->numberOfLayers > 1)
+ {
+ if (video->prevEnhcVop)
+ {
+ video->prevEnhcVop->uChan = NULL;
+ video->prevEnhcVop->vChan = NULL;
+ if (video->prevEnhcVop->yChan) oscl_free(video->prevEnhcVop->yChan);
+ oscl_free(video->prevEnhcVop);
+ }
+ }
+ if (video->currVop)
+ {
+ video->currVop->uChan = NULL;
+ video->currVop->vChan = NULL;
+ if (video->currVop->yChan)
+ video->currVop->yChan = NULL;
+ video->currVop = NULL;
+ }
+ if (video->prevVop)
+ {
+ video->prevVop->uChan = NULL;
+ video->prevVop->vChan = NULL;
+ if (video->prevVop->yChan)
+ video->prevVop->yChan = NULL;
+ video->prevVop = NULL;
+ }
+
+ if (video->vol)
+ {
+ for (idx = 0; idx < video->numberOfLayers; idx++)
+ {
+ if (video->vol[idx])
+ {
+ BitstreamClose(video->vol[idx]->bitstream);
+ video->vol[idx]->bitstream = NULL;
+ video->vol[idx] = NULL;
+ }
+ video->vopHeader[idx] = NULL;
+
+ }
+ video->vol = NULL;
+ video->vopHeader = NULL;
+ }
+
+ video = NULL;
+ decCtrl->videoDecoderData = NULL;
+ }
+
+#else
+
+ if (video)
+ {
+#ifdef PV_POSTPROC_ON
+ if (video->pstprcTypCur) oscl_free(video->pstprcTypCur);
+ if (video->pstprcTypPrv) oscl_free(video->pstprcTypPrv);
+#endif
+ if (video->predDC) oscl_free(video->predDC);
+ video->predDCAC_row = NULL;
+ if (video->predDCAC_col) oscl_free(video->predDCAC_col);
+ if (video->motX) oscl_free(video->motX);
+ if (video->motY) oscl_free(video->motY);
+ if (video->mblock) oscl_free(video->mblock);
+ if (video->QPMB) oscl_free(video->QPMB);
+ if (video->headerInfo.Mode) oscl_free(video->headerInfo.Mode);
+ if (video->headerInfo.CBP) oscl_free(video->headerInfo.CBP);
+ if (video->sliceNo) oscl_free(video->sliceNo);
+ if (video->acPredFlag) oscl_free(video->acPredFlag);
+
+ if (video->numberOfLayers > 1)
+ {
+ if (video->prevEnhcVop)
+ {
+ video->prevEnhcVop->uChan = NULL;
+ video->prevEnhcVop->vChan = NULL;
+ if (video->prevEnhcVop->yChan) oscl_free(video->prevEnhcVop->yChan);
+ oscl_free(video->prevEnhcVop);
+ }
+ }
+ if (video->currVop)
+ {
+
+#ifndef PV_MEMORY_POOL
+ video->currVop->uChan = NULL;
+ video->currVop->vChan = NULL;
+ if (video->currVop->yChan)
+ oscl_free(video->currVop->yChan);
+#endif
+ oscl_free(video->currVop);
+ }
+ if (video->prevVop)
+ {
+#ifndef PV_MEMORY_POOL
+ video->prevVop->uChan = NULL;
+ video->prevVop->vChan = NULL;
+ if (video->prevVop->yChan)
+ oscl_free(video->prevVop->yChan);
+#endif
+ oscl_free(video->prevVop);
+ }
+
+ if (video->vol)
+ {
+ for (idx = 0; idx < video->numberOfLayers; idx++)
+ {
+ if (video->vol[idx])
+ {
+ if (video->vol[idx]->bitstream)
+ {
+ BitstreamClose(video->vol[idx]->bitstream);
+ oscl_free(video->vol[idx]->bitstream);
+ }
+ oscl_free(video->vol[idx]);
+ }
+
+ }
+ oscl_free(video->vol);
+ }
+
+ for (idx = 0; idx < video->numberOfLayers; idx++)
+ {
+ if (video->vopHeader[idx]) oscl_free(video->vopHeader[idx]);
+ }
+
+ if (video->vopHeader) oscl_free(video->vopHeader);
+
+ oscl_free(video);
+ decCtrl->videoDecoderData = NULL;
+ }
+#endif
+ return PV_TRUE;
+}
+/* ======================================================================== */
+/* Function : PVGetVideoDimensions() */
+/* Date : 040505 */
+/* Purpose : */
+/* In/out : */
+/* Return : the display_width and display_height of */
+/* the frame in the current layer. */
+/* Note : This is not a macro or inline function because we do */
+/* not want to expose our internal data structure. */
+/* Modified : */
+/* ======================================================================== */
+OSCL_EXPORT_REF void PVGetVideoDimensions(VideoDecControls *decCtrl, int32 *display_width, int32 *display_height)
+{
+ VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
+ *display_width = video->displayWidth;
+ *display_height = video->displayHeight;
+}
+
+/* ======================================================================== */
+/* Function : PVGetVideoTimeStamp() */
+/* Date : 04/27/2000, 08/29/2000 */
+/* Purpose : */
+/* In/out : */
+/* Return : current time stamp in millisecond. */
+/* Note : */
+/* Modified : */
+/* ======================================================================== */
+uint32 PVGetVideoTimeStamp(VideoDecControls *decCtrl)
+{
+ VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
+ return video->currTimestamp;
+}
+
+
+/* ======================================================================== */
+/* Function : PVSetPostProcType() */
+/* Date : 07/07/2000 */
+/* Purpose : */
+/* In/out : */
+/* Return : Set post-processing filter type. */
+/* Note : */
+/* Modified : . 08/29/2000 changes the name for consistency. */
+/* ======================================================================== */
+OSCL_EXPORT_REF void PVSetPostProcType(VideoDecControls *decCtrl, int mode)
+{
+ VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
+ video->postFilterType = mode;
+}
+
+
+/* ======================================================================== */
+/* Function : PVGetDecBitrate() */
+/* Date : 08/23/2000 */
+/* Purpose : */
+/* In/out : */
+/* Return : This function returns the average bits per second. */
+/* Note : */
+/* Modified : */
+/* ======================================================================== */
+int PVGetDecBitrate(VideoDecControls *decCtrl)
+{
+ VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
+ int idx;
+ int32 sum = 0;
+
+ for (idx = 0; idx < BITRATE_AVERAGE_WINDOW; idx++)
+ {
+ sum += video->nBitsPerVop[idx];
+ }
+ sum = (sum * video->frameRate) / (10 * BITRATE_AVERAGE_WINDOW);
+ return (int) sum;
+}
+
+
+/* ======================================================================== */
+/* Function : PVGetDecFramerate() */
+/* Date : 08/23/2000 */
+/* Purpose : */
+/* In/out : */
+/* Return : This function returns the average frame per 10 second. */
+/* Note : The fps can be calculated by PVGetDecFramerate()/10 */
+/* Modified : */
+/* ======================================================================== */
+int PVGetDecFramerate(VideoDecControls *decCtrl)
+{
+ VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
+
+ return video->frameRate;
+}
+
+/* ======================================================================== */
+/* Function : PVGetOutputFrame() */
+/* Date : 05/07/2001 */
+/* Purpose : */
+/* In/out : */
+/* Return : This function returns the pointer to the output frame */
+/* Note : */
+/* Modified : */
+/* ======================================================================== */
+uint8 *PVGetDecOutputFrame(VideoDecControls *decCtrl)
+{
+ return decCtrl->outputFrame;
+}
+
+/* ======================================================================== */
+/* Function : PVGetLayerID() */
+/* Date : 07/09/2001 */
+/* Purpose : */
+/* In/out : */
+/* Return : This function returns decoded frame layer id (BASE/ENHANCE) */
+/* Note : */
+/* Modified : */
+/* ======================================================================== */
+int PVGetLayerID(VideoDecControls *decCtrl)
+{
+ VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
+ return video->currLayer;
+}
+/* ======================================================================== */
+/* Function : PVGetDecMemoryUsage() */
+/* Date : 08/23/2000 */
+/* Purpose : */
+/* In/out : */
+/* Return : This function returns the amount of memory used. */
+/* Note : */
+/* Modified : */
+/* ======================================================================== */
+int32 PVGetDecMemoryUsage(VideoDecControls *decCtrl)
+{
+ VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
+ return video->memoryUsage;
+}
+
+
+/* ======================================================================== */
+/* Function : PVGetDecBitstreamMode() */
+/* Date : 08/23/2000 */
+/* Purpose : */
+/* In/out : */
+/* Return : This function returns the decoding mode of the baselayer */
+/* bitstream. */
+/* Note : */
+/* Modified : */
+/* ======================================================================== */
+OSCL_EXPORT_REF MP4DecodingMode PVGetDecBitstreamMode(VideoDecControls *decCtrl)
+{
+ VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
+ if (video->shortVideoHeader)
+ {
+ return H263_MODE;
+ }
+ else
+ {
+ return MPEG4_MODE;
+ }
+}
+
+
+/* ======================================================================== */
+/* Function : PVExtractVolHeader() */
+/* Date : 08/29/2000 */
+/* Purpose : */
+/* In/out : */
+/* Return : Extract vol header of the bitstream from buffer[]. */
+/* Note : */
+/* Modified : */
+/* ======================================================================== */
+Bool PVExtractVolHeader(uint8 *video_buffer, uint8 *vol_header, int32 *vol_header_size)
+{
+ int idx = -1;
+ uint8 start_code_prefix[] = { 0x00, 0x00, 0x01 };
+ uint8 h263_prefix[] = { 0x00, 0x00, 0x80 };
+
+ if (oscl_memcmp(h263_prefix, video_buffer, 3) == 0) /* we have short header stream */
+ {
+ oscl_memcpy(vol_header, video_buffer, 32);
+ *vol_header_size = 32;
+ return TRUE;
+ }
+ else
+ {
+ if (oscl_memcmp(start_code_prefix, video_buffer, 3) ||
+ (video_buffer[3] != 0xb0 && video_buffer[3] >= 0x20)) return FALSE;
+
+ do
+ {
+ idx++;
+ while (oscl_memcmp(start_code_prefix, video_buffer + idx, 3))
+ {
+ idx++;
+ if (idx + 3 >= *vol_header_size) goto quit;
+ }
+ }
+ while (video_buffer[idx+3] != 0xb3 && video_buffer[idx+3] != 0xb6);
+
+ oscl_memcpy(vol_header, video_buffer, idx);
+ *vol_header_size = idx;
+ return TRUE;
+ }
+
+quit:
+ oscl_memcpy(vol_header, video_buffer, *vol_header_size);
+ return FALSE;
+}
+
+
+/* ======================================================================== */
+/* Function : PVLocateFrameHeader() */
+/* Date : 04/8/2005 */
+/* Purpose : */
+/* In/out : */
+/* Return : Return the offset to the first SC in the buffer */
+/* Note : */
+/* Modified : */
+/* ======================================================================== */
+int32 PVLocateFrameHeader(uint8 *ptr, int32 size)
+{
+ int 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));
+}
+
+
+/* ======================================================================== */
+/* Function : PVLocateH263FrameHeader() */
+/* Date : 04/8/2005 */
+/* Purpose : */
+/* In/out : */
+/* Return : Return the offset to the first SC in the buffer */
+/* Note : */
+/* Modified : */
+/* ======================================================================== */
+int32 PVLocateH263FrameHeader(uint8 *ptr, int32 size)
+{
+ int count = 0;
+ int32 i = size;
+
+ if (size < 1)
+ {
+ return 0;
+ }
+
+ while (i--)
+ {
+ if ((count > 1) && ((*ptr & 0xFC) == 0x80))
+ {
+ i += 2;
+ break;
+ }
+
+ if (*ptr++)
+ count = 0;
+ else
+ count++;
+ }
+ return (size - (i + 1));
+}
+
+
+/* ======================================================================== */
+/* Function : PVDecodeVideoFrame() */
+/* Date : 08/29/2000 */
+/* Purpose : Decode one video frame and return a YUV-12 image. */
+/* In/out : */
+/* Return : */
+/* Note : */
+/* Modified : 04/17/2001 removed PV_EOS, PV_END_OF_BUFFER */
+/* : 08/22/2002 break up into 2 functions PVDecodeVopHeader and */
+/* PVDecodeVopBody */
+/* ======================================================================== */
+OSCL_EXPORT_REF Bool PVDecodeVideoFrame(VideoDecControls *decCtrl, uint8 *buffer[],
+ uint32 timestamp[], int32 buffer_size[], uint use_ext_timestamp[], uint8 *currYUV)
+{
+ PV_STATUS status = PV_FAIL;
+ VopHeaderInfo header_info;
+
+ status = (PV_STATUS)PVDecodeVopHeader(decCtrl, buffer, timestamp, buffer_size, &header_info, use_ext_timestamp, currYUV);
+ if (status != PV_TRUE)
+ return PV_FALSE;
+
+ if (PVDecodeVopBody(decCtrl, buffer_size) != PV_TRUE)
+ {
+ return PV_FALSE;
+ }
+
+ return PV_TRUE;
+}
+
+/* ======================================================================== */
+/* Function : PVDecodeVopHeader() */
+/* Date : 08/22/2002 */
+/* Purpose : Determine target layer and decode vop header, modified from */
+/* original PVDecodeVideoFrame. */
+/* In/out : */
+/* Return : */
+/* Note : */
+/* Modified : */
+/* ======================================================================== */
+Bool PVDecodeVopHeader(VideoDecControls *decCtrl, uint8 *buffer[],
+ uint32 timestamp[], int32 buffer_size[], VopHeaderInfo *header_info, uint use_ext_timestamp [], uint8 *currYUV)
+{
+ VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
+ Vol *currVol;
+ Vop *currVop = video->currVop;
+ Vop **vopHeader = video->vopHeader;
+ BitstreamDecVideo *stream;
+
+ int target_layer;
+
+#ifdef PV_SUPPORT_TEMPORAL_SCALABILITY
+ PV_STATUS status = PV_FAIL;
+ int idx;
+ int32 display_time;
+
+ /* decide which frame to decode next */
+ if (decCtrl->nLayers > 1)
+ {
+ display_time = target_layer = -1;
+ for (idx = 0; idx < decCtrl->nLayers; idx++)
+ {
+ /* do we have data for this layer? */
+ if (buffer_size[idx] <= 0)
+ {
+ timestamp[idx] = -1;
+ continue;
+ }
+
+ /* did the application provide a timestamp for this vop? */
+ if (timestamp[idx] < 0)
+ {
+ if (vopHeader[idx]->timeStamp < 0)
+ {
+ /* decode the timestamp in the bitstream */
+ video->currLayer = idx;
+ stream = video->vol[idx]->bitstream;
+ BitstreamReset(stream, buffer[idx], buffer_size[idx]);
+
+ while ((status = DecodeVOPHeader(video, vopHeader[idx], FALSE)) != PV_SUCCESS)
+ {
+ /* Try to find a VOP header in the buffer. 08/30/2000. */
+ if (PVSearchNextM4VFrame(stream) != PV_SUCCESS)
+ {
+ /* if we don't have data for enhancement layer, */
+ /* don't just stop. 09/07/2000. */
+ buffer_size[idx] = 0;
+ break;
+ }
+ }
+ if (status == PV_SUCCESS)
+ {
+ vopHeader[idx]->timeStamp =
+ timestamp[idx] = CalcVopDisplayTime(video->vol[idx], vopHeader[idx], video->shortVideoHeader);
+ if (idx == 0) vopHeader[idx]->refSelectCode = 1;
+ }
+ }
+ else
+ {
+ /* We've decoded this vop header in the previous run already. */
+ timestamp[idx] = vopHeader[idx]->timeStamp;
+ }
+ }
+
+ /* Use timestamps to select the next VOP to be decoded */
+ if (timestamp[idx] >= 0 && (display_time < 0 || display_time > timestamp[idx]))
+ {
+ display_time = timestamp[idx];
+ target_layer = idx;
+ }
+ else if (display_time == timestamp[idx])
+ {
+ /* we have to handle either SNR or spatial scalability here. */
+ }
+ }
+ if (target_layer < 0) return PV_FALSE;
+
+ /* set up for decoding the target layer */
+ video->currLayer = target_layer;
+ currVol = video->vol[target_layer];
+ video->bitstream = stream = currVol->bitstream;
+
+ /* We need to decode the vop header if external timestamp */
+ /* is provided. 10/04/2000 */
+ if (vopHeader[target_layer]->timeStamp < 0)
+ {
+ stream = video->vol[target_layer]->bitstream;
+ BitstreamReset(stream, buffer[target_layer], buffer_size[target_layer]);
+
+ while (DecodeVOPHeader(video, vopHeader[target_layer], TRUE) != PV_SUCCESS)
+ {
+ /* Try to find a VOP header in the buffer. 08/30/2000. */
+ if (PVSearchNextM4VFrame(stream) != PV_SUCCESS)
+ {
+ /* if we don't have data for enhancement layer, */
+ /* don't just stop. 09/07/2000. */
+ buffer_size[target_layer] = 0;
+ break;
+ }
+ }
+ video->vol[target_layer]->timeInc_offset = vopHeader[target_layer]->timeInc;
+ video->vol[target_layer]->moduloTimeBase = timestamp[target_layer];
+ vopHeader[target_layer]->timeStamp = timestamp[target_layer];
+ if (target_layer == 0) vopHeader[target_layer]->refSelectCode = 1;
+ }
+ }
+ else /* base layer only decoding */
+ {
+#endif
+ video->currLayer = target_layer = 0;
+ currVol = video->vol[0];
+ video->bitstream = stream = currVol->bitstream;
+ if (buffer_size[0] <= 0) return PV_FALSE;
+ BitstreamReset(stream, buffer[0], buffer_size[0]);
+
+ if (video->shortVideoHeader)
+ {
+ while (DecodeShortHeader(video, vopHeader[0]) != PV_SUCCESS)
+ {
+ if (PVSearchNextH263Frame(stream) != PV_SUCCESS)
+ {
+ /* There is no vop header in the buffer, */
+ /* clean bitstream buffer. 2/5/2001 */
+ buffer_size[0] = 0;
+ if (video->initialized == PV_FALSE)
+ {
+ video->displayWidth = video->width = 0;
+ video->displayHeight = video->height = 0;
+ }
+ return PV_FALSE;
+ }
+ }
+
+ if (use_ext_timestamp[0])
+ {
+ /* MTB for H263 is absolute TR */
+ /* following line is equivalent to round((timestamp[0]*30)/1001); 11/13/2001 */
+ video->vol[0]->moduloTimeBase = 30 * ((timestamp[0] + 17) / 1001) + (30 * ((timestamp[0] + 17) % 1001) / 1001);
+ vopHeader[0]->timeStamp = timestamp[0];
+ }
+ else
+ vopHeader[0]->timeStamp = CalcVopDisplayTime(currVol, vopHeader[0], video->shortVideoHeader);
+ }
+ else
+ {
+ while (DecodeVOPHeader(video, vopHeader[0], FALSE) != PV_SUCCESS)
+ {
+ /* Try to find a VOP header in the buffer. 08/30/2000. */
+ if (PVSearchNextM4VFrame(stream) != PV_SUCCESS)
+ {
+ /* There is no vop header in the buffer, */
+ /* clean bitstream buffer. 2/5/2001 */
+ buffer_size[0] = 0;
+ return PV_FALSE;
+ }
+ }
+
+ if (use_ext_timestamp[0])
+ {
+ video->vol[0]->timeInc_offset = vopHeader[0]->timeInc;
+ video->vol[0]->moduloTimeBase = timestamp[0]; /* 11/12/2001 */
+ vopHeader[0]->timeStamp = timestamp[0];
+ }
+ else
+ {
+ vopHeader[0]->timeStamp = CalcVopDisplayTime(currVol, vopHeader[0], video->shortVideoHeader);
+ }
+ }
+
+ /* set up some base-layer only parameters */
+ vopHeader[0]->refSelectCode = 1;
+#ifdef PV_SUPPORT_TEMPORAL_SCALABILITY
+ }
+#endif
+ timestamp[target_layer] = video->currTimestamp = vopHeader[target_layer]->timeStamp;
+#ifdef PV_MEMORY_POOL
+ vopHeader[target_layer]->yChan = (PIXEL *)currYUV;
+ vopHeader[target_layer]->uChan = (PIXEL *)currYUV + decCtrl->size;
+ vopHeader[target_layer]->vChan = (PIXEL *)(vopHeader[target_layer]->uChan) + (decCtrl->size >> 2);
+#else
+ vopHeader[target_layer]->yChan = currVop->yChan;
+ vopHeader[target_layer]->uChan = currVop->uChan;
+ vopHeader[target_layer]->vChan = currVop->vChan;
+#endif
+ oscl_memcpy(currVop, vopHeader[target_layer], sizeof(Vop));
+
+#ifdef PV_SUPPORT_TEMPORAL_SCALABILITY
+ vopHeader[target_layer]->timeStamp = -1;
+#endif
+ /* put header info into the structure */
+ header_info->currLayer = target_layer;
+ header_info->timestamp = video->currTimestamp;
+ header_info->frameType = (MP4FrameType)currVop->predictionType;
+ header_info->refSelCode = vopHeader[target_layer]->refSelectCode;
+ header_info->quantizer = currVop->quantizer;
+ /***************************************/
+
+ return PV_TRUE;
+}
+
+
+/* ======================================================================== */
+/* Function : PVDecodeVopBody() */
+/* Date : 08/22/2002 */
+/* Purpose : Decode vop body after the header is decoded, modified from */
+/* original PVDecodeVideoFrame. */
+/* In/out : */
+/* Return : */
+/* Note : */
+/* Modified : */
+/* ======================================================================== */
+Bool PVDecodeVopBody(VideoDecControls *decCtrl, int32 buffer_size[])
+{
+ PV_STATUS status = PV_FAIL;
+ VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
+ int target_layer = video->currLayer;
+ Vol *currVol = video->vol[target_layer];
+ Vop *currVop = video->currVop;
+ Vop *prevVop = video->prevVop;
+ Vop *tempVopPtr;
+ int bytes_consumed = 0; /* Record how many bits we used in the buffer. 04/24/2001 */
+
+ int idx;
+
+ if (currVop->vopCoded == 0) /* 07/03/2001 */
+ {
+ PV_BitstreamByteAlign(currVol->bitstream);
+ /* We should always clear up bitstream buffer. 10/10/2000 */
+ bytes_consumed = (getPointer(currVol->bitstream) + 7) >> 3;
+
+ if (bytes_consumed > currVol->bitstream->data_end_pos)
+ {
+ bytes_consumed = currVol->bitstream->data_end_pos;
+ }
+
+ if (bytes_consumed < buffer_size[target_layer])
+ {
+ /* If we only consume part of the bits in the buffer, take those */
+ /* out. 04/24/2001 */
+ /* oscl_memcpy(buffer[target_layer], buffer[target_layer]+bytes_consumed,
+ (buffer_size[target_layer]-=bytes_consumed)); */
+ buffer_size[target_layer] -= bytes_consumed;
+ }
+ else
+ {
+ buffer_size[target_layer] = 0;
+ }
+#ifdef PV_MEMORY_POOL
+
+ if (target_layer)
+ {
+ if (video->prevEnhcVop->timeStamp > video->prevVop->timeStamp)
+ {
+ video->prevVop = video->prevEnhcVop;
+ }
+ }
+
+ oscl_memcpy(currVop->yChan, video->prevVop->yChan, (decCtrl->size*3) / 2);
+
+ video->prevVop = prevVop;
+
+ video->concealFrame = currVop->yChan; /* 07/07/2001 */
+
+ video->vop_coding_type = currVop->predictionType; /* 07/09/01 */
+
+ decCtrl->outputFrame = currVop->yChan;
+
+ /* Swap VOP pointers. No enhc. frame oscl_memcpy() anymore! 04/24/2001 */
+ if (target_layer)
+ {
+ tempVopPtr = video->prevEnhcVop;
+ video->prevEnhcVop = video->currVop;
+ video->currVop = tempVopPtr;
+ }
+ else
+ {
+ tempVopPtr = video->prevVop;
+ video->prevVop = video->currVop;
+ video->currVop = tempVopPtr;
+ }
+#else
+ if (target_layer) /* this is necessary to avoid flashback problems 06/21/2002*/
+ {
+ video->prevEnhcVop->timeStamp = currVop->timeStamp;
+ }
+ else
+ {
+ video->prevVop->timeStamp = currVop->timeStamp;
+ }
+#endif
+ video->vop_coding_type = currVop->predictionType; /* 07/09/01 */
+ /* the following is necessary to avoid displaying an notCoded I-VOP at the beginning of a session
+ or after random positioning 07/03/02*/
+ if (currVop->predictionType == I_VOP)
+ {
+ video->vop_coding_type = P_VOP;
+ }
+
+
+ return PV_TRUE;
+ }
+ /* ======================================================= */
+ /* Decode vop body (if there is no error in the header!) */
+ /* ======================================================= */
+
+ /* first, we need to select a reference frame */
+ if (decCtrl->nLayers > 1)
+ {
+ if (currVop->predictionType == I_VOP)
+ {
+ /* do nothing here */
+ }
+ else if (currVop->predictionType == P_VOP)
+ {
+ switch (currVop->refSelectCode)
+ {
+ case 0 : /* most recently decoded enhancement vop */
+ /* Setup video->prevVop before we call PV_DecodeVop(). 04/24/2001 */
+ if (video->prevEnhcVop->timeStamp >= video->prevVop->timeStamp)
+ video->prevVop = video->prevEnhcVop;
+ break;
+
+ case 1 : /* most recently displayed base-layer vop */
+ if (target_layer)
+ {
+ if (video->prevEnhcVop->timeStamp > video->prevVop->timeStamp)
+ video->prevVop = video->prevEnhcVop;
+ }
+ break;
+
+ case 2 : /* next base-layer vop in display order */
+ break;
+
+ case 3 : /* temporally coincident base-layer vop (no MV's) */
+ break;
+ }
+ }
+ else /* we have a B-Vop */
+ {
+ mp4dec_log("DecodeVideoFrame(): B-VOP not supported.\n");
+ }
+ }
+
+ /* This is for the calculation of the frame rate and bitrate. */
+ idx = ++video->frame_idx % BITRATE_AVERAGE_WINDOW;
+
+ /* Calculate bitrate for this layer. 08/23/2000 */
+ status = PV_DecodeVop(video);
+ video->nBitsPerVop[idx] = getPointer(currVol->bitstream);
+ video->prevTimestamp[idx] = currVop->timeStamp;
+
+ /* restore video->prevVop after PV_DecodeVop(). 04/24/2001 */
+// if (currVop->refSelectCode == 0) video->prevVop = prevVop;
+ video->prevVop = prevVop;
+
+ /* Estimate the frame rate. 08/23/2000 */
+ video->duration = video->prevTimestamp[idx];
+ video->duration -= video->prevTimestamp[(++idx)%BITRATE_AVERAGE_WINDOW];
+ if (video->duration > 0)
+ { /* Only update framerate when the timestamp is right */
+ video->frameRate = (int)(FRAMERATE_SCALE) / video->duration;
+ }
+
+ /* We should always clear up bitstream buffer. 10/10/2000 */
+ bytes_consumed = (getPointer(currVol->bitstream) + 7) >> 3; /* 11/4/03 */
+
+ if (bytes_consumed > currVol->bitstream->data_end_pos)
+ {
+ bytes_consumed = currVol->bitstream->data_end_pos;
+ }
+
+ if (bytes_consumed < buffer_size[target_layer])
+ {
+ /* If we only consume part of the bits in the buffer, take those */
+ /* out. 04/24/2001 */
+ /* oscl_memcpy(buffer[target_layer], buffer[target_layer]+bytes_consumed,
+ (buffer_size[target_layer]-=bytes_consumed)); */
+ buffer_size[target_layer] -= bytes_consumed;
+ }
+ else
+ {
+ buffer_size[target_layer] = 0;
+ }
+ switch (status)
+ {
+ case PV_FAIL :
+ return PV_FALSE; /* this will take care of concealment if we lose whole frame */
+
+ case PV_END_OF_VOP :
+ /* we may want to differenciate PV_END_OF_VOP and PV_SUCCESS */
+ /* in the future. 05/10/2000 */
+
+ case PV_SUCCESS :
+ /* Nohting is wrong :). */
+
+
+ video->concealFrame = video->currVop->yChan; /* 07/07/2001 */
+
+ video->vop_coding_type = video->currVop->predictionType; /* 07/09/01 */
+
+ decCtrl->outputFrame = video->currVop->yChan;
+
+ /* Swap VOP pointers. No enhc. frame oscl_memcpy() anymore! 04/24/2001 */
+ if (target_layer)
+ {
+ tempVopPtr = video->prevEnhcVop;
+ video->prevEnhcVop = video->currVop;
+ video->currVop = tempVopPtr;
+ }
+ else
+ {
+ tempVopPtr = video->prevVop;
+ video->prevVop = video->currVop;
+ video->currVop = tempVopPtr;
+ }
+ break;
+
+ default :
+ /* This will never happen */
+ break;
+ }
+
+ return PV_TRUE;
+}
+
+#ifdef PV_MEMORY_POOL
+OSCL_EXPORT_REF void PVSetReferenceYUV(VideoDecControls *decCtrl, uint8 *YUV)
+{
+ VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
+ video->prevVop->yChan = (PIXEL *)YUV;
+ video->prevVop->uChan = (PIXEL *)YUV + video->size;
+ video->prevVop->vChan = (PIXEL *)video->prevVop->uChan + (decCtrl->size >> 2);
+ oscl_memset(video->prevVop->yChan, 16, sizeof(uint8)*decCtrl->size); /* 10/31/01 */
+ oscl_memset(video->prevVop->uChan, 128, sizeof(uint8)*decCtrl->size / 2);
+ video->concealFrame = video->prevVop->yChan; /* 07/07/2001 */
+ decCtrl->outputFrame = video->prevVop->yChan; /* 06/19/2002 */
+}
+#endif
+
+
+/* ======================================================================== */
+/* Function : VideoDecoderErrorDetected() */
+/* Date : 06/20/2000 */
+/* Purpose : */
+/* In/out : */
+/* Return : This function will be called everytime an error int the */
+/* bitstream is detected. */
+/* Note : */
+/* Modified : */
+/* ======================================================================== */
+uint VideoDecoderErrorDetected(VideoDecData *)
+{
+ /* This is only used for trapping bitstream error for debuging */
+ return 0;
+}
+
+#ifdef ENABLE_LOG
+#include <stdio.h>
+#include <stdarg.h>
+/* ======================================================================== */
+/* Function : m4vdec_dprintf() */
+/* Date : 08/15/2000 */
+/* Purpose : This is a function that logs messages in the mpeg4 video */
+/* decoder. We can call the standard PacketVideo PVMessage */
+/* from inside this function if necessary. */
+/* In/out : */
+/* Return : */
+/* Note : To turn on the logging, LOG_MP4DEC_MESSAGE must be defined */
+/* when compiling this file (only this file). */
+/* Modified : */
+/* ======================================================================== */
+void m4vdec_dprintf(char *format, ...)
+{
+ FILE *log_fp;
+ va_list args;
+ va_start(args, format);
+
+ /* open the log file */
+ log_fp = fopen("\\mp4dec_log.txt", "a+");
+ if (log_fp == NULL) return;
+ /* output the message */
+ vfprintf(log_fp, format, args);
+ fclose(log_fp);
+
+ va_end(args);
+}
+#endif
+
+
+/* ======================================================================== */
+/* Function : IsIntraFrame() */
+/* Date : 05/29/2000 */
+/* Purpose : */
+/* In/out : */
+/* Return : The most recently decoded frame is an Intra frame. */
+/* Note : */
+/* Modified : */
+/* ======================================================================== */
+Bool IsIntraFrame(VideoDecControls *decCtrl)
+{
+ VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
+ return (video->vop_coding_type == I_VOP);
+}
+
+/* ======================================================================== */
+/* Function : PVDecPostProcess() */
+/* Date : 01/09/2002 */
+/* Purpose : PostProcess one video frame and return a YUV-12 image. */
+/* In/out : */
+/* Return : */
+/* Note : */
+/* Modified : */
+/* ======================================================================== */
+void PVDecPostProcess(VideoDecControls *decCtrl, uint8 *outputYUV)
+{
+ uint8 *outputBuffer;
+#ifdef PV_POSTPROC_ON
+ VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
+ int32 tmpvar;
+ if (outputYUV)
+ {
+ outputBuffer = outputYUV;
+ }
+ else
+ {
+ if (video->postFilterType)
+ {
+ outputBuffer = video->currVop->yChan;
+ }
+ else
+ {
+ outputBuffer = decCtrl->outputFrame;
+ }
+ }
+
+ if (video->postFilterType)
+ {
+ /* Post-processing, */
+ PostFilter(video, video->postFilterType, outputBuffer);
+ }
+ else
+ {
+ if (outputYUV)
+ {
+ /* Copy decoded frame to the output buffer. */
+ tmpvar = (int32)video->width * video->height;
+ oscl_memcpy(outputBuffer, decCtrl->outputFrame, tmpvar*3 / 2); /* 3/3/01 */
+ }
+ }
+#else
+ outputBuffer = decCtrl->outputFrame;
+ outputYUV;
+#endif
+ decCtrl->outputFrame = outputBuffer;
+ return;
+}
+
+
+/* ======================================================================== */
+/* Function : PVDecSetReference(VideoDecControls *decCtrl, uint8 *refYUV, */
+/* int32 timestamp) */
+/* Date : 07/22/2003 */
+/* Purpose : Get YUV reference frame from external source. */
+/* In/out : YUV 4-2-0 frame containing new reference frame in the same */
+/* : dimension as original, i.e., doesn't have to be multiple of 16 !!!. */
+/* Return : */
+/* Note : */
+/* Modified : */
+/* ======================================================================== */
+Bool PVDecSetReference(VideoDecControls *decCtrl, uint8 *refYUV, uint32 timestamp)
+{
+ VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
+ Vop *prevVop = video->prevVop;
+ int width = video->width;
+ uint8 *dstPtr, *orgPtr, *dstPtr2, *orgPtr2;
+ int32 size = (int32)width * video->height;
+
+
+ /* set new parameters */
+ prevVop->timeStamp = timestamp;
+ prevVop->predictionType = I_VOP;
+
+ dstPtr = prevVop->yChan;
+ orgPtr = refYUV;
+ oscl_memcpy(dstPtr, orgPtr, size);
+ dstPtr = prevVop->uChan;
+ dstPtr2 = prevVop->vChan;
+ orgPtr = refYUV + size;
+ orgPtr2 = orgPtr + (size >> 2);
+ oscl_memcpy(dstPtr, orgPtr, (size >> 2));
+ oscl_memcpy(dstPtr2, orgPtr2, (size >> 2));
+
+ video->concealFrame = video->prevVop->yChan;
+ video->vop_coding_type = I_VOP;
+ decCtrl->outputFrame = video->prevVop->yChan;
+
+ return PV_TRUE;
+}
+
+/* ======================================================================== */
+/* Function : PVDecSetEnhReference(VideoDecControls *decCtrl, uint8 *refYUV, */
+/* int32 timestamp) */
+/* Date : 07/23/2003 */
+/* Purpose : Get YUV enhance reference frame from external source. */
+/* In/out : YUV 4-2-0 frame containing new reference frame in the same */
+/* : dimension as original, i.e., doesn't have to be multiple of 16 !!!. */
+/* Return : */
+/* Note : */
+/* Modified : */
+/* ======================================================================== */
+Bool PVDecSetEnhReference(VideoDecControls *decCtrl, uint8 *refYUV, uint32 timestamp)
+{
+ VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
+ Vop *prevEnhcVop = video->prevEnhcVop;
+ uint8 *dstPtr, *orgPtr, *dstPtr2, *orgPtr2;
+ int32 size = (int32) video->width * video->height;
+
+ if (video->numberOfLayers <= 1)
+ return PV_FALSE;
+
+
+ /* set new parameters */
+ prevEnhcVop->timeStamp = timestamp;
+ prevEnhcVop->predictionType = I_VOP;
+
+ dstPtr = prevEnhcVop->yChan;
+ orgPtr = refYUV;
+ oscl_memcpy(dstPtr, orgPtr, size);
+ dstPtr = prevEnhcVop->uChan;
+ dstPtr2 = prevEnhcVop->vChan;
+ orgPtr = refYUV + size;
+ orgPtr2 = orgPtr + (size >> 2);
+ oscl_memcpy(dstPtr, orgPtr, (size >> 2));
+ oscl_memcpy(dstPtr2, orgPtr2, (size >> 2));
+ video->concealFrame = video->prevEnhcVop->yChan;
+ video->vop_coding_type = I_VOP;
+ decCtrl->outputFrame = video->prevEnhcVop->yChan;
+
+ return PV_TRUE;
+}
+
+
+/* ======================================================================== */
+/* Function : PVGetVolInfo() */
+/* Date : 08/06/2003 */
+/* Purpose : Get the vol info(only base-layer). */
+/* In/out : */
+/* Return : */
+/* Note : */
+/* Modified : 06/24/2004 */
+/* ======================================================================== */
+Bool PVGetVolInfo(VideoDecControls *decCtrl, VolInfo *pVolInfo)
+{
+ Vol *currVol;
+
+ if (pVolInfo == NULL || decCtrl == NULL || decCtrl->videoDecoderData == NULL ||
+ ((VideoDecData *)decCtrl->videoDecoderData)->vol[0] == NULL) return PV_FALSE;
+
+ currVol = ((VideoDecData *)(decCtrl->videoDecoderData))->vol[0];
+
+ // get the VOL info
+ pVolInfo->shortVideoHeader = (int32)((VideoDecData *)(decCtrl->videoDecoderData))->shortVideoHeader;
+ pVolInfo->dataPartitioning = (int32)currVol->dataPartitioning;
+ pVolInfo->errorResDisable = (int32)currVol->errorResDisable;
+ pVolInfo->useReverseVLC = (int32)currVol->useReverseVLC;
+ pVolInfo->scalability = (int32)currVol->scalability;
+ pVolInfo->nbitsTimeIncRes = (int32)currVol->nbitsTimeIncRes;
+ pVolInfo->profile_level_id = (int32)currVol->profile_level_id;
+
+ return PV_TRUE;
+}
+
+
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/scaling.h b/media/libstagefright/codecs/m4v_h263/dec/src/scaling.h
new file mode 100644
index 0000000..26abbae
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/scaling.h
@@ -0,0 +1,52 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ extern const int32 scale[63];
+
+#define PV_GET_ROW(a,b) ((a) / (b))
+
+ /*----------------------------------------------------------------------------
+ ; SIMPLE TYPEDEF'S
+ ----------------------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------------------
+ ; ENUMERATED TYPEDEF'S
+ ----------------------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------------------
+ ; STRUCTURES TYPEDEF'S
+ ----------------------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------------------
+ ; GLOBAL FUNCTION DEFINITIONS
+ ; Function Prototype declaration
+ ----------------------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------------------
+ ; END
+ ----------------------------------------------------------------------------*/
+#ifdef __cplusplus
+}
+#endif
+
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/scaling_tab.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/scaling_tab.cpp
new file mode 100644
index 0000000..a1f95aa
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/scaling_tab.cpp
@@ -0,0 +1,88 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+
+#include "mp4dec_api.h"
+#include "mp4def.h"
+#include "scaling.h"
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here. Include conditional
+; compile variables also.
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL FUNCTION DEFINITIONS
+; Function Prototype declaration
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; LOCAL STORE/BUFFER/POINTER DEFINITIONS
+; Variable declaration - defined here and used outside this module
+----------------------------------------------------------------------------*/
+
+/* this scaling can be used for dividing values up to 3292 07/10/01 */
+const int32 scale[63] = {0, 262145, 131073, 87382, 65537, 52430, 43692, 37450, 32769, 29128,
+ 26215, 23832, 21846, 20166, 18726, 17477, 16385, 15421, 14565, 13798,
+ 13108, 12484, 11917, 11399, 10924, 10487, 10083, 9710, 9363, 9040,
+ 8739, 8457, 8193, 7945, 7711, 7491, 7283, 7086, 6900, 6723, 6555, 6395,
+ 6243, 6097, 5959, 5826, 5700, 5579, 5462, 5351, 5244, 5141, 5042, 4947, 4856,
+ 4767, 4682, 4600, 4521, 4444, 4370, 4298, 4229
+ };
+/*----------------------------------------------------------------------------
+; EXTERNAL FUNCTION REFERENCES
+; Declare functions defined elsewhere and referenced in this module
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; FUNCTION CODE
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; Define all local variables
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; Function body here
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; Return nothing or data or data pointer
+----------------------------------------------------------------------------*/
+
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vlc_dec_tab.h b/media/libstagefright/codecs/m4v_h263/dec/src/vlc_dec_tab.h
new file mode 100644
index 0000000..404cc8b
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/vlc_dec_tab.h
@@ -0,0 +1,215 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+/*
+* ------------------------------------------------------------------- *
+* MPEG-4 Simple Profile Video Decoder *
+* ------------------------------------------------------------------- *
+*
+* This software module was originally developed by
+*
+* Paulo Nunes (IST / ACTS-MoMuSyS)
+*
+* and edited by
+*
+* Robert Danielsen (Telenor / ACTS-MoMuSyS)
+*
+* in the course of development of the MPEG-4 Video (ISO/IEC 14496-2) standard.
+* This software module is an implementation of a part of one or more MPEG-4
+* Video (ISO/IEC 14496-2) tools as specified by the MPEG-4 Video (ISO/IEC
+* 14496-2) standard.
+*
+* ISO/IEC gives users of the MPEG-4 Video (ISO/IEC 14496-2) standard free
+* license to this software module or modifications thereof for use in hardware
+* or software products claiming conformance to the MPEG-4 Video (ISO/IEC
+* 14496-2) standard.
+*
+* Those intending to use this software module in hardware or software products
+* are advised that its use may infringe existing patents. The original
+* developer of this software module and his/her company, the subsequent
+* editors and their companies, and ISO/IEC have no liability for use of this
+* software module or modifications thereof in an implementation. Copyright is
+* not released for non MPEG-4 Video (ISO/IEC 14496-2) Standard conforming
+* products.
+*
+* ACTS-MoMuSys partners retain full right to use the code for his/her own
+* purpose, assign or donate the code to a third party and to inhibit third
+* parties from using the code for non MPEG-4 Video (ISO/IEC 14496-2) Standard
+* conforming products. This copyright notice must be included in all copies or
+* derivative works.
+*
+* Copyright (c) 1996
+*
+*****************************************************************************
+***********************************************************HeaderBegin*******
+*
+* File: vlc_dec_tab.h
+*
+* Author: Paulo Nunes (IST) - Paulo.Nunes@it.ist.utl.pt
+* Created: 1-Mar-96
+*
+* Description: This file contains the VLC tables for module which deals
+* with VLC decoding.
+*
+* Notes: This file was created based on tmndecode
+* Written by Karl Olav Lillevold <kol@nta.no>,
+* 1995 Telenor R&D.
+* Donated to the Momusys-project as background code by
+* Telenor.
+*
+* based on mpeg2decode, (C) 1994, MPEG Software Simulation Group
+* and mpeg2play, (C) 1994 Stefan Eckart
+* <stefan@lis.e-technik.tu-muenchen.de>
+*
+*
+* Modified: 9-May-96 Paulo Nunes: Reformatted. New headers.
+* 14-May-96 Paulo Nunes: Changed TMNMVtabs according to VM2.1.
+* 04.11.96 Robert Danielsen: Added three new tables for coding
+* of Intra luminance coefficients (VM 4.0)
+* 01.05.97 Luis Ducla-Soares: added VM7.0 Reversible VLC tables (RVLC).
+* 13.05.97 Minhua Zhou: added VlC tables for CBPYtab2 CBPYtab3,
+* revised CBPYtab
+*
+***********************************************************HeaderEnd*********
+
+This module is a header file for "vlc_decode.c". The table data actually
+resides in "vlc_tab.c".
+
+
+------------------------------------------------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+; CONTINUE ONLY IF NOT ALREADY DEFINED
+----------------------------------------------------------------------------*/
+#ifndef vlc_dec_tab_H
+#define vlc_dec_tab_H
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "mp4def.h"
+
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here.
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; EXTERNAL VARIABLES REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ extern const VLCshorttab PV_TMNMVtab0[];
+
+ extern const VLCshorttab PV_TMNMVtab1[];
+
+ extern const VLCshorttab PV_TMNMVtab2[];
+
+ extern const VLCshorttab PV_MCBPCtab[];
+
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ extern const VLCshorttab PV_MCBPCtab1[];
+#endif
+ extern const VLCshorttab PV_MCBPCtabintra[];
+
+ /* Table for separate mode MCBPC, for coding DQUANT-flag and CBPC */
+
+ extern const VLCshorttab MCBPCtab_sep[32];
+
+ extern const VLCshorttab PV_CBPYtab[48];
+
+ extern const VLCshorttab CBPYtab2[16];
+
+ extern const VLCshorttab CBPYtab3[64];
+
+ extern const VLCtab2 PV_DCT3Dtab0[];
+
+
+ extern const VLCtab2 PV_DCT3Dtab1[];
+
+
+ extern const VLCtab2 PV_DCT3Dtab2[];
+
+ /* New tables for Intra luminance blocks */
+
+ extern const VLCtab2 PV_DCT3Dtab3[];
+
+ extern const VLCtab2 PV_DCT3Dtab4[];
+
+ extern const VLCtab2 PV_DCT3Dtab5[];
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ /* Annex I tables */
+ extern const VLCtab2 PV_DCT3Dtab6[];
+
+ extern const VLCtab2 PV_DCT3Dtab7[];
+
+ extern const VLCtab2 PV_DCT3Dtab8[];
+#endif
+ /* RVLC tables */
+ extern const int ptrRvlcTab[];
+
+ extern const VLCtab2 RvlcDCTtabIntra[];
+
+ extern const VLCtab2 RvlcDCTtabInter[];
+
+ /*----------------------------------------------------------------------------
+ ; SIMPLE TYPEDEF'S
+ ----------------------------------------------------------------------------*/
+
+
+ /*----------------------------------------------------------------------------
+ ; ENUMERATED TYPEDEF'S
+ ----------------------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------------------
+ ; STRUCTURES TYPEDEF'S
+ ----------------------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------------------
+ ; GLOBAL FUNCTION DEFINITIONS
+ ; Function Prototype declaration
+ ----------------------------------------------------------------------------*/
+
+
+ /*----------------------------------------------------------------------------
+ ; END
+ ----------------------------------------------------------------------------*/
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+
+
+
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.cpp
new file mode 100644
index 0000000..f7192b1
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.cpp
@@ -0,0 +1,1636 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+/*
+* ------------------------------------------------------------------- *
+* MPEG-4 Simple Profile Video Decoder *
+* ------------------------------------------------------------------- *
+*
+* This software module was originally developed by
+*
+* Paulo Nunes (IST / ACTS-MoMuSyS)
+* Robert Danielsen (Telenor / ACTS-MoMuSyS)
+*
+* in the course of development of the MPEG-4 Video (ISO/IEC 14496-2) standard.
+* This software module is an implementation of a part of one or more MPEG-4
+* Video (ISO/IEC 14496-2) tools as specified by the MPEG-4 Video (ISO/IEC
+* 14496-2) standard.
+*
+* ISO/IEC gives users of the MPEG-4 Video (ISO/IEC 14496-2) standard free
+* license to this software module or modifications thereof for use in hardware
+* or software products claiming conformance to the MPEG-4 Video (ISO/IEC
+* 14496-2) standard.
+*
+* Those intending to use this software module in hardware or software products
+* are advised that its use may infringe existing patents. The original
+* developer of this software module and his/her company, the subsequent
+* editors and their companies, and ISO/IEC have no liability for use of this
+* software module or modifications thereof in an implementation. Copyright is
+* not released for non MPEG-4 Video (ISO/IEC 14496-2) Standard conforming
+* products.
+*
+* ACTS-MoMuSys partners retain full right to use the code for his/her own
+* purpose, assign or donate the code to a third party and to inhibit third
+* parties from using the code for non MPEG-4 Video (ISO/IEC 14496-2) Standard
+* conforming products. This copyright notice must be included in all copies or
+* derivative works.
+*
+* Copyright (c) 1996
+*
+*****************************************************************************/
+
+/***********************************************************HeaderBegin*******
+*
+* File: vlc_dec.c
+*
+* Author: Paulo Nunes (IST) - Paulo.Nunes@lx.it.pt
+* Created: 1-Mar-96
+*
+* Description: This file contains the VLC functions needed to decode a
+* bitstream.
+*
+* Notes:
+* The functions contained in this file were adapted from
+* tmndecode
+* Written by Karl Olav Lillevold <kol@nta.no>,
+* 1995 Telenor R&D.
+* Donated to the Momusys-project as background code by
+* Telenor.
+*
+* based on mpeg2decode, (C) 1994, MPEG Software Simulation Group
+* and mpeg2play, (C) 1994 Stefan Eckart
+* <stefan@lis.e-technik.tu-muenchen.de>
+*
+*
+* Modified: 9-May-96 Paulo Nunes: Reformatted. New headers.
+* 17-Jan-97 Jan De Lameillieure (HHI) : corrected in
+* 01.05.97 Luis Ducla-Soares: added RvlcDecTCOEF() to allow decoding
+* of Reversible VLCs.
+* 09.03.98 Paulo Nunes: Cleaning.
+*
+***********************************************************HeaderEnd*********/
+
+#include "mp4dec_lib.h"
+#include "vlc_dec_tab.h"
+#include "vlc_decode.h"
+#include "bitstream.h"
+#include "max_level.h"
+
+
+/* ====================================================================== /
+ Function : DecodeUserData()
+ Date : 04/10/2000
+ History :
+ Modified : 04/16/2001 : removed status checking of PV_BitstreamFlushBits
+
+ This is simply a realization of the user_data() function
+ in the ISO/IEC 14496-2 manual.
+/ ====================================================================== */
+PV_STATUS DecodeUserData(BitstreamDecVideo *stream)
+{
+ PV_STATUS status;
+ uint32 code;
+
+ BitstreamReadBits32HC(stream);
+ BitstreamShowBits32(stream, 24, &code);
+
+ while (code != 1)
+ {
+ /* Discard user data for now. 04/05/2000 */
+ BitstreamReadBits16(stream, 8);
+ BitstreamShowBits32(stream, 24, &code);
+ status = BitstreamCheckEndBuffer(stream);
+ if (status == PV_END_OF_VOP) return status; /* 03/19/2002 */
+ }
+ return PV_SUCCESS;
+}
+
+
+
+/***********************************************************CommentBegin******
+*
+* 3/10/00 : initial modification to the
+* new PV-Decoder Lib format.
+* 3/29/00 : added return code check to some functions and
+* optimize the code.
+*
+***********************************************************CommentEnd********/
+PV_STATUS PV_GetMBvectors(VideoDecData *video, uint mode)
+{
+ PV_STATUS status;
+ BitstreamDecVideo *stream = video->bitstream;
+ int f_code_f = video->currVop->fcodeForward;
+ int vlc_code_mag;
+
+
+ MOT *mot_x = video->motX;
+ MOT *mot_y = video->motY;
+
+ int k, offset;
+ int x_pos = video->mbnum_col;
+ int y_pos = video->mbnum_row;
+ int doubleWidth = video->nMBPerRow << 1;
+ int pos = (x_pos + y_pos * doubleWidth) << 1;
+ MOT mvx = 0, mvy = 0;
+
+
+ if (f_code_f == 1)
+ {
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ if (mode == MODE_INTER4V || mode == MODE_INTER4V_Q)
+#else
+ if (mode == MODE_INTER4V)
+#endif
+ {
+ for (k = 0; k < 4; k++)
+ {
+ offset = (k & 1) + (k >> 1) * doubleWidth;
+ mv_prediction(video, k, &mvx, &mvy);
+ /* decode component x */
+ status = PV_VlcDecMV(stream, &vlc_code_mag);
+ if (status != PV_SUCCESS)
+ {
+ return status;
+ }
+
+ mvx += (MOT)vlc_code_mag;
+ mvx = (MOT)(((mvx + 32) & 0x3F) - 32);
+
+
+ status = PV_VlcDecMV(stream, &vlc_code_mag);
+ if (status != PV_SUCCESS)
+ {
+ return status;
+ }
+
+ mvy += (MOT)vlc_code_mag;
+ mvy = (MOT)(((mvy + 32) & 0x3F) - 32);
+
+ mot_x[pos+offset] = (MOT) mvx;
+ mot_y[pos+offset] = (MOT) mvy;
+ }
+ }
+ else
+ {
+ mv_prediction(video, 0, &mvx, &mvy);
+ /* For PVOPs, field appears only in MODE_INTER & MODE_INTER_Q */
+ status = PV_VlcDecMV(stream, &vlc_code_mag);
+ if (status != PV_SUCCESS)
+ {
+ return status;
+ }
+
+ mvx += (MOT)vlc_code_mag;
+ mvx = (MOT)(((mvx + 32) & 0x3F) - 32);
+
+
+ status = PV_VlcDecMV(stream, &vlc_code_mag);
+ if (status != PV_SUCCESS)
+ {
+ return status;
+ }
+
+
+ mvy += (MOT)vlc_code_mag;
+ mvy = (MOT)(((mvy + 32) & 0x3F) - 32);
+
+
+ mot_x[pos] = mot_x[pos+1] = (MOT) mvx;
+ mot_y[pos] = mot_y[pos+1] = (MOT) mvy;
+ pos += doubleWidth;
+ mot_x[pos] = mot_x[pos+1] = (MOT) mvx;
+ mot_y[pos] = mot_y[pos+1] = (MOT) mvy;
+ }
+ }
+ else
+ {
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ if (mode == MODE_INTER4V || mode == MODE_INTER4V_Q)
+#else
+ if (mode == MODE_INTER4V)
+#endif
+ {
+ for (k = 0; k < 4; k++)
+ {
+ offset = (k & 1) + (k >> 1) * doubleWidth;
+ mv_prediction(video, k, &mvx, &mvy);
+ status = PV_DecodeMBVec(stream, &mvx, &mvy, f_code_f);
+ mot_x[pos+offset] = (MOT) mvx;
+ mot_y[pos+offset] = (MOT) mvy;
+ if (status != PV_SUCCESS)
+ {
+ return status;
+ }
+ }
+ }
+ else
+ {
+ mv_prediction(video, 0, &mvx, &mvy);
+ /* For PVOPs, field appears only in MODE_INTER & MODE_INTER_Q */
+ status = PV_DecodeMBVec(stream, &mvx, &mvy, f_code_f);
+ mot_x[pos] = mot_x[pos+1] = (MOT) mvx;
+ mot_y[pos] = mot_y[pos+1] = (MOT) mvy;
+ pos += doubleWidth;
+ mot_x[pos] = mot_x[pos+1] = (MOT) mvx;
+ mot_y[pos] = mot_y[pos+1] = (MOT) mvy;
+ if (status != PV_SUCCESS)
+ {
+ return status;
+ }
+ }
+ }
+ return PV_SUCCESS;
+}
+
+
+/***********************************************************CommentBegin******
+* 3/10/00 : initial modification to the
+* new PV-Decoder Lib format.
+* 3/29/00 : added return code check to some functions
+* 5/10/00 : check whether the decoded vector is legal.
+* 4/17/01 : use MOT type
+***********************************************************CommentEnd********/
+PV_STATUS PV_DecodeMBVec(BitstreamDecVideo *stream, MOT *mv_x, MOT *mv_y, int f_code_f)
+{
+ PV_STATUS status;
+ int vlc_code_magx, vlc_code_magy;
+ int residualx = 0, residualy = 0;
+
+ /* decode component x */
+ status = PV_VlcDecMV(stream, &vlc_code_magx);
+ if (status != PV_SUCCESS)
+ {
+ return status;
+ }
+
+ if (vlc_code_magx)
+ {
+ residualx = (int) BitstreamReadBits16_INLINE(stream, (int)(f_code_f - 1));
+ }
+
+
+ /* decode component y */
+ status = PV_VlcDecMV(stream, &vlc_code_magy);
+ if (status != PV_SUCCESS)
+ {
+ return status;
+ }
+
+ if (vlc_code_magy)
+ {
+ residualy = (int) BitstreamReadBits16_INLINE(stream, (int)(f_code_f - 1));
+ }
+
+
+ if (PV_DeScaleMVD(f_code_f, residualx, vlc_code_magx, mv_x) != PV_SUCCESS)
+ {
+ return PV_FAIL;
+ }
+
+ if (PV_DeScaleMVD(f_code_f, residualy, vlc_code_magy, mv_y) != PV_SUCCESS)
+ {
+ return PV_FAIL;
+ }
+
+ return PV_SUCCESS;
+}
+
+
+/***********************************************************CommentBegin******
+* 3/31/2000 : initial modification to the new PV-Decoder Lib format.
+* 5/10/2000 : check to see if the decoded vector falls within
+* the legal fcode range.
+*
+***********************************************************CommentEnd********/
+PV_STATUS PV_DeScaleMVD(
+ int f_code, /* <-- MV range in 1/2 units: 1=32,2=64,...,7=2048 */
+ int residual, /* <-- part of the MV Diff. FLC coded */
+ int vlc_code_mag, /* <-- part of the MV Diff. VLC coded */
+ MOT *vector /* --> Obtained MV component in 1/2 units */
+)
+{
+ int half_range = (1 << (f_code + 4));
+ int mask = (half_range << 1) - 1;
+ int diff_vector;
+
+
+ if (vlc_code_mag == 0)
+ {
+ diff_vector = vlc_code_mag;
+ }
+ else
+ {
+ diff_vector = ((PV_ABS(vlc_code_mag) - 1) << (f_code - 1)) + residual + 1;
+ if (vlc_code_mag < 0)
+ {
+ diff_vector = -diff_vector;
+ }
+ }
+
+ *vector += (MOT)(diff_vector);
+
+ *vector = (MOT)((*vector + half_range) & mask) - half_range;
+
+ return PV_SUCCESS;
+}
+
+
+
+void mv_prediction(
+ VideoDecData *video,
+ int block,
+ MOT *mvx,
+ MOT *mvy
+)
+{
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ MOT *motxdata = video->motX;
+ MOT *motydata = video->motY;
+ int mbnum_col = video->mbnum_col;
+ int mbnum_row = video->mbnum_row;
+ uint8 *slice_nb = video->sliceNo;
+ int nMBPerRow = video->nMBPerRow;
+ int nMVPerRow = nMBPerRow << 1;
+ int mbnum = video->mbnum;
+ int p1x = 0, p2x = 0, p3x = 0;
+ int p1y = 0, p2y = 0, p3y = 0;
+ int rule1 = 0, rule2 = 0, rule3 = 0;
+ int indx;
+
+ indx = ((mbnum_col << 1) + (block & 1)) + ((mbnum_row << 1) + (block >> 1)) * nMVPerRow - 1; /* left block */
+
+ if (block & 1) /* block 1, 3 */
+ {
+ p1x = motxdata[indx];
+ p1y = motydata[indx];
+ rule1 = 1;
+ }
+ else /* block 0, 2 */
+ {
+ if (mbnum_col > 0 && slice_nb[mbnum] == slice_nb[mbnum-1])
+ {
+ p1x = motxdata[indx];
+ p1y = motydata[indx];
+ rule1 = 1;
+ }
+ }
+
+ indx = indx + 1 - nMVPerRow; /* upper_block */
+ if (block >> 1)
+ {
+ indx -= (block & 1);
+ p2x = motxdata[indx];
+ p2y = motydata[indx];
+ p3x = motxdata[indx + 1];
+ p3y = motydata[indx + 1];
+ rule2 = rule3 = 1;
+ }
+ else
+ { /* block 0,1 */
+ if (mbnum_row)
+ {
+ if (slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow])
+ {
+ p2x = motxdata[indx];
+ p2y = motydata[indx];
+ rule2 = 1;
+ }
+ if (mbnum_col < nMBPerRow - 1 && slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow+1])
+ {
+ indx = indx + 2 - (block & 1);
+ p3x = motxdata[indx];
+ p3y = motydata[indx];
+ rule3 = 1;
+ }
+ }
+ }
+
+ if (rule1 + rule2 + rule3 > 1)
+ {
+ *mvx = (MOT)PV_MEDIAN(p1x, p2x, p3x);
+ *mvy = (MOT)PV_MEDIAN(p1y, p2y, p3y);
+ }
+ else if (rule1 + rule2 + rule3 == 1)
+ {
+ /* two of three are zero */
+ *mvx = (MOT)(p1x + p2x + p3x);
+ *mvy = (MOT)(p1y + p2y + p3y);
+ }
+ else
+ {
+ /* all MBs are outside the VOP */
+ *mvx = *mvy = 0;
+ }
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return;
+}
+
+/***********************************************************CommentBegin******
+*
+* 3/30/2000 : initial modification to the new PV-Decoder Lib format.
+* 4/16/2001 : removed checking of status for PV_BitstreamFlushBits
+***********************************************************CommentEnd********/
+
+PV_STATUS PV_VlcDecMV(BitstreamDecVideo *stream, int *mv)
+{
+ PV_STATUS status = PV_SUCCESS;
+ uint code;
+
+ BitstreamShow13Bits(stream, &code);
+
+ if (code >> 12)
+ {
+ *mv = 0; /* Vector difference = 0 */
+ PV_BitstreamFlushBits(stream, 1);
+ return PV_SUCCESS;
+ }
+
+ if (code >= 512)
+ {
+ code = (code >> 8) - 2;
+ PV_BitstreamFlushBits(stream, PV_TMNMVtab0[code].len + 1);
+ *mv = PV_TMNMVtab0[code].val;
+ return status;
+ }
+
+ if (code >= 128)
+ {
+ code = (code >> 2) - 32;
+ PV_BitstreamFlushBits(stream, PV_TMNMVtab1[code].len + 1);
+ *mv = PV_TMNMVtab1[code].val;
+ return status;
+ }
+
+ if (code < 4)
+ {
+ *mv = -1;
+ return PV_FAIL;
+ }
+
+ code -= 4;
+
+ PV_BitstreamFlushBits(stream, PV_TMNMVtab2[code].len + 1);
+
+ *mv = PV_TMNMVtab2[code].val;
+ return status;
+}
+
+
+/***********************************************************CommentBegin******
+* 3/30/2000 : initial modification to the new PV-Decoder Lib
+* format and the change of error-handling method.
+* 4/16/01 : removed status checking of PV_BitstreamFlushBits
+***********************************************************CommentEnd********/
+
+int PV_VlcDecMCBPC_com_intra(BitstreamDecVideo *stream)
+{
+ uint code;
+
+ BitstreamShowBits16(stream, 9, &code);
+
+
+ if (code < 8)
+ {
+ return VLC_CODE_ERROR;
+ }
+
+ code >>= 3;
+
+ if (code >= 32)
+ {
+ PV_BitstreamFlushBits(stream, 1);
+ return 3;
+ }
+
+ PV_BitstreamFlushBits(stream, PV_MCBPCtabintra[code].len);
+
+ return PV_MCBPCtabintra[code].val;
+}
+
+
+/***********************************************************CommentBegin******
+*
+* 3/30/2000 : initial modification to the new PV-Decoder Lib
+* format and the change of error-handling method.
+* 4/16/2001 : removed checking of return status of PV_BitstreamFlushBits
+***********************************************************CommentEnd********/
+
+int PV_VlcDecMCBPC_com_inter(BitstreamDecVideo *stream)
+{
+ uint code;
+
+ BitstreamShowBits16(stream, 9, &code);
+
+ if (code == 0)
+ {
+ return VLC_CODE_ERROR;
+ }
+ else if (code >= 256)
+ {
+ PV_BitstreamFlushBits(stream, 1);
+ return 0;
+ }
+
+ PV_BitstreamFlushBits(stream, PV_MCBPCtab[code].len);
+ return PV_MCBPCtab[code].val;
+}
+
+#ifdef PV_ANNEX_IJKT_SUPPORT
+int PV_VlcDecMCBPC_com_inter_H263(BitstreamDecVideo *stream)
+{
+ uint code;
+
+ BitstreamShow13Bits(stream, &code);
+
+ if (code == 0)
+ {
+ return VLC_CODE_ERROR;
+ }
+ else if (code >= 4096)
+ {
+ PV_BitstreamFlushBits(stream, 1);
+ return 0;
+ }
+ if (code >= 16)
+ {
+ PV_BitstreamFlushBits(stream, PV_MCBPCtab[code >> 4].len);
+ return PV_MCBPCtab[code >> 4].val;
+ }
+ else
+ {
+ PV_BitstreamFlushBits(stream, PV_MCBPCtab1[code - 8].len);
+ return PV_MCBPCtab1[code - 8].val;
+ }
+}
+#endif
+/***********************************************************CommentBegin******
+* 3/30/2000 : initial modification to the new PV-Decoder Lib
+* format and the change of error-handling method.
+* 4/16/2001 : removed status checking for PV_BitstreamFlushBits
+***********************************************************CommentEnd********/
+
+int PV_VlcDecCBPY(BitstreamDecVideo *stream, int intra)
+{
+ int CBPY = 0;
+ uint code;
+
+ BitstreamShowBits16(stream, 6, &code);
+
+
+ if (code < 2)
+ {
+ return -1;
+ }
+ else if (code >= 48)
+ {
+ PV_BitstreamFlushBits(stream, 2);
+ CBPY = 15;
+ }
+ else
+ {
+ PV_BitstreamFlushBits(stream, PV_CBPYtab[code].len);
+ CBPY = PV_CBPYtab[code].val;
+ }
+
+ if (intra == 0) CBPY = 15 - CBPY;
+ CBPY = CBPY & 15;
+ return CBPY;
+}
+
+
+/***********************************************************CommentBegin******
+* 3/31/2000 : initial modification to the new PV-Decoder Lib format.
+*
+* 8/23/2000 : optimize the function by removing unnecessary BitstreamShowBits()
+* function calls.
+*
+* 9/6/2000 : change the API to check for end-of-buffer for proper
+* termination of decoding process.
+***********************************************************CommentEnd********/
+PV_STATUS PV_VlcDecIntraDCPredSize(BitstreamDecVideo *stream, int compnum, uint *DC_size)
+{
+ PV_STATUS status = PV_FAIL; /* 07/09/01 */
+ uint code;
+
+ *DC_size = 0;
+ if (compnum < 4) /* luminance block */
+ {
+
+ BitstreamShowBits16(stream, 11, &code);
+
+ if (code == 1)
+ {
+ *DC_size = 12;
+ PV_BitstreamFlushBits(stream, 11);
+ return PV_SUCCESS;
+ }
+ code >>= 1;
+ if (code == 1)
+ {
+ *DC_size = 11;
+ PV_BitstreamFlushBits(stream, 10);
+ return PV_SUCCESS;
+ }
+ code >>= 1;
+ if (code == 1)
+ {
+ *DC_size = 10;
+ PV_BitstreamFlushBits(stream, 9);
+ return PV_SUCCESS;
+ }
+
+ code >>= 1;
+ if (code == 1)
+ {
+ *DC_size = 9;
+ PV_BitstreamFlushBits(stream, 8);
+ return PV_SUCCESS;
+ }
+
+ code >>= 1;
+ if (code == 1)
+ {
+ *DC_size = 8;
+ PV_BitstreamFlushBits(stream, 7);
+ return PV_SUCCESS;
+ }
+
+ code >>= 1;
+ if (code == 1)
+ {
+ *DC_size = 7;
+ PV_BitstreamFlushBits(stream, 6);
+ return PV_SUCCESS;
+ }
+
+ code >>= 1;
+ if (code == 1)
+ {
+ *DC_size = 6;
+ PV_BitstreamFlushBits(stream, 5);
+ return PV_SUCCESS;
+ }
+
+ code >>= 1;
+ if (code == 1)
+ {
+ *DC_size = 5;
+ PV_BitstreamFlushBits(stream, 4);
+ return PV_SUCCESS;
+ }
+
+ code >>= 1;
+ if (code == 1)
+ {
+ *DC_size = 4;
+ PV_BitstreamFlushBits(stream, 3);
+ return PV_SUCCESS;
+ }
+ else if (code == 2)
+ {
+ *DC_size = 3;
+ PV_BitstreamFlushBits(stream, 3);
+ return PV_SUCCESS;
+ }
+ else if (code == 3)
+ {
+ *DC_size = 0;
+ PV_BitstreamFlushBits(stream, 3);
+ return PV_SUCCESS;
+ }
+
+ code >>= 1;
+ if (code == 2)
+ {
+ *DC_size = 2;
+ PV_BitstreamFlushBits(stream, 2);
+ return PV_SUCCESS;
+ }
+ else if (code == 3)
+ {
+ *DC_size = 1;
+ PV_BitstreamFlushBits(stream, 2);
+ return PV_SUCCESS;
+ }
+ }
+ else /* chrominance block */
+ {
+
+ BitstreamShow13Bits(stream, &code);
+ code >>= 1;
+ if (code == 1)
+ {
+ *DC_size = 12;
+ PV_BitstreamFlushBits(stream, 12);
+ return PV_SUCCESS;
+ }
+
+ code >>= 1;
+ if (code == 1)
+ {
+ *DC_size = 11;
+ PV_BitstreamFlushBits(stream, 11);
+ return PV_SUCCESS;
+ }
+
+ code >>= 1;
+ if (code == 1)
+ {
+ *DC_size = 10;
+ PV_BitstreamFlushBits(stream, 10);
+ return PV_SUCCESS;
+ }
+
+ code >>= 1;
+ if (code == 1)
+ {
+ *DC_size = 9;
+ PV_BitstreamFlushBits(stream, 9);
+ return PV_SUCCESS;
+ }
+
+ code >>= 1;
+ if (code == 1)
+ {
+ *DC_size = 8;
+ PV_BitstreamFlushBits(stream, 8);
+ return PV_SUCCESS;
+ }
+
+ code >>= 1;
+ if (code == 1)
+ {
+ *DC_size = 7;
+ PV_BitstreamFlushBits(stream, 7);
+ return PV_SUCCESS;
+ }
+
+ code >>= 1;
+ if (code == 1)
+ {
+ *DC_size = 6;
+ PV_BitstreamFlushBits(stream, 6);
+ return PV_SUCCESS;
+ }
+
+ code >>= 1;
+ if (code == 1)
+ {
+ *DC_size = 5;
+ PV_BitstreamFlushBits(stream, 5);
+ return PV_SUCCESS;
+ }
+
+ code >>= 1;
+ if (code == 1)
+ {
+ *DC_size = 4;
+ PV_BitstreamFlushBits(stream, 4);
+ return PV_SUCCESS;
+ }
+
+ code >>= 1;
+ if (code == 1)
+ {
+ *DC_size = 3;
+ PV_BitstreamFlushBits(stream, 3);
+ return PV_SUCCESS;
+ }
+
+ code >>= 1;
+ {
+ *DC_size = (int)(3 - code);
+ PV_BitstreamFlushBits(stream, 2);
+ return PV_SUCCESS;
+ }
+ }
+
+ return status;
+}
+
+/***********************************************************CommentBegin******
+*
+*
+* 3/30/2000 : initial modification to the new PV-Decoder Lib
+* format and the change of error-handling method.
+*
+***********************************************************CommentEnd********/
+
+
+
+PV_STATUS VlcDecTCOEFIntra(BitstreamDecVideo *stream, Tcoef *pTcoef)
+{
+ uint code;
+ const VLCtab2 *tab;
+
+ BitstreamShow13Bits(stream, &code);
+
+ /* 10/17/2000, perform a little bit better on ARM by putting the whole function in VlcDecTCOEFFIntra */
+ /* if(GetTcoeffIntra(code,pTcoef,&tab,stream)!=PV_SUCCESS) return status;*/
+ if (code >= 1024)
+ {
+ tab = &PV_DCT3Dtab3[(code >> 6) - 16];
+ }
+ else
+ {
+ if (code >= 256)
+ {
+ tab = &PV_DCT3Dtab4[(code >> 3) - 32];
+ }
+ else
+ {
+ if (code >= 16)
+ {
+ tab = &PV_DCT3Dtab5[(code>>1) - 8];
+ }
+ else
+ {
+ return PV_FAIL;
+ }
+ }
+ }
+
+ PV_BitstreamFlushBits(stream, tab->len + 1);
+ pTcoef->sign = (code >> (12 - tab->len)) & 1;
+ pTcoef->run = (uint) tab->run; //(tab->val >> 8) & 255;
+ pTcoef->level = (int) tab->level; //tab->val & 255;
+ pTcoef->last = (uint) tab->last; //(tab->val >> 16) & 1;
+
+
+ /* the following is modified for 3-mode escape -- boon */
+ if (tab->level != 0xFF)
+ {
+ return PV_SUCCESS;
+ }
+
+ //if (((tab->run<<8)|(tab->level)|(tab->last<<16)) == VLC_ESCAPE_CODE)
+
+ if (!pTcoef->sign)
+ {
+ /* first escape mode. level is offset */
+ BitstreamShow13Bits(stream, &code);
+
+ /* 10/17/2000, perform a little bit better on ARM by putting the whole function in VlcDecTCOEFFIntra */
+ /* if(GetTcoeffIntra(code,pTcoef,&tab,stream)!=PV_SUCCESS) return status;*/
+ if (code >= 1024)
+ {
+ tab = &PV_DCT3Dtab3[(code >> 6) - 16];
+ }
+ else
+ {
+ if (code >= 256)
+ {
+ tab = &PV_DCT3Dtab4[(code >> 3) - 32];
+ }
+ else
+ {
+ if (code >= 16)
+ {
+ tab = &PV_DCT3Dtab5[(code>>1) - 8];
+ }
+ else
+ {
+ return PV_FAIL;
+ }
+ }
+ }
+
+ PV_BitstreamFlushBits(stream, tab->len + 1);
+
+ /* sign bit */
+ pTcoef->sign = (code >> (12 - tab->len)) & 1;
+ pTcoef->run = (uint)tab->run; //(tab->val >> 8) & 255;
+ pTcoef->level = (int)tab->level; //tab->val & 255;
+ pTcoef->last = (uint)tab->last; //(tab->val >> 16) & 1;
+
+
+ /* need to add back the max level */
+ if ((pTcoef->last == 0 && pTcoef->run > 14) || (pTcoef->last == 1 && pTcoef->run > 20))
+ {
+ return PV_FAIL;
+ }
+ pTcoef->level = pTcoef->level + intra_max_level[pTcoef->last][pTcoef->run];
+
+
+ }
+ else
+ {
+ uint run_offset;
+ run_offset = BitstreamRead1Bits_INLINE(stream);
+
+ if (!run_offset)
+ {
+ /* second escape mode. run is offset */
+ BitstreamShow13Bits(stream, &code);
+
+ /* 10/17/2000, perform a little bit better on ARM by putting the whole function in VlcDecTCOEFFIntra */
+ /* if(GetTcoeffIntra(code,pTcoef,&tab,stream)!=PV_SUCCESS) return status;*/
+ if (code >= 1024)
+ {
+ tab = &PV_DCT3Dtab3[(code >> 6) - 16];
+ }
+ else
+ {
+ if (code >= 256)
+ {
+ tab = &PV_DCT3Dtab4[(code >> 3) - 32];
+ }
+ else
+ {
+ if (code >= 16)
+ {
+ tab = &PV_DCT3Dtab5[(code>>1) - 8];
+ }
+ else
+ {
+ return PV_FAIL;
+ }
+ }
+ }
+
+ PV_BitstreamFlushBits(stream, tab->len + 1);
+ /* sign bit */
+ pTcoef->sign = (code >> (12 - tab->len)) & 1;
+ pTcoef->run = (uint)tab->run; //(tab->val >> 8) & 255;
+ pTcoef->level = (int)tab->level; //tab->val & 255;
+ pTcoef->last = (uint)tab->last; //(tab->val >> 16) & 1;
+
+
+
+ /* need to add back the max run */
+ if (pTcoef->last)
+ {
+ if (pTcoef->level > 8)
+ {
+ return PV_FAIL;
+ }
+ pTcoef->run = pTcoef->run + intra_max_run1[pTcoef->level] + 1;
+ }
+ else
+ {
+ if (pTcoef->level > 27)
+ {
+ return PV_FAIL;
+ }
+ pTcoef->run = pTcoef->run + intra_max_run0[pTcoef->level] + 1;
+ }
+
+
+ }
+ else
+ {
+
+ code = BitstreamReadBits16_INLINE(stream, 8);
+ pTcoef->last = code >> 7;
+ pTcoef->run = (code >> 1) & 0x3F;
+ pTcoef->level = (int)(BitstreamReadBits16_INLINE(stream, 13) >> 1);
+
+ if (pTcoef->level >= 2048)
+ {
+ pTcoef->sign = 1;
+ pTcoef->level = 4096 - pTcoef->level;
+ }
+ else
+ {
+ pTcoef->sign = 0;
+ }
+ } /* flc */
+ }
+
+ return PV_SUCCESS;
+
+} /* VlcDecTCOEFIntra */
+
+PV_STATUS VlcDecTCOEFInter(BitstreamDecVideo *stream, Tcoef *pTcoef)
+{
+ uint code;
+ const VLCtab2 *tab;
+
+ BitstreamShow13Bits(stream, &code);
+
+ /* 10/17/2000, perform a little bit better on ARM by putting the whole function in VlcDecTCOEFFInter */
+ /* if(GetTcoeffInter(code,pTcoef,&tab,stream)!=PV_SUCCESS) return status;*/
+ if (code >= 1024)
+ {
+ tab = &PV_DCT3Dtab0[(code >> 6) - 16];
+ }
+ else
+ {
+ if (code >= 256)
+ {
+ tab = &PV_DCT3Dtab1[(code >> 3) - 32];
+ }
+ else
+ {
+ if (code >= 16)
+ {
+ tab = &PV_DCT3Dtab2[(code>>1) - 8];
+ }
+ else
+ {
+ return PV_FAIL;
+ }
+ }
+ }
+ PV_BitstreamFlushBits(stream, tab->len + 1);
+ pTcoef->sign = (code >> (12 - tab->len)) & 1;
+ pTcoef->run = (uint)tab->run; //(tab->val >> 4) & 255;
+ pTcoef->level = (int)tab->level; //tab->val & 15;
+ pTcoef->last = (uint)tab->last; //(tab->val >> 12) & 1;
+
+ /* the following is modified for 3-mode escape -- boon */
+ if (tab->run != 0xBF)
+ {
+ return PV_SUCCESS;
+ }
+ //if (((tab->run<<4)|(tab->level)|(tab->last<<12)) == VLC_ESCAPE_CODE)
+
+
+ if (!pTcoef->sign)
+ {
+ /* first escape mode. level is offset */
+ BitstreamShow13Bits(stream, &code);
+
+ /* 10/17/2000, perform a little bit better on ARM by putting the whole function in VlcDecTCOEFFInter */
+ /* if(GetTcoeffInter(code,pTcoef,&tab,stream)!=PV_SUCCESS) return status;*/
+ if (code >= 1024)
+ {
+ tab = &PV_DCT3Dtab0[(code >> 6) - 16];
+ }
+ else
+ {
+ if (code >= 256)
+ {
+ tab = &PV_DCT3Dtab1[(code >> 3) - 32];
+ }
+ else
+ {
+ if (code >= 16)
+ {
+ tab = &PV_DCT3Dtab2[(code>>1) - 8];
+ }
+ else
+ {
+ return PV_FAIL;
+ }
+ }
+ }
+ PV_BitstreamFlushBits(stream, tab->len + 1);
+ pTcoef->sign = (code >> (12 - tab->len)) & 1;
+ pTcoef->run = (uint)tab->run; //(tab->val >> 4) & 255;
+ pTcoef->level = (int)tab->level; //tab->val & 15;
+ pTcoef->last = (uint)tab->last; //(tab->val >> 12) & 1;
+
+ /* need to add back the max level */
+ if ((pTcoef->last == 0 && pTcoef->run > 26) || (pTcoef->last == 1 && pTcoef->run > 40))
+ {
+ return PV_FAIL;
+ }
+ pTcoef->level = pTcoef->level + inter_max_level[pTcoef->last][pTcoef->run];
+ }
+ else
+ {
+ uint run_offset;
+ run_offset = BitstreamRead1Bits_INLINE(stream);
+
+ if (!run_offset)
+ {
+ /* second escape mode. run is offset */
+ BitstreamShow13Bits(stream, &code);
+
+ /* 10/17/2000, perform a little bit better on ARM by putting the whole function in VlcDecTCOEFFInter */
+ /*if(GetTcoeffInter(code,pTcoef,&tab,stream)!=PV_SUCCESS) return status;*/
+ if (code >= 1024)
+ {
+ tab = &PV_DCT3Dtab0[(code >> 6) - 16];
+ }
+ else
+ {
+ if (code >= 256)
+ {
+ tab = &PV_DCT3Dtab1[(code >> 3) - 32];
+ }
+ else
+ {
+ if (code >= 16)
+ {
+ tab = &PV_DCT3Dtab2[(code>>1) - 8];
+ }
+ else
+ {
+ return PV_FAIL;
+ }
+ }
+ }
+ PV_BitstreamFlushBits(stream, tab->len + 1);
+ pTcoef->sign = (code >> (12 - tab->len)) & 1;
+ pTcoef->run = (uint)tab->run; //(tab->val >> 4) & 255;
+ pTcoef->level = (int)tab->level; //tab->val & 15;
+ pTcoef->last = (uint)tab->last; //(tab->val >> 12) & 1;
+
+ /* need to add back the max run */
+ if (pTcoef->last)
+ {
+ if (pTcoef->level > 3)
+ {
+ return PV_FAIL;
+ }
+ pTcoef->run = pTcoef->run + inter_max_run1[pTcoef->level] + 1;
+ }
+ else
+ {
+ if (pTcoef->level > 12)
+ {
+ return PV_FAIL;
+ }
+ pTcoef->run = pTcoef->run + inter_max_run0[pTcoef->level] + 1;
+ }
+ }
+ else
+ {
+
+ code = BitstreamReadBits16_INLINE(stream, 8);
+ pTcoef->last = code >> 7;
+ pTcoef->run = (code >> 1) & 0x3F;
+ pTcoef->level = (int)(BitstreamReadBits16_INLINE(stream, 13) >> 1);
+
+
+
+ if (pTcoef->level >= 2048)
+ {
+ pTcoef->sign = 1;
+ pTcoef->level = 4096 - pTcoef->level;
+ }
+ else
+ {
+ pTcoef->sign = 0;
+ }
+ } /* flc */
+ }
+
+ return PV_SUCCESS;
+
+} /* VlcDecTCOEFInter */
+
+/*=======================================================
+ Function: VlcDecTCOEFShortHeader()
+ Date : 04/27/99
+ Purpose : New function used in decoding of video planes
+ with short header
+ Modified: 05/23/2000
+ for new decoder structure.
+=========================================================*/
+PV_STATUS VlcDecTCOEFShortHeader(BitstreamDecVideo *stream, Tcoef *pTcoef/*, int intra*/)
+{
+ uint code;
+ const VLCtab2 *tab;
+
+ BitstreamShow13Bits(stream, &code);
+
+ /*intra = 0;*/
+
+ if (code >= 1024) tab = &PV_DCT3Dtab0[(code >> 6) - 16];
+ else
+ {
+ if (code >= 256) tab = &PV_DCT3Dtab1[(code >> 3) - 32];
+ else
+ {
+ if (code >= 16) tab = &PV_DCT3Dtab2[(code>>1) - 8];
+ else return PV_FAIL;
+ }
+ }
+
+ PV_BitstreamFlushBits(stream, tab->len + 1);
+ pTcoef->sign = (code >> (12 - tab->len)) & 1;
+ pTcoef->run = (uint)tab->run;//(tab->val >> 4) & 255;
+ pTcoef->level = (int)tab->level;//tab->val & 15;
+ pTcoef->last = (uint)tab->last;//(tab->val >> 12) & 1;
+
+ /* the following is modified for 3-mode escape -- boon */
+ if (((tab->run << 4) | (tab->level) | (tab->last << 12)) != VLC_ESCAPE_CODE) /* ESCAPE */
+ {
+ return PV_SUCCESS;
+ }
+
+
+ /* escape mode 4 - H.263 type */
+ pTcoef->last = pTcoef->sign; /* Last */
+ pTcoef->run = BitstreamReadBits16_INLINE(stream, 6); /* Run */
+ pTcoef->level = (int) BitstreamReadBits16_INLINE(stream, 8); /* Level */
+
+ if (pTcoef->level == 0 || pTcoef->level == 128)
+ {
+ return PV_FAIL;
+ }
+
+ if (pTcoef->level > 128)
+ {
+ pTcoef->sign = 1;
+ pTcoef->level = 256 - pTcoef->level;
+ }
+ else
+ {
+ pTcoef->sign = 0;
+ }
+
+
+
+ return PV_SUCCESS;
+
+} /* VlcDecTCOEFShortHeader */
+
+#ifdef PV_ANNEX_IJKT_SUPPORT
+PV_STATUS VlcDecTCOEFShortHeader_AnnexI(BitstreamDecVideo *stream, Tcoef *pTcoef/*, int intra*/)
+{
+ uint code;
+ const VLCtab2 *tab;
+
+ BitstreamShow13Bits(stream, &code);
+
+ /*intra = 0;*/
+
+ if (code >= 1024) tab = &PV_DCT3Dtab6[(code >> 6) - 16];
+ else
+ {
+ if (code >= 256) tab = &PV_DCT3Dtab7[(code >> 3) - 32];
+ else
+ {
+ if (code >= 16) tab = &PV_DCT3Dtab8[(code>>1) - 8];
+ else return PV_FAIL;
+ }
+ }
+
+ PV_BitstreamFlushBits(stream, tab->len + 1);
+ pTcoef->sign = (code >> (12 - tab->len)) & 1;
+ pTcoef->run = (uint)tab->run;//(tab->val >> 4) & 255;
+ pTcoef->level = (int)tab->level;//tab->val & 15;
+ pTcoef->last = (uint)tab->last;//(tab->val >> 12) & 1;
+
+ /* the following is modified for 3-mode escape -- boon */
+ if (((tab->run << 6) | (tab->level) | (tab->last << 12)) != VLC_ESCAPE_CODE) /* ESCAPE */
+ {
+ return PV_SUCCESS;
+ }
+ /* escape mode 4 - H.263 type */
+ pTcoef->last = pTcoef->sign; /* Last */
+ pTcoef->run = BitstreamReadBits16(stream, 6); /* Run */
+ pTcoef->level = (int) BitstreamReadBits16(stream, 8); /* Level */
+
+ if (pTcoef->level == 0 || pTcoef->level == 128)
+ {
+ return PV_FAIL;
+ }
+
+
+ if (pTcoef->level > 128)
+ {
+ pTcoef->sign = 1;
+ pTcoef->level = 256 - pTcoef->level;
+ }
+ else pTcoef->sign = 0;
+
+
+
+ return PV_SUCCESS;
+
+} /* VlcDecTCOEFShortHeader_AnnexI */
+
+PV_STATUS VlcDecTCOEFShortHeader_AnnexT(BitstreamDecVideo *stream, Tcoef *pTcoef/*, int intra*/)
+{
+ uint code;
+ const VLCtab2 *tab;
+
+ BitstreamShow13Bits(stream, &code);
+
+ /*intra = 0;*/
+
+ if (code >= 1024) tab = &PV_DCT3Dtab0[(code >> 6) - 16];
+ else
+ {
+ if (code >= 256) tab = &PV_DCT3Dtab1[(code >> 3) - 32];
+ else
+ {
+ if (code >= 16) tab = &PV_DCT3Dtab2[(code>>1) - 8];
+ else return PV_FAIL;
+ }
+ }
+
+ PV_BitstreamFlushBits(stream, tab->len + 1);
+ pTcoef->sign = (code >> (12 - tab->len)) & 1;
+ pTcoef->run = (uint)tab->run;//(tab->val >> 4) & 255;
+ pTcoef->level = (int)tab->level;//tab->val & 15;
+ pTcoef->last = (uint)tab->last;//(tab->val >> 12) & 1;
+
+ /* the following is modified for 3-mode escape -- */
+ if (((tab->run << 4) | (tab->level) | (tab->last << 12)) != VLC_ESCAPE_CODE) /* ESCAPE */
+ {
+ return PV_SUCCESS;
+ }
+ /* escape mode 4 - H.263 type */
+ pTcoef->last = pTcoef->sign; /* Last */
+ pTcoef->run = BitstreamReadBits16(stream, 6); /* Run */
+ pTcoef->level = (int) BitstreamReadBits16(stream, 8); /* Level */
+
+ if (pTcoef->level == 0)
+ {
+ return PV_FAIL;
+ }
+
+ if (pTcoef->level >= 128)
+ {
+ pTcoef->sign = 1;
+ pTcoef->level = 256 - pTcoef->level;
+ }
+ else
+ {
+ pTcoef->sign = 0;
+ }
+
+ if (pTcoef->level == 128)
+ {
+ code = BitstreamReadBits16(stream, 11); /* ANNEX_T */
+
+ code = (code >> 6 & 0x1F) | (code << 5 & 0x7ff);
+ if (code > 1024)
+ {
+ pTcoef->sign = 1;
+ pTcoef->level = (2048 - code);
+ }
+ else
+ {
+ pTcoef->sign = 0;
+ pTcoef->level = code;
+ }
+ }
+
+ return PV_SUCCESS;
+
+} /* VlcDecTCOEFShortHeader */
+
+
+PV_STATUS VlcDecTCOEFShortHeader_AnnexIT(BitstreamDecVideo *stream, Tcoef *pTcoef/*, int intra*/)
+{
+ uint code;
+ const VLCtab2 *tab;
+
+ BitstreamShow13Bits(stream, &code);
+
+ /*intra = 0;*/
+
+ if (code >= 1024) tab = &PV_DCT3Dtab6[(code >> 6) - 16];
+ else
+ {
+ if (code >= 256) tab = &PV_DCT3Dtab7[(code >> 3) - 32];
+ else
+ {
+ if (code >= 16) tab = &PV_DCT3Dtab8[(code>>1) - 8];
+ else return PV_FAIL;
+ }
+ }
+
+ PV_BitstreamFlushBits(stream, tab->len + 1);
+ pTcoef->sign = (code >> (12 - tab->len)) & 1;
+ pTcoef->run = (uint)tab->run;//(tab->val >> 4) & 255;
+ pTcoef->level = (int)tab->level;//tab->val & 15;
+ pTcoef->last = (uint)tab->last;//(tab->val >> 12) & 1;
+
+ /* the following is modified for 3-mode escape -- */
+ if (((tab->run << 6) | (tab->level) | (tab->last << 12)) != VLC_ESCAPE_CODE) /* ESCAPE */
+ {
+ return PV_SUCCESS;
+ }
+ /* escape mode 4 - H.263 type */
+ pTcoef->last = pTcoef->sign; /* Last */
+ pTcoef->run = BitstreamReadBits16(stream, 6); /* Run */
+ pTcoef->level = (int) BitstreamReadBits16(stream, 8); /* Level */
+
+ if (pTcoef->level == 0)
+ {
+ return PV_FAIL;
+ }
+
+ if (pTcoef->level >= 128)
+ {
+ pTcoef->sign = 1;
+ pTcoef->level = 256 - pTcoef->level;
+ }
+ else
+ {
+ pTcoef->sign = 0;
+ }
+
+ if (pTcoef->level == 128)
+ {
+ code = BitstreamReadBits16(stream, 11); /* ANNEX_T */
+
+ code = (code >> 6 & 0x1F) | (code << 5 & 0x7ff);
+ if (code > 1024)
+ {
+ pTcoef->sign = 1;
+ pTcoef->level = (2048 - code);
+ }
+ else
+ {
+ pTcoef->sign = 0;
+ pTcoef->level = code;
+ }
+ }
+
+
+ return PV_SUCCESS;
+
+} /* VlcDecTCOEFShortHeader_AnnexI */
+#endif
+/***********************************************************CommentBegin******
+* 3/30/2000 : initial modification to the new PV-Decoder Lib
+* format and the change of error-handling method.
+* The coefficient is now returned thru a pre-
+* initialized parameters for speedup.
+*
+***********************************************************CommentEnd********/
+
+
+PV_STATUS RvlcDecTCOEFInter(BitstreamDecVideo *stream, Tcoef *pTcoef)
+{
+ uint code, mask;
+ const VLCtab2 *tab2;
+ int count, len, num[2] = {0, 0} /* 01/30/01 */;
+
+ mask = 0x4000; /* mask 100000000000000 */
+ BitstreamShow15Bits(stream, &code); /* 03/07/01 */
+
+ len = 1;
+
+ // 09/20/99 Escape mode
+ /// Bitstream Exchange
+ if (code < 2048)
+ {
+ PV_BitstreamFlushBits(stream, 5);
+ pTcoef->last = BitstreamRead1Bits_INLINE(stream);
+ pTcoef->run = BitstreamReadBits16_INLINE(stream, 6);
+ // 09/20/99 New marker bit
+ PV_BitstreamFlushBits(stream, 1);
+ // 09/20/99 The length for LEVEL used to be 7 in the old version
+ pTcoef->level = (int)(BitstreamReadBits16_INLINE(stream, 12) >> 1);
+ // 09/20/99 Another new marker bit
+// PV_BitstreamFlushBitsCheck(stream, 1);
+ pTcoef->sign = BitstreamReadBits16_INLINE(stream, 5) & 0x1; /* fix 3/13/01 */
+ return PV_SUCCESS;
+ }
+
+ if (code & mask)
+ {
+ count = 1;
+ while (mask && count > 0) /* fix 3/28/01 */
+ {
+ mask = mask >> 1;
+ if (code & mask)
+ count--;
+ else
+ num[0]++; /* number of zeros in the middle */
+ len++;
+ }
+ }
+ else
+ {
+ count = 2;
+ while (mask && count > 0) /* fix 3/28/01 */
+ {
+ mask = mask >> 1;
+ if (!(code & mask))
+ count--;
+ else
+ num[count-1]++; /* number of ones in the middle */
+ len++;
+ }
+ }
+
+ code = code & 0x7fff;
+ code = code >> (15 - (len + 1));
+
+ /* 1/30/01, add fast decoding algorithm here */
+ /* code is in two forms : 0xxxx0xxx00 or 0xxx0xxx01
+ num[1] and num[0] x
+ or : 1xxxxx10 or 1xxxxx11
+ num[0] x */
+
+ /* len+1 is the length of the above */
+
+ if (num[1] > 10 || num[0] > 11) /* invalid RVLC code */
+ return PV_FAIL;
+
+ if (code&(1 << len))
+ tab2 = RvlcDCTtabInter + 146 + (num[0] << 1) + (code & 1);
+ else
+ tab2 = RvlcDCTtabInter + ptrRvlcTab[num[1]] + (num[0] << 1) + (code & 1);
+
+ PV_BitstreamFlushBits(stream, (int) tab2->len);
+ pTcoef->run = (uint)tab2->run;//(tab->val >> 8) & 255;
+ pTcoef->level = (int)tab2->level;//tab->val & 255;
+ pTcoef->last = (uint)tab2->last;//(tab->val >> 16) & 1;
+
+ pTcoef->sign = BitstreamRead1Bits_INLINE(stream);
+ return PV_SUCCESS;
+} /* RvlcDecTCOEFInter */
+
+PV_STATUS RvlcDecTCOEFIntra(BitstreamDecVideo *stream, Tcoef *pTcoef)
+{
+ uint code, mask;
+ const VLCtab2 *tab2;
+ int count, len, num[2] = {0, 0} /* 01/30/01 */;
+
+ mask = 0x4000; /* mask 100000000000000 */
+ BitstreamShow15Bits(stream, &code);
+
+ len = 1;
+
+ // 09/20/99 Escape mode
+ /// Bitstream Exchange
+ if (code < 2048)
+ {
+ PV_BitstreamFlushBits(stream, 5);
+ pTcoef->last = BitstreamRead1Bits_INLINE(stream);
+ pTcoef->run = BitstreamReadBits16_INLINE(stream, 6);
+ // 09/20/99 New marker bit
+ PV_BitstreamFlushBits(stream, 1);
+ // 09/20/99 The length for LEVEL used to be 7 in the old version
+ pTcoef->level = (int)(BitstreamReadBits16_INLINE(stream, 12) >> 1);
+ // 09/20/99 Another new marker bit
+// PV_BitstreamFlushBitsCheck(stream, 1);
+ pTcoef->sign = BitstreamReadBits16_INLINE(stream, 5) & 0x1; /* fix 03/13/01 */
+ return PV_SUCCESS;
+ }
+
+ if (code & mask)
+ {
+ count = 1;
+ while (mask && count > 0) /* fix 03/28/01 */
+ {
+ mask = mask >> 1;
+ if (code & mask)
+ count--;
+ else
+ num[0]++; /* number of zeros in the middle */
+ len++;
+ }
+ }
+ else
+ {
+ count = 2;
+ while (mask && count > 0) /* fix 03/28/01 */
+ {
+ mask = mask >> 1;
+ if (!(code & mask))
+ count--;
+ else
+ num[count-1]++; /* number of ones in the middle */
+ len++;
+ }
+ }
+
+ code = code & 0x7fff;
+ code = code >> (15 - (len + 1));
+
+ /* 1/30/01, add fast decoding algorithm here */
+ /* code is in two forms : 0xxxx0xxx00 or 0xxx0xxx01
+ num[1] and num[0] x
+ or : 1xxxxx10 or 1xxxxx11
+ num[0] x */
+
+ /* len+1 is the length of the above */
+
+ if (num[1] > 10 || num[0] > 11) /* invalid RVLC code */
+ return PV_FAIL;
+
+ if (code & (1 << len))
+ tab2 = RvlcDCTtabIntra + 146 + (num[0] << 1) + (code & 1);
+ else
+ tab2 = RvlcDCTtabIntra + ptrRvlcTab[num[1]] + (num[0] << 1) + (code & 1);
+
+ PV_BitstreamFlushBits(stream, (int) tab2->len);
+ pTcoef->run = (uint)tab2->run;//(tab->val >> 8) & 255;
+ pTcoef->level = (int)tab2->level;//tab->val & 255;
+ pTcoef->last = (uint)tab2->last;//(tab->val >> 16) & 1;
+
+ pTcoef->sign = BitstreamRead1Bits_INLINE(stream);
+ return PV_SUCCESS;
+} /* RvlcDecTCOEFIntra */
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.h b/media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.h
new file mode 100644
index 0000000..a804606
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/vlc_decode.h
@@ -0,0 +1,122 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+/*
+-------------------------------------------------------------------
+ MPEG-4 Simple Profile Video Decoder
+-------------------------------------------------------------------
+*
+* This software module was originally developed by
+*
+* Paulo Nunes (IST / ACTS-MoMuSyS)
+*
+* in the course of development of the MPEG-4 Video (ISO/IEC 14496-2) standard.
+* This software module is an implementation of a part of one or more MPEG-4
+* Video (ISO/IEC 14496-2) tools as specified by the MPEG-4 Video (ISO/IEC
+* 14496-2) standard.
+*
+* ISO/IEC gives users of the MPEG-4 Video (ISO/IEC 14496-2) standard free
+* license to this software module or modifications thereof for use in hardware
+* or software products claiming conformance to the MPEG-4 Video (ISO/IEC
+* 14496-2) standard.
+*
+* Those intending to use this software module in hardware or software products
+* are advised that its use may infringe existing patents. The original
+* developer of this software module and his/her company, the subsequent
+* editors and their companies, and ISO/IEC have no liability for use of this
+* software module or modifications thereof in an implementation. Copyright is
+* not released for non MPEG-4 Video (ISO/IEC 14496-2) Standard conforming
+* products.
+*
+* ACTS-MoMuSys partners retain full right to use the code for his/her own
+* purpose, assign or donate the code to a third party and to inhibit third
+* parties from using the code for non MPEG-4 Video (ISO/IEC 14496-2) Standard
+* conforming products. This copyright notice must be included in all copies or
+* derivative works.
+*
+* Copyright (c) 1996
+*
+*****************************************************************************/
+
+/***********************************************************HeaderBegin*******
+*
+* File: vlc_dec.h
+*
+* Author: Paulo Nunes (IST) - Paulo.Nunes@lx.it.pt
+* Created:
+*
+* Description: This is the header file for the "vlcdec" module.
+*
+* Notes:
+*
+* Modified: 9-May-96 Paulo Nunes: Reformatted. New headers.
+*
+* ================= PacketVideo Modification ================================
+*
+* 3/30/00 : initial modification to the
+* new PV-Decoder Lib format.
+*
+***********************************************************CommentEnd********/
+
+
+#ifndef _VLCDECODE_H_
+#define _VLCDECODE_H_
+
+#include "mp4lib_int.h"
+
+#define VLC_ERROR_DETECTED(x) ((x) < 0)
+#define VLC_IO_ERROR -1
+#define VLC_CODE_ERROR -2
+#define VLC_MB_STUFFING -4
+#define VLC_NO_LAST_BIT -5
+
+#define VLC_ESCAPE_CODE 7167
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+ PV_STATUS DecodeUserData(BitstreamDecVideo *stream);
+ PV_STATUS PV_GetMBvectors(VideoDecData *, uint mode);
+ PV_STATUS PV_DecodeMBVec(BitstreamDecVideo *stream, MOT *mv_x, MOT *mv_y, int f_code_f);
+ PV_STATUS PV_DeScaleMVD(int f_code, int residual, int vlc_code_mag, MOT *vector);
+
+ PV_STATUS PV_VlcDecMV(BitstreamDecVideo *stream, int *mv);
+ int PV_VlcDecMCBPC_com_intra(BitstreamDecVideo *stream);
+ int PV_VlcDecMCBPC_com_inter(BitstreamDecVideo *stream);
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ int PV_VlcDecMCBPC_com_inter_H263(BitstreamDecVideo *stream);
+ PV_STATUS VlcDecTCOEFShortHeader_AnnexI(BitstreamDecVideo *stream, Tcoef *pTcoef);
+ PV_STATUS VlcDecTCOEFShortHeader_AnnexT(BitstreamDecVideo *stream, Tcoef *pTcoef); /* ANNEX_T */
+ PV_STATUS VlcDecTCOEFShortHeader_AnnexIT(BitstreamDecVideo *stream, Tcoef *pTcoef);
+#endif
+ int PV_VlcDecCBPY(BitstreamDecVideo *stream, int intra);
+
+ PV_STATUS VlcDecTCOEFIntra(BitstreamDecVideo *stream, Tcoef *pTcoef);
+ PV_STATUS VlcDecTCOEFInter(BitstreamDecVideo *stream, Tcoef *pTcoef);
+ PV_STATUS VlcDecTCOEFShortHeader(BitstreamDecVideo *stream, Tcoef *pTcoef);
+ PV_STATUS RvlcDecTCOEFIntra(BitstreamDecVideo *stream, Tcoef *pTcoef);
+ PV_STATUS RvlcDecTCOEFInter(BitstreamDecVideo *stream, Tcoef *pTcoef);
+ PV_STATUS PV_VlcDecIntraDCPredSize(BitstreamDecVideo *stream, int compnum, uint *DC_size);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vlc_dequant.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/vlc_dequant.cpp
new file mode 100644
index 0000000..db13a48
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/vlc_dequant.cpp
@@ -0,0 +1,1152 @@
+/* ------------------------------------------------------------------
+ * 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 "mp4dec_lib.h"
+#include "vlc_decode.h"
+#include "zigzag.h"
+
+
+typedef PV_STATUS(*VlcDecFuncP)(BitstreamDecVideo *stream, Tcoef *pTcoef);
+static const uint8 AC_rowcol[64] = { 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ };
+static const uint8 mask[8] = /* for fast bitmap */
+ {128, 64, 32, 16, 8, 4, 2, 1};
+
+
+
+/***********************************************************CommentBegin******
+*
+* -- VlcDequantMpegBlock -- Decodes the DCT coefficients of one 8x8 block and perform
+ dequantization using Mpeg mode.
+ Date: 08/08/2000
+
+ Modified: 3/21/01
+ Added pre IDCT clipping, new ACDC prediction structure, ACDC prediction clipping,
+ 16-bit int case, removed multiple zigzaging
+******************************************************************************/
+
+#ifdef PV_SUPPORT_MAIN_PROFILE
+int VlcDequantMpegIntraBlock(void *vid, int comp, int switched,
+ uint8 *bitmapcol, uint8 *bitmaprow)
+{
+ VideoDecData *video = (VideoDecData*) vid;
+ Vol *currVol = video->vol[video->currLayer];
+ BitstreamDecVideo *stream = video->bitstream;
+ int16 *datablock = video->mblock->block[comp]; /* 10/20/2000, assume it has been reset of all-zero !!!*/
+ int mbnum = video->mbnum;
+ uint CBP = video->headerInfo.CBP[mbnum];
+ int QP = video->QPMB[mbnum];
+ typeDCStore *DC = video->predDC + mbnum;
+ int x_pos = video->mbnum_col;
+ typeDCACStore *DCAC_row = video->predDCAC_row + x_pos;
+ typeDCACStore *DCAC_col = video->predDCAC_col;
+ uint ACpred_flag = (uint) video->acPredFlag[mbnum];
+
+ /*** VLC *****/
+ int i, j, k;
+ Tcoef run_level;
+ int last, return_status;
+ VlcDecFuncP vlcDecCoeff;
+ int direction;
+ const int *inv_zigzag;
+ /*** Quantizer ****/
+ int dc_scaler;
+ int sum;
+ int *qmat;
+ int32 temp;
+
+ const int B_Xtab[6] = {0, 1, 0, 1, 2, 3};
+ const int B_Ytab[6] = {0, 0, 1, 1, 2, 3};
+
+ int16 *dcac_row, *dcac_col;
+
+ dcac_row = (*DCAC_row)[B_Xtab[comp]];
+ dcac_col = (*DCAC_col)[B_Ytab[comp]];
+
+
+ i = 1 - switched;
+
+#ifdef FAST_IDCT
+ *((uint32*)bitmapcol) = *((uint32*)(bitmapcol + 4)) = 0;
+ *bitmaprow = 0;
+#endif
+
+
+ /* select which Huffman table to be used */
+ vlcDecCoeff = video->vlcDecCoeffIntra;
+
+ dc_scaler = (comp < 4) ? video->mblock->DCScalarLum : video->mblock->DCScalarChr;
+
+ /* enter the zero run decoding loop */
+ sum = 0;
+ qmat = currVol->iqmat;
+
+ /* perform only VLC decoding */
+ /* We cannot do DCACrecon before VLC decoding. 10/17/2000 */
+ doDCACPrediction(video, comp, datablock, &direction);
+ if (!ACpred_flag) direction = 0;
+ inv_zigzag = zigzag_inv + (ACpred_flag << 6) + (direction << 6);
+ if (CBP & (1 << (5 - comp)))
+ {
+ do
+ {
+ return_status = (*vlcDecCoeff)(stream, &run_level);
+ if (return_status != PV_SUCCESS)
+ {
+ last = 1;/* 11/1/2000 let it slips undetected, just like
+ in original version */
+ i = VLC_ERROR;
+ ACpred_flag = 0; /* no of coefficients should not get reset 03/07/2002 */
+ break;
+ }
+
+ i += run_level.run;
+ last = run_level.last;
+ if (i >= 64)
+ {
+ /* i = NCOEFF_BLOCK; */ /* 11/1/00 */
+ ACpred_flag = 0; /* no of coefficients should not get reset 03/07/2002 */
+ i = VLC_NO_LAST_BIT;
+ last = 1;
+ break;
+ }
+
+ k = inv_zigzag[i];
+
+ if (run_level.sign == 1)
+ {
+ datablock[k] -= run_level.level;
+ }
+ else
+ {
+ datablock[k] += run_level.level;
+ }
+
+ if (AC_rowcol[k])
+ {
+ temp = (int32)datablock[k] * qmat[k] * QP;
+ temp = (temp + (0x7 & (temp >> 31))) >> 3;
+ if (temp > 2047) temp = 2047;
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int) temp;
+
+#ifdef FAST_IDCT
+ bitmapcol[k&0x7] |= mask[k>>3];
+#endif
+ sum ^= temp;
+ }
+
+ i++;
+ }
+ while (!last);
+
+ }
+ else
+ {
+ i = 1; /* 04/26/01 needed for switched case */
+ }
+ ///// NEED TO DEQUANT THOSE PREDICTED AC COEFF
+ /* dequantize the rest of AC predicted coeff that haven't been dequant */
+ if (ACpred_flag)
+ {
+
+ i = NCOEFF_BLOCK; /* otherwise, FAST IDCT won't work correctly, 10/18/2000 */
+
+ if (!direction) /* check vertical */
+ {
+ dcac_row[0] = datablock[1];
+ dcac_row[1] = datablock[2];
+ dcac_row[2] = datablock[3];
+ dcac_row[3] = datablock[4];
+ dcac_row[4] = datablock[5];
+ dcac_row[5] = datablock[6];
+ dcac_row[6] = datablock[7];
+
+ for (j = 0, k = 8; k < 64; k += 8, j++)
+ {
+ if (dcac_col[j] = datablock[k])
+ { /* ACDC clipping 03/26/01 */
+ if (datablock[k] > 2047) dcac_col[j] = 2047;
+ else if (datablock[k] < -2048) dcac_col[j] = -2048;
+
+ temp = (int32)dcac_col[j] * qmat[k] * QP;
+ temp = (temp + (0x7 & (temp >> 31))) >> 3; /* 03/26/01*/
+ if (temp > 2047) temp = 2047;
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int)temp;
+ sum ^= temp; /* 7/5/01 */
+#ifdef FAST_IDCT
+ bitmapcol[0] |= mask[k>>3];
+#endif
+
+ }
+ }
+ for (k = 1; k < 8; k++)
+ {
+ if (datablock[k])
+ {
+ temp = (int32)datablock[k] * qmat[k] * QP;
+ temp = (temp + (0x7 & (temp >> 31))) >> 3; /* 03/26/01*/
+ if (temp > 2047) temp = 2047;
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int)temp;
+ sum ^= temp; /* 7/5/01 */
+#ifdef FAST_IDCT
+ bitmapcol[k] |= 128;
+#endif
+
+ }
+ }
+
+ }
+ else
+ {
+
+ dcac_col[0] = datablock[8];
+ dcac_col[1] = datablock[16];
+ dcac_col[2] = datablock[24];
+ dcac_col[3] = datablock[32];
+ dcac_col[4] = datablock[40];
+ dcac_col[5] = datablock[48];
+ dcac_col[6] = datablock[56];
+
+
+ for (j = 0, k = 1; k < 8; k++, j++)
+ {
+ if (dcac_row[j] = datablock[k])
+ { /* ACDC clipping 03/26/01 */
+ if (datablock[k] > 2047) dcac_row[j] = 2047;
+ else if (datablock[k] < -2048) dcac_row[j] = -2048;
+
+ temp = (int32)dcac_row[j] * qmat[k] * QP;
+ temp = (temp + (0x7 & (temp >> 31))) >> 3; /* 03/26/01 */
+ if (temp > 2047) temp = 2047;
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int)temp;
+ sum ^= temp;
+#ifdef FAST_IDCT
+ bitmapcol[k] |= 128;
+#endif
+
+ }
+ }
+
+ for (k = 8; k < 64; k += 8)
+ {
+ if (datablock[k])
+ {
+ temp = (int32)datablock[k] * qmat[k] * QP;
+ temp = (temp + (0x7 & (temp >> 31))) >> 3; /* 03/26/01 */
+ if (temp > 2047) temp = 2047;
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int)temp;
+ sum ^= temp;
+#ifdef FAST_IDCT
+ bitmapcol[0] |= mask[k>>3];
+#endif
+ }
+ }
+
+ }
+ }
+ else
+ {
+
+ /* Store the qcoeff-values needed later for prediction */
+
+ dcac_row[0] = datablock[1]; /* ACDC, no need for clipping */
+ dcac_row[1] = datablock[2];
+ dcac_row[2] = datablock[3];
+ dcac_row[3] = datablock[4];
+ dcac_row[4] = datablock[5];
+ dcac_row[5] = datablock[6];
+ dcac_row[6] = datablock[7];
+
+ dcac_col[0] = datablock[8];
+ dcac_col[1] = datablock[16];
+ dcac_col[2] = datablock[24];
+ dcac_col[3] = datablock[32];
+ dcac_col[4] = datablock[40];
+ dcac_col[5] = datablock[48];
+ dcac_col[6] = datablock[56];
+
+ for (k = 1; k < 8; k++)
+ {
+ if (datablock[k])
+ {
+ temp = (int32)datablock[k] * qmat[k] * QP;
+ temp = (temp + (0x7 & (temp >> 31))) >> 3; /* 03/26/01*/
+ if (temp > 2047) temp = 2047;
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int)temp;
+ sum ^= temp; /* 7/5/01 */
+#ifdef FAST_IDCT
+ bitmapcol[k] |= 128;
+#endif
+
+ }
+ }
+ for (k = 8; k < 64; k += 8)
+ {
+ if (datablock[k])
+ {
+ temp = (int32)datablock[k] * qmat[k] * QP;
+ temp = (temp + (0x7 & (temp >> 31))) >> 3; /* 03/26/01 */
+ if (temp > 2047) temp = 2047;
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int)temp;
+ sum ^= temp;
+#ifdef FAST_IDCT
+ bitmapcol[0] |= mask[k>>3];
+#endif
+ }
+ }
+
+ }
+
+
+
+ if (datablock[0])
+ {
+ temp = (int32)datablock[0] * dc_scaler;
+ if (temp > 2047) temp = 2047; /* 03/14/01 */
+ else if (temp < -2048) temp = -2048;
+ datablock[0] = (int)temp;
+ sum ^= temp;
+#ifdef FAST_IDCT
+ bitmapcol[0] |= 128;
+#endif
+ }
+
+ if ((sum & 1) == 0)
+ {
+ datablock[63] = datablock[63] ^ 0x1;
+#ifdef FAST_IDCT /* 7/5/01, need to update bitmap */
+ if (datablock[63])
+ bitmapcol[7] |= 1;
+#endif
+ i = (-64 & i) | NCOEFF_BLOCK; /* if i > -1 then i is set to NCOEFF_BLOCK */
+ }
+
+
+#ifdef FAST_IDCT
+ if (i > 10)
+ {
+ for (k = 1; k < 4; k++)
+ {
+ if (bitmapcol[k] != 0)
+ {
+ (*bitmaprow) |= mask[k];
+ }
+ }
+ }
+#endif
+
+ /* Store the qcoeff-values needed later for prediction */
+ (*DC)[comp] = datablock[0];
+ return i;
+
+}
+
+
+/***********************************************************CommentBegin******
+*
+* -- VlcDequantMpegInterBlock -- Decodes the DCT coefficients of one 8x8 block and perform
+ dequantization using Mpeg mode for INTER block.
+ Date: 08/08/2000
+ Modified: 3/21/01
+ clean up, added clipping, 16-bit int case, new ACDC prediction
+******************************************************************************/
+
+
+int VlcDequantMpegInterBlock(void *vid, int comp,
+ uint8 *bitmapcol, uint8 *bitmaprow)
+{
+ VideoDecData *video = (VideoDecData*) vid;
+ BitstreamDecVideo *stream = video->bitstream;
+ Vol *currVol = video->vol[video->currLayer];
+ int16 *datablock = video->mblock->block[comp]; /* 10/20/2000, assume it has been reset of all-zero !!!*/
+ int mbnum = video->mbnum;
+ int QP = video->QPMB[mbnum];
+ /*** VLC *****/
+ int i, k;
+ Tcoef run_level;
+ int last, return_status;
+ VlcDecFuncP vlcDecCoeff;
+
+ /*** Quantizer ****/
+ int sum;
+ int *qmat;
+
+ int32 temp;
+
+ i = 0 ;
+
+#ifdef FAST_IDCT
+ *((uint32*)bitmapcol) = *((uint32*)(bitmapcol + 4)) = 0;
+ *bitmaprow = 0;
+#endif
+
+ /* select which Huffman table to be used */
+ vlcDecCoeff = video->vlcDecCoeffInter;
+
+ /* enter the zero run decoding loop */
+ sum = 0;
+ qmat = currVol->niqmat;
+ do
+ {
+ return_status = (*vlcDecCoeff)(stream, &run_level);
+ if (return_status != PV_SUCCESS)
+ {
+ last = 1;/* 11/1/2000 let it slips undetected, just like
+ in original version */
+ i = VLC_ERROR;
+ sum = 1; /* no of coefficients should not get reset 03/07/2002 */
+ break;
+ }
+
+ i += run_level.run;
+ last = run_level.last;
+ if (i >= 64)
+ {
+ /* i = NCOEFF_BLOCK; */ /* 11/1/00 */
+ //return VLC_NO_LAST_BIT;
+ i = VLC_NO_LAST_BIT;
+ last = 1;
+ sum = 1; /* no of coefficients should not get reset 03/07/2002 */
+ break;
+ }
+
+ k = zigzag_inv[i];
+
+ if (run_level.sign == 1)
+ {
+ temp = (-(int32)(2 * run_level.level + 1) * qmat[k] * QP + 15) >> 4; /* 03/23/01 */
+ if (temp < -2048) temp = - 2048;
+ }
+ else
+ {
+ temp = ((int32)(2 * run_level.level + 1) * qmat[k] * QP) >> 4; /* 03/23/01 */
+ if (temp > 2047) temp = 2047;
+ }
+
+ datablock[k] = (int)temp;
+
+#ifdef FAST_IDCT
+ bitmapcol[k&0x7] |= mask[k>>3];
+#endif
+ sum ^= temp;
+
+ i++;
+ }
+ while (!last);
+
+ if ((sum & 1) == 0)
+ {
+ datablock[63] = datablock[63] ^ 0x1;
+#ifdef FAST_IDCT /* 7/5/01, need to update bitmap */
+ if (datablock[63])
+ bitmapcol[7] |= 1;
+#endif
+ i = NCOEFF_BLOCK;
+ }
+
+
+#ifdef FAST_IDCT
+ if (i > 10)
+ {
+ for (k = 1; k < 4; k++) /* 07/19/01 */
+ {
+ if (bitmapcol[k] != 0)
+ {
+ (*bitmaprow) |= mask[k];
+ }
+ }
+ }
+#endif
+
+ return i;
+}
+#endif
+/***********************************************************CommentBegin******
+*
+* -- VlcDequantIntraH263Block -- Decodes the DCT coefficients of one 8x8 block and perform
+ dequantization in H.263 mode for INTRA block.
+ Date: 08/08/2000
+ Modified: 3/21/01
+ clean up, added clipping, 16-bit int case, removed multiple zigzaging
+******************************************************************************/
+
+
+int VlcDequantH263IntraBlock(VideoDecData *video, int comp, int switched,
+ uint8 *bitmapcol, uint8 *bitmaprow)
+{
+ BitstreamDecVideo *stream = video->bitstream;
+ int16 *datablock = video->mblock->block[comp]; /* 10/20/2000, assume it has been reset of all-zero !!!*/
+ int32 temp;
+ int mbnum = video->mbnum;
+ uint CBP = video->headerInfo.CBP[mbnum];
+ int QP = video->QPMB[mbnum];
+ typeDCStore *DC = video->predDC + mbnum;
+ int x_pos = video->mbnum_col;
+ typeDCACStore *DCAC_row = video->predDCAC_row + x_pos;
+ typeDCACStore *DCAC_col = video->predDCAC_col;
+ uint ACpred_flag = (uint) video->acPredFlag[mbnum];
+
+ /*** VLC *****/
+ int i, j, k;
+ Tcoef run_level;
+ int last, return_status;
+ VlcDecFuncP vlcDecCoeff;
+ int direction;
+ const int *inv_zigzag;
+
+ /*** Quantizer ****/
+ int dc_scaler;
+ int sgn_coeff;
+
+
+
+ const int B_Xtab[6] = {0, 1, 0, 1, 2, 3};
+ const int B_Ytab[6] = {0, 0, 1, 1, 2, 3};
+
+ int16 *dcac_row, *dcac_col;
+
+ dcac_row = (*DCAC_row)[B_Xtab[comp]];
+ dcac_col = (*DCAC_col)[B_Ytab[comp]];
+
+#ifdef FAST_IDCT
+ *((uint32*)bitmapcol) = *((uint32*)(bitmapcol + 4)) = 0;
+ *bitmaprow = 0;
+#endif
+ /* select which Huffman table to be used */
+ vlcDecCoeff = video->vlcDecCoeffIntra;
+
+ dc_scaler = (comp < 4) ? video->mblock->DCScalarLum : video->mblock->DCScalarChr;
+
+ /* perform only VLC decoding */
+ doDCACPrediction(video, comp, datablock, &direction);
+ if (!ACpred_flag) direction = 0;
+
+ inv_zigzag = zigzag_inv + (ACpred_flag << 6) + (direction << 6); /* 04/17/01 */
+
+ i = 1;
+ if (CBP & (1 << (5 - comp)))
+ {
+ i = 1 - switched;
+ do
+ {
+ return_status = (*vlcDecCoeff)(stream, &run_level);
+ if (return_status != PV_SUCCESS)
+ {
+ last = 1;/* 11/1/2000 let it slips undetected, just like
+ in original version */
+ i = VLC_ERROR;
+ ACpred_flag = 0; /* no of coefficients should not get reset 03/07/2002 */
+ break;
+ }
+
+ i += run_level.run;
+ last = run_level.last;
+ if (i >= 64)
+ {
+ ACpred_flag = 0; /* no of coefficients should not get reset 03/07/2002 */
+ i = VLC_NO_LAST_BIT;
+ last = 1;
+ break;
+ }
+
+ k = inv_zigzag[i];
+
+ if (run_level.sign == 1)
+ {
+ datablock[k] -= run_level.level;
+ sgn_coeff = -1;
+ }
+ else
+ {
+ datablock[k] += run_level.level;
+ sgn_coeff = 1;
+ }
+
+
+ if (AC_rowcol[k]) /* 10/25/2000 */
+ {
+ temp = (int32)QP * (2 * datablock[k] + sgn_coeff) - sgn_coeff + (QP & 1) * sgn_coeff;
+ if (temp > 2047) temp = 2047; /* 03/14/01 */
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int16) temp;
+
+#ifdef FAST_IDCT
+ bitmapcol[k&0x7] |= mask[k>>3];
+#endif
+ }
+
+ i++;
+ }
+ while (!last);
+
+ }
+
+ ///// NEED TO DEQUANT THOSE PREDICTED AC COEFF
+ /* dequantize the rest of AC predicted coeff that haven't been dequant */
+ if (ACpred_flag)
+ {
+
+ i = NCOEFF_BLOCK; /* otherwise, FAST IDCT won't work correctly, 10/18/2000 */
+
+ if (!direction) /* check vertical */
+ {
+
+ dcac_row[0] = datablock[1];
+ dcac_row[1] = datablock[2];
+ dcac_row[2] = datablock[3];
+ dcac_row[3] = datablock[4];
+ dcac_row[4] = datablock[5];
+ dcac_row[5] = datablock[6];
+ dcac_row[6] = datablock[7];
+
+ for (j = 0, k = 8; k < 64; k += 8, j++)
+ {
+ dcac_col[j] = datablock[k];
+ if (dcac_col[j])
+ {
+ if (datablock[k] > 0)
+ {
+ if (datablock[k] > 2047) dcac_col[j] = 2047;
+ sgn_coeff = 1;
+ }
+ else
+ {
+ if (datablock[k] < -2048) dcac_col[j] = -2048;
+ sgn_coeff = -1;
+ }
+ temp = (int32)QP * (2 * datablock[k] + sgn_coeff) - sgn_coeff + (QP & 1) * sgn_coeff;
+ if (temp > 2047) temp = 2047; /* 03/14/01 */
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int16) temp;
+#ifdef FAST_IDCT
+ bitmapcol[0] |= mask[k>>3];
+#endif
+
+ }
+ }
+
+ for (k = 1; k < 8; k++)
+ {
+ if (datablock[k])
+ {
+ sgn_coeff = (datablock[k] > 0) ? 1 : -1;
+ temp = (int32)QP * (2 * datablock[k] + sgn_coeff) - sgn_coeff + (QP & 1) * sgn_coeff;
+ if (temp > 2047) temp = 2047; /* 03/14/01 */
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int16) temp;
+#ifdef FAST_IDCT
+ bitmapcol[k] |= 128;
+#endif
+
+ }
+ }
+ }
+ else
+ {
+
+ dcac_col[0] = datablock[8];
+ dcac_col[1] = datablock[16];
+ dcac_col[2] = datablock[24];
+ dcac_col[3] = datablock[32];
+ dcac_col[4] = datablock[40];
+ dcac_col[5] = datablock[48];
+ dcac_col[6] = datablock[56];
+
+
+ for (j = 0, k = 1; k < 8; k++, j++)
+ {
+ dcac_row[j] = datablock[k];
+ if (dcac_row[j])
+ {
+ if (datablock[k] > 0)
+ {
+ if (datablock[k] > 2047) dcac_row[j] = 2047;
+ sgn_coeff = 1;
+ }
+ else
+ {
+ if (datablock[k] < -2048) dcac_row[j] = -2048;
+ sgn_coeff = -1;
+ }
+
+ temp = (int32)QP * (2 * datablock[k] + sgn_coeff) - sgn_coeff + (QP & 1) * sgn_coeff;
+ if (temp > 2047) temp = 2047; /* 03/14/01 */
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int) temp;
+#ifdef FAST_IDCT
+ bitmapcol[k] |= 128;
+#endif
+
+ }
+ }
+ for (k = 8; k < 64; k += 8)
+ {
+ if (datablock[k])
+ {
+ sgn_coeff = (datablock[k] > 0) ? 1 : -1;
+ temp = (int32)QP * (2 * datablock[k] + sgn_coeff) - sgn_coeff + (QP & 1) * sgn_coeff;
+ if (temp > 2047) temp = 2047; /* 03/14/01 */
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int16) temp;
+#ifdef FAST_IDCT
+ bitmapcol[0] |= mask[k>>3];
+#endif
+ }
+ }
+
+ }
+ }
+ else
+ {
+ dcac_row[0] = datablock[1];
+ dcac_row[1] = datablock[2];
+ dcac_row[2] = datablock[3];
+ dcac_row[3] = datablock[4];
+ dcac_row[4] = datablock[5];
+ dcac_row[5] = datablock[6];
+ dcac_row[6] = datablock[7];
+
+ dcac_col[0] = datablock[8];
+ dcac_col[1] = datablock[16];
+ dcac_col[2] = datablock[24];
+ dcac_col[3] = datablock[32];
+ dcac_col[4] = datablock[40];
+ dcac_col[5] = datablock[48];
+ dcac_col[6] = datablock[56];
+
+ for (k = 1; k < 8; k++)
+ {
+ if (datablock[k])
+ {
+ sgn_coeff = (datablock[k] > 0) ? 1 : -1;
+ temp = (int32)QP * (2 * datablock[k] + sgn_coeff) - sgn_coeff + (QP & 1) * sgn_coeff;
+ if (temp > 2047) temp = 2047; /* 03/14/01 */
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int16) temp;
+#ifdef FAST_IDCT
+ bitmapcol[k] |= 128;
+#endif
+ }
+ }
+ for (k = 8; k < 64; k += 8)
+ {
+ if (datablock[k])
+ {
+ sgn_coeff = (datablock[k] > 0) ? 1 : -1;
+ temp = (int32)QP * (2 * datablock[k] + sgn_coeff) - sgn_coeff + (QP & 1) * sgn_coeff;
+ if (temp > 2047) temp = 2047; /* 03/14/01 */
+ else if (temp < -2048) temp = -2048;
+ datablock[k] = (int16) temp;
+#ifdef FAST_IDCT
+ bitmapcol[0] |= mask[k>>3];
+#endif
+ }
+ }
+ }
+ if (datablock[0])
+ {
+#ifdef FAST_IDCT
+ bitmapcol[0] |= 128;
+#endif
+
+ temp = (int32)datablock[0] * dc_scaler;
+ if (temp > 2047) temp = 2047; /* 03/14/01 */
+ else if (temp < -2048) temp = -2048;
+ datablock[0] = (int16)temp;
+ }
+
+
+#ifdef FAST_IDCT
+ if (i > 10)
+ {
+ for (k = 1; k < 4; k++) /* if i > 10 then k = 0 does not matter */
+ {
+ if (bitmapcol[k] != 0)
+ {
+ (*bitmaprow) |= mask[k]; /* (1<<(7-i)); */
+ }
+ }
+ }
+#endif
+
+ /* Store the qcoeff-values needed later for prediction */
+ (*DC)[comp] = datablock[0];
+ return i;
+}
+
+int VlcDequantH263IntraBlock_SH(VideoDecData *video, int comp, uint8 *bitmapcol, uint8 *bitmaprow)
+{
+ BitstreamDecVideo *stream = video->bitstream;
+ int16 *datablock = video->mblock->block[comp]; /*, 10/20/2000, assume it has been reset of all-zero !!!*/
+ int32 temp;
+ int mbnum = video->mbnum;
+ uint CBP = video->headerInfo.CBP[mbnum];
+ int16 QP = video->QPMB[mbnum];
+ typeDCStore *DC = video->predDC + mbnum;
+ int x_pos = video->mbnum_col;
+ typeDCACStore *DCAC_row = video->predDCAC_row + x_pos;
+ typeDCACStore *DCAC_col = video->predDCAC_col;
+ uint ACpred_flag = (uint) video->acPredFlag[mbnum];
+
+ /*** VLC *****/
+ int i, k;
+ Tcoef run_level;
+ int last, return_status;
+ VlcDecFuncP vlcDecCoeff;
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ int direction;
+ const int *inv_zigzag;
+#endif
+ /*** Quantizer ****/
+
+
+
+ const int B_Xtab[6] = {0, 1, 0, 1, 2, 3};
+ const int B_Ytab[6] = {0, 0, 1, 1, 2, 3};
+
+ int16 *dcac_row, *dcac_col;
+
+ dcac_row = (*DCAC_row)[B_Xtab[comp]];
+ dcac_col = (*DCAC_col)[B_Ytab[comp]];
+ i = 1;
+
+#ifdef FAST_IDCT
+ *((uint32*)bitmapcol) = *((uint32*)(bitmapcol + 4)) = 0;
+ *bitmaprow = 0;
+#endif
+
+ /* select which Huffman table to be used */
+ vlcDecCoeff = video->vlcDecCoeffIntra;
+
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ if (comp > 3) /* ANNEX_T */
+ {
+ QP = video->QP_CHR;
+ }
+ if (!video->advanced_INTRA)
+ {
+#endif
+
+ if ((CBP & (1 << (5 - comp))) == 0)
+ {
+#ifdef FAST_IDCT
+ bitmapcol[0] = 128;
+ bitmapcol[1] = bitmapcol[2] = bitmapcol[3] = bitmapcol[4] = bitmapcol[5] = bitmapcol[6] = bitmapcol[7] = 0;
+#endif
+ datablock[0] <<= 3; /* no need to clip */
+ return 1;//ncoeffs;
+ }
+ else
+ {
+ /* enter the zero run decoding loop */
+ do
+ {
+ return_status = (*vlcDecCoeff)(stream, &run_level);
+ if (return_status != PV_SUCCESS)
+ {
+ last = 1;/* 11/1/2000 let it slips undetected, just like
+ in original version */
+ i = VLC_ERROR;
+ break;
+ }
+
+ i += run_level.run;
+ last = run_level.last;
+ if (i >= 64)
+ {
+ /* i = NCOEFF_BLOCK; */ /* 11/1/00 */
+ i = VLC_NO_LAST_BIT;
+ last = 1;
+ break;
+ }
+ k = zigzag_inv[i];
+
+ if (run_level.sign == 0)
+ {
+ temp = (int32)QP * (2 * run_level.level + 1) - 1 + (QP & 1);
+ if (temp > 2047) temp = 2047;
+ }
+ else
+ {
+ temp = -(int32)QP * (2 * run_level.level + 1) + 1 - (QP & 1);
+ if (temp < -2048) temp = -2048;
+ }
+
+
+ datablock[k] = (int16) temp;
+
+#ifdef FAST_IDCT
+ bitmapcol[k&0x7] |= mask[k>>3];
+#endif
+ i++;
+ }
+ while (!last);
+
+ }
+ /* no ACDC prediction when ACDC disable */
+ if (datablock[0])
+ {
+#ifdef FAST_IDCT
+ bitmapcol[0] |= 128;
+#endif
+ datablock[0] <<= 3; /* no need to clip 09/18/2001 */
+ }
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ }
+ else /* advanced_INTRA mode */
+ {
+ i = 1;
+ doDCACPrediction_I(video, comp, datablock);
+ /* perform only VLC decoding */
+ if (!ACpred_flag)
+ {
+ direction = 0;
+ }
+ else
+ {
+ direction = video->mblock->direction;
+ }
+
+ inv_zigzag = zigzag_inv + (ACpred_flag << 6) + (direction << 6); /* 04/17/01 */
+
+ if (CBP & (1 << (5 - comp)))
+ {
+ i = 0;
+ do
+ {
+ return_status = (*vlcDecCoeff)(stream, &run_level);
+ if (return_status != PV_SUCCESS)
+ {
+ last = 1;/* 11/1/2000 let it slips undetected, just like
+ in original version */
+ i = VLC_ERROR;
+ ACpred_flag = 0; /* no of coefficients should not get reset 03/07/2002 */
+ break;
+ }
+
+ i += run_level.run;
+ last = run_level.last;
+ if (i >= 64)
+ {
+ /* i = NCOEFF_BLOCK; */ /* 11/1/00 */
+ ACpred_flag = 0; /* no of coefficients should not get reset 03/07/2002 */
+ i = VLC_NO_LAST_BIT;
+ last = 1;
+ break;
+ }
+
+ k = inv_zigzag[i];
+
+ if (run_level.sign == 0)
+ {
+ datablock[k] += (int16)QP * 2 * run_level.level;
+ if (datablock[k] > 2047) datablock[k] = 2047;
+ }
+ else
+ {
+ datablock[k] -= (int16)QP * 2 * run_level.level;
+ if (datablock[k] < -2048) datablock[k] = -2048;
+ }
+#ifdef FAST_IDCT
+ bitmapcol[k&0x7] |= mask[k>>3];
+#endif
+
+ i++;
+ }
+ while (!last);
+
+ }
+ ///// NEED TO DEQUANT THOSE PREDICTED AC COEFF
+ /* dequantize the rest of AC predicted coeff that haven't been dequant */
+
+ if (ACpred_flag)
+ {
+ i = NCOEFF_BLOCK;
+ for (k = 1; k < 8; k++)
+ {
+ if (datablock[k])
+ {
+ bitmapcol[k] |= 128;
+ }
+
+ if (datablock[k<<3])
+ {
+ bitmapcol[0] |= mask[k];
+ }
+ }
+ }
+
+ dcac_row[0] = datablock[1];
+ dcac_row[1] = datablock[2];
+ dcac_row[2] = datablock[3];
+ dcac_row[3] = datablock[4];
+ dcac_row[4] = datablock[5];
+ dcac_row[5] = datablock[6];
+ dcac_row[6] = datablock[7];
+
+ dcac_col[0] = datablock[8];
+ dcac_col[1] = datablock[16];
+ dcac_col[2] = datablock[24];
+ dcac_col[3] = datablock[32];
+ dcac_col[4] = datablock[40];
+ dcac_col[5] = datablock[48];
+ dcac_col[6] = datablock[56];
+
+ if (datablock[0])
+ {
+#ifdef FAST_IDCT
+ bitmapcol[0] |= 128;
+#endif
+
+ datablock[0] |= 1;
+ if (datablock[0] < 0)
+ {
+ datablock[0] = 0;
+ }
+ }
+ }
+#endif
+
+#ifdef FAST_IDCT
+ if (i > 10)
+ {
+ for (k = 1; k < 4; k++) /* if i > 10 then k = 0 does not matter */
+ {
+ if (bitmapcol[k] != 0)
+ {
+ (*bitmaprow) |= mask[k]; /* (1<<(7-i)); */
+ }
+ }
+ }
+#endif
+
+ /* Store the qcoeff-values needed later for prediction */
+ (*DC)[comp] = datablock[0];
+ return i;
+}
+
+/***********************************************************CommentBegin******
+*
+* -- VlcDequantInterH263Block -- Decodes the DCT coefficients of one 8x8 block and perform
+ dequantization in H.263 mode for INTER block.
+ Date: 08/08/2000
+ Modified: 3/21/01
+ clean up, added clipping, 16-bit int case
+******************************************************************************/
+
+
+int VlcDequantH263InterBlock(VideoDecData *video, int comp,
+ uint8 *bitmapcol, uint8 *bitmaprow)
+{
+ BitstreamDecVideo *stream = video->bitstream;
+ int16 *datablock = video->mblock->block[comp]; /* 10/20/2000, assume it has been reset of all-zero !!!*/
+ int32 temp;
+ int mbnum = video->mbnum;
+ int QP = video->QPMB[mbnum];
+
+ /*** VLC *****/
+ int i, k;
+ Tcoef run_level;
+ int last, return_status;
+ VlcDecFuncP vlcDecCoeff;
+
+ /*** Quantizer ****/
+
+
+ i = 0;
+
+#ifdef FAST_IDCT
+ *((uint32*)bitmapcol) = *((uint32*)(bitmapcol + 4)) = 0;
+ *bitmaprow = 0;
+#endif
+
+ /* select which Huffman table to be used */
+ vlcDecCoeff = video->vlcDecCoeffInter;
+
+ /* enter the zero run decoding loop */
+ do
+ {
+ return_status = (*vlcDecCoeff)(stream, &run_level);
+ if (return_status != PV_SUCCESS)
+ {
+
+
+ last = 1;/* 11/1/2000 let it slips undetected, just like
+ in original version */
+ i = -1;
+ break;
+ }
+
+ i += run_level.run;
+ last = run_level.last;
+ if (i >= 64)
+ {
+ i = -1;
+ last = 1;
+ break;
+ }
+
+ if (run_level.sign == 0)
+ {
+ temp = (int32)QP * (2 * run_level.level + 1) - 1 + (QP & 1);
+ if (temp > 2047) temp = 2047;
+
+ }
+ else
+ {
+ temp = -(int32)QP * (2 * run_level.level + 1) + 1 - (QP & 1);
+ if (temp < -2048) temp = -2048;
+ }
+
+ k = zigzag_inv[i];
+ datablock[k] = (int16)temp;
+#ifdef FAST_IDCT
+ bitmapcol[k&0x7] |= mask[k>>3];
+#endif
+ i++;
+ }
+ while (!last);
+
+#ifdef FAST_IDCT
+ if (i > 10) /* 07/19/01 */
+ {
+ for (k = 1; k < 4; k++) /* if (i > 10 ) k = 0 does not matter */
+ {
+ if (bitmapcol[k] != 0)
+ {
+ (*bitmaprow) |= mask[k]; /* (1<<(7-i)); */
+ }
+ }
+ }
+#endif
+ return i;
+}
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vlc_tab.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/vlc_tab.cpp
new file mode 100644
index 0000000..704992f
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/vlc_tab.cpp
@@ -0,0 +1,835 @@
+/* ------------------------------------------------------------------
+ * 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 "mp4dec_api.h"
+#include "mp4def.h"
+#include "mp4lib_int.h"
+#include "vlc_dec_tab.h"
+#include "max_level.h"
+
+
+const int intra_max_level[2][NCOEFF_BLOCK] =
+{
+ {27, 10, 5, 4, 3, 3, 3, 3,
+ 2, 2, 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+
+ {8, 3, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+ }
+};
+
+
+const int inter_max_level[2][NCOEFF_BLOCK] =
+{
+ {12, 6, 4, 3, 3, 3, 3, 2,
+ 2, 2, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0},
+
+ {3, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0}
+};
+
+
+const int intra_max_run0[28] = { 999, 14, 9, 7, 3, 2, 1,
+ 1, 1, 1, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0
+ };
+
+
+const int intra_max_run1[9] = { 999, 20, 6,
+ 1, 0, 0,
+ 0, 0, 0
+ };
+
+const int inter_max_run0[13] = { 999,
+ 26, 10, 6, 2, 1, 1,
+ 0, 0, 0, 0, 0, 0
+ };
+
+
+const int inter_max_run1[4] = { 999, 40, 1, 0 };
+
+const VLCshorttab PV_TMNMVtab0[] =
+{
+ {3, 4}, { -3, 4}, {2, 3}, {2, 3}, { -2, 3}, { -2, 3}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
+ { -1, 2}, { -1, 2}, { -1, 2}, { -1, 2}
+};
+
+const VLCshorttab PV_TMNMVtab1[] =
+{
+ {12, 10}, { -12, 10}, {11, 10}, { -11, 10}, {10, 9}, {10, 9}, { -10, 9}, { -10, 9},
+ {9, 9}, {9, 9}, { -9, 9}, { -9, 9}, {8, 9}, {8, 9}, { -8, 9}, { -8, 9}, {7, 7}, {7, 7},
+ {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, { -7, 7}, { -7, 7}, { -7, 7}, { -7, 7},
+ { -7, 7}, { -7, 7}, { -7, 7}, { -7, 7}, {6, 7}, {6, 7}, {6, 7}, {6, 7}, {6, 7}, {6, 7},
+ {6, 7}, {6, 7}, { -6, 7}, { -6, 7}, { -6, 7}, { -6, 7}, { -6, 7}, { -6, 7}, { -6, 7},
+ { -6, 7}, {5, 7}, {5, 7}, {5, 7}, {5, 7}, {5, 7}, {5, 7}, {5, 7}, {5, 7}, { -5, 7},
+ { -5, 7}, { -5, 7}, { -5, 7}, { -5, 7}, { -5, 7}, { -5, 7}, { -5, 7}, {4, 6}, {4, 6}, {4, 6},
+ {4, 6}, {4, 6}, {4, 6}, {4, 6}, {4, 6}, {4, 6}, {4, 6}, {4, 6}, {4, 6}, {4, 6}, {4, 6},
+ {4, 6}, {4, 6}, { -4, 6}, { -4, 6}, { -4, 6}, { -4, 6}, { -4, 6}, { -4, 6}, { -4, 6},
+ { -4, 6}, { -4, 6}, { -4, 6}, { -4, 6}, { -4, 6}, { -4, 6}, { -4, 6}, { -4, 6}, { -4, 6}
+};
+
+const VLCshorttab PV_TMNMVtab2[] =
+{
+ {32, 12}, { -32, 12}, {31, 12}, { -31, 12}, {30, 11}, {30, 11}, { -30, 11}, { -30, 11},
+ {29, 11}, {29, 11}, { -29, 11}, { -29, 11}, {28, 11}, {28, 11}, { -28, 11}, { -28, 11},
+ {27, 11}, {27, 11}, { -27, 11}, { -27, 11}, {26, 11}, {26, 11}, { -26, 11}, { -26, 11},
+ {25, 11}, {25, 11}, { -25, 11}, { -25, 11}, {24, 10}, {24, 10}, {24, 10}, {24, 10},
+ { -24, 10}, { -24, 10}, { -24, 10}, { -24, 10}, {23, 10}, {23, 10}, {23, 10}, {23, 10},
+ { -23, 10}, { -23, 10}, { -23, 10}, { -23, 10}, {22, 10}, {22, 10}, {22, 10}, {22, 10},
+ { -22, 10}, { -22, 10}, { -22, 10}, { -22, 10}, {21, 10}, {21, 10}, {21, 10}, {21, 10},
+ { -21, 10}, { -21, 10}, { -21, 10}, { -21, 10}, {20, 10}, {20, 10}, {20, 10}, {20, 10},
+ { -20, 10}, { -20, 10}, { -20, 10}, { -20, 10}, {19, 10}, {19, 10}, {19, 10}, {19, 10},
+ { -19, 10}, { -19, 10}, { -19, 10}, { -19, 10}, {18, 10}, {18, 10}, {18, 10}, {18, 10},
+ { -18, 10}, { -18, 10}, { -18, 10}, { -18, 10}, {17, 10}, {17, 10}, {17, 10}, {17, 10},
+ { -17, 10}, { -17, 10}, { -17, 10}, { -17, 10}, {16, 10}, {16, 10}, {16, 10}, {16, 10},
+ { -16, 10}, { -16, 10}, { -16, 10}, { -16, 10}, {15, 10}, {15, 10}, {15, 10}, {15, 10},
+ { -15, 10}, { -15, 10}, { -15, 10}, { -15, 10}, {14, 10}, {14, 10}, {14, 10}, {14, 10},
+ { -14, 10}, { -14, 10}, { -14, 10}, { -14, 10}, {13, 10}, {13, 10}, {13, 10}, {13, 10},
+ { -13, 10}, { -13, 10}, { -13, 10}, { -13, 10}
+};
+
+const VLCshorttab PV_MCBPCtab[] =
+{
+ {VLC_ERROR, 0},
+ {255, 9}, {52, 9}, {36, 9}, {20, 9}, {49, 9}, {35, 8}, {35, 8}, {19, 8}, {19, 8},
+ {50, 8}, {50, 8}, {51, 7}, {51, 7}, {51, 7}, {51, 7}, {34, 7}, {34, 7}, {34, 7},
+ {34, 7}, {18, 7}, {18, 7}, {18, 7}, {18, 7}, {33, 7}, {33, 7}, {33, 7}, {33, 7},
+ {17, 7}, {17, 7}, {17, 7}, {17, 7}, {4, 6}, {4, 6}, {4, 6}, {4, 6}, {4, 6},
+ {4, 6}, {4, 6}, {4, 6}, {48, 6}, {48, 6}, {48, 6}, {48, 6}, {48, 6}, {48, 6},
+ {48, 6}, {48, 6}, {3, 5}, {3, 5}, {3, 5}, {3, 5}, {3, 5}, {3, 5}, {3, 5},
+ {3, 5}, {3, 5}, {3, 5}, {3, 5}, {3, 5}, {3, 5}, {3, 5}, {3, 5}, {3, 5},
+ {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4},
+ {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4},
+ {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4},
+ {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4},
+ {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4},
+ {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4},
+ {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4},
+ {16, 4}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3},
+ {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3},
+ {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3},
+ {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3},
+ {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3},
+ {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3},
+ {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3},
+ {2, 3}, {2, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3},
+ {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3},
+ {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3},
+ {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3},
+ {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3},
+ {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3},
+ {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3},
+ {1, 3}, {1, 3}, {1, 3}
+};
+
+#ifdef PV_ANNEX_IJKT_SUPPORT
+const VLCshorttab PV_MCBPCtab1[] =
+{
+ {5, 11}, {5, 11}, {5, 11}, {5, 11}, {21, 13}, {21, 13}, {37, 13}, {53, 13},
+};
+#endif
+const VLCshorttab PV_MCBPCtabintra[] =
+{
+ {VLC_ERROR, 0},
+ {20, 6}, {36, 6}, {52, 6}, {4, 4}, {4, 4}, {4, 4},
+ {4, 4}, {19, 3}, {19, 3}, {19, 3}, {19, 3}, {19, 3},
+ {19, 3}, {19, 3}, {19, 3}, {35, 3}, {35, 3}, {35, 3},
+ {35, 3}, {35, 3}, {35, 3}, {35, 3}, {35, 3}, {51, 3},
+ {51, 3}, {51, 3}, {51, 3}, {51, 3}, {51, 3}, {51, 3},
+ {51, 3}
+};
+
+
+
+const VLCshorttab PV_CBPYtab[48] =
+{
+ {VLC_ERROR, 0}, {VLC_ERROR, 0}, {6, 6}, {9, 6}, {8, 5}, {8, 5}, {4, 5}, {4, 5},
+ {2, 5}, {2, 5}, {1, 5}, {1, 5}, {0, 4}, {0, 4}, {0, 4}, {0, 4},
+ {12, 4}, {12, 4}, {12, 4}, {12, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4},
+ {14, 4}, {14, 4}, {14, 4}, {14, 4}, {5, 4}, {5, 4}, {5, 4}, {5, 4},
+ {13, 4}, {13, 4}, {13, 4}, {13, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4},
+ {11, 4}, {11, 4}, {11, 4}, {11, 4}, {7, 4}, {7, 4}, {7, 4}, {7, 4}
+};
+
+
+
+const VLCtab2 PV_DCT3Dtab0[] =
+{
+ {0x8, 1, 1, 7}, {0x7, 1, 1, 7}, {0x6, 1, 1, 7}, {0x5, 1, 1, 7}, {0xc, 1, 0, 7}, {0xb, 1, 0, 7},
+ {0xa, 1, 0, 7}, {0x0, 4, 0, 7}, {0x4, 1, 1, 6}, {0x4, 1, 1, 6}, {0x3, 1, 1, 6}, {0x3, 1, 1, 6},
+ {0x2, 1, 1, 6}, {0x2, 1, 1, 6}, {0x1, 1, 1, 6}, {0x1, 1, 1, 6}, {0x9, 1, 0, 6}, {0x9, 1, 0, 6},
+ {0x8, 1, 0, 6}, {0x8, 1, 0, 6}, {0x7, 1, 0, 6}, {0x7, 1, 0, 6}, {0x6, 1, 0, 6}, {0x6, 1, 0, 6},
+ {0x1, 2, 0, 6}, {0x1, 2, 0, 6}, {0x0, 3, 0, 6}, {0x0, 3, 0, 6}, {0x5, 1, 0, 5}, {0x5, 1, 0, 5},
+ {0x5, 1, 0, 5}, {0x5, 1, 0, 5}, {0x4, 1, 0, 5}, {0x4, 1, 0, 5}, {0x4, 1, 0, 5}, {0x4, 1, 0, 5},
+ {0x3, 1, 0, 5}, {0x3, 1, 0, 5}, {0x3, 1, 0, 5}, {0x3, 1, 0, 5}, {0x0, 1, 1, 4}, {0x0, 1, 1, 4},
+ {0x0, 1, 1, 4}, {0x0, 1, 1, 4}, {0x0, 1, 1, 4}, {0x0, 1, 1, 4}, {0x0, 1, 1, 4}, {0x0, 1, 1, 4},
+ {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2},
+ {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2},
+ {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2},
+ {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2},
+ {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2},
+ {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x1, 1, 0, 3}, {0x1, 1, 0, 3}, {0x1, 1, 0, 3}, {0x1, 1, 0, 3},
+ {0x1, 1, 0, 3}, {0x1, 1, 0, 3}, {0x1, 1, 0, 3}, {0x1, 1, 0, 3}, {0x1, 1, 0, 3}, {0x1, 1, 0, 3},
+ {0x1, 1, 0, 3}, {0x1, 1, 0, 3}, {0x1, 1, 0, 3}, {0x1, 1, 0, 3}, {0x1, 1, 0, 3}, {0x1, 1, 0, 3},
+ {0x2, 1, 0, 4}, {0x2, 1, 0, 4}, {0x2, 1, 0, 4}, {0x2, 1, 0, 4}, {0x2, 1, 0, 4}, {0x2, 1, 0, 4},
+ {0x2, 1, 0, 4}, {0x2, 1, 0, 4}, {0x0, 2, 0, 4}, {0x0, 2, 0, 4}, {0x0, 2, 0, 4}, {0x0, 2, 0, 4},
+ {0x0, 2, 0, 4}, {0x0, 2, 0, 4}, {0x0, 2, 0, 4}, {0x0, 2, 0, 4}
+};
+
+
+const VLCtab2 PV_DCT3Dtab1[] =
+{
+ {0x0, 9, 0, 10}, {0x0, 8, 0, 10}, {0x18, 1, 1, 9}, {0x18, 1, 1, 9}, {0x17, 1, 1, 9}, {0x17, 1, 1, 9},
+ {0x16, 1, 1, 9}, {0x16, 1, 1, 9}, {0x15, 1, 1, 9}, {0x15, 1, 1, 9}, {0x14, 1, 1, 9}, {0x14, 1, 1, 9},
+ {0x13, 1, 1, 9}, {0x13, 1, 1, 9}, {0x12, 1, 1, 9}, {0x12, 1, 1, 9}, {0x11, 1, 1, 9}, {0x11, 1, 1, 9},
+ {0x0, 2, 1, 9}, {0x0, 2, 1, 9}, {0x16, 1, 0, 9}, {0x16, 1, 0, 9}, {0x15, 1, 0, 9}, {0x15, 1, 0, 9},
+ {0x14, 1, 0, 9}, {0x14, 1, 0, 9}, {0x13, 1, 0, 9}, {0x13, 1, 0, 9}, {0x12, 1, 0, 9}, {0x12, 1, 0, 9},
+ {0x11, 1, 0, 9}, {0x11, 1, 0, 9}, {0x10, 1, 0, 9}, {0x10, 1, 0, 9}, {0xf, 1, 0, 9}, {0xf, 1, 0, 9},
+ {0x4, 2, 0, 9}, {0x4, 2, 0, 9}, {0x3, 2, 0, 9}, {0x3, 2, 0, 9}, {0x0, 7, 0, 9}, {0x0, 7, 0, 9},
+ {0x0, 6, 0, 9}, {0x0, 6, 0, 9}, {0x10, 1, 1, 8}, {0x10, 1, 1, 8}, {0x10, 1, 1, 8}, {0x10, 1, 1, 8},
+ {0xf, 1, 1, 8}, {0xf, 1, 1, 8}, {0xf, 1, 1, 8}, {0xf, 1, 1, 8}, {0xe, 1, 1, 8}, {0xe, 1, 1, 8},
+ {0xe, 1, 1, 8}, {0xe, 1, 1, 8}, {0xd, 1, 1, 8}, {0xd, 1, 1, 8}, {0xd, 1, 1, 8}, {0xd, 1, 1, 8},
+ {0xc, 1, 1, 8}, {0xc, 1, 1, 8}, {0xc, 1, 1, 8}, {0xc, 1, 1, 8}, {0xb, 1, 1, 8}, {0xb, 1, 1, 8},
+ {0xb, 1, 1, 8}, {0xb, 1, 1, 8}, {0xa, 1, 1, 8}, {0xa, 1, 1, 8}, {0xa, 1, 1, 8}, {0xa, 1, 1, 8},
+ {0x9, 1, 1, 8}, {0x9, 1, 1, 8}, {0x9, 1, 1, 8}, {0x9, 1, 1, 8}, {0xe, 1, 0, 8}, {0xe, 1, 0, 8},
+ {0xe, 1, 0, 8}, {0xe, 1, 0, 8}, {0xd, 1, 0, 8}, {0xd, 1, 0, 8}, {0xd, 1, 0, 8}, {0xd, 1, 0, 8},
+ {0x2, 2, 0, 8}, {0x2, 2, 0, 8}, {0x2, 2, 0, 8}, {0x2, 2, 0, 8}, {0x1, 3, 0, 8}, {0x1, 3, 0, 8},
+ {0x1, 3, 0, 8}, {0x1, 3, 0, 8}, {0x0, 5, 0, 8}, {0x0, 5, 0, 8}, {0x0, 5, 0, 8}, {0x0, 5, 0, 8}
+};
+
+
+const VLCtab2 PV_DCT3Dtab2[] =
+{
+ {0x1, 2, 1, 11}, {0x1, 2, 1, 11}, {0x0, 3, 1, 11}, {0x0, 3, 1, 11}, {0x0, 0xb, 0, 11}, {0x0, 0xb, 0, 11},
+ {0x0, 0xa, 0, 11}, {0x0, 0xa, 0, 11}, {0x1c, 1, 1, 10}, {0x1c, 1, 1, 10}, {0x1c, 1, 1, 10}, {0x1c, 1, 1, 10},
+ {0x1b, 1, 1, 10}, {0x1b, 1, 1, 10}, {0x1b, 1, 1, 10}, {0x1b, 1, 1, 10}, {0x1a, 1, 1, 10}, {0x1a, 1, 1, 10},
+ {0x1a, 1, 1, 10}, {0x1a, 1, 1, 10}, {0x19, 1, 1, 10}, {0x19, 1, 1, 10}, {0x19, 1, 1, 10}, {0x19, 1, 1, 10},
+ {0x9, 2, 0, 10}, {0x9, 2, 0, 10}, {0x9, 2, 0, 10}, {0x9, 2, 0, 10}, {0x8, 2, 0, 10}, {0x8, 2, 0, 10},
+ {0x8, 2, 0, 10}, {0x8, 2, 0, 10}, {0x7, 2, 0, 10}, {0x7, 2, 0, 10}, {0x7, 2, 0, 10}, {0x7, 2, 0, 10},
+ {0x6, 2, 0, 10}, {0x6, 2, 0, 10}, {0x6, 2, 0, 10}, {0x6, 2, 0, 10}, {0x5, 2, 0, 10}, {0x5, 2, 0, 10},
+ {0x5, 2, 0, 10}, {0x5, 2, 0, 10}, {0x3, 3, 0, 10}, {0x3, 3, 0, 10}, {0x3, 3, 0, 10}, {0x3, 3, 0, 10},
+ {0x2, 3, 0, 10}, {0x2, 3, 0, 10}, {0x2, 3, 0, 10}, {0x2, 3, 0, 10}, {0x1, 4, 0, 10}, {0x1, 4, 0, 10},
+ {0x1, 4, 0, 10}, {0x1, 4, 0, 10}, {0x0, 0xc, 0, 11}, {0x0, 0xc, 0, 11}, {0x1, 5, 0, 11}, {0x1, 5, 0, 11},
+ {0x17, 1, 0, 11}, {0x17, 1, 0, 11}, {0x18, 1, 0, 11}, {0x18, 1, 0, 11}, {0x1d, 1, 1, 11}, {0x1d, 1, 1, 11},
+ {0x1e, 1, 1, 11}, {0x1e, 1, 1, 11}, {0x1f, 1, 1, 11}, {0x1f, 1, 1, 11}, {0x20, 1, 1, 11}, {0x20, 1, 1, 11},
+ {0x1, 6, 0, 12}, {0x2, 4, 0, 12}, {0x4, 3, 0, 12}, {0x5, 3, 0, 12}, {0x6, 3, 0, 12}, {0xa, 2, 0, 12},
+ {0x19, 1, 0, 12}, {0x1a, 1, 0, 12}, {0x21, 1, 1, 12}, {0x22, 1, 1, 12}, {0x23, 1, 1, 12}, {0x24, 1, 1, 12},
+ {0x25, 1, 1, 12}, {0x26, 1, 1, 12}, {0x27, 1, 1, 12}, {0x28, 1, 1, 12}, {0xbf, 0xf, 1, 7},
+ {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7},
+ {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7},
+ {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7},
+ {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7},
+ {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7}, {0xbf, 0xf, 1, 7},
+ {0xbf, 0xf, 1, 7}
+};
+
+/* New tables for Intra luminance blocks */
+
+const VLCtab2 PV_DCT3Dtab3[] =
+{
+ {0x4, 1, 1, 7}, {0x3, 1, 1, 7}, {0x6, 1, 0, 7}, {0x5, 1, 1, 7},
+ {0x7, 1, 0, 7}, {0x2, 2, 0, 7}, {0x1, 3, 0, 7}, {0x0, 9, 0, 7},
+ {0x0, 2, 1, 6}, {0x0, 2, 1, 6}, {0x5, 1, 0, 6}, {0x5, 1, 0, 6},
+ {0x2, 1, 1, 6}, {0x2, 1, 1, 6}, {0x1, 1, 1, 6}, {0x1, 1, 1, 6},
+ {0x4, 1, 0, 6}, {0x4, 1, 0, 6}, {0x3, 1, 0, 6}, {0x3, 1, 0, 6},
+ {0x0, 8, 0, 6}, {0x0, 8, 0, 6}, {0x0, 7, 0, 6}, {0x0, 7, 0, 6},
+ {0x1, 2, 0, 6}, {0x1, 2, 0, 6}, {0x0, 6, 0, 6}, {0x0, 6, 0, 6},
+ {0x2, 1, 0, 5}, {0x2, 1, 0, 5}, {0x2, 1, 0, 5}, {0x2, 1, 0, 5},
+ {0x0, 5, 0, 5}, {0x0, 5, 0, 5}, {0x0, 5, 0, 5}, {0x0, 5, 0, 5},
+ {0x0, 4, 0, 5}, {0x0, 4, 0, 5}, {0x0, 4, 0, 5}, {0x0, 4, 0, 5},
+ {0x0, 1, 1, 4}, {0x0, 1, 1, 4}, {0x0, 1, 1, 4}, {0x0, 1, 1, 4},
+ {0x0, 1, 1, 4}, {0x0, 1, 1, 4}, {0x0, 1, 1, 4}, {0x0, 1, 1, 4},
+ {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2},
+ {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2},
+ {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2},
+ {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2},
+ {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2},
+ {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2},
+ {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2},
+ {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2},
+ {0x0, 2, 0, 3}, {0x0, 2, 0, 3}, {0x0, 2, 0, 3}, {0x0, 2, 0, 3},
+ {0x0, 2, 0, 3}, {0x0, 2, 0, 3}, {0x0, 2, 0, 3}, {0x0, 2, 0, 3},
+ {0x0, 2, 0, 3}, {0x0, 2, 0, 3}, {0x0, 2, 0, 3}, {0x0, 2, 0, 3},
+ {0x0, 2, 0, 3}, {0x0, 2, 0, 3}, {0x0, 2, 0, 3}, {0x0, 2, 0, 3},
+ {0x1, 1, 0, 4}, {0x1, 1, 0, 4}, {0x1, 1, 0, 4}, {0x1, 1, 0, 4},
+ {0x1, 1, 0, 4}, {0x1, 1, 0, 4}, {0x1, 1, 0, 4}, {0x1, 1, 0, 4},
+ {0x0, 3, 0, 4}, {0x0, 3, 0, 4}, {0x0, 3, 0, 4}, {0x0, 3, 0, 4},
+ {0x0, 3, 0, 4}, {0x0, 3, 0, 4}, {0x0, 3, 0, 4}, {0x0, 3, 0, 4}
+};
+
+const VLCtab2 PV_DCT3Dtab4[] =
+{
+ {0x0, 0x12, 0, 10}, {0x0, 0x11, 0, 10}, {0xe, 1, 1, 9}, {0xe, 1, 1, 9},
+ {0xd, 1, 1, 9}, {0xd, 1, 1, 9}, {0xc, 1, 1, 9}, {0xc, 1, 1, 9},
+ {0xb, 1, 1, 9}, {0xb, 1, 1, 9}, {0xa, 1, 1, 9}, {0xa, 1, 1, 9},
+ {0x1, 2, 1, 9}, {0x1, 2, 1, 9}, {0x0, 4, 1, 9}, {0x0, 4, 1, 9},
+ {0xc, 1, 0, 9}, {0xc, 1, 0, 9}, {0xb, 1, 0, 9}, {0xb, 1, 0, 9},
+ {0x7, 2, 0, 9}, {0x7, 2, 0, 9}, {0x6, 2, 0, 9}, {0x6, 2, 0, 9},
+ {0x5, 2, 0, 9}, {0x5, 2, 0, 9}, {0x3, 3, 0, 9}, {0x3, 3, 0, 9},
+ {0x2, 3, 0, 9}, {0x2, 3, 0, 9}, {0x1, 6, 0, 9}, {0x1, 6, 0, 9},
+ {0x1, 5, 0, 9}, {0x1, 5, 0, 9}, {0x0, 0x10, 0, 9}, {0x0, 0x10, 0, 9},
+ {0x4, 2, 0, 9}, {0x4, 2, 0, 9}, {0x0, 0xf, 0, 9}, {0x0, 0xf, 0, 9},
+ {0x0, 0xe, 0, 9}, {0x0, 0xe, 0, 9}, {0x0, 0xd, 0, 9}, {0x0, 0xd, 0, 9},
+ {0x8, 1, 1, 8}, {0x8, 1, 1, 8}, {0x8, 1, 1, 8}, {0x8, 1, 1, 8},
+ {0x7, 1, 1, 8}, {0x7, 1, 1, 8}, {0x7, 1, 1, 8}, {0x7, 1, 1, 8},
+ {0x6, 1, 1, 8}, {0x6, 1, 1, 8}, {0x6, 1, 1, 8}, {0x6, 1, 1, 8},
+ {0x0, 3, 1, 8}, {0x0, 3, 1, 8}, {0x0, 3, 1, 8}, {0x0, 3, 1, 8},
+ {0xa, 1, 0, 8}, {0xa, 1, 0, 8}, {0xa, 1, 0, 8}, {0xa, 1, 0, 8},
+ {0x9, 1, 0, 8}, {0x9, 1, 0, 8}, {0x9, 1, 0, 8}, {0x9, 1, 0, 8},
+ {0x8, 1, 0, 8}, {0x8, 1, 0, 8}, {0x8, 1, 0, 8}, {0x8, 1, 0, 8},
+ {0x9, 1, 1, 8}, {0x9, 1, 1, 8}, {0x9, 1, 1, 8}, {0x9, 1, 1, 8},
+ {0x3, 2, 0, 8}, {0x3, 2, 0, 8}, {0x3, 2, 0, 8}, {0x3, 2, 0, 8},
+ {0x1, 4, 0, 8}, {0x1, 4, 0, 8}, {0x1, 4, 0, 8}, {0x1, 4, 0, 8},
+ {0x0, 0xc, 0, 8}, {0x0, 0xc, 0, 8}, {0x0, 0xc, 0, 8}, {0x0, 0xc, 0, 8},
+ {0x0, 0xb, 0, 8}, {0x0, 0xb, 0, 8}, {0x0, 0xb, 0, 8}, {0x0, 0xb, 0, 8},
+ {0x0, 0xa, 0, 8}, {0x0, 0xa, 0, 8}, {0x0, 0xa, 0, 8}, {0x0, 0xa, 0, 8}
+};
+
+const VLCtab2 PV_DCT3Dtab5[] =
+{
+ {0x0, 7, 1, 11}, {0x0, 7, 1, 11}, {0x0, 6, 1, 11}, {0x0, 6, 1, 11},
+ {0x0, 0x16, 0, 11}, {0x0, 0x16, 0, 11}, {0x0, 0x15, 0, 11}, {0x0, 0x15, 0, 11},
+ {0x2, 2, 1, 10}, {0x2, 2, 1, 10}, {0x2, 2, 1, 10}, {0x2, 2, 1, 10},
+ {0x1, 3, 1, 10}, {0x1, 3, 1, 10}, {0x1, 3, 1, 10}, {0x1, 3, 1, 10},
+ {0x0, 5, 1, 10}, {0x0, 5, 1, 10}, {0x0, 5, 1, 10}, {0x0, 5, 1, 10},
+ {0xd, 1, 0, 10}, {0xd, 1, 0, 10}, {0xd, 1, 0, 10}, {0xd, 1, 0, 10},
+ {0x5, 3, 0, 10}, {0x5, 3, 0, 10}, {0x5, 3, 0, 10}, {0x5, 3, 0, 10},
+ {0x8, 2, 0, 10}, {0x8, 2, 0, 10}, {0x8, 2, 0, 10}, {0x8, 2, 0, 10},
+ {0x4, 3, 0, 10}, {0x4, 3, 0, 10}, {0x4, 3, 0, 10}, {0x4, 3, 0, 10},
+ {0x3, 4, 0, 10}, {0x3, 4, 0, 10}, {0x3, 4, 0, 10}, {0x3, 4, 0, 10},
+ {0x2, 4, 0, 10}, {0x2, 4, 0, 10}, {0x2, 4, 0, 10}, {0x2, 4, 0, 10},
+ {0x1, 7, 0, 10}, {0x1, 7, 0, 10}, {0x1, 7, 0, 10}, {0x1, 7, 0, 10},
+ {0x0, 0x14, 0, 10}, {0x0, 0x14, 0, 10}, {0x0, 0x14, 0, 10}, {0x0, 0x14, 0, 10},
+ {0x0, 0x13, 0, 10}, {0x0, 0x13, 0, 10}, {0x0, 0x13, 0, 10}, {0x0, 0x13, 0, 10},
+ {0x0, 0x17, 0, 11}, {0x0, 0x17, 0, 11}, {0x0, 0x18, 0, 11}, {0x0, 0x18, 0, 11},
+ {0x1, 8, 0, 11}, {0x1, 8, 0, 11}, {0x9, 2, 0, 11}, {0x9, 2, 0, 11},
+ {0x3, 2, 1, 11}, {0x3, 2, 1, 11}, {0x4, 2, 1, 11}, {0x4, 2, 1, 11},
+ {0xf, 1, 1, 11}, {0xf, 1, 1, 11}, {0x10, 1, 1, 11}, {0x10, 1, 1, 11},
+ {0, 0x19, 0, 12}, {0, 0x1a, 0, 12}, {0, 0x1b, 0, 12}, {1, 9, 0, 12},
+ {0x6, 3, 0, 12}, {0x1, 0xa, 0, 12}, {0x2, 5, 0, 12}, {0x7, 3, 0, 12},
+ {0xe, 1, 0, 12}, {0x0, 8, 1, 12}, {0x5, 2, 1, 12}, {0x6, 2, 1, 12},
+ {0x11, 1, 1, 12}, {0x12, 1, 1, 12}, {0x13, 1, 1, 12}, {0x14, 1, 1, 12},
+ {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7},
+ {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7},
+ {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7},
+ {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7},
+ {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7},
+ {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7},
+ {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7},
+ {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7}, {0x1b, 0xff, 0, 7}
+};
+
+#ifdef PV_ANNEX_IJKT_SUPPORT
+const VLCtab2 PV_DCT3Dtab6[] =
+{
+ {0x0, 3, 1, 7}, {0x4, 1, 1, 7}, {0x6, 1, 1, 7}, {0x5, 1, 1, 7}, {0x1, 3, 0, 7}, {0x2, 2, 0, 7},
+ {0x0, 9, 0, 7}, {0x5, 1, 0, 7}, {0x0, 2, 1, 6}, {0x0, 2, 1, 6}, {0x3, 1, 1, 6}, {0x3, 1, 1, 6},
+ {0x2, 1, 1, 6}, {0x2, 1, 1, 6}, {0x1, 1, 1, 6}, {0x1, 1, 1, 6}, {0x0, 6, 0, 6}, {0x0, 6, 0, 6},
+ {0x0, 7, 0, 6}, {0x0, 7, 0, 6}, {0x0, 8, 0, 6}, {0x0, 8, 0, 6}, {0x4, 1, 0, 6}, {0x4, 1, 0, 6},
+ {0x1, 2, 0, 6}, {0x1, 2, 0, 6}, {0x3, 1, 0, 6}, {0x3, 1, 0, 6}, {0x2, 1, 0, 5}, {0x2, 1, 0, 5},
+ {0x2, 1, 0, 5}, {0x2, 1, 0, 5}, {0x0, 4, 0, 5}, {0x0, 4, 0, 5}, {0x0, 4, 0, 5}, {0x0, 4, 0, 5},
+ {0x0, 5, 0, 5}, {0x0, 5, 0, 5}, {0x0, 5, 0, 5}, {0x0, 5, 0, 5}, {0x0, 1, 1, 4}, {0x0, 1, 1, 4},
+ {0x0, 1, 1, 4}, {0x0, 1, 1, 4}, {0x0, 1, 1, 4}, {0x0, 1, 1, 4}, {0x0, 1, 1, 4}, {0x0, 1, 1, 4},
+ {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2},
+ {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2},
+ {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2},
+ {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2},
+ {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 1, 0, 2},
+ {0x0, 1, 0, 2}, {0x0, 1, 0, 2}, {0x0, 2, 0, 3}, {0x0, 2, 0, 3}, {0x0, 2, 0, 3}, {0x0, 2, 0, 3},
+ {0x0, 2, 0, 3}, {0x0, 2, 0, 3}, {0x0, 2, 0, 3}, {0x0, 2, 0, 3}, {0x0, 2, 0, 3}, {0x0, 2, 0, 3},
+ {0x0, 2, 0, 3}, {0x0, 2, 0, 3}, {0x0, 2, 0, 3}, {0x0, 2, 0, 3}, {0x0, 2, 0, 3}, {0x0, 2, 0, 3},
+ {0x0, 3, 0, 4}, {0x0, 3, 0, 4}, {0x0, 3, 0, 4}, {0x0, 3, 0, 4}, {0x0, 3, 0, 4}, {0x0, 3, 0, 4},
+ {0x0, 3, 0, 4}, {0x0, 3, 0, 4}, {0x1, 1, 0, 4}, {0x1, 1, 0, 4}, {0x1, 1, 0, 4}, {0x1, 1, 0, 4},
+ {0x1, 1, 0, 4}, {0x1, 1, 0, 4}, {0x1, 1, 0, 4}, {0x1, 1, 0, 4}
+};
+
+const VLCtab2 PV_DCT3Dtab7[] =
+{
+ {0xb, 1, 0, 10}, {0xa, 1, 0, 10}, {0x0, 5, 1, 9}, {0x0, 5, 1, 9}, {0x0, 6, 1, 9}, {0x0, 6, 1, 9},
+ {0x1, 2, 1, 9}, {0x1, 2, 1, 9}, {0x2, 2, 1, 9}, {0x2, 2, 1, 9}, {0xf, 1, 1, 9}, {0xf, 1, 1, 9},
+ {0x10, 1, 1, 9}, {0x10, 1, 1, 9}, {0x12, 1, 1, 9}, {0x12, 1, 1, 9}, {0x11, 1, 1, 9}, {0x11, 1, 1, 9},
+ {0xe, 1, 1, 9}, {0xe, 1, 1, 9}, {0x0, 13, 0, 9}, {0x0, 13, 0, 9}, {0x0, 14, 0, 9}, {0x0, 14, 0, 9},
+ {0x0, 15, 0, 9}, {0x0, 15, 0, 9}, {0x0, 16, 0, 9}, {0x0, 16, 0, 9}, {0x0, 17, 0, 9}, {0x0, 17, 0, 9},
+ {0x0, 18, 0, 9}, {0x0, 18, 0, 9}, {0x0, 11, 0, 9}, {0x0, 11, 0, 9}, {0x0, 12, 0, 9}, {0x0, 12, 0, 9},
+ {0x5, 2, 0, 9}, {0x5, 2, 0, 9}, {0x4, 2, 0, 9}, {0x4, 2, 0, 9}, {0x9, 1, 0, 9}, {0x9, 1, 0, 9},
+ {0x8, 1, 0, 9}, {0x8, 1, 0, 9}, {0x0, 4, 1, 8}, {0x0, 4, 1, 8}, {0x0, 4, 1, 8}, {0x0, 4, 1, 8},
+ {0x7, 1, 1, 8}, {0x7, 1, 1, 8}, {0x7, 1, 1, 8}, {0x7, 1, 1, 8}, {0x8, 1, 1, 8}, {0x8, 1, 1, 8},
+ {0x8, 1, 1, 8}, {0x8, 1, 1, 8}, {0xd, 1, 1, 8}, {0xd, 1, 1, 8}, {0xd, 1, 1, 8}, {0xd, 1, 1, 8},
+ {0xc, 1, 1, 8}, {0xc, 1, 1, 8}, {0xc, 1, 1, 8}, {0xc, 1, 1, 8}, {0xb, 1, 1, 8}, {0xb, 1, 1, 8},
+ {0xb, 1, 1, 8}, {0xb, 1, 1, 8}, {0xa, 1, 1, 8}, {0xa, 1, 1, 8}, {0xa, 1, 1, 8}, {0xa, 1, 1, 8},
+ {0x9, 1, 1, 8}, {0x9, 1, 1, 8}, {0x9, 1, 1, 8}, {0x9, 1, 1, 8}, {0x0, 10, 0, 8}, {0x0, 10, 0, 8},
+ {0x0, 10, 0, 8}, {0x0, 10, 0, 8}, {0x6, 1, 0, 8}, {0x6, 1, 0, 8}, {0x6, 1, 0, 8}, {0x6, 1, 0, 8},
+ {0x3, 2, 0, 8}, {0x3, 2, 0, 8}, {0x3, 2, 0, 8}, {0x3, 2, 0, 8}, {0x1, 4, 0, 8}, {0x1, 4, 0, 8},
+ {0x1, 4, 0, 8}, {0x1, 4, 0, 8}, {0x7, 1, 0, 8}, {0x7, 1, 0, 8}, {0x7, 1, 0, 8}, {0x7, 1, 0, 8}
+};
+
+
+const VLCtab2 PV_DCT3Dtab8[] =
+{
+ {0x13, 0x1, 1, 11}, {0x13, 0x1, 1, 11}, {0x14, 0x1, 1, 11}, {0x14, 0x1, 1, 11}, {0x9, 0x2, 0, 11}, {0x9, 0x2, 0, 11},
+ {0x4, 0x3, 0, 11}, {0x4, 0x3, 0, 11}, {0x0, 0x7, 1, 10}, {0x0, 0x7, 1, 10}, {0x0, 0x7, 1, 10}, {0x0, 0x7, 1, 10},
+ {0x1, 0x3, 1, 10}, {0x1, 0x3, 1, 10}, {0x1, 0x3, 1, 10}, {0x1, 0x3, 1, 10}, {0x3, 0x2, 1, 10}, {0x3, 0x2, 1, 10},
+ {0x3, 0x2, 1, 10}, {0x3, 0x2, 1, 10}, {0x4, 0x2, 1, 10}, {0x4, 0x2, 1, 10}, {0x4, 0x2, 1, 10}, {0x4, 0x2, 1, 10},
+ {0xc, 0x1, 0, 10}, {0xc, 0x1, 0, 10}, {0xc, 0x1, 0, 10}, {0xc, 0x1, 0, 10}, {0x2, 0x4, 0, 10}, {0x2, 0x4, 0, 10},
+ {0x2, 0x4, 0, 10}, {0x2, 0x4, 0, 10}, {0x8, 0x2, 0, 10}, {0x8, 0x2, 0, 10}, {0x8, 0x2, 0, 10}, {0x8, 0x2, 0, 10},
+ {0x7, 0x2, 0, 10}, {0x7, 0x2, 0, 10}, {0x7, 0x2, 0, 10}, {0x7, 0x2, 0, 10}, {0x6, 0x2, 0, 10}, {0x6, 0x2, 0, 10},
+ {0x6, 0x2, 0, 10}, {0x6, 0x2, 0, 10}, {0x3, 0x3, 0, 10}, {0x3, 0x3, 0, 10}, {0x3, 0x3, 0, 10}, {0x3, 0x3, 0, 10},
+ {0x2, 0x3, 0, 10}, {0x2, 0x3, 0, 10}, {0x2, 0x3, 0, 10}, {0x2, 0x3, 0, 10}, {0x1, 0x5, 0, 10}, {0x1, 0x5, 0, 10},
+ {0x1, 0x5, 0, 10}, {0x1, 0x5, 0, 10}, {0xd, 0x1, 0, 11}, {0xd, 0x1, 0, 11}, {0x1, 0x6, 0, 11}, {0x1, 0x6, 0, 11},
+ {0x0, 0x14, 0, 11}, {0x0, 0x14, 0, 11}, {0x0, 0x13, 0, 11}, {0x0, 0x13, 0, 11}, {0x2, 0x3, 1, 11}, {0x2, 0x3, 1, 11},
+ {0x1, 0x4, 1, 11}, {0x1, 0x4, 1, 11}, {0x0, 0x9, 1, 11}, {0x0, 0x9, 1, 11}, {0x0, 0x8, 1, 11}, {0x0, 0x8, 1, 11},
+ {0x1, 0x7, 0, 12}, {0x3, 0x4, 0, 12}, {0x5, 0x3, 0, 12}, {0x0, 0x19, 0, 12}, {0x0, 0x18, 0, 12}, {0x0, 0x17, 0, 12},
+ {0x0, 0x16, 0, 12}, {0x0, 0x15, 0, 12}, {0x15, 0x1, 1, 12}, {0x16, 0x1, 1, 12}, {0x17, 0x1, 1, 12}, {0x7, 0x2, 1, 12},
+ {0x6, 0x2, 1, 12}, {0x5, 0x2, 1, 12}, {0x3, 0x3, 1, 12}, {0x0, 0xa, 1, 12}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7},
+ {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7},
+ {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7},
+ {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7},
+ {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7},
+ {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}, {0x2f, 0x3f, 1, 7}
+};
+#endif
+/* RVLC tables */
+const int ptrRvlcTab[11] = {0, 24, 46, 66, 84, 100, 114, 126, 134, 140, 144};
+
+const VLCtab2 RvlcDCTtabIntra[170] = /* 00xxxx00 or 00xxxx01 */
+{
+ {27, 255, 0, 5}, /* 0000 is escape code */
+ {1, 1, 0, 4},
+ {2, 1, 0, 5},
+ {3, 1, 0, 5},
+ {4, 1, 0, 6},
+ {5, 1, 0, 6},
+ {6, 1, 0, 7},
+ {7, 1, 0, 7},
+ {8, 1, 0, 8},
+ {9, 1, 0, 8},
+ {10, 1, 0, 9},
+ {5, 2, 0, 9},
+ {11, 1, 0, 10},
+ {12, 1, 0, 10},
+ {13, 1, 0, 11},
+ {9, 2, 0, 11},
+ {10, 2, 0, 12},
+ {4, 4, 0, 12},
+ {14, 1, 0, 13},
+ {15, 1, 0, 13},
+ {16, 1, 0, 14},
+ {17, 1, 0, 14},
+ {0, 27, 0, 15},
+ {3, 9, 0, 15},
+ /* 010xxxx00 or 010xxxx01 */
+ {1, 2, 0, 5},
+ {0, 4, 0, 5},
+ {0, 5, 0, 6},
+ {0, 6, 0, 6},
+ {2, 2, 0, 7},
+ {1, 3, 0, 7},
+ {3, 2, 0, 8},
+ {4, 2, 0, 8},
+ {2, 3, 0, 9},
+ {3, 3, 0, 9},
+ {6, 2, 0, 10},
+ {7, 2, 0, 10},
+ {5, 3, 0, 11},
+ {6, 3, 0, 11},
+ {5, 4, 0, 12},
+ {6, 4, 0, 12},
+ {11, 2, 0, 13},
+ {8, 3, 0, 13},
+ {18, 1, 0, 14},
+ {8, 4, 0, 14},
+ {6, 5, 0, 15},
+ {7, 5, 0, 15},
+ /* 0110xxxx00 or 0110xxxx01 */
+ {3, 1, 1, 6},
+ {4, 1, 1, 6},
+ {0, 7, 0, 7},
+ {7, 1, 1, 7},
+ {1, 4, 0, 8},
+ {1, 5, 0, 8},
+ {1, 6, 0, 9},
+ {0, 10, 0, 9},
+ {8, 2, 0, 10},
+ {4, 3, 0, 10},
+ {7, 3, 0, 11},
+ {3, 4, 0, 11},
+ {3, 5, 0, 12},
+ {4, 5, 0, 12},
+ {9, 3, 0, 13},
+ {7, 4, 0, 13},
+ {5, 5, 0, 14},
+ {4, 6, 0, 14},
+ {9, 4, 0, 15},
+ {12, 2, 0, 15},
+ /* 01110xxxx00 or 01110xxxx01 */
+ {8, 1, 1, 7},
+ {9, 1, 1, 7},
+ {0, 8, 0, 8},
+ {0, 9, 0, 8},
+ {0, 11, 0, 9},
+ {1, 2, 1, 9},
+ {2, 4, 0, 10},
+ {1, 7, 0, 10},
+ {2, 5, 0, 11},
+ {2, 6, 0, 11},
+ {1, 10, 0, 12},
+ {0, 18, 0, 12},
+ {3, 6, 0, 13},
+ {2, 7, 0, 13},
+ {5, 6, 0, 14},
+ {3, 7, 0, 14},
+ {19, 1, 0, 15},
+ {1, 5, 1, 15},
+ /* 011110xxxx00 or 011110xxxx01 */
+ {0, 2, 1, 8},
+ {12, 1, 1, 8},
+ {15, 1, 1, 9},
+ {16, 1, 1, 9},
+ {0, 12, 0, 10},
+ {0, 13, 0, 10},
+ {1, 8, 0, 11},
+ {1, 9, 0, 11},
+ {0, 19, 0, 12},
+ {0, 22, 0, 12},
+ {2, 8, 0, 13},
+ {2, 9, 0, 13},
+ {3, 8, 0, 14},
+ {2, 10, 0, 14},
+ {2, 3, 1, 15},
+ {13, 2, 1, 15},
+ /* 0111110xxxx00 or 0111110xxxx01 */
+ {17, 1, 1, 9},
+ {18, 1, 1, 9},
+ {0, 14, 0, 10},
+ {21, 1, 1, 10},
+ {0, 15, 0, 11},
+ {0, 16, 0, 11},
+ {1, 3, 1, 12},
+ {3, 2, 1, 12},
+ {1, 11, 0, 13},
+ {0, 20, 0, 13},
+ {2, 11, 0, 14},
+ {1, 12, 0, 14},
+ {41, 1, 1, 15},
+ {42, 1, 1, 15},
+ /* 01111110xxxx00 or 01111110xxxx01 */
+ {22, 1, 1, 10},
+ {23, 1, 1, 10},
+ {0, 17, 0, 11},
+ {0, 3, 1, 11},
+ {4, 2, 1, 12},
+ {29, 1, 1, 12},
+ {0, 21, 0, 13},
+ {0, 23, 0, 13},
+ {1, 13, 0, 14},
+ {0, 24, 0, 14},
+ {43, 1, 1, 15},
+ {44, 1, 1, 15},
+ /* 011111110xxxx00 or 011111110xxxx01 */
+ {2, 2, 1, 11},
+ {26, 1, 1, 11},
+ {30, 1, 1, 12},
+ {31, 1, 1, 12},
+ {0, 4, 1, 13},
+ {5, 2, 1, 13},
+ {0, 25, 0, 14},
+ {0, 26, 0, 14},
+ /* 0111111110xxxx00 or 0111111110xxxx01 */
+ {32, 1, 1, 12},
+ {33, 1, 1, 12},
+ {6, 2, 1, 13},
+ {7, 2, 1, 13},
+ {0, 5, 1, 14},
+ {1, 4, 1, 14},
+ /* 01111111110xxxx00 or 01111111110xxxx01 */
+ {8, 2, 1, 13},
+ {9, 2, 1, 13},
+ {10, 2, 1, 14},
+ {11, 2, 1, 14},
+ /* 011111111110xxxx00 or 011111111110xxxx01 */
+ {12, 2, 1, 14},
+ {38, 1, 1, 14},
+ /* 1xxxx10 or 1xxxx11 from 11 zeros to 0 zeros*/
+ {0, 1, 0, 3},
+ {0, 2, 0, 3},
+ {0, 3, 0, 4},
+ {0, 1, 1, 4},
+ {1, 1, 1, 5},
+ {2, 1, 1, 5},
+ {5, 1, 1, 6},
+ {6, 1, 1, 6},
+ {10, 1, 1, 7},
+ {11, 1, 1, 7},
+ {13, 1, 1, 8},
+ {14, 1, 1, 8},
+ {19, 1, 1, 9},
+ {20, 1, 1, 9},
+ {24, 1, 1, 10},
+ {25, 1, 1, 10},
+ {27, 1, 1, 11},
+ {28, 1, 1, 11},
+ {34, 1, 1, 12},
+ {35, 1, 1, 12},
+ {36, 1, 1, 13},
+ {37, 1, 1, 13},
+ {39, 1, 1, 14},
+ {40, 1, 1, 14}
+};
+
+const VLCtab2 RvlcDCTtabInter[170] = /* 00xxxx00 or 00xxxx01 */
+{
+ {27, 255, 0, 5}, /* 0000 is escape code */
+ {0, 2, 0, 4},
+ {0, 3, 0, 5},
+ {3, 1, 0, 5},
+ {1, 2, 0, 6},
+ {6, 1, 0, 6},
+ {0, 4, 0, 7},
+ {2, 2, 0, 7},
+ {0, 5, 0, 8},
+ {0, 6, 0, 8},
+ {0, 7, 0, 9},
+ {1, 4, 0, 9},
+ {0, 8, 0, 10},
+ {0, 9, 0, 10},
+ {0, 10, 0, 11},
+ {0, 11, 0, 11},
+ {0, 12, 0, 12},
+ {1, 7, 0, 12},
+ {0, 13, 0, 13},
+ {0, 14, 0, 13},
+ {0, 17, 0, 14},
+ {0, 18, 0, 14},
+ {0, 19, 0, 15},
+ {3, 7, 0, 15},
+ /* 010xxxx00 or 010xxxx01 */
+ {4, 1, 0, 5},
+ {5, 1, 0, 5},
+ {7, 1, 0, 6},
+ {8, 1, 0, 6},
+ {9, 1, 0, 7},
+ {10, 1, 0, 7},
+ {1, 3, 0, 8},
+ {3, 2, 0, 8},
+ {2, 3, 0, 9},
+ {5, 2, 0, 9},
+ {1, 5, 0, 10},
+ {3, 3, 0, 10},
+ {1, 6, 0, 11},
+ {2, 4, 0, 11},
+ {2, 5, 0, 12},
+ {3, 4, 0, 12},
+ {0, 15, 0, 13},
+ {0, 16, 0, 13},
+ {1, 9, 0, 14},
+ {1, 10, 0, 14},
+ {4, 5, 0, 15},
+ {7, 4, 0, 15},
+ /* 0110xxxx00 or 0110xxxx01 */
+ {3, 1, 1, 6},
+ {4, 1, 1, 6},
+ {11, 1, 0, 7},
+ {7, 1, 1, 7},
+ {4, 2, 0, 8},
+ {12, 1, 0, 8},
+ {15, 1, 0, 9},
+ {16, 1, 0, 9},
+ {6, 2, 0, 10},
+ {7, 2, 0, 10},
+ {4, 3, 0, 11},
+ {5, 3, 0, 11},
+ {6, 3, 0, 12},
+ {7, 3, 0, 12},
+ {1, 8, 0, 13},
+ {3, 5, 0, 13},
+ {2, 6, 0, 14},
+ {2, 7, 0, 14},
+ {17, 2, 0, 15},
+ {37, 1, 0, 15},
+ /* 01110xxxx00 or 01110xxxx01 */
+ {8, 1, 1, 7},
+ {9, 1, 1, 7},
+ {13, 1, 0, 8},
+ {14, 1, 0, 8},
+ {17, 1, 0, 9},
+ {1, 2, 1, 9},
+ {8, 2, 0, 10},
+ {9, 2, 0, 10},
+ {10, 2, 0, 11},
+ {21, 1, 0, 11},
+ {11, 2, 0, 12},
+ {27, 1, 0, 12},
+ {4, 4, 0, 13},
+ {5, 4, 0, 13},
+ {3, 6, 0, 14},
+ {6, 4, 0, 14},
+ {38, 1, 0, 15},
+ {1, 5, 1, 15},
+ /* 011110xxxx00 or 011110xxxx01 */
+ {0, 2, 1, 8},
+ {12, 1, 1, 8},
+ {15, 1, 1, 9},
+ {16, 1, 1, 9},
+ {18, 1, 0, 10},
+ {19, 1, 0, 10},
+ {22, 1, 0, 11},
+ {23, 1, 0, 11},
+ {28, 1, 0, 12},
+ {29, 1, 0, 12},
+ {8, 3, 0, 13},
+ {12, 2, 0, 13},
+ {9, 3, 0, 14},
+ {13, 2, 0, 14},
+ {2, 3, 1, 15},
+ {13, 2, 1, 15},
+ /* 0111110xxxx00 or 0111110xxxx01 */
+ {17, 1, 1, 9},
+ {18, 1, 1, 9},
+ {20, 1, 0, 10},
+ {21, 1, 1, 10},
+ {24, 1, 0, 11},
+ {25, 1, 0, 11},
+ {1, 3, 1, 12},
+ {3, 2, 1, 12},
+ {30, 1, 0, 13},
+ {31, 1, 0, 13},
+ {14, 2, 0, 14},
+ {15, 2, 0, 14},
+ {41, 1, 1, 15},
+ {42, 1, 1, 15},
+ /* 01111110xxxx00 or 01111110xxxx01 */
+ {22, 1, 1, 10},
+ {23, 1, 1, 10},
+ {26, 1, 0, 11},
+ {0, 3, 1, 11},
+ {4, 2, 1, 12},
+ {29, 1, 1, 12},
+ {32, 1, 0, 13},
+ {33, 1, 0, 13},
+ {16, 2, 0, 14},
+ {34, 1, 0, 14},
+ {43, 1, 1, 15},
+ {44, 1, 1, 15},
+ /* 011111110xxxx00 or 011111110xxxx01 */
+ {2, 2, 1, 11},
+ {26, 1, 1, 11},
+ {30, 1, 1, 12},
+ {31, 1, 1, 12},
+ {0, 4, 1, 13},
+ {5, 2, 1, 13},
+ {35, 1, 0, 14},
+ {36, 1, 0, 14},
+ /* 0111111110xxxx00 or 0111111110xxxx01 */
+ {32, 1, 1, 12},
+ {33, 1, 1, 12},
+ {6, 2, 1, 13},
+ {7, 2, 1, 13},
+ {0, 5, 1, 14},
+ {1, 4, 1, 14},
+ /* 01111111110xxxx00 or 01111111110xxxx01 */
+ {8, 2, 1, 13},
+ {9, 2, 1, 13},
+ {10, 2, 1, 14},
+ {11, 2, 1, 14},
+ /* 011111111110xxxx00 or 011111111110xxxx01 */
+ {12, 2, 1, 14},
+ {38, 1, 1, 14},
+ /* 1xxxx10 or 1xxxx11 from 11 zeros to 0 zeros*/
+ {0, 1, 0, 3},
+ {1, 1, 0, 3},
+ {2, 1, 0, 4},
+ {0, 1, 1, 4},
+ {1, 1, 1, 5},
+ {2, 1, 1, 5},
+ {5, 1, 1, 6},
+ {6, 1, 1, 6},
+ {10, 1, 1, 7},
+ {11, 1, 1, 7},
+ {13, 1, 1, 8},
+ {14, 1, 1, 8},
+ {19, 1, 1, 9},
+ {20, 1, 1, 9},
+ {24, 1, 1, 10},
+ {25, 1, 1, 10},
+ {27, 1, 1, 11},
+ {28, 1, 1, 11},
+ {34, 1, 1, 12},
+ {35, 1, 1, 12},
+ {36, 1, 1, 13},
+ {37, 1, 1, 13},
+ {39, 1, 1, 14},
+ {40, 1, 1, 14}
+};
+
+/*----------------------------------------------------------------------------
+; EXTERNAL FUNCTION REFERENCES
+; Declare functions defined elsewhere and referenced in this module
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; FUNCTION CODE
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; Define all local variables
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; Function body here
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; Return nothing or data or data pointer
+----------------------------------------------------------------------------*/
+
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
new file mode 100644
index 0000000..74fe478
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
@@ -0,0 +1,1643 @@
+/* ------------------------------------------------------------------
+ * 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 "mp4dec_lib.h"
+#include "bitstream.h"
+#include "vlc_decode.h"
+#include "zigzag.h"
+
+#define OSCL_DISABLE_WARNING_CONV_POSSIBLE_LOSS_OF_DATA
+
+#ifdef PV_SUPPORT_MAIN_PROFILE
+/* INTRA */
+const static int mpeg_iqmat_def[NCOEFF_BLOCK] =
+{
+ 8, 17, 18, 19, 21, 23, 25, 27,
+ 17, 18, 19, 21, 23, 25, 27, 28,
+ 20, 21, 22, 23, 24, 26, 28, 30,
+ 21, 22, 23, 24, 26, 28, 30, 32,
+ 22, 23, 24, 26, 28, 30, 32, 35,
+ 23, 24, 26, 28, 30, 32, 35, 38,
+ 25, 26, 28, 30, 32, 35, 38, 41,
+ 27, 28, 30, 32, 35, 38, 41, 45
+};
+
+/* INTER */
+const static int mpeg_nqmat_def[64] =
+{
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 17, 18, 19, 20, 21, 22, 23, 24,
+ 18, 19, 20, 21, 22, 23, 24, 25,
+ 19, 20, 21, 22, 23, 24, 26, 27,
+ 20, 21, 22, 23, 25, 26, 27, 28,
+ 21, 22, 23, 24, 26, 27, 28, 30,
+ 22, 23, 24, 26, 27, 28, 30, 31,
+ 23, 24, 25, 27, 28, 30, 31, 33
+};
+#endif
+
+/* ======================================================================== */
+/* Function : CalcNumBits() */
+/* Purpose : */
+/* In/out : */
+/* Return : Calculate the minimum number of bits required to */
+/* represent x. */
+/* Note : This is an equivalent implementation of */
+/* (long)ceil(log((double)x)/log(2.0)) */
+/* Modified : */
+/* ======================================================================== */
+int CalcNumBits(uint x)
+{
+ int i = 1;
+ while (x >>= 1) i++;
+ return i;
+}
+
+
+
+/***********************************************************CommentBegin******
+*
+* -- DecodeVolHeader -- Decode the header of a VOL
+*
+* 04/10/2000 : initial modification to the new PV-Decoder Lib format.
+* 10/12/2001 : reject non compliant bitstreams
+*
+***********************************************************CommentEnd********/
+PV_STATUS DecodeVOLHeader(VideoDecData *video, int layer)
+{
+ PV_STATUS status;
+ Vol *currVol;
+ BitstreamDecVideo *stream;
+ uint32 tmpvar, vol_shape;
+ uint32 startCode;
+#ifdef PV_SUPPORT_MAIN_PROFILE
+ int *qmat, i, j;
+#endif
+ int version_id = 1;
+#ifdef PV_TOLERATE_VOL_ERRORS
+ uint32 profile = 0x01;
+#endif
+ /* There's a "currLayer" variable inside videoDecData. */
+ /* However, we don't maintain it until we decode frame data. 04/05/2000 */
+ currVol = video->vol[layer];
+ stream = currVol->bitstream;
+ currVol->moduloTimeBase = 0;
+
+ /* Determine which start code for the decoder to begin with */
+ status = BitstreamShowBits32HC(stream, &startCode);
+
+ if (startCode == VISUAL_OBJECT_SEQUENCE_START_CODE)
+ { /* Bitstream Exhchange Fix 9/99 */
+ /* Bitstream Exchange requires we allow start with Video Object Sequence */
+ /* visual_object_sequence_start_code */
+ (void) BitstreamReadBits32HC(stream);
+ tmpvar = (uint32) BitstreamReadBits16(stream, 8); /* profile */
+#ifndef PV_TOLERATE_VOL_ERRORS
+ if (layer) /* */
+ {
+ /* support SSPL0-2 */
+ if (tmpvar != 0x10 && tmpvar != 0x11 && tmpvar != 0x12 &&
+ tmpvar != 0xA1 && tmpvar != 0xA2 && tmpvar != 0xA3/* Core SP@L1-L3 */)
+ return PV_FAIL;
+ }
+ else
+ {
+ /* support SPL0-3 & SSPL0-2 */
+ if (tmpvar != 0x01 && tmpvar != 0x02 && tmpvar != 0x03 && tmpvar != 0x08 &&
+ tmpvar != 0x10 && tmpvar != 0x11 && tmpvar != 0x12 &&
+ tmpvar != 0x21 && tmpvar != 0x22 && /* Core Profile Levels */
+ tmpvar != 0xA1 && tmpvar != 0xA2 && tmpvar != 0xA3 &&
+ tmpvar != 0xF0 && tmpvar != 0xF1 && /* Advanced Simple Profile Levels*/
+ tmpvar != 0xF2 && tmpvar != 0xF3 &&
+ tmpvar != 0xF4 && tmpvar != 0xF5)
+ return PV_FAIL;
+ }
+#else
+ profile = tmpvar;
+#endif
+
+ // save the profile and level for the query
+ currVol->profile_level_id = (uint)tmpvar; // 6/10/04
+
+
+
+ status = BitstreamShowBits32HC(stream, &tmpvar);
+ if (tmpvar == USER_DATA_START_CODE)
+ {
+ /* Something has to be done with user data 11/11/99 */
+ status = DecodeUserData(stream);
+ if (status != PV_SUCCESS) return PV_FAIL;
+ }
+ /* visual_object_start_code */
+ BitstreamShowBits32HC(stream, &tmpvar);
+ if (tmpvar != VISUAL_OBJECT_START_CODE)
+ {
+ do
+ {
+ /* Search for VOL_HEADER */
+ status = PVSearchNextM4VFrame(stream); /* search 0x00 0x00 0x01 */
+ if (status != PV_SUCCESS) return PV_FAIL; /* breaks the loop */
+ BitstreamShowBits32(stream, VOL_START_CODE_LENGTH, &tmpvar);
+ PV_BitstreamFlushBits(stream, 8);
+ }
+ while (tmpvar != VOL_START_CODE);
+ goto decode_vol;
+ }
+ else
+ {
+ BitstreamReadBits32HC(stream);
+ }
+
+ /* is_visual_object_identifier */
+ tmpvar = (uint32) BitstreamRead1Bits(stream);
+ if (tmpvar)
+ {
+ /* visual_object_verid */
+ tmpvar = (uint32) BitstreamReadBits16(stream, 4);
+ /* visual_object_priority */
+ tmpvar = (uint32) BitstreamReadBits16(stream, 3);
+ }
+ /* visual_object_type */
+ BitstreamShowBits32(stream, 4, &tmpvar);
+ if (tmpvar == 1)
+ { /* video_signal_type */
+ PV_BitstreamFlushBits(stream, 4);
+ tmpvar = (uint32) BitstreamRead1Bits(stream);
+ if (tmpvar == 1)
+ {
+ /* video_format */
+ tmpvar = (uint32) BitstreamReadBits16(stream, 3);
+ /* video_range */
+ tmpvar = (uint32) BitstreamRead1Bits(stream);
+ /* color_description */
+ tmpvar = (uint32) BitstreamRead1Bits(stream);
+ if (tmpvar == 1)
+ {
+ /* color_primaries */
+ tmpvar = (uint32) BitstreamReadBits16(stream, 8);
+ /* transfer_characteristics */
+ tmpvar = (uint32) BitstreamReadBits16(stream, 8);
+ /* matrix_coefficients */
+ tmpvar = (uint32) BitstreamReadBits16(stream, 8);
+ }
+ }
+ }
+ else
+ {
+ do
+ {
+ /* Search for VOL_HEADER */
+ status = PVSearchNextM4VFrame(stream); /* search 0x00 0x00 0x01 */
+ if (status != PV_SUCCESS) return PV_FAIL; /* breaks the loop */
+ BitstreamShowBits32(stream, VOL_START_CODE_LENGTH, &tmpvar);
+ PV_BitstreamFlushBits(stream, 8);
+ }
+ while (tmpvar != VOL_START_CODE);
+ goto decode_vol;
+ }
+
+ /* next_start_code() */
+ status = PV_BitstreamByteAlign(stream); /* 10/12/01 */
+ status = BitstreamShowBits32HC(stream, &tmpvar);
+
+ if (tmpvar == USER_DATA_START_CODE)
+ {
+ /* Something has to be done to deal with user data (parse it) 11/11/99 */
+ status = DecodeUserData(stream);
+ if (status != PV_SUCCESS) return PV_FAIL;
+ }
+ status = BitstreamShowBits32(stream, 27, &tmpvar); /* 10/12/01 */
+ }
+ else
+ {
+ /* tmpvar = 0; */ /* 10/12/01 */
+ status = BitstreamShowBits32(stream, 27, &tmpvar); /* uncomment this line if you want
+ to start decoding with a
+ video_object_start_code */
+ }
+
+ if (tmpvar == VO_START_CODE)
+ {
+ /*****
+ *
+ * Read the VOL header entries from the bitstream
+ *
+ *****/
+ /* video_object_start_code */
+ tmpvar = BitstreamReadBits32(stream, 27);
+ tmpvar = (uint32) BitstreamReadBits16(stream, 5);
+
+
+ /* video_object_layer_start_code */
+ BitstreamShowBits32(stream, VOL_START_CODE_LENGTH, &tmpvar);
+ if (tmpvar != VOL_START_CODE)
+ {
+ status = BitstreamCheckEndBuffer(stream);
+ if (status == PV_END_OF_VOP)
+ {
+ video->shortVideoHeader = TRUE;
+ return PV_SUCCESS;
+ }
+ else
+ {
+ do
+ {
+ /* Search for VOL_HEADER */
+ status = PVSearchNextM4VFrame(stream);/* search 0x00 0x00 0x01 */
+ if (status != PV_SUCCESS) return PV_FAIL; /* breaks the loop */
+ BitstreamShowBits32(stream, VOL_START_CODE_LENGTH, &tmpvar);
+ PV_BitstreamFlushBits(stream, 8); /* advance the byte ptr */
+ }
+ while (tmpvar != VOL_START_CODE);
+ }
+ }
+ else
+ {
+ PV_BitstreamFlushBits(stream, 8);
+ }
+
+decode_vol:
+ PV_BitstreamFlushBits(stream, VOL_START_CODE_LENGTH - 8);
+ video->shortVideoHeader = 0;
+
+ /* vol_id (4 bits) */
+ currVol->volID = (int) BitstreamReadBits16(stream, 4);
+
+ /* RandomAccessible flag */
+ tmpvar = (uint32) BitstreamRead1Bits(stream);
+
+ /* object type */
+ tmpvar = (uint32) BitstreamReadBits16(stream, 8); /* */
+
+#ifdef PV_TOLERATE_VOL_ERRORS
+ if (tmpvar == 0)
+ {
+ if (layer) /* */
+ {
+ /* support SSPL0-2 */
+ if (profile != 0x10 && profile != 0x11 && profile != 0x12)
+ return PV_FAIL;
+ tmpvar = 0x02;
+ }
+ else
+ {
+ /* support SPL0-3 & SSPL0-2 */
+ if (profile != 0x01 && profile != 0x02 && profile != 0x03 && profile != 0x08 &&
+ profile != 0x10 && profile != 0x11 && profile != 0x12)
+ return PV_FAIL;
+ tmpvar = 0x01;
+ }
+ profile |= 0x0100;
+ }
+#endif
+
+ if (layer)
+ {
+ if (tmpvar != 0x02) return PV_FAIL;
+ }
+ else
+ {
+ if (tmpvar != 0x01) return PV_FAIL;
+ }
+
+ /* version id specified? */
+ tmpvar = (uint32) BitstreamRead1Bits(stream);
+ if (tmpvar == 1)
+ {
+ /* version ID */
+ version_id = (uint32) BitstreamReadBits16(stream, 4);
+ /* priority */
+ tmpvar = (uint32) BitstreamReadBits16(stream, 3);
+
+ }
+
+ /* aspect ratio info */
+ tmpvar = (uint32) BitstreamReadBits16(stream, 4);
+ if (tmpvar == 0) return PV_FAIL;
+ if (tmpvar == 0xf /* extended_par */)
+ {
+ /* width */
+ tmpvar = (uint32) BitstreamReadBits16(stream, 8);
+ /* height */
+ tmpvar = (uint32) BitstreamReadBits16(stream, 8);
+ }
+
+
+ /* control parameters present? */
+ tmpvar = (uint32) BitstreamRead1Bits(stream);
+
+ /* Get the parameters (skipped) */
+ /* 03/10/99 */
+ if (tmpvar)
+ {
+ /* chroma_format */
+ tmpvar = BitstreamReadBits16(stream, 2);
+ if (tmpvar != 1) return PV_FAIL;
+ /* low_delay */
+ tmpvar = BitstreamRead1Bits(stream);
+
+ /* vbv_parameters present? */
+ tmpvar = (uint32) BitstreamRead1Bits(stream);
+ if (tmpvar)
+ {
+ /* first_half_bit_rate */
+ BitstreamReadBits16(stream, 15);
+ if (!BitstreamRead1Bits(stream)) return PV_FAIL;
+ /* latter_half_bit_rate */
+ BitstreamReadBits16(stream, 15);
+ if (!BitstreamRead1Bits(stream)) return PV_FAIL;
+ /* first_half_vbv_buffer_size */
+ BitstreamReadBits16(stream, 15);
+ if (!BitstreamRead1Bits(stream)) return PV_FAIL;
+ /* latter_half_vbv_buffer_size */
+ BitstreamReadBits16(stream, 3);
+ /* first_half_vbv_occupancy */
+ BitstreamReadBits16(stream, 11);
+ if (!BitstreamRead1Bits(stream)) return PV_FAIL;
+ /* latter_half_vbv_occupancy */
+ BitstreamReadBits16(stream, 15);
+ if (!BitstreamRead1Bits(stream)) return PV_FAIL;
+ }
+ }
+
+ /* video_object_layer_shape (2 bits), only 00 (rect) is supported for now */
+ vol_shape = (uint32) BitstreamReadBits16(stream, 2);
+ if (vol_shape) return PV_FAIL;
+
+ /* marker bit, 03/10/99 */
+ if (!BitstreamRead1Bits(stream)) return PV_FAIL;
+
+ /* vop_time_increment_resolution */
+ currVol->timeIncrementResolution = BitstreamReadBits16(stream, 16);
+ if (currVol->timeIncrementResolution == 0) return PV_FAIL;
+
+ /* . since nbitsTimeIncRes will be used over and over again, */
+ /* we should put it in Vol structure. 04/12/2000. */
+ currVol->nbitsTimeIncRes = CalcNumBits((uint)currVol->timeIncrementResolution - 1);
+
+ if (!BitstreamRead1Bits(stream)) return PV_FAIL;
+
+ /* fixed_vop_rate */
+ currVol->fixedVopRate = (int) BitstreamRead1Bits(stream);
+ if (currVol->fixedVopRate)
+ {
+ /* fixed_vop_time_increment */
+ tmpvar = BitstreamReadBits16(stream, currVol->nbitsTimeIncRes);
+ }
+
+ /* marker bit */
+ if (!BitstreamRead1Bits(stream)) return PV_FAIL;
+
+ /* video_object_layer_width (13 bits) */
+ video->displayWidth = video->width = (int) BitstreamReadBits16(stream, 13);
+
+ /* round up to a multiple of MB_SIZE. 08/09/2000 */
+ video->width = (video->width + 15) & -16;
+// video->displayWidth += (video->displayWidth & 0x1); /* displayed image should be even size */
+
+ /* marker bit */
+ if (!BitstreamRead1Bits(stream)) return PV_FAIL;
+
+ /* video_object_layer_height (13 bits) */
+ video->displayHeight = video->height = (int) BitstreamReadBits16(stream, 13);
+
+ /* round up to a multiple of MB_SIZE. 08/09/2000 */
+ video->height = (video->height + 15) & -16;
+// video->displayHeight += (video->displayHeight & 0x1); /* displayed image should be even size */
+ if (!BitstreamRead1Bits(stream)) return PV_FAIL;
+
+ /* 03/10/99 */
+ /* interlaced */
+ tmpvar = (uint32) BitstreamRead1Bits(stream);
+ if (tmpvar != 0)
+ {
+ mp4dec_log("DecodeVOLHeader(): Interlaced video is not supported.\n");
+ return PV_FAIL;
+ }
+
+ /* obmc_disable */
+ tmpvar = (uint32) BitstreamRead1Bits(stream);
+ if (tmpvar == 0) return PV_FAIL;
+
+ if (version_id == 1)
+ {
+ /* sprite_enable (1 bits) */
+ tmpvar = (uint32) BitstreamRead1Bits(stream);
+ if (tmpvar)
+ {
+ mp4dec_log("DecodeVOLHeader(): Sprite is not supported.\n");
+ return PV_FAIL;
+ }
+ }
+ else
+ {
+ /* For version 2, vol_sprite_usage has two bits. */
+ /* sprite_enable */
+ tmpvar = (uint32) BitstreamReadBits16(stream, 2);
+ if (tmpvar)
+ {
+ mp4dec_log("DecodeVOLHeader(): Sprite is not supported.\n");
+ return PV_FAIL;
+ }
+ }
+
+ /* not_8_bit */
+ if (BitstreamRead1Bits(stream))
+ {
+ /* quant_precision */
+ currVol->quantPrecision = BitstreamReadBits16(stream, 4);
+ /* bits_per_pixel */
+ currVol->bitsPerPixel = BitstreamReadBits16(stream, 4);
+ mp4dec_log("DecodeVOLHeader(): not an 8-bit stream.\n"); // For the time being we do not support != 8 bits
+
+ return PV_FAIL;
+ }
+ else
+ {
+ currVol->quantPrecision = 5;
+ currVol->bitsPerPixel = 8;
+ }
+
+ /* quant_type (1 bit) */
+ currVol->quantType = BitstreamRead1Bits(stream);
+ if (currVol->quantType)
+ {
+#ifdef PV_SUPPORT_MAIN_PROFILE
+ /* load quantization matrices. 5/22/2000 */
+ /* load_intra_quant_mat (1 bit) */
+ qmat = currVol->iqmat;
+ currVol->loadIntraQuantMat = BitstreamRead1Bits(stream);
+ if (currVol->loadIntraQuantMat)
+ {
+ /* intra_quant_mat (8*64 bits) */
+ i = 0;
+ do
+ {
+ qmat[*(zigzag_inv+i)] = (int) BitstreamReadBits16(stream, 8);
+ }
+ while ((qmat[*(zigzag_inv+i)] != 0) && (++i < 64));
+
+ for (j = i; j < 64; j++)
+ qmat[*(zigzag_inv+j)] = qmat[*(zigzag_inv+i-1)];
+ }
+ else
+ {
+ oscl_memcpy(qmat, mpeg_iqmat_def, 64*sizeof(int));
+ }
+
+ qmat[0] = 0; /* necessary for switched && MPEG quant 07/09/01 */
+
+ /* load_nonintra_quant_mat (1 bit) */
+ qmat = currVol->niqmat;
+ currVol->loadNonIntraQuantMat = BitstreamRead1Bits(stream);
+ if (currVol->loadNonIntraQuantMat)
+ {
+ /* nonintra_quant_mat (8*64 bits) */
+ i = 0;
+ do
+ {
+ qmat[*(zigzag_inv+i)] = (int) BitstreamReadBits16(stream, 8);
+ }
+ while ((qmat[*(zigzag_inv+i)] != 0) && (++i < 64));
+
+ for (j = i; j < 64; j++)
+ qmat[*(zigzag_inv+j)] = qmat[*(zigzag_inv+i-1)];
+ }
+ else
+ {
+ oscl_memcpy(qmat, mpeg_nqmat_def, 64*sizeof(int));
+ }
+#else
+ return PV_FAIL;
+#endif
+ }
+
+ if (version_id != 1)
+ {
+ /* quarter_sample enabled */
+ tmpvar = BitstreamRead1Bits(stream);
+ if (tmpvar) return PV_FAIL;
+ }
+
+ /* complexity_estimation_disable */
+ currVol->complexity_estDisable = BitstreamRead1Bits(stream);
+ if (currVol->complexity_estDisable == 0)
+ {
+ currVol->complexity_estMethod = BitstreamReadBits16(stream, 2);
+
+ if (currVol->complexity_estMethod < 2)
+ {
+ /* shape_complexity_estimation_disable */
+ tmpvar = BitstreamRead1Bits(stream);
+ if (tmpvar == 0)
+ {
+ mp4dec_log("DecodeVOLHeader(): Shape Complexity estimation is not supported.\n");
+ return PV_FAIL;
+ }
+ /* texture_complexity_estimation_set_1_disable */
+ tmpvar = BitstreamRead1Bits(stream);
+ if (tmpvar == 0)
+ {
+ currVol->complexity.text_1 = BitstreamReadBits16(stream, 4);
+ }
+ /* marker bit */
+ if (!BitstreamRead1Bits(stream)) return PV_FAIL;
+ /* texture_complexity_estimation_set_2_disable */
+ tmpvar = BitstreamRead1Bits(stream);
+ if (tmpvar == 0)
+ {
+ currVol->complexity.text_2 = BitstreamReadBits16(stream, 4);
+ }
+ /* motion_compensation_complexity_disable */
+ tmpvar = BitstreamRead1Bits(stream);
+ if (tmpvar == 0)
+ {
+ currVol->complexity.mc = BitstreamReadBits16(stream, 6);
+ }
+ /* marker bit */
+ if (!BitstreamRead1Bits(stream)) return PV_FAIL;
+
+ if (currVol->complexity_estMethod == 1)
+ { /* version2_complexity_estimation_disable */
+ tmpvar = BitstreamRead1Bits(stream);
+ if (tmpvar == 0)
+ {
+ mp4dec_log("DecodeVOLHeader(): sadct, quarter pel not supported.\n");
+ return PV_FAIL;
+ }
+ }
+ }
+ }
+
+ /* 03/10/99 */
+ /* resync_marker_disable */
+ currVol->errorResDisable = (int) BitstreamRead1Bits(stream);
+ /* data_partititioned */
+ currVol->dataPartitioning = (int) BitstreamRead1Bits(stream);
+
+ video->vlcDecCoeffIntra = &VlcDecTCOEFIntra;
+ video->vlcDecCoeffInter = &VlcDecTCOEFInter;
+
+ if (currVol->dataPartitioning)
+ {
+ if (layer) return PV_FAIL; /* */
+ /* reversible_vlc */
+ currVol->useReverseVLC = (int)BitstreamRead1Bits(stream);
+ if (currVol->useReverseVLC)
+ {
+ video->vlcDecCoeffIntra = &RvlcDecTCOEFIntra;
+ video->vlcDecCoeffInter = &RvlcDecTCOEFInter;
+ }
+ currVol->errorResDisable = 0;
+ }
+ else
+ {
+ currVol->useReverseVLC = 0;
+ }
+
+ if (version_id != 1)
+ {
+ /* newpred_enable */
+ tmpvar = BitstreamRead1Bits(stream);
+ if (tmpvar) return PV_FAIL;
+
+ /* reduced_resolution_vop */
+ tmpvar = BitstreamRead1Bits(stream);
+ if (tmpvar) return PV_FAIL;
+
+ }
+
+ /* Intra AC/DC prediction is always true */
+ video->intra_acdcPredDisable = 0;
+ /* scalability */
+ currVol->scalability = (int) BitstreamRead1Bits(stream);
+
+ if (currVol->scalability)
+ {
+ if (layer == 0) return PV_FAIL; /* */
+ /* hierarchy_type: 1 : temporal, 0 : spatial */
+ /* 03/10/99 */
+ currVol->scalType = (int) BitstreamRead1Bits(stream); /* */
+ if (!currVol->scalType) return PV_FAIL;
+
+ /* ref_layer_id (4 bits) */
+ currVol->refVolID = (int) BitstreamReadBits16(stream, 4);
+ if (layer) /* */
+ {
+ if (currVol->refVolID != video->vol[0]->volID) return PV_FAIL;
+ }
+ /* ref_layer_sampling_direc (1 bits) */
+ /* 1 : ref. layer has higher resolution */
+ /* 0 : ref. layer has equal or lower resolution */
+ currVol->refSampDir = (int) BitstreamRead1Bits(stream);
+ if (currVol->refSampDir) return PV_FAIL;
+
+ /* hor_sampling_factor_n (5 bits) */
+ currVol->horSamp_n = (int) BitstreamReadBits16(stream, 5);
+
+ /* hor_sampling_factor_m (5 bits) */
+ currVol->horSamp_m = (int) BitstreamReadBits16(stream, 5);
+
+ if (currVol->horSamp_m == 0) return PV_FAIL;
+ if (currVol->horSamp_n != currVol->horSamp_m) return PV_FAIL;
+
+ /* ver_sampling_factor_n (5 bits) */
+ currVol->verSamp_n = (int) BitstreamReadBits16(stream, 5);
+
+ /* ver_sampling_factor_m (5 bits) */
+ currVol->verSamp_m = (int) BitstreamReadBits16(stream, 5);
+
+ if (currVol->verSamp_m == 0) return PV_FAIL;
+ if (currVol->verSamp_n != currVol->verSamp_m) return PV_FAIL;
+
+
+ /* enhancement_type: 1 : partial region, 0 : full region */
+ /* 04/10/2000: we only support full region enhancement layer. */
+ if (BitstreamRead1Bits(stream)) return PV_FAIL;
+ }
+
+ PV_BitstreamByteAlign(stream);
+
+ status = BitstreamShowBits32HC(stream, &tmpvar);
+
+ /* if we hit the end of buffer, tmpvar == 0. 08/30/2000 */
+ if (tmpvar == USER_DATA_START_CODE)
+ {
+ status = DecodeUserData(stream);
+ /* you should not check for status here 03/19/2002 */
+ status = PV_SUCCESS;
+ }
+
+ /* Compute some convenience variables: 04/13/2000 */
+ video->nMBPerRow = video->width / MB_SIZE;
+ video->nMBPerCol = video->height / MB_SIZE;
+ video->nTotalMB = video->nMBPerRow * video->nMBPerCol;
+ video->nBitsForMBID = CalcNumBits((uint)video->nTotalMB - 1);
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ video->modified_quant = 0;
+ video->advanced_INTRA = 0;
+ video->deblocking = 0;
+ video->slice_structure = 0;
+#endif
+ }
+ else
+ {
+ /* SHORT_HEADER */
+ status = BitstreamShowBits32(stream, SHORT_VIDEO_START_MARKER_LENGTH, &tmpvar);
+
+ if (tmpvar == SHORT_VIDEO_START_MARKER)
+ {
+ video->shortVideoHeader = TRUE;
+ }
+ else
+ {
+ do
+ {
+ /* Search for VOL_HEADER */
+ status = PVSearchNextM4VFrame(stream); /* search 0x00 0x00 0x01 */
+ if (status != PV_SUCCESS) return PV_FAIL; /* breaks the loop */
+ BitstreamShowBits32(stream, VOL_START_CODE_LENGTH, &tmpvar);
+ PV_BitstreamFlushBits(stream, 8);
+ }
+ while (tmpvar != VOL_START_CODE);
+ goto decode_vol;
+ }
+ }
+#ifdef PV_TOLERATE_VOL_ERRORS
+ if (profile > 0xFF || profile == 0)
+ {
+ return PV_BAD_VOLHEADER;
+ }
+#endif
+
+ return status;
+}
+
+
+/***********************************************************CommentBegin******
+*
+* -- DecodeGOV -- Decodes the Group of VOPs from bitstream
+*
+* 04/20/2000 initial modification to the new PV-Decoder Lib format.
+*
+***********************************************************CommentEnd********/
+PV_STATUS DecodeGOVHeader(BitstreamDecVideo *stream, uint32 *time_base)
+{
+ uint32 tmpvar, time_s;
+ int closed_gov, broken_link;
+
+ /* group_start_code (32 bits) */
+// tmpvar = BitstreamReadBits32(stream, 32);
+
+ /* hours */
+ tmpvar = (uint32) BitstreamReadBits16(stream, 5);
+ time_s = tmpvar * 3600;
+
+ /* minutes */
+ tmpvar = (uint32) BitstreamReadBits16(stream, 6);
+ time_s += tmpvar * 60;
+
+ /* marker bit */
+ tmpvar = (uint32) BitstreamRead1Bits(stream);
+
+ /* seconds */
+ tmpvar = (uint32) BitstreamReadBits16(stream, 6);
+ time_s += tmpvar;
+
+ /* We have to check the timestamp here. If the sync timestamp is */
+ /* earlier than the previous timestamp or longer than 60 sec. */
+ /* after the previous timestamp, assume the GOV header is */
+ /* corrupted. 05/12/2000 */
+ *time_base = time_s; /* 02/27/2002 */
+// *time_base = *time_base/1000;
+// tmpvar = time_s - *time_base;
+// if (tmpvar <= 60) *time_base = time_s;
+// else return PV_FAIL;
+
+ tmpvar = (uint32) BitstreamRead1Bits(stream);
+ closed_gov = tmpvar;
+ tmpvar = (uint32) BitstreamRead1Bits(stream);
+ broken_link = tmpvar;
+
+ if ((closed_gov == 0) && (broken_link == 1))
+ {
+ return PV_SUCCESS; /* 03/15/2002 you can also return PV_FAIL */
+ }
+
+ PV_BitstreamByteAlign(stream);
+
+ BitstreamShowBits32HC(stream, &tmpvar);
+
+ while (tmpvar == USER_DATA_START_CODE) /* 03/15/2002 */
+ {
+ DecodeUserData(stream);
+ BitstreamShowBits32HC(stream, &tmpvar);
+ }
+
+ return PV_SUCCESS;
+}
+
+/***********************************************************CommentBegin******
+*
+* -- DecodeVopHeader -- Decodes the VOPheader information from the bitstream
+*
+* 04/12/2000 Initial port to the new PV decoder library format.
+* 05/10/2000 Error resilient decoding of vop header.
+*
+***********************************************************CommentEnd********/
+PV_STATUS DecodeVOPHeader(VideoDecData *video, Vop *currVop, Bool use_ext_timestamp)
+{
+ PV_STATUS status = PV_SUCCESS;
+ Vol *currVol = video->vol[video->currLayer];
+ BitstreamDecVideo *stream = currVol->bitstream;
+ uint32 tmpvar;
+ int time_base;
+
+ /*****
+ * Read the VOP header from the bitstream (No shortVideoHeader Mode here!)
+ *****/
+ BitstreamShowBits32HC(stream, &tmpvar);
+
+ /* check if we have a GOV header here. 08/30/2000 */
+ if (tmpvar == GROUP_START_CODE)
+ {
+ tmpvar = BitstreamReadBits32HC(stream);
+// rewindBitstream(stream, START_CODE_LENGTH); /* for backward compatibility */
+ status = DecodeGOVHeader(stream, &tmpvar);
+ if (status != PV_SUCCESS)
+ {
+ return status;
+ }
+// use_ext_timestamp = TRUE; /* 02/08/2002 */
+ /* We should have a VOP header following the GOV header. 03/15/2001 */
+ BitstreamShowBits32HC(stream, &tmpvar);
+ }
+#ifdef PV_SUPPORT_TEMPORAL_SCALABILITY
+ currVop->timeStamp = -1;
+#endif
+ if (tmpvar == VOP_START_CODE)
+ {
+ tmpvar = BitstreamReadBits32HC(stream);
+ }
+ else
+ {
+ PV_BitstreamFlushBits(stream, 8); // advance by a byte
+ status = PV_FAIL;
+ goto return_point;
+ }
+
+
+
+ /* vop_prediction_type (2 bits) */
+ currVop->predictionType = (int) BitstreamReadBits16(stream, 2);
+
+ /* modulo_time_base (? bits) */
+ time_base = -1;
+ do
+ {
+ time_base++;
+ tmpvar = (uint32) BitstreamRead1Bits(stream);
+ }
+ while (tmpvar == 1);
+
+
+
+ if (!use_ext_timestamp)
+ {
+ currVol->moduloTimeBase += 1000 * time_base; /* milliseconds based MTB 11/12/01 */
+ }
+
+ /* marker_bit (1 bit) */
+ if (!BitstreamRead1Bits(stream))
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+
+ /* vop_time_increment (1-15 bits) in Nov_Compliant (1-16 bits) */
+ /* we always assumes fixed vop rate here */
+ currVop->timeInc = BitstreamReadBits16(stream, currVol->nbitsTimeIncRes);
+
+
+ /* marker_bit (1 bit) */
+ if (!BitstreamRead1Bits(stream))
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+
+ /* vop_coded */
+ currVop->vopCoded = (int) BitstreamRead1Bits(stream);
+
+
+ if (currVop->vopCoded == 0)
+ {
+ status = PV_SUCCESS;
+ goto return_point;
+ }
+
+
+ /* read vop_rounding_type */
+ if (currVop->predictionType == P_VOP)
+ {
+ currVop->roundingType = (int) BitstreamRead1Bits(stream);
+ }
+ else
+ {
+ currVop->roundingType = 0;
+ }
+
+ if (currVol->complexity_estDisable == 0)
+ {
+ if (currVol->complexity_estMethod < 2) /* OCT 2002 */
+ {
+ if ((currVol->complexity.text_1 >> 3) & 0x1) /* intra */
+ BitstreamReadBits16(stream, 8);
+ if (currVol->complexity.text_1 & 0x1) /* not_coded */
+ BitstreamReadBits16(stream, 8);
+ if ((currVol->complexity.text_2 >> 3) & 0x1) /* dct_coefs */
+ BitstreamReadBits16(stream, 8);
+ if ((currVol->complexity.text_2 >> 2) & 0x1) /* dct_lines */
+ BitstreamReadBits16(stream, 8);
+ if ((currVol->complexity.text_2 >> 1) & 0x1) /* vlc_symbols */
+ BitstreamReadBits16(stream, 8);
+ if (currVol->complexity.text_2 & 0x1) /* vlc_bits */
+ BitstreamReadBits16(stream, 4);
+
+ if (currVop->predictionType != I_VOP)
+ {
+ if ((currVol->complexity.text_1 >> 2) & 0x1) /* inter */
+ BitstreamReadBits16(stream, 8);
+ if ((currVol->complexity.text_1 >> 1) & 0x1) /* inter_4v */
+ BitstreamReadBits16(stream, 8);
+ if ((currVol->complexity.mc >> 5) & 0x1) /* apm */
+ BitstreamReadBits16(stream, 8);
+ if ((currVol->complexity.mc >> 4) & 0x1) /* npm */
+ BitstreamReadBits16(stream, 8);
+ /* interpolate_mc_q */
+ if ((currVol->complexity.mc >> 2) & 0x1) /* forw_back_mc_q */
+ BitstreamReadBits16(stream, 8);
+ if ((currVol->complexity.mc >> 1) & 0x1) /* halfpel2 */
+ BitstreamReadBits16(stream, 8);
+ if (currVol->complexity.mc & 0x1) /* halfpel4 */
+ BitstreamReadBits16(stream, 8);
+ }
+ if (currVop->predictionType == B_VOP)
+ {
+ if ((currVol->complexity.mc >> 3) & 0x1) /* interpolate_mc_q */
+ BitstreamReadBits16(stream, 8);
+ }
+ }
+ }
+
+ /* read intra_dc_vlc_thr */
+ currVop->intraDCVlcThr = (int) BitstreamReadBits16(stream, 3);
+
+ /* read vop_quant (currVol->quantPrecision bits) */
+ currVop->quantizer = (int16) BitstreamReadBits16(stream, currVol->quantPrecision);
+ if (currVop->quantizer == 0)
+ {
+ currVop->quantizer = video->prevVop->quantizer;
+ status = PV_FAIL;
+ goto return_point;
+ }
+
+
+ /* read vop_fcode_forward */
+ if (currVop->predictionType != I_VOP)
+ {
+ tmpvar = (uint32) BitstreamReadBits16(stream, 3);
+ if (tmpvar < 1)
+ {
+ currVop->fcodeForward = 1;
+ status = PV_FAIL;
+ goto return_point;
+ }
+ currVop->fcodeForward = tmpvar;
+ }
+ else
+ {
+ currVop->fcodeForward = 0;
+ }
+
+ /* read vop_fcode_backward */
+ if (currVop->predictionType == B_VOP)
+ {
+ tmpvar = (uint32) BitstreamReadBits16(stream, 3);
+ if (tmpvar < 1)
+ {
+ currVop->fcodeBackward = 1;
+ status = PV_FAIL;
+ goto return_point;
+ }
+ currVop->fcodeBackward = tmpvar;
+ }
+ else
+ {
+ currVop->fcodeBackward = 0;
+ }
+
+ if (currVol->scalability)
+ {
+ currVop->refSelectCode = (int) BitstreamReadBits16(stream, 2);
+ }
+
+return_point:
+ return status;
+}
+
+
+/***********************************************************CommentBegin******
+*
+* -- VideoPlaneWithShortHeader -- Decodes the short_video_header information from the bitstream
+* Modified :
+ 04/23/2001. Remove the codes related to the
+ "first pass" decoding. We use a different function
+ to set up the decoder now.
+***********************************************************CommentEnd********/
+PV_STATUS DecodeShortHeader(VideoDecData *video, Vop *currVop)
+{
+ PV_STATUS status = PV_SUCCESS;
+ Vol *currVol = video->vol[0];
+ BitstreamDecVideo *stream = currVol->bitstream;
+ uint32 tmpvar;
+ int32 size;
+
+ int extended_PTYPE = FALSE;
+ int UFEP = 0, custom_PFMT = 0, custom_PCF = 0;
+
+ status = BitstreamShowBits32(stream, SHORT_VIDEO_START_MARKER_LENGTH, &tmpvar);
+
+ if (tmpvar != SHORT_VIDEO_START_MARKER)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+
+
+ PV_BitstreamFlushBits(stream, SHORT_VIDEO_START_MARKER_LENGTH);
+
+ /* Temporal reference. Using vop_time_increment_resolution = 30000 */
+ tmpvar = (uint32) BitstreamReadBits16(stream, 8);
+ currVop->temporalRef = (int) tmpvar;
+
+
+ currVop->timeInc = 0xff & (256 + currVop->temporalRef - video->prevVop->temporalRef);
+ currVol->moduloTimeBase += currVop->timeInc; /* mseconds 11/12/01 */
+ /* Marker Bit */
+ if (!BitstreamRead1Bits(stream))
+ {
+ mp4dec_log("DecodeShortHeader(): Market bit wrong.\n");
+ status = PV_FAIL;
+ goto return_point;
+ }
+
+ /* Zero Bit */
+ if (BitstreamRead1Bits(stream))
+ {
+ mp4dec_log("DecodeShortHeader(): Zero bit wrong.\n");
+ status = PV_FAIL;
+ goto return_point;
+ }
+
+ /*split_screen_indicator*/
+ if (BitstreamRead1Bits(stream))
+ {
+ mp4dec_log("DecodeShortHeader(): Split Screen not supported.\n");
+ VideoDecoderErrorDetected(video);
+ }
+
+ /*document_freeze_camera*/
+ if (BitstreamRead1Bits(stream))
+ {
+ mp4dec_log("DecodeShortHeader(): Freeze Camera not supported.\n");
+ VideoDecoderErrorDetected(video);
+ }
+
+ /*freeze_picture_release*/
+ if (BitstreamRead1Bits(stream))
+ {
+ mp4dec_log("DecodeShortHeader(): Freeze Release not supported.\n");
+ VideoDecoderErrorDetected(video);
+ }
+ /* source format */
+ switch (BitstreamReadBits16(stream, 3))
+ {
+ case 1:
+ if (video->size < 128*96)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ video->displayWidth = video->width = 128;
+ video->displayHeight = video->height = 96;
+ break;
+
+ case 2:
+ if (video->size < 176*144)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ video->displayWidth = video->width = 176;
+ video->displayHeight = video->height = 144;
+ break;
+
+ case 3:
+ if (video->size < 352*288)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ video->displayWidth = video->width = 352;
+ video->displayHeight = video->height = 288;
+ break;
+
+ case 4:
+ if (video->size < 704*576)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ video->displayWidth = video->width = 704;
+ video->displayHeight = video->height = 576;
+ break;
+
+ case 5:
+ if (video->size < 1408*1152)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ video->displayWidth = video->width = 1408;
+ video->displayHeight = video->height = 1152;
+ break;
+
+ case 7:
+ extended_PTYPE = TRUE;
+ break;
+
+ default:
+ /* Msg("H.263 source format not legal\n"); */
+ status = PV_FAIL;
+ goto return_point;
+ }
+
+
+ currVop->roundingType = 0;
+
+ if (extended_PTYPE == FALSE)
+ {
+ currVop->predictionType = (int) BitstreamRead1Bits(stream);
+
+ /* four_reserved_zero_bits */
+ if (BitstreamReadBits16(stream, 4))
+ {
+ mp4dec_log("DecodeShortHeader(): Reserved bits wrong.\n");
+ status = PV_FAIL;
+ goto return_point;
+ }
+ }
+ else
+ {
+ UFEP = BitstreamReadBits16(stream, 3);
+ if (UFEP == 1)
+ {
+ /* source format */
+ switch (BitstreamReadBits16(stream, 3))
+ {
+ case 1:
+ if (video->size < 128*96)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ video->displayWidth = video->width = 128;
+ video->displayHeight = video->height = 96;
+ break;
+
+ case 2:
+ if (video->size < 176*144)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ video->displayWidth = video->width = 176;
+ video->displayHeight = video->height = 144;
+ break;
+
+ case 3:
+ if (video->size < 352*288)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ video->displayWidth = video->width = 352;
+ video->displayHeight = video->height = 288;
+ break;
+
+ case 4:
+ if (video->size < 704*576)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ video->displayWidth = video->width = 704;
+ video->displayHeight = video->height = 576;
+ break;
+
+ case 5:
+ if (video->size < 1408*1152)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ video->displayWidth = video->width = 1408;
+ video->displayHeight = video->height = 1152;
+ break;
+
+ case 6:
+ custom_PFMT = TRUE;
+ break;
+
+ default:
+ /* Msg("H.263 source format not legal\n"); */
+ status = PV_FAIL;
+ goto return_point;
+ }
+
+ custom_PCF = BitstreamRead1Bits(stream);
+ /* unrestricted MV */
+ if (BitstreamRead1Bits(stream))
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ /* SAC */
+ if (BitstreamRead1Bits(stream))
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+
+ /* AP */
+ if (BitstreamRead1Bits(stream))
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+
+ video->advanced_INTRA = BitstreamRead1Bits(stream);
+
+ video->deblocking = BitstreamRead1Bits(stream);
+
+ video->slice_structure = BitstreamRead1Bits(stream);
+
+ /* RPS, ISD, AIV */
+ if (BitstreamReadBits16(stream, 3))
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ video->modified_quant = BitstreamRead1Bits(stream);
+
+ /* Marker Bit and reserved*/
+ if (BitstreamReadBits16(stream, 4) != 8)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ }
+#ifndef PV_ANNEX_IJKT_SUPPORT
+ if (video->advanced_INTRA | video->deblocking | video->modified_quant | video->modified_quant)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+#endif
+
+ if (UFEP == 0 || UFEP == 1)
+ {
+ tmpvar = BitstreamReadBits16(stream, 3);
+ if (tmpvar > 1)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ currVop->predictionType = tmpvar;
+ /* RPR */
+ if (BitstreamRead1Bits(stream))
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+
+ /* RRU */
+ if (BitstreamRead1Bits(stream))
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ currVop->roundingType = (int) BitstreamRead1Bits(stream);
+ if (BitstreamReadBits16(stream, 3) != 1)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ }
+ else
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ /* CPM */
+ if (BitstreamRead1Bits(stream))
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ /* CPFMT */
+ if (custom_PFMT == 1 && UFEP == 1)
+ {
+ /* aspect ratio */
+ tmpvar = BitstreamReadBits16(stream, 4);
+ if (tmpvar == 0)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ /* Extended PAR */
+ if (tmpvar == 0xF)
+ {
+ /* Read par_width and par_height but do nothing */
+ /* par_width */
+ tmpvar = BitstreamReadBits16(stream, 8);
+
+ /* par_height */
+ tmpvar = BitstreamReadBits16(stream, 8);
+ }
+ tmpvar = BitstreamReadBits16(stream, 9);
+
+ video->displayWidth = (tmpvar + 1) << 2;
+ video->width = (video->displayWidth + 15) & -16;
+ /* marker bit */
+ if (!BitstreamRead1Bits(stream))
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ tmpvar = BitstreamReadBits16(stream, 9);
+ if (tmpvar == 0)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ video->displayHeight = tmpvar << 2;
+ video->height = (video->displayHeight + 15) & -16;
+
+ if (video->height * video->width > video->size)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+
+ video->nTotalMB = video->width / MB_SIZE * video->height / MB_SIZE;
+
+ if (video->nTotalMB <= 48)
+ {
+ video->nBitsForMBID = 6;
+ }
+ else if (video->nTotalMB <= 99)
+ {
+ video->nBitsForMBID = 7;
+ }
+ else if (video->nTotalMB <= 396)
+ {
+ video->nBitsForMBID = 9;
+ }
+ else if (video->nTotalMB <= 1584)
+ {
+ video->nBitsForMBID = 11;
+ }
+ else if (video->nTotalMB <= 6336)
+ {
+ video->nBitsForMBID = 13 ;
+ }
+ else if (video->nTotalMB <= 9216)
+ {
+ video->nBitsForMBID = 14 ;
+ }
+ else
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ }
+ if (UFEP == 1 && custom_PCF == 1)
+ {
+ BitstreamRead1Bits(stream);
+
+ tmpvar = BitstreamReadBits16(stream, 7);
+ if (tmpvar == 0)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ }
+
+ if (custom_PCF == 1)
+ {
+ currVop->ETR = BitstreamReadBits16(stream, 2);
+ }
+
+ if (UFEP == 1 && video->slice_structure == 1)
+ {
+ /* SSS */
+ tmpvar = BitstreamReadBits16(stream, 2);
+ if (tmpvar != 0)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ }
+ }
+
+ /* Recalculate number of macroblocks per row & col since */
+ /* the frame size can change. 04/23/2001. */
+ video->nMBinGOB = video->nMBPerRow = video->width / MB_SIZE;
+ video->nGOBinVop = video->nMBPerCol = video->height / MB_SIZE;
+ video->nTotalMB = video->nMBPerRow * video->nMBPerCol;
+ if (custom_PFMT == 0 || UFEP == 0)
+ {
+ video->nBitsForMBID = CalcNumBits((uint)video->nTotalMB - 1); /* otherwise calculate above */
+ }
+ size = (int32)video->width * video->height;
+ if (video->currVop->predictionType == P_VOP && size > video->videoDecControls->size)
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+ video->videoDecControls->size = size;
+ video->currVop->uChan = video->currVop->yChan + size;
+ video->currVop->vChan = video->currVop->uChan + (size >> 2);
+ video->prevVop->uChan = video->prevVop->yChan + size;
+ video->prevVop->vChan = video->prevVop->uChan + (size >> 2);
+
+
+ currVop->quantizer = (int16) BitstreamReadBits16(stream, 5);
+
+ if (currVop->quantizer == 0) /* 04/03/01 */
+ {
+ currVop->quantizer = video->prevVop->quantizer;
+ status = PV_FAIL;
+ goto return_point;
+ }
+
+
+ /* Zero bit */
+ if (extended_PTYPE == FALSE)
+ {
+ if (BitstreamRead1Bits(stream))
+ {
+ mp4dec_log("DecodeShortHeader(): Zero bit wrong.\n");
+ status = PV_FAIL;
+ goto return_point;
+ }
+ }
+ /* pei */
+ tmpvar = (uint32) BitstreamRead1Bits(stream);
+
+ while (tmpvar)
+ {
+ tmpvar = (uint32) BitstreamReadBits16(stream, 8); /* "PSPARE" */
+ tmpvar = (uint32) BitstreamRead1Bits(stream); /* "PEI" */
+ }
+
+ if (video->slice_structure) /* ANNEX_K */
+ {
+ if (!BitstreamRead1Bits(stream)) /* SEPB1 */
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+
+ // if (currVol->nBitsForMBID //
+ if (BitstreamReadBits16(stream, video->nBitsForMBID))
+ {
+ status = PV_FAIL; /* no ASO, RS support for Annex K */
+ goto return_point;
+ }
+
+ if (!BitstreamRead1Bits(stream)) /*SEPB3 */
+ {
+ status = PV_FAIL;
+ goto return_point;
+ }
+
+ }
+ /* Setting of other VOP-header parameters */
+ currVop->gobNumber = 0;
+ currVop->vopCoded = 1;
+
+ currVop->intraDCVlcThr = 0;
+ currVop->gobFrameID = 0; /* initial value, 05/22/00 */
+ currVol->errorResDisable = 0;
+ /*PutVopInterlaced(0,curr_vop); no implemented yet */
+ if (currVop->predictionType != I_VOP)
+ currVop->fcodeForward = 1;
+ else
+ currVop->fcodeForward = 0;
+
+return_point:
+
+ return status;
+}
+/***********************************************************CommentBegin******
+*
+* -- PV_DecodeVop -- Decodes the VOP information from the bitstream
+*
+* 04/12/2000
+* Initial port to the new PV decoder library format.
+* This function is different from the one in MoMuSys MPEG-4
+* visual decoder. We handle combined mode with or withput
+* error resilience and H.263 mode through the sam path now.
+*
+* 05/04/2000
+* Added temporal scalability to the decoder.
+*
+***********************************************************CommentEnd********/
+PV_STATUS PV_DecodeVop(VideoDecData *video)
+{
+ Vol *currVol = video->vol[video->currLayer];
+ PV_STATUS status;
+ uint32 tmpvar;
+
+ /*****
+ * Do scalable or non-scalable decoding of the current VOP
+ *****/
+
+ if (!currVol->scalability)
+ {
+ if (currVol->dataPartitioning)
+ {
+ /* Data partitioning mode comes here */
+ status = DecodeFrameDataPartMode(video);
+ }
+ else
+ {
+ /* Combined mode with or without error resilience */
+ /* and short video header comes here. */
+ status = DecodeFrameCombinedMode(video);
+ }
+ }
+ else
+ {
+#ifdef DO_NOT_FOLLOW_STANDARD
+ /* according to the standard, only combined mode is allowed */
+ /* in the enhancement layer. 06/01/2000. */
+ if (currVol->dataPartitioning)
+ {
+ /* Data partitioning mode comes here */
+ status = DecodeFrameDataPartMode(video);
+ }
+ else
+ {
+ /* Combined mode with or without error resilience */
+ /* and short video header comes here. */
+ status = DecodeFrameCombinedMode(video);
+ }
+#else
+ status = DecodeFrameCombinedMode(video);
+#endif
+ }
+
+ /* This part is for consuming Visual_object_sequence_end_code and EOS Code */ /* 10/15/01 */
+ if (!video->shortVideoHeader)
+ {
+ /* at this point bitstream is expected to be byte aligned */
+ BitstreamByteAlignNoForceStuffing(currVol->bitstream);
+
+ status = BitstreamShowBits32HC(currVol->bitstream, &tmpvar); /* 07/07/01 */
+ if (tmpvar == VISUAL_OBJECT_SEQUENCE_END_CODE)/* VOS_END_CODE */
+ {
+ PV_BitstreamFlushBits(currVol->bitstream, 16);
+ PV_BitstreamFlushBits(currVol->bitstream, 16);
+ }
+
+ }
+ else
+ {
+#ifdef PV_ANNEX_IJKT_SUPPORT
+ if (video->deblocking)
+ {
+ H263_Deblock(video->currVop->yChan, video->width, video->height, video->QPMB, video->headerInfo.Mode, 0, 0);
+ H263_Deblock(video->currVop->uChan, video->width >> 1, video->height >> 1, video->QPMB, video->headerInfo.Mode, 1, video->modified_quant);
+ H263_Deblock(video->currVop->vChan, video->width >> 1, video->height >> 1, video->QPMB, video->headerInfo.Mode, 1, video->modified_quant);
+ }
+#endif
+ /* Read EOS code for shortheader bitstreams */
+ status = BitstreamShowBits32(currVol->bitstream, 22, &tmpvar);
+ if (tmpvar == SHORT_VIDEO_END_MARKER)
+ {
+ PV_BitstreamFlushBits(currVol->bitstream, 22);
+ }
+ else
+ {
+ status = PV_BitstreamShowBitsByteAlign(currVol->bitstream, 22, &tmpvar);
+ if (tmpvar == SHORT_VIDEO_END_MARKER)
+ {
+ PV_BitstreamByteAlign(currVol->bitstream);
+ PV_BitstreamFlushBits(currVol->bitstream, 22);
+ }
+ }
+ }
+ return status;
+}
+
+
+/***********************************************************CommentBegin******
+*
+* -- CalcVopDisplayTime -- calculate absolute time when VOP is to be displayed
+*
+* 04/12/2000 Initial port to the new PV decoder library format.
+*
+***********************************************************CommentEnd********/
+uint32 CalcVopDisplayTime(Vol *currVol, Vop *currVop, int shortVideoHeader)
+{
+ uint32 display_time;
+
+
+ /*****
+ * Calculate the time when the VOP is to be displayed next
+ *****/
+
+ if (!shortVideoHeader)
+ {
+ display_time = (uint32)(currVol->moduloTimeBase + (((int32)currVop->timeInc - (int32)currVol->timeInc_offset) * 1000) / ((int32)currVol->timeIncrementResolution)); /* 11/12/2001 */
+ if (currVop->timeStamp >= display_time)
+ {
+ display_time += 1000; /* this case is valid if GOVHeader timestamp is ignored */
+ }
+ }
+ else
+ {
+ display_time = (uint32)(currVol->moduloTimeBase * 33 + (currVol->moduloTimeBase * 11) / 30); /* 11/12/2001 */
+ }
+
+ return(display_time);
+}
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/zigzag.h b/media/libstagefright/codecs/m4v_h263/dec/src/zigzag.h
new file mode 100644
index 0000000..4690a18
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/zigzag.h
@@ -0,0 +1,72 @@
+/* ------------------------------------------------------------------
+ * 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 zigzag_H
+#define zigzag_H
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here.
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL VARIABLES REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ extern const int zigzag_inv[3*NCOEFF_BLOCK];
+ /*----------------------------------------------------------------------------
+ ; SIMPLE TYPEDEF'S
+ ----------------------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------------------
+ ; ENUMERATED TYPEDEF'S
+ ----------------------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------------------
+ ; STRUCTURES TYPEDEF'S
+ ----------------------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------------------
+ ; GLOBAL FUNCTION DEFINITIONS
+ ; Function Prototype declaration
+ ----------------------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------------------
+ ; END
+ ----------------------------------------------------------------------------*/
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/zigzag_tab.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/zigzag_tab.cpp
new file mode 100644
index 0000000..33dbb14
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/zigzag_tab.cpp
@@ -0,0 +1,110 @@
+/* ------------------------------------------------------------------
+ * 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 "mp4dec_api.h"
+#include "mp4def.h"
+#include "zigzag.h"
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here. Include conditional
+; compile variables also.
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL FUNCTION DEFINITIONS
+; Function Prototype declaration
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; LOCAL STORE/BUFFER/POINTER DEFINITIONS
+; Variable declaration - defined here and used outside this module
+----------------------------------------------------------------------------*/
+const int zigzag_inv[3*NCOEFF_BLOCK] =
+{
+ 0, 1, 8, 16, 9, 2, 3, 10,
+ 17, 24, 32, 25, 18, 11, 4, 5,
+ 12, 19, 26, 33, 40, 48, 41, 34,
+ 27, 20, 13, 6, 7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36,
+ 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46,
+ 53, 60, 61, 54, 47, 55, 62, 63,
+//};
+
+ /* Vertical inverse zigzag */
+//const static Int zigzag_v_inv[NCOEFF_BLOCK] = {
+ 0, 8, 16, 24, 1, 9, 2, 10,
+ 17, 25, 32, 40, 48, 56, 57, 49,
+ 41, 33, 26, 18, 3, 11, 4, 12,
+ 19, 27, 34, 42, 50, 58, 35, 43,
+ 51, 59, 20, 28, 5, 13, 6, 14,
+ 21, 29, 36, 44, 52, 60, 37, 45,
+ 53, 61, 22, 30, 7, 15, 23, 31,
+ 38, 46, 54, 62, 39, 47, 55, 63,
+//};
+ /* Horizontal inverse zigzag*/
+//const static Int zizag_h_inv[NCOEFF_BLOCK] = {
+ 0, 1, 2, 3, 8, 9, 16, 17,
+ 10, 11, 4, 5, 6, 7, 15, 14,
+ 13, 12, 19, 18, 24, 25, 32, 33,
+ 26, 27, 20, 21, 22, 23, 28, 29,
+ 30, 31, 34, 35, 40, 41, 48, 49,
+ 42, 43, 36, 37, 38, 39, 44, 45,
+ 46, 47, 50, 51, 56, 57, 58, 59,
+ 52, 53, 54, 55, 60, 61, 62, 63
+};
+
+/*----------------------------------------------------------------------------
+; EXTERNAL FUNCTION REFERENCES
+; Declare functions defined elsewhere and referenced in this module
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; FUNCTION CODE
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; Define all local variables
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; Function body here
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; Return nothing or data or data pointer
+----------------------------------------------------------------------------*/
+
+
diff --git a/media/libstagefright/codecs/m4v_h263/patent_disclaimer.txt b/media/libstagefright/codecs/m4v_h263/patent_disclaimer.txt
new file mode 100644
index 0000000..b4bf11d
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/patent_disclaimer.txt
@@ -0,0 +1,9 @@
+
+THIS IS NOT A GRANT OF PATENT RIGHTS.
+
+Google makes no representation or warranty that the codecs for which
+source code is made available hereunder are unencumbered by
+third-party patents. Those intending to use this source code in
+hardware or software products are advised that implementations of
+these codecs, including in open source software or shareware, may
+require patent licenses from the relevant patent holders.