diff options
author | James Dong <jdong@google.com> | 2009-12-15 16:26:55 -0800 |
---|---|---|
committer | James Dong <jdong@google.com> | 2009-12-17 12:53:03 -0800 |
commit | 3306cfee3bf38ab207a0504e49c2d492bb73ffbf (patch) | |
tree | b68a76349710c58af816476c3cb8dcfda4f7bc49 /media/libstagefright | |
parent | 134ee6a324c35f39e3576172e4eae4c6de6eb9dc (diff) | |
download | frameworks_av-3306cfee3bf38ab207a0504e49c2d492bb73ffbf.zip frameworks_av-3306cfee3bf38ab207a0504e49c2d492bb73ffbf.tar.gz frameworks_av-3306cfee3bf38ab207a0504e49c2d492bb73ffbf.tar.bz2 |
Initial checkins of the mpeg4 and h263 software decoders based on PV
Diffstat (limited to 'media/libstagefright')
55 files changed, 21759 insertions, 0 deletions
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk index fb75aef..f7df69c 100644 --- a/media/libstagefright/Android.mk +++ b/media/libstagefright/Android.mk @@ -59,6 +59,7 @@ LOCAL_STATIC_LIBRARIES := \ libstagefright_amrnbenc \ libstagefright_amrwbdec \ libstagefright_avcdec \ + libstagefright_m4vh263dec \ libstagefright_mp3dec LOCAL_SHARED_LIBRARIES += \ diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 47bbda3..8d728ce 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -24,6 +24,7 @@ #include "include/AMRNBEncoder.h" #include "include/AMRWBDecoder.h" #include "include/AVCDecoder.h" +#include "include/M4vH263Decoder.h" #include "include/MP3Decoder.h" #endif @@ -70,6 +71,7 @@ FACTORY_CREATE(AMRNBDecoder) FACTORY_CREATE(AMRWBDecoder) FACTORY_CREATE(AACDecoder) FACTORY_CREATE(AVCDecoder) +FACTORY_CREATE(M4vH263Decoder) FACTORY_CREATE(AMRNBEncoder) static sp<MediaSource> InstantiateSoftwareCodec( @@ -85,6 +87,7 @@ static sp<MediaSource> InstantiateSoftwareCodec( FACTORY_REF(AMRWBDecoder) FACTORY_REF(AACDecoder) FACTORY_REF(AVCDecoder) + FACTORY_REF(M4vH263Decoder) FACTORY_REF(AMRNBEncoder) }; for (size_t i = 0; @@ -120,9 +123,11 @@ static const CodecInfo kDecoderInfo[] = { { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacdec" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" }, + OPTIONAL(MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH264Decoder") { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4dec" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.Decoder" }, + OPTIONAL(MEDIA_MIMETYPE_VIDEO_H263, "M4vH264Decoder") { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263dec" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" }, diff --git a/media/libstagefright/codecs/m4v_h263/Android.mk b/media/libstagefright/codecs/m4v_h263/Android.mk new file mode 100644 index 0000000..2e43120 --- /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..fbc7be1 --- /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. diff --git a/media/libstagefright/include/M4vH263Decoder.h b/media/libstagefright/include/M4vH263Decoder.h new file mode 100644 index 0000000..d4e4e3a --- /dev/null +++ b/media/libstagefright/include/M4vH263Decoder.h @@ -0,0 +1,67 @@ +/* + * 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. + */ + +#ifndef M4V_H263_DECODER_H_ + +#define M4V_H263_DECODER_H_ + +#include <media/stagefright/MediaBuffer.h> +#include <media/stagefright/MediaSource.h> + +struct tagvideoDecControls; + +namespace android { + +struct M4vH263Decoder : public MediaSource, + public MediaBufferObserver { + M4vH263Decoder(const sp<MediaSource> &source); + + virtual status_t start(MetaData *params); + virtual status_t stop(); + + virtual sp<MetaData> getFormat(); + + virtual status_t read( + MediaBuffer **buffer, const ReadOptions *options); + + virtual void signalBufferReturned(MediaBuffer *buffer); + +protected: + virtual ~M4vH263Decoder(); + +private: + sp<MediaSource> mSource; + bool mStarted; + bool mInitialized; + int32_t mWidth, mHeight; + + sp<MetaData> mFormat; + + tagvideoDecControls *mHandle; + MediaBuffer *mFrames[2]; + MediaBuffer *mInputBuffer; + + int64_t mNumSamplesOutput; + + void releaseFrames(); + + M4vH263Decoder(const M4vH263Decoder &); + M4vH263Decoder &operator=(const M4vH263Decoder &); +}; + +} // namespace android + +#endif // M4V_H263_DECODER_H_ |